@arnilo/prism 0.3.1 → 0.4.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.
Files changed (123) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +34 -57
  3. package/dist/agent-definitions.js +4 -1
  4. package/dist/agent-run-lifecycle.js +4 -0
  5. package/dist/agent-run-state.d.ts +4 -0
  6. package/dist/agent-run-state.js +18 -5
  7. package/dist/agent-session/session.d.ts +7 -0
  8. package/dist/agent-session/session.js +59 -2
  9. package/dist/cli-dev.d.ts +29 -0
  10. package/dist/cli-dev.js +52 -0
  11. package/dist/cli-init.d.ts +17 -2
  12. package/dist/cli-init.js +194 -21
  13. package/dist/cli-runner.d.ts +5 -1
  14. package/dist/cli-runner.js +12 -1
  15. package/dist/contracts-core/agent.d.ts +29 -2
  16. package/dist/contracts-protocol.d.ts +18 -0
  17. package/dist/contracts-run-state.d.ts +1 -2
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.js +2 -1
  20. package/dist/input.d.ts +8 -0
  21. package/dist/input.js +4 -0
  22. package/dist/rpc.d.ts +4 -1
  23. package/dist/rpc.js +5 -1
  24. package/dist/testing/persistence-schema.d.ts +1 -1
  25. package/dist/testing/persistence-schema.js +32 -28
  26. package/dist/testing/tool-conformance.d.ts +25 -0
  27. package/dist/testing/tool-conformance.js +128 -1
  28. package/dist/tool-search.d.ts +76 -0
  29. package/dist/tool-search.js +199 -0
  30. package/docs/0.1.0-readiness.md +2 -2
  31. package/docs/acp-agent.md +1 -1
  32. package/docs/agent-definitions.md +1 -1
  33. package/docs/antigravity-agent.md +1 -1
  34. package/docs/browser-automation.md +5 -5
  35. package/docs/caveman.md +2 -2
  36. package/docs/cli-rpc.md +26 -3
  37. package/docs/coding-agent-tools.md +7 -1
  38. package/docs/coding-security.md +1 -1
  39. package/docs/coding-tools.md +82 -0
  40. package/docs/compaction-and-retry.md +5 -2
  41. package/docs/compaction-llm.md +4 -4
  42. package/docs/compaction-observational-memory.md +49 -2
  43. package/docs/context-and-skills.md +2 -0
  44. package/docs/core.md +85 -0
  45. package/docs/credential-storage.md +1 -1
  46. package/docs/database-persistence.md +4 -0
  47. package/docs/dev-inspector.md +103 -0
  48. package/docs/diagrams.md +247 -0
  49. package/docs/documents.md +213 -0
  50. package/docs/evaluations.md +35 -1
  51. package/docs/extension-authoring.md +42 -0
  52. package/docs/graft.md +3 -3
  53. package/docs/guardrails.md +1 -1
  54. package/docs/host-security.md +4 -3
  55. package/docs/impeccable.md +2 -2
  56. package/docs/index.md +34 -23
  57. package/docs/mcp-tools.md +1 -1
  58. package/docs/migrate-to-0.4.md +312 -0
  59. package/docs/migration.md +22 -0
  60. package/docs/model-routing.md +1 -1
  61. package/docs/multi-agent-patterns.md +177 -0
  62. package/docs/multimodal-content.md +1 -1
  63. package/docs/obscura.md +10 -10
  64. package/docs/openapi-tools.md +1 -1
  65. package/docs/performance.md +23 -3
  66. package/docs/persistence-credentials-multimodality-primitives.md +1 -1
  67. package/docs/policy-and-audit.md +1 -1
  68. package/docs/ponytail.md +2 -2
  69. package/docs/prompt-registry.md +106 -0
  70. package/docs/provider-caching.md +32 -32
  71. package/docs/provider-conformance.md +1 -1
  72. package/docs/provider-packages.md +19 -19
  73. package/docs/provider-primitives.md +4 -4
  74. package/docs/providers/ai-sdk.md +3 -3
  75. package/docs/providers/alibaba.md +5 -5
  76. package/docs/providers/anthropic.md +6 -6
  77. package/docs/providers/azure.md +3 -3
  78. package/docs/providers/bedrock.md +3 -3
  79. package/docs/providers/clinepass.md +3 -3
  80. package/docs/providers/deepseek.md +3 -3
  81. package/docs/providers/google.md +4 -4
  82. package/docs/providers/kimi.md +3 -3
  83. package/docs/providers/neuralwatt.md +8 -8
  84. package/docs/providers/ollama.md +3 -3
  85. package/docs/providers/openai-compatible.md +1 -1
  86. package/docs/providers/openai.md +5 -5
  87. package/docs/providers/opencode-go.md +4 -4
  88. package/docs/providers/openrouter.md +3 -3
  89. package/docs/providers/vertex.md +5 -5
  90. package/docs/providers/xai.md +3 -3
  91. package/docs/providers/zai.md +3 -3
  92. package/docs/public-contracts.md +1 -1
  93. package/docs/rag.md +5 -5
  94. package/docs/release-and-install.md +116 -50
  95. package/docs/runs-and-usage.md +14 -1
  96. package/docs/server.md +90 -1
  97. package/docs/sheets.md +229 -0
  98. package/docs/supervisors.md +9 -1
  99. package/docs/thinking-and-reasoning.md +10 -10
  100. package/docs/tool-conformance.md +27 -2
  101. package/docs/tools.md +29 -2
  102. package/docs/web-tools.md +2 -2
  103. package/docs/wiki.md +24 -10
  104. package/docs/workflow-orchestration-primitives.md +24 -0
  105. package/docs/workflows.md +102 -8
  106. package/docs/working-and-semantic-memory.md +53 -5
  107. package/package.json +10 -30
  108. package/templates/README.md +23 -0
  109. package/templates/deep-research/README.md.tmpl +47 -0
  110. package/templates/deep-research/env.example.tmpl +12 -0
  111. package/templates/deep-research/gitignore.tmpl +7 -0
  112. package/templates/deep-research/manifest.json +12 -0
  113. package/templates/deep-research/package.json.tmpl +23 -0
  114. package/templates/deep-research/src/agent.ts.tmpl +81 -0
  115. package/templates/deep-research/src/index.ts.tmpl +53 -0
  116. package/templates/deep-research/src/tests/research.test.ts.tmpl +114 -0
  117. package/templates/deep-research/src/tools.ts.tmpl +86 -0
  118. package/templates/deep-research/src/types.ts.tmpl +45 -0
  119. package/templates/deep-research/src/workflow.ts.tmpl +156 -0
  120. package/templates/deep-research/tsconfig.json.tmpl +15 -0
  121. package/templates/init/manifest.json +5 -0
  122. package/templates/init/package.json.tmpl +2 -1
  123. package/templates/init/providers.json +16 -16
