@arnilo/prism 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -1
- package/README.md +42 -62
- package/dist/agent-run-lifecycle.js +4 -0
- package/dist/agent-run-state.d.ts +5 -2
- package/dist/agent-run-state.js +18 -8
- package/dist/agent-session/session/assemble.d.ts +6 -0
- package/dist/agent-session/session/assemble.js +391 -0
- package/dist/agent-session/session/persist.d.ts +28 -0
- package/dist/agent-session/session/persist.js +166 -0
- package/dist/agent-session/session/provider-round.d.ts +6 -0
- package/dist/agent-session/session/provider-round.js +231 -0
- package/dist/agent-session/session/tool-round.d.ts +31 -0
- package/dist/agent-session/session/tool-round.js +473 -0
- package/dist/agent-session/session/types.d.ts +115 -0
- package/dist/agent-session/session/types.js +5 -0
- package/dist/agent-session/session.d.ts +54 -41
- package/dist/agent-session/session.js +23 -1132
- package/dist/capture.d.ts +63 -0
- package/dist/capture.js +67 -0
- package/dist/cli-dev.d.ts +29 -0
- package/dist/cli-dev.js +52 -0
- package/dist/cli-init.d.ts +34 -3
- package/dist/cli-init.js +192 -24
- package/dist/cli-runner.d.ts +6 -2
- package/dist/cli-runner.js +57 -10
- package/dist/content.d.ts +3 -3
- package/dist/content.js +3 -1
- package/dist/contracts-core/agent.d.ts +8 -0
- package/dist/contracts-core/batch.d.ts +97 -0
- package/dist/contracts-core/batch.js +65 -0
- package/dist/contracts-core/content.d.ts +72 -1
- package/dist/contracts-core/embeddings.d.ts +30 -0
- package/dist/contracts-core/embeddings.js +17 -0
- package/dist/contracts-core/images.d.ts +60 -0
- package/dist/contracts-core/images.js +17 -0
- package/dist/contracts-core/moderation.d.ts +46 -0
- package/dist/contracts-core/moderation.js +34 -0
- package/dist/contracts-core/speech.d.ts +39 -0
- package/dist/contracts-core/speech.js +17 -0
- package/dist/contracts-core/transcription.d.ts +48 -0
- package/dist/contracts-core/transcription.js +17 -0
- package/dist/contracts-core/video.d.ts +61 -0
- package/dist/contracts-core/video.js +17 -0
- package/dist/contracts-core.d.ts +7 -0
- package/dist/contracts-core.js +7 -0
- package/dist/contracts-protocol.d.ts +18 -0
- package/dist/contracts-run-state.d.ts +1 -2
- package/dist/index.d.ts +7 -3
- package/dist/index.js +5 -3
- package/dist/input.d.ts +8 -0
- package/dist/input.js +4 -0
- package/dist/node/agent-definitions.d.ts +1 -8
- package/dist/node/agent-definitions.js +0 -34
- package/dist/node/settings.d.ts +0 -1
- package/dist/node/settings.js +0 -5
- package/dist/pinned-fetch.js +29 -3
- package/dist/provider-events.js +3 -4
- package/dist/providers/media.d.ts +1 -2
- package/dist/providers/media.js +1 -4
- package/dist/rpc.d.ts +1 -1
- package/dist/rpc.js +4 -4
- package/dist/testing/persistence-schema.d.ts +1 -1
- package/dist/testing/persistence-schema.js +32 -28
- package/dist/testing/provider-conformance.d.ts +114 -5
- package/dist/testing/provider-conformance.js +342 -0
- package/dist/testing/tool-conformance.d.ts +25 -0
- package/dist/testing/tool-conformance.js +128 -1
- package/dist/testing/tool-effect-store-conformance.d.ts +0 -1
- package/dist/testing/tool-effect-store-conformance.js +0 -3
- package/dist/thinking.d.ts +48 -9
- package/dist/thinking.js +134 -8
- package/dist/tool-search.d.ts +76 -0
- package/dist/tool-search.js +199 -0
- package/docs/0.1.0-readiness.md +3 -3
- package/docs/a2a.md +2 -2
- package/docs/acp-agent.md +1 -1
- package/docs/acp.md +3 -3
- package/docs/ag-ui-adoption.md +1 -1
- package/docs/ag-ui.md +1 -2
- package/docs/agent-definitions.md +1 -1
- package/docs/agent-events.md +5 -5
- package/docs/agent-identity.md +13 -2
- package/docs/audit-export.md +3 -3
- package/docs/batch-jobs.md +120 -0
- package/docs/browser-automation.md +5 -5
- package/docs/caveman.md +2 -2
- package/docs/cli-rpc.md +43 -9
- package/docs/coding-agent-tools.md +19 -19
- package/docs/coding-review-and-diagnostics.md +2 -2
- package/docs/coding-security.md +5 -5
- package/docs/coding-tools.md +82 -0
- package/docs/coding-workspaces.md +2 -2
- package/docs/compaction-and-retry.md +2 -2
- package/docs/compaction-llm.md +4 -4
- package/docs/compaction-observational-memory.md +3 -3
- package/docs/computer-use-linux.md +13 -2
- package/docs/context-and-skills.md +3 -1
- package/docs/conversations.md +4 -4
- package/docs/core.md +85 -0
- package/docs/credential-storage.md +12 -8
- package/docs/credentials-and-redaction.md +1 -1
- package/docs/data-classification.md +1 -1
- package/docs/database-persistence.md +7 -3
- package/docs/dev-inspector.md +103 -0
- package/docs/device-adapters.md +2 -2
- package/docs/diagrams.md +247 -0
- package/docs/document-reader.md +6 -6
- package/docs/documents.md +214 -0
- package/docs/embeddings.md +112 -0
- package/docs/enterprise-postgres-state.md +7 -7
- package/docs/evaluations.md +41 -7
- package/docs/extensions.md +3 -3
- package/docs/forge-integration.md +3 -3
- package/docs/graft.md +5 -5
- package/docs/guardrails.md +2 -2
- package/docs/host-security.md +16 -15
- package/docs/image-generation.md +129 -0
- package/docs/impeccable.md +7 -5
- package/docs/index.md +84 -46
- package/docs/indexed-code-search.md +2 -2
- package/docs/language-intelligence.md +4 -4
- package/docs/live-testing.md +126 -0
- package/docs/mcp-tools.md +44 -13
- package/docs/middleware-hooks.md +1 -1
- package/docs/migrate-to-0.4.md +312 -0
- package/docs/migrate-to-0.5.md +122 -0
- package/docs/migration.md +51 -1
- package/docs/model-registry.md +38 -0
- package/docs/model-routing.md +6 -6
- package/docs/moderation.md +117 -0
- package/docs/multi-agent-patterns.md +177 -0
- package/docs/multimodal-content.md +27 -3
- package/docs/obscura.md +12 -12
- package/docs/observability.md +32 -7
- package/docs/openapi-tools.md +14 -4
- package/docs/operations.md +11 -0
- package/docs/performance.md +30 -10
- package/docs/persistence-credentials-multimodality-primitives.md +7 -7
- package/docs/policy-and-audit.md +18 -8
- package/docs/ponytail.md +3 -3
- package/docs/postgres-persistence.md +5 -5
- package/docs/process-sessions.md +2 -2
- package/docs/prompt-registry.md +106 -0
- package/docs/provider-caching.md +36 -32
- package/docs/provider-conformance.md +24 -2
- package/docs/provider-packages.md +58 -22
- package/docs/provider-primitives.md +5 -5
- package/docs/provider-request-policies.md +1 -1
- package/docs/providers/ai-sdk.md +18 -6
- package/docs/providers/alibaba.md +10 -6
- package/docs/providers/anthropic.md +10 -6
- package/docs/providers/azure.md +20 -4
- package/docs/providers/bedrock.md +18 -3
- package/docs/providers/clinepass.md +7 -3
- package/docs/providers/commandcode.md +253 -0
- package/docs/providers/deepseek.md +7 -3
- package/docs/providers/google.md +8 -4
- package/docs/providers/hyper.md +284 -0
- package/docs/providers/kimi.md +7 -3
- package/docs/providers/neuralwatt.md +12 -8
- package/docs/providers/ollama.md +18 -3
- package/docs/providers/openai-compatible.md +5 -1
- package/docs/providers/openai.md +9 -5
- package/docs/providers/opencode-go.md +8 -4
- package/docs/providers/openrouter.md +8 -4
- package/docs/providers/vertex.md +21 -5
- package/docs/providers/xai.md +7 -3
- package/docs/providers/zai.md +7 -3
- package/docs/rag.md +31 -9
- package/docs/release-and-install.md +181 -76
- package/docs/resource-loading.md +1 -1
- package/docs/runs-and-usage.md +28 -3
- package/docs/server.md +94 -5
- package/docs/settings-auth-trust-security.md +7 -5
- package/docs/sheets.md +229 -0
- package/docs/speech.md +126 -0
- package/docs/sqlite-persistence.md +4 -4
- package/docs/supervisors.md +4 -3
- package/docs/thinking-and-reasoning.md +93 -60
- package/docs/tool-conformance.md +28 -3
- package/docs/tool-execution-primitives.md +8 -8
- package/docs/tools.md +32 -5
- package/docs/web-tools.md +3 -3
- package/docs/wiki.md +7 -7
- package/docs/work-artifacts-and-review.md +17 -6
- package/docs/work-connectors.md +4 -4
- package/docs/work-tools.md +5 -5
- package/docs/workflow-orchestration-primitives.md +35 -11
- package/docs/workflows.md +74 -13
- package/docs/working-and-semantic-memory.md +53 -5
- package/package.json +14 -31
- package/templates/README.md +23 -0
- package/templates/deep-research/README.md.tmpl +47 -0
- package/templates/deep-research/env.example.tmpl +12 -0
- package/templates/deep-research/gitignore.tmpl +7 -0
- package/templates/deep-research/manifest.json +12 -0
- package/templates/deep-research/package.json.tmpl +23 -0
- package/templates/deep-research/src/agent.ts.tmpl +81 -0
- package/templates/deep-research/src/index.ts.tmpl +53 -0
- package/templates/deep-research/src/tests/research.test.ts.tmpl +114 -0
- package/templates/deep-research/src/tools.ts.tmpl +86 -0
- package/templates/deep-research/src/types.ts.tmpl +45 -0
- package/templates/deep-research/src/workflow.ts.tmpl +156 -0
- package/templates/deep-research/tsconfig.json.tmpl +15 -0
- package/templates/init/manifest.json +5 -0
- package/templates/init/package.json.tmpl +2 -1
- package/templates/init/providers.json +40 -24
- package/docs/antigravity-agent.md +0 -207
package/docs/process-sessions.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
`createProcessSessions` is an optional host-activated registry in `@arnilo/prism-coding-agent` for **long-running** child processes: start, cursor-paged output, input, wait, signal/kill, and release (detach). Sessions have bounded lifetime (sweep on registry access — no import-time timers), ownership/identity attribution, durable metadata (command fingerprint without env/secrets), and typed `CodingProcessEvent`s via a host callback. Reuses `ExecutionPolicy`, `killProcessTree`, and `OutputAccumulator` (including spill + `readRaw` cursor paging). Optional duck-typed `sandbox` backend uses `startProcess` when present; one-shot adapters fail closed. Nothing spawns on import or construction.
|
|
5
|
+
`createProcessSessions` is an optional host-activated registry in `@arnilo/prism-coding-tools/agent` for **long-running** child processes: start, cursor-paged output, input, wait, signal/kill, and release (detach). Sessions have bounded lifetime (sweep on registry access — no import-time timers), ownership/identity attribution, durable metadata (command fingerprint without env/secrets), and typed `CodingProcessEvent`s via a host callback. Reuses `ExecutionPolicy`, `killProcessTree`, and `OutputAccumulator` (including spill + `readRaw` cursor paging). Optional duck-typed `sandbox` backend uses `startProcess` when present; one-shot adapters fail closed. Nothing spawns on import or construction.
|
|
6
6
|
|
|
7
7
|
| Export | Purpose |
|
|
8
8
|
| --- | --- |
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
Use when a host needs attachable long-running processes (watch modes, language servers, interactive CLIs) that one-shot `shell` cannot model. Do not use as a job-control language. `pty: true` (host-selected PTY) requires a `ptyBackend` passed to `createProcessSessions`; without one it fails closed before spawn with `ERR_PRISM_PROCESS_PTY_UNSUPPORTED`. Pass a sandbox with `startProcess` for contained long-running work; omit `sandbox` for native spawn.
|
|
21
21
|
|
|
22
22
|
```ts
|
|
23
|
-
import { createProcessSessions } from "@arnilo/prism-coding-agent";
|
|
23
|
+
import { createProcessSessions } from "@arnilo/prism-coding-tools/agent";
|
|
24
24
|
|
|
25
25
|
const sessions = createProcessSessions({ cwd: workspaceRoot, policy, sandbox, onEvent });
|
|
26
26
|
const p = await sessions.start({ command: "npm", args: ["test", "--", "--watch"] });
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Versioned prompt registry
|
|
2
|
+
|
|
3
|
+
## What it does
|
|
4
|
+
|
|
5
|
+
The optional `@arnilo/prism-core/governance/prompts` package stores prompt assets as immutable, content-hashed versions. It provides a memory store plus SQLite and PostgreSQL adapters. The registry returns prompt data; it does not compose system-prompt layers, evaluate prompt quality, discover files, or activate text.
|
|
6
|
+
|
|
7
|
+
## Inputs / request
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { createMemoryPromptStore } from "@arnilo/prism-core/governance/prompts";
|
|
11
|
+
|
|
12
|
+
const store = createMemoryPromptStore();
|
|
13
|
+
const version = await store.put({
|
|
14
|
+
tenantId: "tenant-1",
|
|
15
|
+
name: "support-agent",
|
|
16
|
+
body: "Answer support questions briefly.",
|
|
17
|
+
labels: ["production"],
|
|
18
|
+
metadata: { owner: "support" },
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`put` always appends the next version for one ownership/name scope. It computes `hash` as `sha256:<64 lowercase hex>` over exact UTF-8 body bytes. Records, labels, and JSON metadata are frozen before return.
|
|
23
|
+
|
|
24
|
+
Ownership fields (`tenantId`, optional `accountId` and `userId`) are direct fields on every operation. Omitted ownership is a separate local scope, never a wildcard over tenant-owned rows.
|
|
25
|
+
|
|
26
|
+
## Outputs / response / events
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const latest = await store.resolve({ tenantId: "tenant-1", name: "support-agent" });
|
|
30
|
+
const production = await store.resolve({ tenantId: "tenant-1", name: "support-agent", label: "production" });
|
|
31
|
+
const exact = await store.resolve({ tenantId: "tenant-1", name: "support-agent", version: 1 });
|
|
32
|
+
|
|
33
|
+
for (let page = await store.list({ tenantId: "tenant-1", name: "support-agent", limit: 50 });; ) {
|
|
34
|
+
consume(page.items);
|
|
35
|
+
if (!page.nextCursor) break;
|
|
36
|
+
page = await store.list({ tenantId: "tenant-1", name: "support-agent", cursor: page.nextCursor, limit: 50 });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const diff = await store.diff({ tenantId: "tenant-1", name: "support-agent", fromVersion: 1, toVersion: 2 });
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`resolve` returns the latest version by default, or the latest version carrying `label`; exact `version` can be combined with a label. `list` uses bounded keyset cursors ordered by name/version. `diff` returns bounded `context`/`add`/`remove` lines plus `added`, `removed`, and `truncated` counts. The host decides how a resolved body enters the existing `composeSystemPrompt` layers.
|
|
43
|
+
|
|
44
|
+
## Run provenance
|
|
45
|
+
|
|
46
|
+
Pass the resolved version's identity to a run so every ledger record answers "which prompt version produced this output":
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const resolved = await store.resolve({ tenantId, name: "support-agent" });
|
|
50
|
+
await session.run(input, {
|
|
51
|
+
promptVersion: { name: resolved.name, version: resolved.version, hash: resolved.hash },
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The ref is opaque identity — name, version number, and the store's SHA-256 body hash — never prompt content. It rides on the start/finish `RunRecord`s, round-trips through first-party SQLite/PostgreSQL run rows (`prompt_version` column, schema migration `009_run_prompt_version`), and stays subject to the existing ledger redaction and field-policy boundaries. See [Runs and usage](runs-and-usage.md#prompt-provenance).
|
|
56
|
+
|
|
57
|
+
## Durable adapters
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { createSqlitePromptStore } from "@arnilo/prism-core/governance/prompts";
|
|
61
|
+
const sqlite = createSqlitePromptStore({ filename: "./prompts.db" });
|
|
62
|
+
|
|
63
|
+
import { createPostgresPromptStore } from "@arnilo/prism-core/governance/prompts";
|
|
64
|
+
const postgres = await createPostgresPromptStore({
|
|
65
|
+
connectionString: process.env.DATABASE_URL,
|
|
66
|
+
schema: "prism",
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
SQLite uses `better-sqlite3`; PostgreSQL uses a caller-supplied or adapter-owned `pg` pool. Both adapters use the package-owned `prism_prompts` and `prism_prompt_labels` tables, exact ownership predicates, bound values, and an indexed label lookup. Startup applies checked `001_init` migration history and refuses checksum drift. SQLite exposes `applySqlitePromptMigrations` for managed setup tests; PostgreSQL migration setup is guarded by `pg_advisory_xact_lock`.
|
|
71
|
+
|
|
72
|
+
## Eval-gated promotion
|
|
73
|
+
|
|
74
|
+
`assertPromptPromotion` composes [evaluations](evaluations.md) with the store to answer one question — should this candidate version replace the baseline? It resolves both versions (read-only), runs them head-to-head over a dataset through `runComparison`, and returns a typed verdict. It never promotes anything, writes nothing, and never touches a live agent:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { assertPromptPromotion } from "@arnilo/prism-core/governance/prompts";
|
|
78
|
+
|
|
79
|
+
const v = await assertPromptPromotion({
|
|
80
|
+
store,
|
|
81
|
+
name: "support-agent",
|
|
82
|
+
candidate: { label: "candidate" }, // or an exact version
|
|
83
|
+
baseline: { label: "production" }, // must resolve to a different version
|
|
84
|
+
dataset,
|
|
85
|
+
scorers,
|
|
86
|
+
run: (prompt) => hostRunnerFactory(prompt.body), // host bridge: body → candidate
|
|
87
|
+
minimumWinRate: 0.8, // optional; default gate is a strict win majority
|
|
88
|
+
thresholds: { maximumFailures: 0 }, // optional; forwarded to assertEvaluationThreshold
|
|
89
|
+
});
|
|
90
|
+
if (v.verdict === "promote") await store.put({ ...hostInput, body: v.candidate.body, labels: ["production"] });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The verdict carries `promote`/`hold`, per-scorer `wins/losses/ties/failures`, `winRate`, the raw `ComparisonReport`, a redacted bounded `reportJson` (`serializeEvaluationReport`), and `reasons` on hold. The default gate holds unless the candidate wins strictly more scored comparisons than the baseline; `minimumWinRate` and `thresholds` add stricter gates, and threshold equality passes. Requires the optional peer `@arnilo/prism-core/governance/evals` (install it or the helper fails closed with `ERR_PRISM_PROMPT_EVALS_PEER`). Promotion itself stays a host decision: applying the verdict means `put`-ing a new version with labels — the helper never does.
|
|
94
|
+
|
|
95
|
+
## Limits and security
|
|
96
|
+
|
|
97
|
+
Names, bodies, labels, metadata, cursors, pages, and diffs have finite defaults and hard caps. Prompt bodies are data: no evaluation, template execution, file discovery, or implicit layer injection occurs. Store body hashes are integrity checks; a durable row whose hash no longer matches its body fails closed. Never put credentials or provider clients in prompt metadata.
|
|
98
|
+
|
|
99
|
+
Threat model: the registry is **host-trusted data**. Anyone who can write versions into the store is inside the trust boundary — `put`, label management, and `assertPromptPromotion` verdicts are host operations, never agent-reachable surfaces. Untrusted prompt-injection defense stays at Prism's existing untrusted-content boundaries (tool results, attachments, and provider output), which the store neither bypasses nor weakens: a resolved body enters the system-prompt layer exactly like a host-authored constant. The optional `@arnilo/prism-core/governance/evals` peer is only loaded by `assertPromptPromotion` and never makes the store itself depend on evaluation infrastructure.
|
|
100
|
+
|
|
101
|
+
## Related APIs
|
|
102
|
+
|
|
103
|
+
- [System prompts](system-prompts.md): existing explicit layering and file adapters.
|
|
104
|
+
- [Input and prompt assembly](input-and-prompt-assembly.md): host-controlled message/context assembly.
|
|
105
|
+
- [Evaluations](evaluations.md): bounded evaluation primitives; `assertPromptPromotion` composes `runComparison` + `assertEvaluationThreshold`.
|
|
106
|
+
- [Database persistence](database-persistence.md): persistence and ownership conventions.
|
package/docs/provider-caching.md
CHANGED
|
@@ -147,46 +147,50 @@ Provider request policies can set `ProviderRequestOptions.cache` or the legacy `
|
|
|
147
147
|
|
|
148
148
|
| Provider package | Cache kind | Explicit cache hints | Multi-turn reuse notes | Caveats |
|
|
149
149
|
| --- | --- | --- | --- | --- |
|
|
150
|
-
| `@arnilo/prism-
|
|
151
|
-
| `@arnilo/prism-
|
|
152
|
-
| `@arnilo/prism-
|
|
153
|
-
| `@arnilo/prism-
|
|
154
|
-
| `@arnilo/prism-
|
|
155
|
-
| `@arnilo/prism-
|
|
156
|
-
| `@arnilo/prism-
|
|
157
|
-
| `@arnilo/prism-
|
|
158
|
-
| `@arnilo/prism-
|
|
159
|
-
| `@arnilo/prism-
|
|
160
|
-
| `@arnilo/prism-
|
|
161
|
-
| `@arnilo/prism-
|
|
162
|
-
| `@arnilo/prism-
|
|
163
|
-
| `@arnilo/prism-
|
|
164
|
-
| `@arnilo/prism-
|
|
165
|
-
| `@arnilo/prism-
|
|
166
|
-
| `@arnilo/prism-
|
|
150
|
+
| `@arnilo/prism-providers/openai` | `openai_key` | Sends sanitized `prompt_cache_key`; pre-5.6 models emit `prompt_cache_retention: "24h"` when `longRetention`; GPT-5.6+ models (`explicitBreakpoints`) map `cache.breakpoints`/`cache.mode: "on"` to `prompt_cache_options: { mode: "explicit" }` + `prompt_cache_breakpoint` markers (≤4 writes). | Stable cache key + stable prefix can improve reuse; keep selected anchors stable. | Best-effort only; `"short"`/`"none"` omit retention; `"30m"` TTL is the default and never emitted. |
|
|
151
|
+
| `@arnilo/prism-providers/anthropic` | `cache_control` | Marks only selected Anthropic message anchors; `system_prompt` breakpoints emit native `system` text blocks with the marker; `"long"` maps to documented `ttl: "1h"`. | Keep selected anchors stable. | Best-effort; never stamp every block. |
|
|
152
|
+
| `@arnilo/prism-providers/google` | none | Sends no Prism cache marker. | Host/model may have upstream behavior. | Gemini cache controls are not mapped in this package. |
|
|
153
|
+
| `@arnilo/prism-providers/openrouter` | `cache_control` | Top-level automatic `cache_control` when enabled without breakpoints; otherwise markers only on caller-selected `cache.breakpoints`; `"long"` may add `ttl: "1h"`. Sticky `session_id` routing. | Breakpoint-stable / automatic prefixes can be reused by upstream providers. | Best-effort only; top-level automatic may exclude some backends from routing. |
|
|
154
|
+
| `@arnilo/prism-providers/opencode-go` | route-specific | Sends sanitized `x-opencode-session`; Anthropic route applies selected `cache_control` breakpoints; OpenAI route sends none. | Session id + unchanged selected anchors can help route-native caches. | Best-effort and route-dependent. |
|
|
155
|
+
| `@arnilo/prism-providers/hyper` | route-specific implicit / `cache_control` | Chat route sends no markers (implicit prefix caching); `qwen3.6-*` messages route applies `cache_control` only to caller-selected `cache.breakpoints` (max 4); **no `ttl`** (undocumented). Opt-in responses route emits OpenAI-standard `prompt_cache_key` from hints only, never retention/options. | Keep selected Anthropic anchors and prior history stable. | Best-effort only; `402 billing_error` when Hypercredits run out. |
|
|
156
|
+
| `@arnilo/prism-providers/commandcode` | route-specific implicit / `cache_control` | Chat route sends no markers (implicit prefix caching); `claude-*` messages route applies `cache_control` only to caller-selected `cache.breakpoints` (max 4); **no `ttl`** (undocumented). GPT-5.6 tiers keep docs `cacheWrite` prices in `cost` but stay implicit until the live probe verifies `prompt_cache_key`. | Keep selected Anthropic anchors and prior history stable. | Best-effort only; GPT-5.6 explicit `prompt_cache_key` upgrade pending probe (plan 055 Task 9); OSS models bill at mean per-provider price; DeepSeek off-peak 17h/day, peak 2×. |
|
|
157
|
+
| `@arnilo/prism-providers/zai` | `implicit` | No explicit cache payload; GLM context caching is automatic. | Resend unchanged prior history for implicit context-cache reuse. | Best-effort only; cache options do not force hits. |
|
|
158
|
+
| `@arnilo/prism-providers/kimi` | implicit by default, optional `cache_control` | Default catalog models send no `cache_control`; hosts may opt in on Anthropic `/messages` models with `ModelConfig.cache.kind: "cache_control"`. | Keep selected Anthropic anchors and prior history stable. | Best-effort and model/route-dependent. |
|
|
159
|
+
| `@arnilo/prism-providers/neuralwatt` | `implicit` | No `cache_control`, `cacheKey`, `prompt_cache`, or `cacheRetention` payload; NeuralWatt vLLM prefix caching is automatic. | Full prior history must be resent unchanged with only the new turn appended; `inputLayout: "cache_aware"` keeps stable prefixes first. | Best-effort only; does not promise cache hits; `cacheRetention: "none"` disables Prism hints only, not the implicit backend prefix cache. |
|
|
160
|
+
| `@arnilo/prism-providers/ai-sdk` | host-owned | No Prism cache payload; host `LanguageModelV4` owns upstream caching. | Host model/provider decides cache keys, breakpoints, and sticky routing. | Adapter maps `inputTokens.cacheRead`/`cacheWrite` from `finish.usage` only; does not invent cache fields. |
|
|
161
|
+
| `@arnilo/prism-providers/alibaba` | implicit by default, optional `cache_control` | DashScope implicit prefix caching is automatic; opt-in `cache_control: {"type":"ephemeral"}` markers only on caller-selected `cache.breakpoints`, capped at 4. | Keep selected anchors and prior history stable; each cached prefix needs ≥1024 tokens and lives ~5 minutes upstream. | Best-effort and model-dependent; `cached_tokens`→read, `cache_creation_input_tokens`→write. |
|
|
162
|
+
| `@arnilo/prism-providers/ollama` | `implicit` | No `cache_control`, `cacheKey`, `prompt_cache`, or `cacheRetention` payload; Ollama KV/prefix caching is automatic with no request knob. | Resend unchanged prior history for implicit KV reuse. | Best-effort only; Ollama reports no cached-token count, so `Usage.cacheReadTokens` stays `undefined`. |
|
|
163
|
+
| `@arnilo/prism-providers/deepseek` | `implicit` | No `cache_control` / `prompt_cache_key`; tool `parameters` go through shared `canonicalizeJsonSchema`. | Resend unchanged history from token 0; append only the new turn. Thinking-on strips temperature/top_p/penalties so they cannot break the prefix. | Best-effort prefix units (~1024 practical min). `prompt_cache_hit_tokens` → `cacheReadTokens`. |
|
|
164
|
+
| `@arnilo/prism-providers/xai` | `implicit` | No `prompt_cache_key`. Package-local `x-grok-conv-id` is `sanitizeCacheKey(cache.key ?? cacheKey ?? sessionId, 128)`. | Same server + unchanged message prefix. Replay `reasoning_content` on reasoning models or the prefix breaks. | Conv-id is never a credential or SuperGrok token. Omitted when `cache.mode` is `off` or `cacheRetention` is `none`. `cached_tokens` → `cacheReadTokens` (inclusive or exclusive reports kept as-is). |
|
|
165
|
+
| `@arnilo/prism-providers/clinepass` | `implicit` | No `cache_control` / `prompt_cache_key`. Gateway-owned prefix cache. | Resend unchanged prior history. Stream only. | Best-effort and backend-dependent (`cline-pass/*` slugs). `cached_tokens` / `prompt_cache_hit_tokens` map when present. |
|
|
166
|
+
| `@arnilo/prism-providers/azure` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Azure cache policy. |
|
|
167
|
+
| `@arnilo/prism-providers/bedrock` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Bedrock cache policy. |
|
|
168
|
+
| `@arnilo/prism-providers/vertex` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Vertex cache policy. |
|
|
167
169
|
|
|
168
170
|
Detailed first-party provider notes:
|
|
169
171
|
|
|
170
|
-
- OpenAI Responses (`@arnilo/prism-
|
|
172
|
+
- OpenAI Responses (`@arnilo/prism-providers/openai`): `kind: "openai_key"`. Sanitizes/clamps `prompt_cache_key` to 64 chars; pre-GPT-5.6 models (`cache.longRetention: true`) map `"long"` retention to `prompt_cache_retention: "24h"`; GPT-5.6+ models (`cache.explicitBreakpoints: true`) map `cache.breakpoints`/`cache.mode: "on"` to `prompt_cache_options: { mode: "explicit" }` plus `prompt_cache_breakpoint: { mode: "explicit" }` markers on selected message anchors (≤4 writes; the only TTL `"30m"` is the default, so none is emitted). Resolved cache fields win over caller `extra`. `input_tokens_details.cached_tokens`/`cache_write_tokens` map to `Usage.cacheReadTokens`/`Usage.cacheWriteTokens`.
|
|
171
173
|
- OpenAI-compatible Chat Completions adapter: minimal scope, sends no cache payload; see [OpenAI-compatible provider](providers/openai-compatible.md).
|
|
172
|
-
- Anthropic (`@arnilo/prism-
|
|
173
|
-
- Google (`@arnilo/prism-
|
|
174
|
-
- OpenRouter (`@arnilo/prism-
|
|
175
|
-
- OpenCode Go (`@arnilo/prism-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
174
|
+
- Anthropic (`@arnilo/prism-providers/anthropic`): `kind: "cache_control"`; selected Anthropic message anchors receive `cache_control` and eligible long retention maps to `ttl: "1h"`. A `system_prompt` breakpoint serializes `system` as native text blocks carrying the marker (shared `systemCacheControlField()` helper; plain joined string when unmarked). Cache read/create usage maps to normalized cache read/write tokens.
|
|
175
|
+
- Google (`@arnilo/prism-providers/google`): sends no Prism cache-control payload. Do not infer cache hits or cache token counts from absent Gemini fields.
|
|
176
|
+
- OpenRouter (`@arnilo/prism-providers/openrouter`): `kind: "cache_control"`. Sanitizes/clamps `session_id`/`X-Session-Id` to 256 chars for sticky routing (from `cache.key` ?? legacy `cacheKey` ?? `sessionId`); with no breakpoints emits top-level automatic `cache_control: { type: "ephemeral" }`; with breakpoints applies Anthropic-style markers only to caller-selected locations (last content block of each selected message); `"long"` retention adds `ttl: "1h"` when the model allows it. `prompt_tokens_details.cached_tokens`/`cache_write_tokens` map to `Usage.cacheReadTokens`/`cacheWriteTokens`. Optional `listOpenRouterModels()` may populate `ModelConfig.cache`/`cost` from live pricing.
|
|
177
|
+
- OpenCode Go (`@arnilo/prism-providers/opencode-go`): default base `https://opencode.ai/zen/go/v1`; `x-opencode-session` from `cacheKey ?? sessionId`, sanitized to 128 chars; the Anthropic route (MiniMax/Qwen) applies `cache_control` markers only to selected breakpoints (`"long"` → `ttl: "1h"`), the OpenAI route (Grok/GLM/Kimi/MiMo/DeepSeek) sends none and preserves `reasoning_content`. OpenAI route maps `prompt_tokens_details.cached_tokens`/`cache_write_tokens`; Anthropic route maps `cache_read_input_tokens`/`cache_creation_input_tokens`. Caller-gated `listOpenCodeGoModels` against official `GET /zen/go/v1/models`.
|
|
178
|
+
- Hyper (`@arnilo/prism-providers/hyper`): `kind: "implicit"` on the chat route, `kind: "cache_control"` on the messages route. Model route selection follows the live catalog's pricing shape: models with explicit cache-write pricing (qwen3.6-*) default to the Anthropic route; the rest stay chat-route implicit with the write fee recorded in `cost.cacheWrite`. The messages route applies `cache_control: { type: "ephemeral" }` only to caller-selected `cache.breakpoints` (shared `applyCacheControl`, max 4) — never every block, and **never a `ttl`** (Hyper documents no TTL values). Chat route maps `prompt_tokens_details.cached_tokens`/`cache_write_tokens` (and `prompt_cache_hit_tokens`); messages route maps `cache_read_input_tokens`/`cache_creation_input_tokens`. `parseHyperUsageCost` surfaces USD/cost/remaining Hypercredits from the OpenAI usage chunk for cost telemetry; `402 billing_error` is the drained-balance signal. Caller-gated `listHyperModels`; operator-gated `getHyperCredits`.
|
|
179
|
+
- Command Code (`@arnilo/prism-providers/commandcode`): `kind: "implicit"` on the chat route, `kind: "cache_control"` on the messages route. `claude-*` tiers (the only Anthropic-route models by server-enforced routing) default to `cache_control` with markers only on caller-selected `cache.breakpoints` max 4 — never every block, and **never a `ttl`** (the upstream TTL window is undocumented). GPT-5.6 sol/terra/luna keep the docs cache-write price in `cost.cacheWrite` but stay `implicit` until the live `prompt_cache_key` probe passes (plan 055 Task 9); all other chat-route models are implicit with `prompt_cache_hit_tokens`/`cached_tokens` mapped by the shared OpenAI usage mapping. Messages route maps `cache_read_input_tokens`/`cache_creation_input_tokens`. Billing caveats: OSS models bill at the mean per-provider price; DeepSeek off-peak rates (17h/day) with ~2× peak 01–04 & 06–10 UTC; deals (MiniMax M3, MiMo) auto-applied. Caller-gated `listCommandCodeModels`; optional ZDR (`zdr: true`) adds `x-cmd-zdr: 1` and may route to costlier upstreams or fail `422 cmd_zdr_no_providers`.
|
|
180
|
+
- Z.AI (`@arnilo/prism-providers/zai`): `kind: "implicit"`. GLM context caching is automatic; sends no explicit cache payload regardless of cache options. `prompt_tokens_details.cached_tokens`/`cache_write_tokens` map to `Usage.cacheReadTokens`/`cacheWriteTokens`.
|
|
181
|
+
- NeuralWatt (`@arnilo/prism-providers/neuralwatt`): `kind: "implicit"`. NeuralWatt prefix caching is automatic; sends no explicit cache payload regardless of cache options. `cacheRetention: "none"` disables Prism cache-control hints only (not the implicit backend prefix cache). `prompt_tokens_details.cached_tokens` maps to `Usage.cacheReadTokens`; NeuralWatt does not report a cache-write token, so `Usage.cacheWriteTokens` is never fabricated (stays `undefined`). NeuralWatt's `/v1/models` catalog advertises exact `cached_input_per_million` rates for cache reads and `cached_output_per_million: null`; static curated aliases do not guess those prices.
|
|
182
|
+
- Kimi (`@arnilo/prism-providers/kimi`): default catalog models use implicit caching (no `cache_control`); hosts opt in via `ModelConfig.cache.kind: "cache_control"` on the Anthropic `/messages` route, then `cache_control` markers apply only to selected breakpoints (`"long"` → `ttl: "1h"`); the Moonshot OpenAI route sends none. `cache_read_input_tokens`/`cache_creation_input_tokens` map to `Usage.cacheReadTokens`/`cacheWriteTokens`.
|
|
183
|
+
- AI SDK adapter (`@arnilo/prism-providers/ai-sdk`): **host-owned**. Sends no Prism cache payload; the supplied `LanguageModelV4` and its upstream provider own request caching. Maps AI SDK v4 `finish.usage.inputTokens.cacheRead`/`cacheWrite` to `Usage.cacheReadTokens`/`cacheWriteTokens`. No `list*Models()` export.
|
|
184
|
+
- Alibaba Cloud (`@arnilo/prism-providers/alibaba`): implicit by default, optional `cache_control`. DashScope implicit prefix caching is automatic (no marker); explicit opt-in `cache_control: {"type":"ephemeral"}` markers apply only to selected breakpoints when `ModelConfig.cache.kind: "cache_control"` and the caller supplies breakpoints, capped at 4 (each prefix ≥1024 tokens, ~5 minute TTL). `prompt_tokens_details.cached_tokens`/`cache_creation_input_tokens` map to `Usage.cacheReadTokens`/`cacheWriteTokens`. Caller-gated `listAlibabaModels` against OpenAI-compatible `GET {base}/models`.
|
|
185
|
+
- Ollama (`@arnilo/prism-providers/ollama`): `kind: "implicit"`. Ollama reuses its KV/prompt cache automatically; there is no request knob and no wire marker, so Prism never emits `cache_control`. Ollama reports no cached-token count, so `Usage.cacheReadTokens` is intentionally left `undefined` (not `0`). Caller-gated `listOllamaModels` against OpenAI-compatible `GET {base}/models`.
|
|
186
|
+
- DeepSeek (`@arnilo/prism-providers/deepseek`): `kind: "implicit"`. Official disk prefix cache is automatic (byte-identical prefix from token 0). Adapter sends no cache payload; tool `parameters` use shared `canonicalizeJsonSchema` (object keys + unordered `required` only; `enum`/`prefixItems`/`examples` keep caller order). `prompt_cache_hit_tokens` maps to `Usage.cacheReadTokens`. Caller-gated `listDeepSeekModels`.
|
|
187
|
+
- xAI (`@arnilo/prism-providers/xai`): `kind: "implicit"`. Automatic prefix cache. Sticky `x-grok-conv-id` is a sanitized session/cache key (128 chars), never an OAuth access token. Reasoning models must replay `reasoning_content`. `prompt_tokens_details.cached_tokens` maps to `Usage.cacheReadTokens`. Caller-gated `listXaiModels`.
|
|
188
|
+
- ClinePass (`@arnilo/prism-providers/clinepass`): `kind: "implicit"`. No explicit cache payload; multi-backend gateway may report `cached_tokens` or `prompt_cache_hit_tokens`. Static `cline-pass/*` catalog only — no `listClinePassModels`.
|
|
185
189
|
- Azure, Bedrock, and Vertex: their OpenAI-compatible packages intentionally emit no Prism cache fields. Endpoint/model-specific cache controls remain host-owned rather than guessed from another provider family.
|
|
186
190
|
|
|
187
191
|
### NeuralWatt cache-aware limiter
|
|
188
192
|
|
|
189
|
-
NeuralWatt (`@arnilo/prism-
|
|
193
|
+
NeuralWatt (`@arnilo/prism-providers/neuralwatt`) runs a cache-aware backend rate
|
|
190
194
|
limiter on top of its implicit vLLM prefix cache. This shapes long-running agent
|
|
191
195
|
sessions differently from one-shot chat:
|
|
192
196
|
|
|
@@ -31,13 +31,15 @@ Offline conformance is mandatory for every package; credentialed probes are not
|
|
|
31
31
|
| Package | Required offline evidence | Restricted live evidence |
|
|
32
32
|
| --- | --- | --- |
|
|
33
33
|
| OpenAI | Responses serialization/stream ordering, provider-hosted authority, continuation cap/cursor, Realtime fake WebSocket caps | Standard API-key smoke; separate protected hosted-tool/Realtime entitlement probe |
|
|
34
|
-
| AI SDK | Exact 4.0.
|
|
34
|
+
| AI SDK | Exact 4.0.10/V4 gate (`4.0.3` and `4.0.4` also listed); every mapped stream part; authority, cache usage, redaction, unsupported mapping | Host-created V4 model only; no Prism credential fixture |
|
|
35
35
|
| Anthropic | Messages serialization, cache/thinking/tools, header/redaction/abort assertions | Protected `ANTHROPIC_API_KEY` smoke |
|
|
36
36
|
| Google | `generateContent` serialization, complete tool calls, media/abort/redaction assertions | Protected `GOOGLE_API_KEY` or `GEMINI_API_KEY` smoke |
|
|
37
37
|
| Kimi | Coding/Moonshot route fixtures, thinking/tool reconstruction, headers/redaction | Protected `KIMI_API_KEY` smoke |
|
|
38
38
|
| Z.AI | GLM thinking/tool-stream fixtures, implicit-cache usage, headers/redaction | Protected `ZAI_API_KEY` smoke |
|
|
39
39
|
| OpenRouter | routing/reasoning/cache-control fixture, stream/tool reconstruction, headers/redaction | Protected `OPENROUTER_API_KEY` smoke |
|
|
40
40
|
| OpenCode Go | OpenAI/Anthropic route fixture, completion proof, PDF/media boundary, headers/redaction | Protected `OPENCODE_API_KEY` smoke |
|
|
41
|
+
| Hyper | dual-route OpenAI/Anthropic fixtures, thinking/effort replay, message-delta usage at end, cache-breakpoint fixture, auth/redaction | Protected `HYPER_API_KEY` smoke |
|
|
42
|
+
| Command Code | dual-route OpenAI/Anthropic fixtures, thinking replay, no-`ttl` cache-breakpoint fixture, ZDR header ownership, 403/422 classification, auth/redaction | Protected `COMMAND_CODE_API_KEY` smoke |
|
|
41
43
|
| Alibaba | DashScope presets, Qwen thinking, image rejection/mapping, cache/usage fixture | Protected account/region host probe; no generic key fixture |
|
|
42
44
|
| Ollama | cloud/local preset, reasoning/image mapping, implicit-cache fixture | Protected cloud or host-local authenticated daemon probe; no daemon starts in tests |
|
|
43
45
|
| NeuralWatt | stream/retry/quota/telemetry fixtures, implicit-cache usage, headers/redaction | Protected `NEURALWATT_API_KEY` smoke |
|
|
@@ -47,6 +49,26 @@ Offline conformance is mandatory for every package; credentialed probes are not
|
|
|
47
49
|
|
|
48
50
|
All rows must retain bounded request/response fixtures, abort propagation, provider-owned-header precedence, and fake-secret leak assertions where the package surfaces those values. A successful fake transport proves Prism mapping, not account entitlement or vendor availability.
|
|
49
51
|
|
|
52
|
+
## Modality conformance matrix (plan 061)
|
|
53
|
+
|
|
54
|
+
One provider-neutral contract per modality, each with a capability flag, a typed error family, and an offline conformance runner from `@arnilo/prism/testing/provider-conformance`. Fake transports prove Prism mapping and typed-cap behavior only — never account entitlement or vendor availability.
|
|
55
|
+
|
|
56
|
+
| Contract / runner | Offline evidence (fake transport) | Live probe |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| `EmbeddingsProvider` — `runEmbeddingsConformance` | batch-cap/empty-input typed errors, index-ordered vectors, dimensions truthfulness, usage | probe pending |
|
|
59
|
+
| `SpeechProvider` — `runSpeechConformance` | input/byte caps typed, audio bytes + mime provenance, first-chunk streaming | probe pending |
|
|
60
|
+
| `TranscriptionProvider` — `runTranscriptionConformance` | audio caps typed, SSE partials, terminal transcript | probe pending |
|
|
61
|
+
| `ImageGenerationProvider` — `runImageGenerationConformance` | prompt/byte caps typed, b64 provenance, edit route | probe pending |
|
|
62
|
+
| `VideoGenerationProvider` — `runVideoGenerationConformance` | submit/status lifecycle, terminal-only resolution, provenance | probe pending |
|
|
63
|
+
| `ModerationProvider` — `runModerationConformance` | empty/oversized typed errors, neutral category mapping + raw passthrough, score range [0,1], no local thresholds | probe pending |
|
|
64
|
+
| `BatchJobsProvider` — `runBatchJobsConformance` | empty/oversized submits typed, opaque ids, state union, `pollBatch` terminal resolution, paged results walk to exhaustion | probe pending |
|
|
65
|
+
|
|
66
|
+
Failure/cancel terminal transitions for long-running contracts (video, batch) are covered by provider fakes in the adapter suites; `pollBatch` surfaces typed `job_failed`/`job_cancelled`/`job_expired` errors. Live probes stay operator-gated like the package matrix above; ledger rows live in `docs/_evidence/modality-contracts-2026-09-03.md` marked "probe pending" until run.
|
|
67
|
+
|
|
68
|
+
## Nightly live-provider canary (plan 060)
|
|
69
|
+
|
|
70
|
+
`.github/workflows/canary-providers.yml` runs nightly (`0 3 * * *`, plus `workflow_dispatch`) against the `live-canaries` environment. Each matrix leg runs one provider's existing live suite (text completion + tool-call/structured legs, `assertNoSecretLeak` inside); legs skip without their key. The provider set is the `PRISM_CANARY_PROVIDERS` repo variable (JSON array, default `["openai"]`). Evidence is per-leg and aggregate job summaries (statuses only — responses are never logged); any failure opens a tracking issue and blocks nothing.
|
|
71
|
+
|
|
50
72
|
## Inputs / request
|
|
51
73
|
|
|
52
74
|
```ts
|
|
@@ -189,7 +211,7 @@ Canonical contract: [Thinking and reasoning](thinking-and-reasoning.md).
|
|
|
189
211
|
|
|
190
212
|
## AI SDK adapter checklist
|
|
191
213
|
|
|
192
|
-
`@arnilo/prism-
|
|
214
|
+
`@arnilo/prism-providers/ai-sdk` is a host-owned `LanguageModelV4` bridge. It does not participate in the discovery or thinking/reasoning checklists above. Cover instead:
|
|
193
215
|
|
|
194
216
|
1. **No catalog / no setup fetch** — package exports no `list*Models()`; `createAiSdkProvider` wraps a host model only.
|
|
195
217
|
2. **Version + specification gate** — exact `@ai-sdk/provider` matrix version is verified at setup; rejects version skew, non-v4 models (`specificationVersion !== "v4"`), or missing `doStream`.
|
|
@@ -18,19 +18,51 @@ Use provider packages when a host wants to bundle model metadata, provider adapt
|
|
|
18
18
|
|
|
19
19
|
Do not use provider packages as a package manager, credential store, env loader, provider-specific cache implementation, or live integration runner.
|
|
20
20
|
|
|
21
|
+
### Provider inventory
|
|
22
|
+
|
|
23
|
+
<!-- generated:package-truth:providers begin -->
|
|
24
|
+
**20 provider adapters** — first-party adapters ship as `@arnilo/prism-providers/<adapter>` subpaths in one tarball (importing one never evaluates another):
|
|
25
|
+
|
|
26
|
+
| adapter package | version |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `@arnilo/prism-providers/ai-sdk` | 0.5.0 |
|
|
29
|
+
| `@arnilo/prism-providers/alibaba` | 0.5.0 |
|
|
30
|
+
| `@arnilo/prism-providers/anthropic` | 0.5.0 |
|
|
31
|
+
| `@arnilo/prism-providers/azure` | 0.5.0 |
|
|
32
|
+
| `@arnilo/prism-providers/bedrock` | 0.5.0 |
|
|
33
|
+
| `@arnilo/prism-providers/clinepass` | 0.5.0 |
|
|
34
|
+
| `@arnilo/prism-providers/commandcode` | 0.5.0 |
|
|
35
|
+
| `@arnilo/prism-providers/deepseek` | 0.5.0 |
|
|
36
|
+
| `@arnilo/prism-providers/google` | 0.5.0 |
|
|
37
|
+
| `@arnilo/prism-providers/hyper` | 0.5.0 |
|
|
38
|
+
| `@arnilo/prism-providers/kimi` | 0.5.0 |
|
|
39
|
+
| `@arnilo/prism-providers/model-discovery` | 0.5.0 |
|
|
40
|
+
| `@arnilo/prism-providers/neuralwatt` | 0.5.0 |
|
|
41
|
+
| `@arnilo/prism-providers/ollama` | 0.5.0 |
|
|
42
|
+
| `@arnilo/prism-providers/openai` | 0.5.0 |
|
|
43
|
+
| `@arnilo/prism-providers/opencode-go` | 0.5.0 |
|
|
44
|
+
| `@arnilo/prism-providers/openrouter` | 0.5.0 |
|
|
45
|
+
| `@arnilo/prism-providers/vertex` | 0.5.0 |
|
|
46
|
+
| `@arnilo/prism-providers/xai` | 0.5.0 |
|
|
47
|
+
| `@arnilo/prism-providers/zai` | 0.5.0 |
|
|
48
|
+
<!-- generated:package-truth:providers end -->
|
|
49
|
+
|
|
50
|
+
|
|
21
51
|
### Subscription OAuth support matrix
|
|
22
52
|
|
|
23
53
|
| Package | 0.0.12 auth registration | Subscription OAuth boundary |
|
|
24
54
|
| --- | --- | --- |
|
|
25
|
-
| `@arnilo/prism-
|
|
26
|
-
| `@arnilo/prism-
|
|
27
|
-
| `@arnilo/prism-
|
|
28
|
-
| `@arnilo/prism-
|
|
29
|
-
| `@arnilo/prism-
|
|
30
|
-
| `@arnilo/prism-
|
|
31
|
-
| `@arnilo/prism-
|
|
32
|
-
| `@arnilo/prism-
|
|
33
|
-
| `@arnilo/prism-
|
|
55
|
+
| `@arnilo/prism-providers/openai` | `api_key` for `openai`; `oauth` for `openai-codex` | Existing host-invoked OpenAI Codex PKCE/device-code flow only. |
|
|
56
|
+
| `@arnilo/prism-providers/xai` | `api_key` and `oauth` for `xai` | Host-invoked SuperGrok / X Premium RFC 8628 device-code against `auth.x.ai`. Public Grok CLI client id is not a secret. No PKCE loopback, no `~/.grok` import, no `cli-chat-proxy.grok.com`. |
|
|
57
|
+
| `@arnilo/prism-providers/deepseek` | `api_key` only | No subscription OAuth. |
|
|
58
|
+
| `@arnilo/prism-providers/clinepass` | `api_key` only | No Cline WorkOS / Cline OAuth store share. Host supplies `CLINE_API_KEY`. |
|
|
59
|
+
| `@arnilo/prism-providers/anthropic` | `api_key` only | No Claude Code/Claude.ai subscription OAuth, credential-file/setup-token import, or routing. [Anthropic requires product developers to use API keys or supported cloud providers](https://docs.anthropic.com/en/docs/claude-code/legal-and-compliance). |
|
|
60
|
+
| `@arnilo/prism-providers/google` | `api_key` only | No Gemini CLI OAuth or credential/token import. [Gemini CLI prohibits third-party OAuth piggybacking](https://github.com/google-gemini/gemini-cli/blob/main/docs/resources/tos-privacy.md); use Google AI Studio API keys. Vertex/ADC uses separate [`@arnilo/prism-providers/vertex`](providers/vertex.md). |
|
|
61
|
+
| `@arnilo/prism-providers/hyper` | `api_key` only | No subscription OAuth — Charm Hyper is pay-per-use Hypercredits; host supplies `HYPER_API_KEY` (keys start `sk-hyper-`). |
|
|
62
|
+
| `@arnilo/prism-providers/commandcode` | `api_key` only | No subscription OAuth — Command Code Go/GOAT/Pro/Max coding plans and the Provider plan all authenticate with the same Studio API key; host supplies `COMMAND_CODE_API_KEY`. |
|
|
63
|
+
| `@arnilo/prism-providers/azure` | host Entra token or Azure resource key | Workload identity via `credential` callback; endpoint host preserved ([docs](providers/azure.md)). |
|
|
64
|
+
| `@arnilo/prism-providers/bedrock` | host IAM/IRSA credentials | SigV4 over OpenAI-compatible Bedrock Runtime; region/PrivateLink preserved ([docs](providers/bedrock.md)). |
|
|
65
|
+
| `@arnilo/prism-providers/vertex` | host ADC / workload token | OpenAPI-compatible Vertex endpoint; separate from consumer Google package ([docs](providers/vertex.md)). |
|
|
34
66
|
|
|
35
67
|
A future provider-local OAuth package must first have explicit third-party permission and documented authorize/token/refresh flow. Before it registers an OAuth descriptor, it must add bounded request/response, abort, PKCE/state where required, expiry/refresh, secret-redaction, durable-store round-trip, and offline protocol tests. Do not add a generic OAuth framework, CLI credential scanner, automatic refresh timer, or success stub.
|
|
36
68
|
|
|
@@ -79,13 +111,13 @@ First-party providers map generic `ModelConfig.parameters.maxTokens` to real out
|
|
|
79
111
|
|
|
80
112
|
Scaffold new OpenAI-compatible provider packages with `prism providers add <name>` (see [CLI/RPC](cli-rpc.md#prism-providers-add-017)): it generates the manifest, provider (`createOpenAICompatibleProvider`), starter models, cache-hint helpers, an offline conformance test, and a docs stub — mirroring the first-party skeleton conventions below. Scaffold output is host-chosen and never auto-registered.
|
|
81
113
|
|
|
82
|
-
Phase 12 adds explicit npm workspaces for [`@arnilo/prism-
|
|
114
|
+
Phase 12 adds explicit npm workspaces for [`@arnilo/prism-providers/openai`](providers/openai.md), [`@arnilo/prism-providers/opencode-go`](providers/opencode-go.md), [`@arnilo/prism-providers/openrouter`](providers/openrouter.md), [`@arnilo/prism-providers/zai`](providers/zai.md), [`@arnilo/prism-providers/kimi`](providers/kimi.md), and [`@arnilo/prism-providers/neuralwatt`](providers/neuralwatt.md). Each package starts with a side-effect-free `create*ProviderPackage()` export, README, TypeScript build, network-free default tests, and real opt-in live smoke tests.
|
|
83
115
|
|
|
84
|
-
Phase 6 also adds optional [`@arnilo/prism-
|
|
116
|
+
Phase 6 also adds optional [`@arnilo/prism-providers/ai-sdk`](providers/ai-sdk.md), which adapts a host-owned AI SDK `LanguageModelV4` to Prism's `AIProvider`. It joins `@arnilo/prism-providers` as the seventh adapter while remaining independent from the six HTTP implementations.
|
|
85
117
|
|
|
86
|
-
Provider live tests are real smoke tests gated by `PRISM_LIVE_PROVIDER_TESTS=1` plus the provider-specific API key (`OPENAI_API_KEY`, `OPENROUTER_API_KEY`, `KIMI_API_KEY`, `ZAI_API_KEY`, `NEURALWATT_API_KEY`, `OPENCODE_API_KEY`, `DEEPSEEK_API_KEY`, `XAI_API_KEY`, or `
|
|
118
|
+
Provider live tests are real smoke tests gated by `PRISM_LIVE_PROVIDER_TESTS=1` plus the provider-specific API key (`OPENAI_API_KEY`, `OPENROUTER_API_KEY`, `KIMI_API_KEY`, `ZAI_API_KEY`, `NEURALWATT_API_KEY`, `OPENCODE_API_KEY`, `DEEPSEEK_API_KEY`, `XAI_API_KEY`, `CLINE_API_KEY`, `HYPER_API_KEY`, or `COMMAND_CODE_API_KEY`). They cover text generation, tool-call loop behavior, abort/error paths where supported, and no-secret-leak assertions; they skip by default and never run in release verification. SuperGrok login is operator-only (`PRISM_LIVE_XAI_OAUTH=1`).
|
|
87
119
|
|
|
88
|
-
These workspaces still follow the same rule as external packages: no provider SDK dependency, catalog fetch, env scan, keychain/file credential lookup, shell auth command, OAuth login, or live provider call runs by default. `@arnilo/prism-
|
|
120
|
+
These workspaces still follow the same rule as external packages: no provider SDK dependency, catalog fetch, env scan, keychain/file credential lookup, shell auth command, OAuth login, or live provider call runs by default. `@arnilo/prism-providers/openai` now registers OpenAI Responses and OpenAI Codex providers from caller-supplied credentials only, with optional `models`/`codexModels` overrides and an opt-in `listOpenAIModels()` helper for official `GET /models` discovery. `@arnilo/prism-providers/opencode-go` now registers docs-verified OpenCode Go open coding models with dual OpenAI/Anthropic routes (`compat.route`), official default base `https://opencode.ai/zen/go/v1`, `reasoning_content`/thinking preserve, and an opt-in `listOpenCodeGoModels()` helper for official `GET /zen/go/v1/models`. `@arnilo/prism-providers/openrouter` now registers an app-controlled OpenRouter catalog with routing/`reasoning`/cache passthrough, assistant `reasoning` replay, optional top-level automatic `cache_control`, and an opt-in `listOpenRouterModels()` helper for official `GET /api/v1/models` (setup still never fetches). `@arnilo/prism-providers/zai` now registers featured GLM-5.x/4.x metadata with official `thinking`/`reasoning_effort`/`tool_stream`/`clear_thinking` mapping, Preserved Thinking `reasoning_content` replay, implicit context caching, and an opt-in `listZaiModels()` helper for OpenAI-compatible `GET /models`. `@arnilo/prism-providers/kimi` now registers Kimi Coding Anthropic-compatible behavior by default, optional callable Moonshot Open Platform Chat Completions when `includeMoonshotModels` is requested, official Coding/Open Platform featured ids, thinking/`reasoning_effort` compat mapping, and an opt-in `listKimiModels()` helper for Moonshot `GET /v1/models`. `@arnilo/prism-providers/neuralwatt` now registers static featured model metadata with NeuralWatt reasoning_effort/thinking_token_budget/chat_template_kwargs request mapping, SSE comment tolerance, an opt-in `listNeuralWattModels()` helper for explicit `/v1/models` discovery, `getNeuralWattQuota()` for on-demand account balance/usage/energy, `neuralWattEventsWithTelemetry()`/`mapNeuralWattTelemetry()` for `: energy`/`: cost` telemetry, and `classifyNeuralWattError()` for retry classification. None of these helpers run during package setup or generation. `@arnilo/prism-providers/deepseek` registers featured `deepseek-v4-flash` / `deepseek-v4-pro` with official `thinking` / `reasoning_effort`, tool-turn `reasoning_content` replay, implicit prefix cache, and caller-gated `listDeepSeekModels`. `@arnilo/prism-providers/xai` registers featured Completions (`grok-4.6` / `grok-4.3` / `grok-build-0.1`), `x-grok-conv-id`, `reasoning_content` replay, caller-gated `listXaiModels`, and host-invoked SuperGrok device-code OAuth against `auth.x.ai`. `@arnilo/prism-providers/clinepass` registers a static `cline-pass/*` catalog, stream-only Chat Completions, per-model `reasoning_effort` maps, and `api_key` only (no WorkOS, no `listClinePassModels`). `@arnilo/prism-providers/anthropic` registers native Anthropic Messages (`createAnthropicProviderPackage` / `listAnthropicModels`). `@arnilo/prism-providers/google` registers native Gemini `generateContent` streaming (`createGoogleProviderPackage` / `listGoogleModels`; Vertex identity stays in the separate package). Both follow the same zero-setup-network / host-owned credential / provider-owned-header rules; see [`docs/providers/anthropic.md`](providers/anthropic.md) and [`docs/providers/google.md`](providers/google.md).
|
|
89
121
|
|
|
90
122
|
### Phase 10 compatibility matrix
|
|
91
123
|
|
|
@@ -94,13 +126,15 @@ Every package remains explicit, setup-zero-fetch, and late-credential-bound. `Mo
|
|
|
94
126
|
| Package | Protocol / model source | Content mapping | Stream, tools, and reasoning | Cache / canary |
|
|
95
127
|
| --- | --- | --- | --- | --- |
|
|
96
128
|
| OpenAI | Responses; featured or caller-gated `listOpenAIModels` | text, image, audio, file, document | Host and provider-hosted tools; 8-hop continuation; Realtime seam; Responses reasoning | `openai_key`; checked-in standard smoke + protected hosted/Realtime probe |
|
|
97
|
-
| AI SDK | Host `LanguageModelV4`; no Prism catalog | declared text/image/audio/file/document prompt parts (role-limited) | v4 mapping; provider-executed tool authority; host-owned reasoning | host-owned; exact 4.0.
|
|
129
|
+
| AI SDK | Host `LanguageModelV4`; no Prism catalog | declared text/image/audio/file/document prompt parts (role-limited) | v4 mapping; provider-executed tool authority; host-owned reasoning | host-owned; exact 4.0.10 matrix (`4.0.3` and `4.0.4` also listed); protected host integration |
|
|
98
130
|
| Anthropic | Messages; caller-gated list | text, image, PDF document/file | tool deltas, thinking | `cache_control`; protected API-key smoke |
|
|
99
131
|
| Google | Gemini `generateContent`; caller-gated list | text, image, audio, document/file | complete tool calls, thinking | no Prism cache marker; protected API-key smoke |
|
|
100
132
|
| Kimi | Coding Messages or opt-in Moonshot; caller-gated list | text, image, PDF document/file by route/model | tool deltas, route-native thinking replay | implicit / optional Anthropic markers; protected API-key smoke |
|
|
101
133
|
| Z.AI | OpenAI-compatible; caller-gated list | text, image | tool deltas, `reasoning_content` | implicit; protected API-key smoke |
|
|
102
134
|
| OpenRouter | OpenAI-compatible; host catalog + caller-gated list | text, image | tool deltas, reasoning replay/routing metadata | `cache_control`; protected API-key smoke |
|
|
103
135
|
| OpenCode Go | OpenAI or Anthropic route; caller-gated list | text/image OpenAI route; PDF document/file Anthropic route | tool deltas, route-native thinking | route-specific; protected API-key smoke |
|
|
136
|
+
| Hyper | OpenAI, Anthropic, or explicit-pass-through Responses route (`compat.route: "responses"` reuses the shared OpenAI Responses machinery); caller-gated list | text, image | tool deltas, route-native thinking, `reasoning_effort` | route-specific implicit / `cache_control`; protected API-key smoke |
|
|
137
|
+
| Command Code | OpenAI or Anthropic route; caller-gated list | text, image | tool deltas, route-native thinking | route-specific implicit / `cache_control`; protected API-key smoke |
|
|
104
138
|
| Alibaba | DashScope OpenAI-compatible; caller-gated list | text, image | tool deltas, Qwen thinking | implicit / optional markers; protected host probe |
|
|
105
139
|
| Ollama | Cloud/local OpenAI-compatible; caller-gated list | text, image | tool deltas, reasoning effort | implicit only; protected host/daemon probe |
|
|
106
140
|
| NeuralWatt | OpenAI-compatible; caller-gated list | text, image | tool deltas, reasoning and telemetry | implicit; protected API-key smoke |
|
|
@@ -119,6 +153,8 @@ Every first-party provider package hardens prompt-cache behavior so it cannot em
|
|
|
119
153
|
- **OpenAI-compatible core adapter**: Chat Completions sends no `prompt_cache_key`/`prompt_cache_retention`/`cache_control` fields; endpoints cache implicitly. `prompt_tokens_details.cached_tokens` maps to `Usage.cacheReadTokens`.
|
|
120
154
|
- **OpenRouter** (`kind: cache_control`): `session_id`/`x-session-id` sanitized and clamped to 256 chars; with no breakpoints, emits top-level automatic `cache_control: { type: ephemeral }`; with breakpoints, markers applied only to caller-selected locations (not every block); `cacheRetention: long` adds `ttl: 1h` when allowed. Preserves `cached_tokens`/`cache_write_tokens`.
|
|
121
155
|
- **OpenCode Go**: default base `https://opencode.ai/zen/go/v1`; `x-opencode-session` from `cacheKey ?? sessionId` sanitized to 128 chars; Anthropic route (MiniMax/Qwen) applies `cache_control` only to selected breakpoints (`long` → `ttl: 1h`); OpenAI route (Grok/GLM/Kimi/MiMo/DeepSeek) sends none and preserves `reasoning_content`. Per-route usage mapping. Caller-gated `listOpenCodeGoModels`.
|
|
156
|
+
- **Hyper** (`kind: implicit` chat route / `cache_control` messages route): `qwen3.6-*` models default to the Anthropic route with `cache_control` markers applied only to selected breakpoints (max 4; **no `ttl`** — undocumented). DeepSeek/Kimi/GLM/Gemma/etc. stay on the chat route with implicit prefix caching; `prompt_tokens_details.cached_tokens`/`cache_write_tokens` map to cache usage. Third route: `compat.route: "responses"` opts into the Codex-style `/v1/responses` OpenAI-standard pass-through, reusing the OpenAI package's Responses machinery wholesale (stream/usage/continuation/media; errors labeled `Hyper …`); cache hints surface as OpenAI-standard `prompt_cache_key` there, never retention/options. Hypercredits: `parseHyperUsageCost` surfaces USD/cost/remaining from the usage chunk. Caller-gated `listHyperModels`, operator-gated `getHyperCredits`. Billing caveat: `402 billing_error` when Hypercredits run out.
|
|
157
|
+
- **Command Code** (`kind: implicit` chat route / `cache_control` messages route): `claude-*` tiers default to the Anthropic route with `cache_control` markers only on selected breakpoints (max 4; **no `ttl`** — undocumented); GPT-5.6/OSS models stay `implicit` with docs cache-write prices recorded in `cost.cacheWrite` (explicit `prompt_cache_key` upgrade pending live-probe verification). `prompt_cache_hit_tokens` chat-route and `cache_read_input_tokens`/`cache_creation_input_tokens` messages-route map to cache usage. ZDR opt-in (`zdr: true` → `x-cmd-zdr: 1`) may route to costlier upstreams or fail `422 cmd_zdr_no_providers`. Billing caveats: OSS models bill at the mean per-provider price; DeepSeek off-peak 17h/day, peak 2×; deals auto-applied. Caller-gated `listCommandCodeModels`.
|
|
122
158
|
- **Z.AI** (`kind: implicit`): GLM context caching is automatic; no explicit cache payload sent regardless of cache options. `prompt_tokens_details.cached_tokens`/`cache_write_tokens` map to cache usage.
|
|
123
159
|
- **NeuralWatt** (`kind: implicit`): NeuralWatt prefix caching is automatic; sends no explicit cache payload regardless of cache options. `cacheRetention: "none"` disables Prism cache-control hints only (not the implicit backend prefix cache). `prompt_tokens_details.cached_tokens` maps to `Usage.cacheReadTokens`; NeuralWatt does not report a cache-write token so `Usage.cacheWriteTokens` is never fabricated.
|
|
124
160
|
- **Kimi**: default catalog models use implicit caching (no `cache_control`); hosts opt in via `ModelConfig.cache.kind: cache_control` on the Anthropic `/messages` route, then markers apply only to selected breakpoints (`long` → `ttl: 1h`); the Moonshot OpenAI route sends none. `cache_read_input_tokens`/`cache_creation_input_tokens` map to cache usage.
|
|
@@ -158,7 +194,7 @@ export async function listExampleModels(options: {
|
|
|
158
194
|
| Static catalog | Featured aliases / offline bootstrap only; may omit live pricing until discovery fills `cost` / `cache` |
|
|
159
195
|
| Core | Prefer package-local helpers. Do **not** add a core model-discovery registry. Extract a shared HTTP/list helper only when ≥2 packages share identical parsing |
|
|
160
196
|
|
|
161
|
-
Template: [`listNeuralWattModels`](providers/neuralwatt.md) in `@arnilo/prism-
|
|
197
|
+
Template: [`listNeuralWattModels`](providers/neuralwatt.md) in `@arnilo/prism-providers/neuralwatt`.
|
|
162
198
|
|
|
163
199
|
### Per-package policy
|
|
164
200
|
|
|
@@ -195,11 +231,11 @@ Canonical contract: [Thinking and reasoning](thinking-and-reasoning.md). Package
|
|
|
195
231
|
A third party ships their own providers the same way Prism ships first-party
|
|
196
232
|
provider packages: an `Extension` whose `setup(api)` calls
|
|
197
233
|
`api.registerProvider(provider)` for each provider it owns. First-party
|
|
198
|
-
provider packages (`@arnilo/prism-
|
|
199
|
-
`@arnilo/prism-
|
|
200
|
-
`@arnilo/prism-
|
|
201
|
-
`@arnilo/prism-
|
|
202
|
-
`@arnilo/prism-
|
|
234
|
+
provider packages (`@arnilo/prism-providers/openai`, `@arnilo/prism-providers/openrouter`,
|
|
235
|
+
`@arnilo/prism-providers/kimi`, `@arnilo/prism-providers/zai`,
|
|
236
|
+
`@arnilo/prism-providers/opencode-go`, `@arnilo/prism-providers/alibaba`,
|
|
237
|
+
`@arnilo/prism-providers/ollama`, `@arnilo/prism-providers/deepseek`,
|
|
238
|
+
`@arnilo/prism-providers/xai`, `@arnilo/prism-providers/clinepass`) are **opt-in and individually installable**;
|
|
203
239
|
`@arnilo/prism` core runs without any first-party provider package (mock-only).
|
|
204
240
|
|
|
205
241
|
A host mixes first-party packages and third-party providers in one resolver.
|
|
@@ -207,7 +243,7 @@ The host owns the resolver — declaring a provider does not activate it:
|
|
|
207
243
|
|
|
208
244
|
```ts
|
|
209
245
|
import { createExtensionKernel, createProviderResolver, createAgent } from "@arnilo/prism";
|
|
210
|
-
import { createOpenAIProviderPackage } from "@arnilo/prism-
|
|
246
|
+
import { createOpenAIProviderPackage } from "@arnilo/prism-providers/openai";
|
|
211
247
|
|
|
212
248
|
// First-party package, inert until loaded.
|
|
213
249
|
const kernel = createExtensionKernel();
|
|
@@ -310,7 +346,7 @@ await kernel.load([pkg]);
|
|
|
310
346
|
- Provider-specific behavior belongs in provider packages, not Prism core.
|
|
311
347
|
- Adapter serializers should preserve Prism content blocks (text, thinking, tool_call, tool_result, and image when the model declares image input) in provider-native request shape, or fail explicitly when a block is unsupported.
|
|
312
348
|
- Adapter header merging must put caller-supplied `ProviderRequest.options.headers` first and provider-owned headers last. Caller headers may add non-owned headers, but cannot replace resolved credentials, content type, session/cache/security headers, or provider attribution headers.
|
|
313
|
-
- For allow-list/residency/budget/circuit selection before resolve, use optional `@arnilo/prism-model-router` over `createProviderResolver` — do not fork provider packages for governance.
|
|
349
|
+
- For allow-list/residency/budget/circuit selection before resolve, use optional `@arnilo/prism-core/governance/model-router` over `createProviderResolver` — do not fork provider packages for governance.
|
|
314
350
|
- Enterprise cloud adapters (`azure` / `bedrock` / `vertex`) stay separate from consumer Anthropic/Google packages and authenticate only through host credential callbacks.
|
|
315
351
|
|
|
316
352
|
## Manifest declarations
|
|
@@ -14,7 +14,7 @@ Implementation is **shipped** for transport and OpenAI serialization primitives
|
|
|
14
14
|
|
|
15
15
|
## Inventory (2026-07-14 baseline)
|
|
16
16
|
|
|
17
|
-
Static scan of root `src/providers/` and `packages/
|
|
17
|
+
Static scan of root `src/providers/` and `packages/prism-providers/src/*/` before Plan 054 implementation.
|
|
18
18
|
|
|
19
19
|
### Duplicated protocol helpers (baseline → Task 2)
|
|
20
20
|
|
|
@@ -34,8 +34,8 @@ Static scan of root `src/providers/` and `packages/provider-*/src/` before Plan
|
|
|
34
34
|
| --- | --- | --- |
|
|
35
35
|
| Runtime retry | `@arnilo/prism` `AgentConfig.retry` / `RunOptions.retry` | Classifies `ErrorInfo.code`; provider packages set numeric HTTP `code` on errors |
|
|
36
36
|
| `ProviderRequestOptions.maxRetries` / `timeoutMs` | Contracts | **Removed in 0.1.5**; use `RunOptions.signal` / `AgentConfig.retry` / `RunOptions.retry` |
|
|
37
|
-
| NeuralWatt `classifyNeuralWattError` | `packages/
|
|
38
|
-
| Quota endpoint throttling | `packages/
|
|
37
|
+
| NeuralWatt `classifyNeuralWattError` | `packages/prism-providers/src/neuralwatt` | Parses `Retry-After`, `error.retry_after`, `retry_strategy`; no extra network calls |
|
|
38
|
+
| Quota endpoint throttling | `packages/prism-providers/src/neuralwatt/quota.ts` | Documents 1 rps limit; caller-owned cache |
|
|
39
39
|
|
|
40
40
|
No generic core helper extracts `Retry-After` / `x-request-id` for all providers yet.
|
|
41
41
|
|
|
@@ -251,7 +251,7 @@ export interface ProviderTurnMetadata {
|
|
|
251
251
|
// - provider_turn_finished { sessionId, runId, turn, metadata, usage?, error? }
|
|
252
252
|
```
|
|
253
253
|
|
|
254
|
-
Optional package `@arnilo/prism-observability
|
|
254
|
+
Optional package `@arnilo/prism-core/governance/observability` subscribes via middleware + agent events. **Default:** content redacted/absent; high-cardinality IDs are span attributes, not metric labels. NeuralWatt `neuralwatt:telemetry` events remain package-local; the adapter may forward numeric energy/cost fields.
|
|
255
255
|
|
|
256
256
|
## Migration conformance fixtures
|
|
257
257
|
|
|
@@ -310,7 +310,7 @@ Every migrated provider must pass this shared matrix (implemented in Task 1 test
|
|
|
310
310
|
| Finding / capability | Plan 054 task | Primitive / doc |
|
|
311
311
|
| --- | --- | --- |
|
|
312
312
|
| R-008 Unbounded SSE/error bodies | 1, 2 | `readSseEvents`, `readBoundedResponseText` |
|
|
313
|
-
| R-009 OAuth device polling | 3 | `packages/
|
|
313
|
+
| R-009 OAuth device polling | 3 | `packages/prism-providers/src/openai/src/oauth.ts` |
|
|
314
314
|
| R-010 Duplicated helpers | 1, 2 | This page + subpaths |
|
|
315
315
|
| C-002 Native structured output | 4 | `StructuredOutputOptions` |
|
|
316
316
|
| C-004 Shared resilient transport | 1, 2 | `providers/transport` |
|
|
@@ -104,7 +104,7 @@ Policy output should stay generic: use `ProviderRequestOptions.cache`, `headers`
|
|
|
104
104
|
- Cache keys must never be credentials.
|
|
105
105
|
- Policy chains are O(number of policies) plus option merge cost.
|
|
106
106
|
- Policies should be pure and synchronous unless the host explicitly accepts async work.
|
|
107
|
-
- Optional `@arnilo/prism-model-router` returns a `ProviderRequestPolicy` that strips `openRouterRouting` unless governance allows it — chain it with other policies.
|
|
107
|
+
- Optional `@arnilo/prism-core/governance/model-router` returns a `ProviderRequestPolicy` that strips `openRouterRouting` unless governance allows it — chain it with other policies.
|
|
108
108
|
|
|
109
109
|
## Related APIs
|
|
110
110
|
|