Implement extensions/vision/src/config.ts (env resolution + defaults) #254
Labels
No labels
bug
chore
documentation
enhancement
feature
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
david/pi-extensions-and-skills#254
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Create
extensions/vision/src/config.ts: load the project.envwithout touchingprocess.env, merge it with the real environment, and resolve thevisionextension's configuration — returningnullwhenDEEPSEEK_API_KEYis absent so the extension can register zero tools.Background
Depends on: #253
The
visionextension is unconfigured-safe: with noDEEPSEEK_API_KEYit must register no tool and boot pi cleanly (the same shapeextensions/mongodbandextensions/postgresuse for an unsetMONGODB_URI). When keyed, it needs a resolved config object that every later module consumes — the HTTP client readsapiKey/baseUrl/timeoutMs/model, the tool readsmaxTokens/defaultThinking.The
.envhandling deliberately mirrorsextensions/mongodb/src/env.ts:dotenv.parseon the file contents (neverdotenv.config, which would mutateprocess.env), with the realprocess.envwinning on conflicts.Invalid numeric settings must fail loudly at load time with a
ToolError(configcategory) rather than silently falling back to a default — a typo inVISION_MAX_TOKENSshould be visible immediately.Documentation Required
A separate process downloads these into the listed folders before this issue is implemented. Check the folder for the actual reference material before starting.
docs/reference/dotenv/dotenv.parse()behaviour (returns a record, does not mutateprocess.env), which is the whole point of using it overdotenv.config.parsesignature for typing.docs/reference/nodejs/process.envsemantics (values arestring | undefined).docs/reference/deepseek-api/deepseek-flashandhttps://api.deepseek.comas the model/base URL defaults.Implementation Details
Create
extensions/vision/src/config.tswith this public surface:loadEnvFilecopiesextensions/mongodb/src/env.ts'sloadEnvFile(fs read ofpath.join(process.cwd(), ".env"),dotenv.parse, return{}on any error). The factory calls it and merges as{ ...loadEnvFile(), ...process.env }soprocess.envwins.Variables and defaults (all optional except the key):
DEEPSEEK_API_KEYnullVISION_MODELdeepseek-flashVISION_BASE_URLhttps://api.deepseek.com${base}/chat/completionsVISION_MAX_TOKENS8000VISION_TIMEOUT120000VISION_THINKINGfalsetrue/false/1/0Details:
https://api.deepseek.com///⇒https://api.deepseek.com.VISION_MAX_TOKENS/VISION_TIMEOUT, or aVISION_THINKINGvalue outside the four accepted forms, throwsnew ToolError(..., "config")with a message naming the variable and the bad value (e.g.`VISION_MAX_TOKENS must be a number, got "abc"`). Numeric values must also be > 0.process.env.ToolErrorfrom./errors.Test file
extensions/vision/src/config.test.ts(TDD, no filesystem or network needed except where a temp.envis written):DEEPSEEK_API_KEYis set;process.envvalue beats.envvalue (merged-object precedence);null;VISION_MAX_TOKENS, invalidVISION_TIMEOUT, non-positive numbers, and badVISION_THINKING⇒ToolErrorwithcategory === "config";true/false/1/0.Acceptance Criteria
resolveConfigreturnsnullwhenDEEPSEEK_API_KEYis missing or empty, and a fully-populatedVisionConfigotherwise.VISION_BASE_URLtrailing slashes are stripped.VISION_THINKINGaccepts exactlytrue/false/1/0and defaults tofalse.ToolErrorwithcategory === "config", and the message names the offending variable.loadEnvFile()parses.envviadotenv.parseand never mutatesprocess.env.extensions/vision/src/config.test.tscovers every row above andnode --test extensions/vision/src/config.test.tspasses.Test Plan
Expected: all tests pass with no network access; the only filesystem access is a temp
.envfixture.Manual unconfigured check (no
.env, no key):Expected:
null.pi-loop opened and merged a pull request for this issue: #268