@@ -65,6 +65,26 @@ serialized provider event at the exact response-byte cap succeeds; one byte belo
65
65
  fails closed, including multibyte Unicode deltas. Context-budget omission order and
66
66
  newest-history preservation remain covered by the root context-budget tests.
67
67
 
68
+ ## Tool progressive disclosure (plan 041)
69
+
70
+ `node scripts/benchmark.mjs --scenario tool-search` is network-free (mock assembly, in-memory, no credentials). It builds a 128-tool fixture registry and assembles the provider input once per mode through `assembleProviderInput`: `toolsDisclosure "all"` (default, full tool set) vs `"search"` (top-k 16 plus the generated `search_tools` tool), then asserts provider-request tool-definition bytes shrink ≥ 60% and the index+score pass stays well under a turn. Frozen caps live in `scripts/budgets.json#toolSearch` (reduction floor 0.6, index+score ceiling 50 ms, disclosed-count ceiling 33 — sanity bounds, machine-dependent). Schema/caps/network-free gating in `npm test`: `scripts/benchmark-tool-search.test.mjs`.
71
+
72
+ ```bash
73
+ node scripts/benchmark.mjs --scenario tool-search --out /tmp/prism-tool-search.json
74
+ ```
75
+
76
+ Recorded 2026-08-30, Node v24.19.0 / Linux x64: tool bytes 31,923 → 4,329 (**86.4% reduction**, floor 60%), index+score 1.9–2.5 ms across three runs, disclosed 17 tools (top-k 16 + `search_tools`). Tool-accuracy fixtures (mock provider picking by name among 64/128 distractors, scripted scanner reading only the disclosed list) show search mode at full-exposure pick accuracy in both sizes — the conformance floor `search ≥ all` holds (`src/__tests__/tool-search.test.ts`).
77
+
78
+ ## Workflow loop refinement (plan 045)
79
+
80
+ `node scripts/benchmark.mjs --scenario workflow-loop` is network-free: five serial `loopNode` iterations each run one refinement through a mock provider and an in-memory checkpoint adapter. The frozen budget in `scripts/budgets.json#workflowLoop` allows 50 ms p95 per node execution, or 250 ms across all five iterations. The scenario also checks five provider calls, five finished iteration records, peak provider concurrency of one, and zero active work after completion.
81
+
82
+ Recorded 2026-08-31 on Node v24.19.0 / Linux x64: 5 warmups + 20 measured runs, p50 **2.356 ms**, p95 **6.443 ms** (**1.289 ms/iteration**), 352.88 runs/s. `maxNodes` remains the declared-node count; `maxIterations` is the independent runtime budget and stays hard-capped at 64. These timings are local evidence, not portable SLOs.
83
+
84
+ ```bash
85
+ node scripts/benchmark.mjs --scenario workflow-loop --out /tmp/prism-workflow-loop.json
86
+ ```
87
+
68
88
  ## Current-line root artifact diet
