Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/migrations/195-cerebras-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* (https://api.cerebras.ai/v1) authenticated with a plain API key, so the
* toolkit's generic `executeApiRun` drives it with no runner changes — the
* provider is pure configuration. `api.cerebras.ai` is allowlisted in
* aiToolkit/internal/endpointGuard.js so the key may be attached outbound.
* aiToolkit/endpointGuard.js so the key may be attached outbound.
*
* `setup-data.js` merges *missing* provider entries from data.reference, but
* only when an install re-runs setup. This migration delivers the provider on a
Expand Down
2 changes: 1 addition & 1 deletion server/lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ The barrel `server/lib/index.js` is a machine-checkable enumeration of every pub

| Module | Purpose |
|---|---|
| `aiToolkit/` | Vendored toolkit (providers + runner + prompts + status). See `aiToolkit/index.js`. `aiToolkit/endpointGuard.js` — a peer of `aiToolkit/errorDetection.js`, not under `internal/` — publicly exports `evaluateSecretEndpoint`/`assertSecretEndpoint`, the SSRF/key-exfiltration guard for provider `endpoint` URLs; PortOS's own `server/services/*` should import both directly from there (also re-exported through `aiToolkit/index.js` for barrel completeness, but that pulls the toolkit's much larger route/provider/runner graph — not worth it for just this guard). |
| `aiToolkit/` | Vendored toolkit (providers + runner + prompts + status). See `aiToolkit/index.js`. `aiToolkit/endpointGuard.js` is the public SSRF / key-exfiltration guard for provider `endpoint` URLs (`evaluateSecretEndpoint` / `assertSecretEndpoint`) — import it from there, not from `internal/`. |
| `aiToolkitState.js` | Module-level singleton for the toolkit instance shared by the `providers`/`runner`/`promptService` shims — `setAIToolkitInstance` / `requireToolkit` (throws `AI_TOOLKIT_NOT_INITIALIZED`) / `getAIToolkitInstance` (no-throw for cleanup paths). |
| `antigravity.js` | Antigravity (`agy`) CLI provider helpers — id/sentinel constants (`ANTIGRAVITY_CLI_ID`, `ANTIGRAVITY_CONFIGURED_DEFAULT`, `LEGACY_GEMINI_*`), `isAntigravityCommand`/`isAntigravityCliProvider` predicates, and `ensureAntigravityPrintArgs(args, {model, effort})`/`ensureAntigravityTuiArgs(args, {model, effort})`/`stripAntigravityUnsupportedArgs` argv normalizers. `parseAntigravityModelList(stdout)` parses `agy models` rows — accepts both the modern `<id>\t<Label>` shape and the older bare-id-per-line one, deduped, sentinel dropped (mirrored in the vendored toolkit's `internal/antigravity.js`; used by both the provider-catalog refresh and Image Gen's agy model picker). `isAntigravityModelId(id)` is the same id shape as a bare predicate, for spawn sites building an `agy --model` argv from a value no route schema bounded. The strip drops legacy Gemini `--yolo`/`-m`/`--output-format` but PRESERVES the long `--model` (agy accepts it as a per-session flag, so a user-baked pin is a real selection and suppresses the injected one); the two builders inject `--model`/`--effort` from the per-run overrides, always ahead of the trailing `--print` marker whose value is the prompt. |
| `llmText.js` | Pure LLM-output text helpers — `stripCodeFences` (unfence a model reply) and `parseLLMJSON` (unfence then JSON.parse with a descriptive throw). Below the provider layer, so lib can clean model output without importing provider orchestration. |
Expand Down
14 changes: 14 additions & 0 deletions server/lib/aiToolkit/endpointGuard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,17 @@ describe('endpointGuard — assertSecretEndpoint', () => {
expect(() => assertSecretEndpoint('http://169.254.169.254/', { hasSecret: true, allowCustomEndpoint: true })).toThrow();
});
});

// The guard's public path is this module; `index.js` also re-exports it via
// `export *` so the barrel advertises the surface. That line is otherwise only
// exercised at server boot (bootstrap.js is the sole barrel importer), so a
// rename here would fail a live start rather than a test. Load the barrel
// lazily — a static import would pull the toolkit's route/provider/runner graph
// into every case in this file.
describe('endpointGuard — public barrel re-export', () => {
it('resolves both functions through aiToolkit/index.js, same identities', async () => {
const barrel = await import('./index.js');
expect(barrel.evaluateSecretEndpoint).toBe(evaluateSecretEndpoint);
expect(barrel.assertSecretEndpoint).toBe(assertSecretEndpoint);
});
});