69
89
 
70
90
  `npm pack --dry-run --json` on `@arnilo/prism` is gated by `scripts/budget-gate.test.mjs` against `scripts/budgets.json#root` (±5%). Repository-only history stays out of the tarball: `docs/_evidence/**`, `docs/release-*-evidence.md`, `docs/api-page-template.md`, `dist/__tests__`, and `*.map`. Every page linked from shipped `docs/index.md` must be in the pack. Recorded 2026-08-27: **923,045 packed / 3,149,665 unpacked / 375 files** (226 `dist` js+d.ts, 124 index-linked docs, 25 other). 0.1.0 freeze 713,454 / 293 stays historical.
@@ -365,7 +385,7 @@ Structured Git/check/handoff defaults/hard caps: paths 1,000/10,000; refs 1 KiB/
365
385
 
366
386
  Durable coding plan/checkpoint defaults/hard caps: plan Markdown 256 KiB/1 MiB; todos 1,000/10,000 with 512 B/4 KiB text; checkpoint metadata 64 KiB/512 KiB; artifact references 16/64 at 256 MiB/2 GiB each; check summaries 1 KiB/8 KiB. Checkpoints store URI/hash/summaries/fingerprints only; resume revalidates workspace root, base branch, plan hash, and tool/policy/image fingerprints before import.
367
387
 
368
- Browser automation defaults/hard caps from `@arnilo/prism-browser`: pages 4/16; actions 100/256; queued actions 16/64; snapshot refs 2,000/10,000; depth 30/100; snapshot bytes 256 KiB/2 MiB; navigation 30 s/120 s; action 10 s/60 s; wait 30 s/120 s; run wall 20 min/30 min; popups 4/16; dialogs 16/64; listeners 64/256; action input 64 KiB/256 KiB; close grace 5 s/30 s; network requests 1,000/10,000 with 10/32 redirects per request and 8/32 WebSockets; screenshots 16/64 with 16/64 megapixels and 10 MiB/32 MiB encoded; uploads 8/32 files, 16 MiB/64 MiB each, 64 MiB/256 MiB aggregate; downloads 8/32 files, 32 MiB/256 MiB each, 64 MiB/512 MiB aggregate. Caps charge before context/page/action/queue/snapshot/network/artifact retention. Host supplies Playwright and egress proxy attestation; package import launches nothing.
388
+ Browser automation defaults/hard caps from the `browser` subpath: pages 4/16; actions 100/256; queued actions 16/64; snapshot refs 2,000/10,000; depth 30/100; snapshot bytes 256 KiB/2 MiB; navigation 30 s/120 s; action 10 s/60 s; wait 30 s/120 s; run wall 20 min/30 min; popups 4/16; dialogs 16/64; listeners 64/256; action input 64 KiB/256 KiB; close grace 5 s/30 s; network requests 1,000/10,000 with 10/32 redirects per request and 8/32 WebSockets; screenshots 16/64 with 16/64 megapixels and 10 MiB/32 MiB encoded; uploads 8/32 files, 16 MiB/64 MiB each, 64 MiB/256 MiB aggregate; downloads 8/32 files, 32 MiB/256 MiB each, 64 MiB/512 MiB aggregate. Caps charge before context/page/action/queue/snapshot/network/artifact retention. Host supplies Playwright and egress proxy attestation; package import launches nothing.
369
389
 
370
390
  0.0.14 co-work defaults/hard caps (frozen in [Phase 9 evidence](_evidence/review-coverage-2026-07-25-phase-9.md)): conversation thread list pages 50/200, active branches per thread 16/64, replay/export page 100/500 events; artifact revisions per artifact 32/128, artifacts per thread 64/256, metadata record 8/64 KiB, preview 16/64 KiB, citations 32/128 (2/8 KiB each), delivery-link TTL 5 min/24 h, delivery token 4/16 KiB, compare exactly 2 revisions; memory retention batch 500/5000; proactive capability TTL 24 h/31 d, capability token record 16 KiB; browser checkpoint URL 8 KiB/16 KiB, domain-state hash 256 B/1 KiB, host-data ref 2 KiB/8 KiB, 16/64 checkpoints per run; device stream chunk 1 MiB/8 MiB, concurrent device sessions per identity 1/4 (device wall/turns/tool calls consume shared `RunLimits`). All caps charge before persist/emit and fail closed on overflow. Benchmark placeholder: `node scripts/benchmark-0.0.14.mjs` (release Task 12) reports conversation replay, memory injection/consent, artifact revision/delivery, AG-UI co-work mapping, and connector refresh overhead against these budgets.
371
391
 
@@ -595,7 +615,7 @@ Experiment concurrency is capped at 32 workers and defaults to 1. Scorers operat
595
615
 
596
616
  ### 0.0.5 Phase 6 verification (2026-07-15)
597
617
 
598
- Optional `@arnilo/prism-provider-ai-sdk` adapts AI SDK `LanguageModelV4` streams to Prism without adding an AI SDK dependency to core.
618
+ Optional `@arnilo/prism-providers/ai-sdk` adapts AI SDK `LanguageModelV4` streams to Prism without adding an AI SDK dependency to core.
599
619
 
600
620
  | Surface | Result |
601
621
  | --- | --- |
@@ -751,7 +771,7 @@ Offline behavior tests (identity propagation, policy export, router deny paths,
751
771
 
752
772
  ### 0.3.x Phase 39 Obscura browser-engine envelopes (2026-08-29)
753
773
 
754
- `@arnilo/prism-obscura` binary-backed legs, network-free, driven by a deterministic fake CLI: `node scripts/benchmark-obscura.mjs` (3 runs, medians vs reviewed ceilings; artifact `scripts/benchmark-obscura.json`). Startup leg probes SIG-0 liveness after spawn — a real host waits on its readiness endpoint inside the same bound.
774
+ `obscura` binary-backed legs, network-free, driven by a deterministic fake CLI: `node scripts/benchmark-obscura.mjs` (3 runs, medians vs reviewed ceilings; artifact `scripts/benchmark-obscura.json`). Startup leg probes SIG-0 liveness after spawn — a real host waits on its readiness endpoint inside the same bound.
755
775
 
756
776
  | Leg | Median (3 runs) | Ceiling | Notes |
757
777
  | --- | --- | --- | --- |
@@ -70,7 +70,7 @@ Static review of `src/contracts.ts`, `src/session-stores.ts`, `src/credentials.t
70
70
  | `refreshOAuthCredential` | `src/credentials.ts` | Calls `OAuthProvider.refresh`; optional `OAuthCredentialStore.set` |
71
71
  | `OAuthCredentialStore` | `src/contracts.ts` | `set(provider, credentials)` only — no `get`/`delete` in core contract |
72
72
  | `OAuthProvider` / `OAuthCredentials` | `src/contracts.ts` | `login`, optional `refresh`, optional `getCredential` |
73
- | Device-code OAuth | `packages/provider-openai` | Bounded polling; abort via `OAuthLoginCallbacks.signal` |
73
+ | Device-code OAuth | `packages/prism-providers/src/openai` | Bounded polling; abort via `OAuthLoginCallbacks.signal` |
74
74
  | Redaction | `src/redaction.ts` | Exact known-secret replacement; not secret detection |
75
75
 
76
76
  **Gaps (C-011):** No encrypted file store, no system keychain adapter, no versioned credential envelope, no `OAuthCredentialStore` `get`/`delete`/`list` in core (Task 4 package may extend store interface locally while integrating `refreshOAuthCredential`).
@@ -203,4 +203,4 @@ await evaluateAndAppend(request, { store: state.policy, evaluator, id: crypto.ra
203
203
  - [Workflows](workflows.md): proactive schedule capability enable/revoke events bridge here via `onCapability`.
204
204
  - [Host security](host-security.md)
205
205
  - [Enterprise PostgreSQL state](enterprise-postgres-state.md): durable policy/evaluation/work/router composition.
206
- - Package README: [`@arnilo/prism-policy`](../packages/policy/README.md)
206
+ - Package README: [`@arnilo/prism-core`](../packages/prism-core/README.md)
package/docs/ponytail.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- `@arnilo/prism-ponytail` is an optional package that wires [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail) into Prism contribution contracts.
5
+ `@arnilo/prism-coding-tools/ponytail` is an optional package that wires [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail) into Prism contribution contracts.
6
6
 
7
7
  It registers upstream skills and commands, injects active mode instructions via upstream `getPonytailInstructions` / `filterSkillBodyForMode`, and persists mode as session custom `ponytail-mode` entries. Import is inert; missing upstream fails closed at `setup` with a bounded redacted error.
8
8
 
@@ -66,7 +66,7 @@ Deactivation: exact phrases `stop ponytail` and `normal mode`.
66
66
  ## Implementation example
67
67
 
68
68
  ```ts
69
- import { createPonytailExtension } from "@arnilo/prism-ponytail";
69
+ import { createPonytailExtension } from "@arnilo/prism-coding-tools/ponytail";
70
70
  import {
71
71
  createExtensionKernel,
72
72
  createLoadSkillTool,
@@ -0,0 +1,106 @@
1
+ # Versioned prompt registry
2
+
3
+ ## What it does
4
+
5
+ The optional `@arnilo/prism-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-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-prompts";
61
+ const sqlite = createSqlitePromptStore({ filename: "./prompts.db" });
62
+
63
+ import { createPostgresPromptStore } from "@arnilo/prism-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-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-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-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.
@@ -147,46 +147,46 @@ 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-provider-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-provider-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-provider-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-provider-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-provider-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-provider-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. |
156
- | `@arnilo/prism-provider-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. |
157
- | `@arnilo/prism-provider-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. |
158
- | `@arnilo/prism-provider-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. |
159
- | `@arnilo/prism-provider-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. |
160
- | `@arnilo/prism-provider-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`. |
161
- | `@arnilo/prism-provider-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`. |
162
- | `@arnilo/prism-provider-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). |
163
- | `@arnilo/prism-provider-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. |
164
- | `@arnilo/prism-provider-azure` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Azure cache policy. |
165
- | `@arnilo/prism-provider-bedrock` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Bedrock cache policy. |
166
- | `@arnilo/prism-provider-vertex` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Vertex cache policy. |
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/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. |
156
+ | `@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. |
157
+ | `@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. |
158
+ | `@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. |
159
+ | `@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. |
160
+ | `@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`. |
161
+ | `@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`. |
162
+ | `@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). |
163
+ | `@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. |
164
+ | `@arnilo/prism-providers/azure` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Azure cache policy. |
165
+ | `@arnilo/prism-providers/bedrock` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Bedrock cache policy. |
166
+ | `@arnilo/prism-providers/vertex` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Vertex cache policy. |
167
167
 
168
168
  Detailed first-party provider notes:
169
169
 
170
- - OpenAI Responses (`@arnilo/prism-provider-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`.
170
+ - 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
171
  - OpenAI-compatible Chat Completions adapter: minimal scope, sends no cache payload; see [OpenAI-compatible provider](providers/openai-compatible.md).
172
- - Anthropic (`@arnilo/prism-provider-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.
173
- - Google (`@arnilo/prism-provider-google`): sends no Prism cache-control payload. Do not infer cache hits or cache token counts from absent Gemini fields.
174
- - OpenRouter (`@arnilo/prism-provider-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.
175
- - OpenCode Go (`@arnilo/prism-provider-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`.
176
- - Z.AI (`@arnilo/prism-provider-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`.
177
- - NeuralWatt (`@arnilo/prism-provider-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.
178
- - Kimi (`@arnilo/prism-provider-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`.
179
- - AI SDK adapter (`@arnilo/prism-provider-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.
180
- - Alibaba Cloud (`@arnilo/prism-provider-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`.
181
- - Ollama (`@arnilo/prism-provider-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`.
182
- - DeepSeek (`@arnilo/prism-provider-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`.
183
- - xAI (`@arnilo/prism-provider-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`.
184
- - ClinePass (`@arnilo/prism-provider-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`.
172
+ - 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.
173
+ - Google (`@arnilo/prism-providers/google`): sends no Prism cache-control payload. Do not infer cache hits or cache token counts from absent Gemini fields.
174
+ - 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.
175
+ - 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`.
176
+ - 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`.
177
+ - 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.
178
+ - 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`.
179
+ - 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.
180
+ - 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`.
181
+ - 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`.
182
+ - 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`.
183
+ - 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`.
184
+ - 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
185
  - 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
186
 
187
187
  ### NeuralWatt cache-aware limiter
188
188
 
189
- NeuralWatt (`@arnilo/prism-provider-neuralwatt`) runs a cache-aware backend rate
189
+ NeuralWatt (`@arnilo/prism-providers/neuralwatt`) runs a cache-aware backend rate
190
190
  limiter on top of its implicit vLLM prefix cache. This shapes long-running agent
191
191
  sessions differently from one-shot chat:
192
192
 
@@ -189,7 +189,7 @@ Canonical contract: [Thinking and reasoning](thinking-and-reasoning.md).
189
189
 
190
190
  ## AI SDK adapter checklist
191
191
 
192
- `@arnilo/prism-provider-ai-sdk` is a host-owned `LanguageModelV4` bridge. It does not participate in the discovery or thinking/reasoning checklists above. Cover instead:
192
+ `@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
193
 
194
194
  1. **No catalog / no setup fetch** — package exports no `list*Models()`; `createAiSdkProvider` wraps a host model only.
195
195
  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`.
@@ -22,15 +22,15 @@ Do not use provider packages as a package manager, credential store, env loader,
22
22
 
23
23
  | Package | 0.0.12 auth registration | Subscription OAuth boundary |
24
24
  | --- | --- | --- |
25
- | `@arnilo/prism-provider-openai` | `api_key` for `openai`; `oauth` for `openai-codex` | Existing host-invoked OpenAI Codex PKCE/device-code flow only. |
26
- | `@arnilo/prism-provider-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`. |
27
- | `@arnilo/prism-provider-deepseek` | `api_key` only | No subscription OAuth. |
28
- | `@arnilo/prism-provider-clinepass` | `api_key` only | No Cline WorkOS / Cline OAuth store share. Host supplies `CLINE_API_KEY`. |
29
- | `@arnilo/prism-provider-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). |
30
- | `@arnilo/prism-provider-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-provider-vertex`](providers/vertex.md). |
31
- | `@arnilo/prism-provider-azure` | host Entra token or Azure resource key | Workload identity via `credential` callback; endpoint host preserved ([docs](providers/azure.md)). |
32
- | `@arnilo/prism-provider-bedrock` | host IAM/IRSA credentials | SigV4 over OpenAI-compatible Bedrock Runtime; region/PrivateLink preserved ([docs](providers/bedrock.md)). |
33
- | `@arnilo/prism-provider-vertex` | host ADC / workload token | OpenAPI-compatible Vertex endpoint; separate from consumer Google package ([docs](providers/vertex.md)). |
25
+ | `@arnilo/prism-providers/openai` | `api_key` for `openai`; `oauth` for `openai-codex` | Existing host-invoked OpenAI Codex PKCE/device-code flow only. |
26
+ | `@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`. |
27
+ | `@arnilo/prism-providers/deepseek` | `api_key` only | No subscription OAuth. |
28
+ | `@arnilo/prism-providers/clinepass` | `api_key` only | No Cline WorkOS / Cline OAuth store share. Host supplies `CLINE_API_KEY`. |
29
+ | `@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). |
30
+ | `@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). |
31
+ | `@arnilo/prism-providers/azure` | host Entra token or Azure resource key | Workload identity via `credential` callback; endpoint host preserved ([docs](providers/azure.md)). |
32
+ | `@arnilo/prism-providers/bedrock` | host IAM/IRSA credentials | SigV4 over OpenAI-compatible Bedrock Runtime; region/PrivateLink preserved ([docs](providers/bedrock.md)). |
33
+ | `@arnilo/prism-providers/vertex` | host ADC / workload token | OpenAPI-compatible Vertex endpoint; separate from consumer Google package ([docs](providers/vertex.md)). |
34
34
 
35
35
  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
36
 
@@ -79,13 +79,13 @@ First-party providers map generic `ModelConfig.parameters.maxTokens` to real out
79
79
 
80
80
  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
81
 
82
- Phase 12 adds explicit npm workspaces for [`@arnilo/prism-provider-openai`](providers/openai.md), [`@arnilo/prism-provider-opencode-go`](providers/opencode-go.md), [`@arnilo/prism-provider-openrouter`](providers/openrouter.md), [`@arnilo/prism-provider-zai`](providers/zai.md), [`@arnilo/prism-provider-kimi`](providers/kimi.md), and [`@arnilo/prism-provider-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.
82
+ 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
83
 
84
- Phase 6 also adds optional [`@arnilo/prism-provider-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.
84
+ 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
85
 
86
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 `CLINE_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
87
 
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-provider-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-provider-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-provider-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-provider-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-provider-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-provider-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-provider-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-provider-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-provider-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-provider-anthropic` registers native Anthropic Messages (`createAnthropicProviderPackage` / `listAnthropicModels`). `@arnilo/prism-provider-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).
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-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
89
 
90
90
  ### Phase 10 compatibility matrix
91
91
 
@@ -158,7 +158,7 @@ export async function listExampleModels(options: {
158
158
  | Static catalog | Featured aliases / offline bootstrap only; may omit live pricing until discovery fills `cost` / `cache` |
159
159
  | 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
160
 
161
- Template: [`listNeuralWattModels`](providers/neuralwatt.md) in `@arnilo/prism-provider-neuralwatt`.
161
+ Template: [`listNeuralWattModels`](providers/neuralwatt.md) in `@arnilo/prism-providers/neuralwatt`.
162
162
 
163
163
  ### Per-package policy
164
164
 
@@ -195,11 +195,11 @@ Canonical contract: [Thinking and reasoning](thinking-and-reasoning.md). Package
195
195
  A third party ships their own providers the same way Prism ships first-party
196
196
  provider packages: an `Extension` whose `setup(api)` calls
197
197
  `api.registerProvider(provider)` for each provider it owns. First-party
198
- provider packages (`@arnilo/prism-provider-openai`, `@arnilo/prism-provider-openrouter`,
199
- `@arnilo/prism-provider-kimi`, `@arnilo/prism-provider-zai`,
200
- `@arnilo/prism-provider-opencode-go`, `@arnilo/prism-provider-alibaba`,
201
- `@arnilo/prism-provider-ollama`, `@arnilo/prism-provider-deepseek`,
202
- `@arnilo/prism-provider-xai`, `@arnilo/prism-provider-clinepass`) are **opt-in and individually installable**;
198
+ provider packages (`@arnilo/prism-providers/openai`, `@arnilo/prism-providers/openrouter`,
199
+ `@arnilo/prism-providers/kimi`, `@arnilo/prism-providers/zai`,
200
+ `@arnilo/prism-providers/opencode-go`, `@arnilo/prism-providers/alibaba`,
201
+ `@arnilo/prism-providers/ollama`, `@arnilo/prism-providers/deepseek`,
202
+ `@arnilo/prism-providers/xai`, `@arnilo/prism-providers/clinepass`) are **opt-in and individually installable**;
203
203
  `@arnilo/prism` core runs without any first-party provider package (mock-only).
204
204
 
205
205
  A host mixes first-party packages and third-party providers in one resolver.
@@ -207,7 +207,7 @@ The host owns the resolver — declaring a provider does not activate it:
207
207
 
208
208
  ```ts
209
209
  import { createExtensionKernel, createProviderResolver, createAgent } from "@arnilo/prism";
210
- import { createOpenAIProviderPackage } from "@arnilo/prism-provider-openai";
210
+ import { createOpenAIProviderPackage } from "@arnilo/prism-providers/openai";
211
211
 
212
212
  // First-party package, inert until loaded.
213
213
  const kernel = createExtensionKernel();
@@ -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/provider-*/src/` before Plan 054 implementation.
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/provider-neuralwatt` | Parses `Retry-After`, `error.retry_after`, `retry_strategy`; no extra network calls |
38
- | Quota endpoint throttling | `packages/provider-neuralwatt/quota.ts` | Documents 1 rps limit; caller-owned cache |
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
 
@@ -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/provider-openai/src/oauth.ts` |
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` |
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- `@arnilo/prism-provider-ai-sdk` adapts a host-supplied AI SDK `LanguageModelV4` into a Prism `AIProvider`. It maps Prism messages, tools, and structured-output options into `doStream` call options, then translates stream parts into Prism provider events incrementally.
5
+ `@arnilo/prism-providers/ai-sdk` adapts a host-supplied AI SDK `LanguageModelV4` into a Prism `AIProvider`. It maps Prism messages, tools, and structured-output options into `doStream` call options, then translates stream parts into Prism provider events incrementally.
6
6
 
7
7
  Core `@arnilo/prism` does not depend on the AI SDK.
8
8
 
@@ -24,7 +24,7 @@ Do not use it as a credential store, model catalog, or high-level `streamText`/`
24
24
  ## Inputs / request
25
25
 
26
26
  ```ts
27
- import { createAiSdkProvider } from "@arnilo/prism-provider-ai-sdk";
27
+ import { createAiSdkProvider } from "@arnilo/prism-providers/ai-sdk";
28
28
 
29
29
  createAiSdkProvider(options: {
30
30
  model: LanguageModelV4;
@@ -91,7 +91,7 @@ No AI SDK stream part is silently coerced into Prism content: the table above ma
91
91
 
92
92
  ```ts
93
93
  import { createAgent } from "@arnilo/prism";
94
- import { createAiSdkProvider } from "@arnilo/prism-provider-ai-sdk";
94
+ import { createAiSdkProvider } from "@arnilo/prism-providers/ai-sdk";
95
95
 
96
96
  const provider = createAiSdkProvider({ model: hostCreatedLanguageModelV4 });
97
97
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- `@arnilo/prism-provider-alibaba` is a side-effect-free adapter for Alibaba Cloud
5
+ `@arnilo/prism-providers/alibaba` is a side-effect-free adapter for Alibaba Cloud
6
6
  Model Studio / DashScope (including the Coding Plan) over the **OpenAI-compatible**
7
7
  `POST {base}/chat/completions` endpoint.
8
8
 
@@ -64,7 +64,7 @@ import {
64
64
  listAlibabaModels,
65
65
  defineAlibabaModel,
66
66
  alibabaBaseUrl,
67
- } from "@arnilo/prism-provider-alibaba";
67
+ } from "@arnilo/prism-providers/alibaba";
68
68
 
69
69
  createAlibabaProviderPackage(options: AlibabaProviderPackageOptions): ProviderPackage
70
70
  createAlibabaProvider(options?: AlibabaProviderOptions): AIProvider
@@ -104,7 +104,7 @@ verbatim via `baseUrl`.
104
104
  dependency-free).
105
105
 
106
106
  ```ts
107
- import { createAlibabaEmbedder } from "@arnilo/prism-provider-alibaba";
107
+ import { createAlibabaEmbedder } from "@arnilo/prism-providers/alibaba";
108
108
 
109
109
  const embedder = createAlibabaEmbedder({
110
110
  apiKey: process.env.DASHSCOPE_API_KEY,
@@ -208,7 +208,7 @@ import { createExtensionKernel } from "@arnilo/prism";
208
208
  import {
209
209
  createAlibabaProviderPackage,
210
210
  listAlibabaModels,
211
- } from "@arnilo/prism-provider-alibaba";
211
+ } from "@arnilo/prism-providers/alibaba";
212
212
 
213
213
  const kernel = createExtensionKernel();
214
214
 
@@ -255,7 +255,7 @@ await kernel.load([
255
255
  `Authorization: Bearer`; keys are redacted from all thrown errors (including
256
256
  discovery failures). No local filesystem paths enter request payloads.
257
257
  - Opt-in live probe (never part of `npm test`/CI):
258
- `PRISM_LIVE_DASHSCOPE_KEY=… npm run test:live --workspace @arnilo/prism-provider-alibaba`
258
+ `PRISM_LIVE_DASHSCOPE_KEY=… npm run test:live --workspace @arnilo/prism-providers/alibaba`
259
259
  exercises an embeddings round-trip against the real endpoint (model override via
260
260
  `PRISM_LIVE_DASHSCOPE_MODEL`); absent env = documented skip, never a failure.
261
261
  - Caller-supplied `ProviderRequest.options.headers` can add non-owned headers, but
@@ -2,13 +2,13 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- `@arnilo/prism-provider-anthropic` is the first-party Anthropic Messages provider for Prism (`POST /v1/messages`). Setup is side-effect-free: no network, env scan, or keychain lookup during import/setup. Wire format is package-local (OpenCode Go / Kimi Anthropic routes are pattern-only, not a shared core serializer).
5
+ `@arnilo/prism-providers/anthropic` is the first-party Anthropic Messages provider for Prism (`POST /v1/messages`). Setup is side-effect-free: no network, env scan, or keychain lookup during import/setup. Wire format is package-local (OpenCode Go / Kimi Anthropic routes are pattern-only, not a shared core serializer).
6
6
 
7
7
  ## When to use it
8
8
 
9
9
  Use for native Claude Messages (tools, `cache_control`, thinking/reasoning, media, usage, abort). Prefer this over the AI SDK escape hatch when Anthropic is a primary coding host.
10
10
 
11
- Do **not** use for OpenCode Go Anthropic *route* hosting (`@arnilo/prism-provider-opencode-go`), automatic credential discovery, Claude Code credential-file/setup-token import, or Claude.ai subscription login/routing. This package is API-key-only.
11
+ Do **not** use for OpenCode Go Anthropic *route* hosting (`@arnilo/prism-providers/opencode-go`), automatic credential discovery, Claude Code credential-file/setup-token import, or Claude.ai subscription login/routing. This package is API-key-only.
12
12
 
13
13
  ## Inputs / request
14
14
 
@@ -18,7 +18,7 @@ import {
18
18
  createAnthropicMessagesProvider,
19
19
  listAnthropicModels,
20
20
  defineAnthropicModel,
21
- } from "@arnilo/prism-provider-anthropic";
21
+ } from "@arnilo/prism-providers/anthropic";
22
22
 
23
23
  createAnthropicProviderPackage(options?: AnthropicProviderPackageOptions): ProviderPackage
24
24
  createAnthropicMessagesProvider(options?): AIProvider
@@ -60,7 +60,7 @@ Featured offline aliases: `claude-opus-4-8`, `claude-sonnet-5`, `claude-haiku-4-
60
60
 
61
61
  ```ts
62
62
  import { createProviderRegistry, createModelRegistry } from "@arnilo/prism";
63
- import { createAnthropicProviderPackage, listAnthropicModels } from "@arnilo/prism-provider-anthropic";
63
+ import { createAnthropicProviderPackage, listAnthropicModels } from "@arnilo/prism-providers/anthropic";
64
64
 
65
65
  const api = /* ExtensionAPI or host registries */;
66
66
  api.registerProviderPackage(createAnthropicProviderPackage({ apiKey: hostKey }));
@@ -73,7 +73,7 @@ api.registerProviderPackage(createAnthropicProviderPackage({ apiKey: hostKey, mo
73
73
  ## Extension and configuration notes
74
74
 
75
75
  - Register via `defineProviderPackage` / host registries; no package auto-discovery.
76
- - AI SDK (`@arnilo/prism-provider-ai-sdk`) remains an escape hatch, not the primary Anthropic path.
76
+ - AI SDK (`@arnilo/prism-providers/ai-sdk`) remains an escape hatch, not the primary Anthropic path.
77
77
  - Live smoke: `PRISM_LIVE_PROVIDER_TESTS=1` + `ANTHROPIC_API_KEY`.
78
78
  - Anthropic says OAuth is for purchasers' ordinary Claude Code/native-app use; developers building products must use Claude Console API keys or a supported cloud provider and may not offer Claude.ai login or route Free/Pro/Max credentials ([legal and compliance](https://docs.anthropic.com/en/docs/claude-code/legal-and-compliance)). Prism therefore has no Anthropic subscription OAuth API or token-import shortcut.
79
79
 
@@ -90,4 +90,4 @@ api.registerProviderPackage(createAnthropicProviderPackage({ apiKey: hostKey, mo
90
90
  - [Provider caching](../provider-caching.md): `cache_control` breakpoints.
91
91
  - [Thinking and reasoning](../thinking-and-reasoning.md): portable thinking helpers.
92
92
  - [Provider conformance](../provider-conformance.md): network-free assertions.
93
- - Package README: [`packages/provider-anthropic/README.md`](../../packages/provider-anthropic/README.md)
93
+ - Package README: [`@arnilo/prism-providers` family README](../../packages/prism-providers/README.md)