@arnilo/prism 0.0.96 → 0.1.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 (203) hide show
  1. package/CHANGELOG.md +285 -2
  2. package/README.md +17 -3
  3. package/dist/agent-definitions.js +2 -3
  4. package/dist/agent-event-source.d.ts +11 -0
  5. package/dist/agent-event-source.js +512 -0
  6. package/dist/agent-loops.d.ts +5 -0
  7. package/dist/agent-loops.js +99 -14
  8. package/dist/agent-run-lifecycle.d.ts +5 -2
  9. package/dist/agent-run-lifecycle.js +18 -2
  10. package/dist/agent-run-state.d.ts +27 -1
  11. package/dist/agent-run-state.js +113 -7
  12. package/dist/agents.d.ts +3 -1
  13. package/dist/agents.js +1255 -129
  14. package/dist/artifacts.d.ts +132 -0
  15. package/dist/artifacts.js +44 -0
  16. package/dist/cache-helpers.js +18 -9
  17. package/dist/checkpoints.d.ts +4 -0
  18. package/dist/checkpoints.js +17 -9
  19. package/dist/cli-init.js +3 -7
  20. package/dist/cli-runner.d.ts +2 -6
  21. package/dist/cli-runner.js +71 -33
  22. package/dist/compaction.js +5 -4
  23. package/dist/config.js +7 -4
  24. package/dist/content.js +26 -24
  25. package/dist/context-budget.d.ts +67 -0
  26. package/dist/context-budget.js +288 -0
  27. package/dist/contracts.d.ts +590 -8
  28. package/dist/contracts.js +142 -1
  29. package/dist/contribution-parsing.js +6 -2
  30. package/dist/contributions.d.ts +2 -0
  31. package/dist/contributions.js +3 -0
  32. package/dist/conversations.d.ts +50 -0
  33. package/dist/conversations.js +98 -0
  34. package/dist/credentials.d.ts +22 -2
  35. package/dist/credentials.js +18 -3
  36. package/dist/devices.d.ts +94 -0
  37. package/dist/devices.js +138 -0
  38. package/dist/event-multiplexer.js +18 -4
  39. package/dist/extensions.d.ts +18 -1
  40. package/dist/extensions.js +79 -6
  41. package/dist/feedback.js +12 -10
  42. package/dist/guardrails.d.ts +1 -1
  43. package/dist/guardrails.js +26 -17
  44. package/dist/identity.d.ts +92 -0
  45. package/dist/identity.js +265 -0
  46. package/dist/index.d.ts +94 -72
  47. package/dist/index.js +48 -36
  48. package/dist/input.d.ts +10 -1
  49. package/dist/input.js +152 -52
  50. package/dist/instruction-injection.d.ts +1 -1
  51. package/dist/middleware.js +9 -1
  52. package/dist/models.d.ts +2 -0
  53. package/dist/models.js +3 -0
  54. package/dist/node/agent-definitions.js +16 -8
  55. package/dist/node/contribution-discovery.d.ts +1 -2
  56. package/dist/node/contribution-discovery.js +3 -3
  57. package/dist/node/session-store-jsonl.js +13 -7
  58. package/dist/node/settings.d.ts +1 -1
  59. package/dist/node/settings.js +1 -1
  60. package/dist/node/system-project-prompts.js +2 -4
  61. package/dist/node/trust.js +1 -1
  62. package/dist/persistence-lifecycle.d.ts +103 -0
  63. package/dist/persistence-lifecycle.js +202 -0
  64. package/dist/provider-events.d.ts +1 -0
  65. package/dist/provider-events.js +6 -1
  66. package/dist/provider-request-policy.js +3 -4
  67. package/dist/providers/media.d.ts +1 -1
  68. package/dist/providers/openai-compatible.d.ts +46 -1
  69. package/dist/providers/openai-compatible.js +123 -53
  70. package/dist/providers/openai-primitives.js +10 -7
  71. package/dist/providers/transport.d.ts +6 -0
  72. package/dist/providers/transport.js +21 -0
  73. package/dist/providers.d.ts +2 -0
  74. package/dist/providers.js +3 -0
  75. package/dist/redaction.d.ts +1 -0
  76. package/dist/redaction.js +26 -9
  77. package/dist/resources.d.ts +2 -2
  78. package/dist/resources.js +2 -2
  79. package/dist/retry.d.ts +5 -0
  80. package/dist/retry.js +8 -1
  81. package/dist/rpc.js +55 -11
  82. package/dist/run-ledger.d.ts +6 -0
  83. package/dist/run-ledger.js +16 -13
  84. package/dist/run-limits.js +49 -10
  85. package/dist/secure-agent.js +8 -2
  86. package/dist/security.js +7 -2
  87. package/dist/session-stores.d.ts +7 -2
  88. package/dist/session-stores.js +195 -21
  89. package/dist/skill-disclosure.d.ts +35 -0
  90. package/dist/skill-disclosure.js +101 -0
  91. package/dist/skill-load.d.ts +25 -0
  92. package/dist/skill-load.js +112 -0
  93. package/dist/structured-output.d.ts +5 -1
  94. package/dist/structured-output.js +20 -2
  95. package/dist/system-prompts.js +7 -2
  96. package/dist/testing/agent-event-source-conformance.d.ts +4 -0
  97. package/dist/testing/agent-event-source-conformance.js +54 -0
  98. package/dist/testing/compaction-conformance.js +5 -1
  99. package/dist/testing/extension-conformance.js +15 -3
  100. package/dist/testing/feedback.d.ts +1 -3
  101. package/dist/testing/feedback.js +1 -1
  102. package/dist/testing/persistence-schema.d.ts +2 -2
  103. package/dist/testing/persistence-schema.js +280 -35
  104. package/dist/testing/provider-conformance.js +3 -3
  105. package/dist/testing/run-ledger-conformance.js +1 -1
  106. package/dist/testing/session-store-conformance.d.ts +6 -0
  107. package/dist/testing/session-store-conformance.js +37 -2
  108. package/dist/testing/tool-conformance.js +30 -5
  109. package/dist/testing/tool-effect-store-conformance.d.ts +9 -0
  110. package/dist/testing/tool-effect-store-conformance.js +85 -0
  111. package/dist/thinking.js +4 -1
  112. package/dist/tool-effects.d.ts +15 -0
  113. package/dist/tool-effects.js +352 -0
  114. package/dist/tool-result-fold.d.ts +40 -0
  115. package/dist/tool-result-fold.js +176 -0
  116. package/dist/tools.d.ts +8 -3
  117. package/dist/tools.js +248 -13
  118. package/docs/0.1.0-readiness.md +202 -0
  119. package/docs/a2a.md +33 -2
  120. package/docs/acp.md +126 -0
  121. package/docs/ag-ui-adoption.md +77 -0
  122. package/docs/ag-ui.md +225 -0
  123. package/docs/agent-events.md +34 -3
  124. package/docs/agent-identity.md +144 -0
  125. package/docs/agent-loops.md +17 -2
  126. package/docs/agent-session-runtime.md +21 -4
  127. package/docs/browser-automation.md +5 -0
  128. package/docs/caveman.md +129 -0
  129. package/docs/cli-rpc.md +3 -6
  130. package/docs/coding-agent-tools.md +229 -25
  131. package/docs/coding-security.md +77 -11
  132. package/docs/compaction-and-retry.md +5 -2
  133. package/docs/compaction-llm.md +20 -1
  134. package/docs/compaction-observational-memory.md +52 -8
  135. package/docs/context-and-skills.md +94 -7
  136. package/docs/contribution-registries.md +1 -0
  137. package/docs/conversations.md +135 -0
  138. package/docs/credential-storage.md +34 -1
  139. package/docs/credentials-and-redaction.md +11 -1
  140. package/docs/database-persistence.md +27 -7
  141. package/docs/device-adapters.md +97 -0
  142. package/docs/enterprise-postgres-state.md +178 -0
  143. package/docs/evaluations.md +14 -1
  144. package/docs/extensions.md +4 -1
  145. package/docs/forge-integration.md +113 -0
  146. package/docs/guardrails.md +16 -2
  147. package/docs/host-security.md +35 -4
  148. package/docs/index.md +69 -37
  149. package/docs/input-and-prompt-assembly.md +8 -7
  150. package/docs/language-intelligence.md +162 -0
  151. package/docs/mcp-tools.md +62 -5
  152. package/docs/middleware-hooks.md +2 -2
  153. package/docs/migration.md +423 -2
  154. package/docs/model-routing.md +111 -0
  155. package/docs/multimodal-content.md +8 -5
  156. package/docs/node-jsonl-session-store.md +1 -1
  157. package/docs/observability.md +2 -0
  158. package/docs/openapi-tools.md +56 -0
  159. package/docs/performance.md +282 -0
  160. package/docs/policy-and-audit.md +171 -0
  161. package/docs/ponytail.md +127 -0
  162. package/docs/postgres-persistence.md +8 -4
  163. package/docs/process-sessions.md +147 -0
  164. package/docs/provider-caching.md +13 -1
  165. package/docs/provider-conformance.md +29 -5
  166. package/docs/provider-packages.md +43 -2
  167. package/docs/provider-request-policies.md +2 -0
  168. package/docs/providers/ai-sdk.md +24 -7
  169. package/docs/providers/alibaba.md +179 -0
  170. package/docs/providers/anthropic.md +93 -0
  171. package/docs/providers/azure.md +74 -0
  172. package/docs/providers/bedrock.md +72 -0
  173. package/docs/providers/google.md +89 -0
  174. package/docs/providers/ollama.md +166 -0
  175. package/docs/providers/openai-compatible.md +31 -2
  176. package/docs/providers/openai.md +24 -5
  177. package/docs/providers/openrouter.md +2 -0
  178. package/docs/providers/vertex.md +71 -0
  179. package/docs/public-contracts.md +61 -4
  180. package/docs/rag.md +41 -12
  181. package/docs/release-and-install.md +323 -206
  182. package/docs/resource-loading.md +3 -0
  183. package/docs/runs-and-usage.md +3 -0
  184. package/docs/server.md +44 -6
  185. package/docs/session-store-conformance.md +2 -0
  186. package/docs/session-stores.md +41 -2
  187. package/docs/sqlite-persistence.md +11 -3
  188. package/docs/structured-output.md +7 -1
  189. package/docs/supervisors.md +8 -0
  190. package/docs/tool-effects.md +95 -0
  191. package/docs/tools.md +5 -0
  192. package/docs/work-artifacts-and-review.md +102 -0
  193. package/docs/work-connectors.md +32 -0
  194. package/docs/work-tools.md +137 -0
  195. package/docs/workflows.md +6 -0
  196. package/docs/working-and-semantic-memory.md +40 -7
  197. package/package.json +30 -8
  198. package/templates/init/providers.json +22 -0
  199. package/docs/review-coverage-2026-07-14.md +0 -260
  200. package/docs/review-coverage-2026-07-15.md +0 -193
  201. package/docs/review-coverage-2026-07-17-provider-validation.md +0 -192
  202. package/docs/review-coverage-2026-07-19-phase-3.md +0 -174
  203. package/docs/review-coverage-2026-07-20-phase-4.md +0 -175
@@ -18,6 +18,19 @@ 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
+ ### Subscription OAuth support matrix
22
+
23
+ | Package | 0.0.12 auth registration | Subscription OAuth boundary |
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-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). |
27
+ | `@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). |
28
+ | `@arnilo/prism-provider-azure` | host Entra token or Azure resource key | Workload identity via `credential` callback; endpoint host preserved ([docs](providers/azure.md)). |
29
+ | `@arnilo/prism-provider-bedrock` | host IAM/IRSA credentials | SigV4 over OpenAI-compatible Bedrock Runtime; region/PrivateLink preserved ([docs](providers/bedrock.md)). |
30
+ | `@arnilo/prism-provider-vertex` | host ADC / workload token | OpenAPI-compatible Vertex endpoint; separate from consumer Google package ([docs](providers/vertex.md)). |
31
+
32
+ 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.
33
+
21
34
  ## Inputs / request
22
35
 
23
36
  ```ts
@@ -67,7 +80,28 @@ Phase 6 also adds optional [`@arnilo/prism-provider-ai-sdk`](providers/ai-sdk.md
67
80
 
68
81
  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`, or `OPENCODE_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.
69
82
 
70
- 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.
83
+ 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-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).
84
+
85
+ ### Phase 10 compatibility matrix
86
+
87
+ Every package remains explicit, setup-zero-fetch, and late-credential-bound. `ModelConfig.capabilities.input` is authoritative: a listed wire mapping is usable only when the selected model declares that tag; unsupported blocks reject before provider I/O. “Protected” means an operator/release-environment probe, never default CI; its exact key/command boundary is in [Release and install](release-and-install.md#015-protected-live-canary-matrix).
88
+
89
+ | Package | Protocol / model source | Content mapping | Stream, tools, and reasoning | Cache / canary |
90
+ | --- | --- | --- | --- | --- |
91
+ | 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 |
92
+ | 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.4 matrix (`4.0.3` also listed); protected host integration |
93
+ | Anthropic | Messages; caller-gated list | text, image, PDF document/file | tool deltas, thinking | `cache_control`; protected API-key smoke |
94
+ | Google | Gemini `generateContent`; caller-gated list | text, image, audio, document/file | complete tool calls, thinking | no Prism cache marker; protected API-key smoke |
95
+ | 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 |
96
+ | Z.AI | OpenAI-compatible; caller-gated list | text, image | tool deltas, `reasoning_content` | implicit; protected API-key smoke |
97
+ | OpenRouter | OpenAI-compatible; host catalog + caller-gated list | text, image | tool deltas, reasoning replay/routing metadata | `cache_control`; protected API-key smoke |
98
+ | 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 |
99
+ | Alibaba | DashScope OpenAI-compatible; caller-gated list | text, image | tool deltas, Qwen thinking | implicit / optional markers; protected host probe |
100
+ | Ollama | Cloud/local OpenAI-compatible; caller-gated list | text, image | tool deltas, reasoning effort | implicit only; protected host/daemon probe |
101
+ | NeuralWatt | OpenAI-compatible; caller-gated list | text, image | tool deltas, reasoning and telemetry | implicit; protected API-key smoke |
102
+ | Azure | Azure/Foundry OpenAI-compatible; host models | selected endpoint/model capability | normalized OpenAI-compatible tools | no Prism cache mapping; protected host workload-identity probe |
103
+ | Bedrock | Bedrock OpenAI-compatible; host models | selected endpoint/model capability | normalized OpenAI-compatible tools | no Prism cache mapping; protected host IAM/IRSA probe |
104
+ | Vertex | Vertex OpenAPI-compatible; host models | selected endpoint/model capability | normalized OpenAI-compatible tools | no Prism cache mapping; protected host ADC/WIF probe |
71
105
 
72
106
  ### First-party cache behavior
73
107
 
@@ -80,6 +114,8 @@ Every first-party provider package hardens prompt-cache behavior so it cannot em
80
114
  - **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.
81
115
  - **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.
82
116
  - **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.
117
+ - **Alibaba Cloud** (implicit by default, optional `cache_control`): DashScope implicit prefix caching is automatic; hosts opt in via `ModelConfig.cache.kind: cache_control`, then `cache_control: {"type":"ephemeral"}` markers apply only to selected breakpoints, capped at 4. `prompt_tokens_details.cached_tokens`/`cache_creation_input_tokens` map to cache usage. Caller-gated `listAlibabaModels`.
118
+ - **Ollama** (`kind: implicit`): Ollama KV/prefix caching is automatic with no request knob; sends no explicit cache payload. Ollama reports no cached-token count, so `Usage.cacheReadTokens` stays `undefined`. Caller-gated `listOllamaModels`.
83
119
 
84
120
  See [Provider caching](provider-caching.md) for the `PromptCacheHints` surface and shared helpers, and [Provider conformance](provider-conformance.md) for the `assertUsageAccounting` and `assertProviderOwnedHeadersWin` checks every first-party package exercises.
85
121
 
@@ -147,7 +183,8 @@ provider packages: an `Extension` whose `setup(api)` calls
147
183
  `api.registerProvider(provider)` for each provider it owns. First-party
148
184
  provider packages (`@arnilo/prism-provider-openai`, `@arnilo/prism-provider-openrouter`,
149
185
  `@arnilo/prism-provider-kimi`, `@arnilo/prism-provider-zai`,
150
- `@arnilo/prism-provider-opencode-go`) are **opt-in and individually installable**;
186
+ `@arnilo/prism-provider-opencode-go`, `@arnilo/prism-provider-alibaba`,
187
+ `@arnilo/prism-provider-ollama`) are **opt-in and individually installable**;
151
188
  `@arnilo/prism` core runs without any first-party provider package (mock-only).
152
189
 
153
190
  A host mixes first-party packages and third-party providers in one resolver.
@@ -258,6 +295,8 @@ await kernel.load([pkg]);
258
295
  - Provider-specific behavior belongs in provider packages, not Prism core.
259
296
  - 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.
260
297
  - 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.
298
+ - For allow-list/residency/budget/circuit selection before resolve, use optional `@arnilo/prism-model-router` over `createProviderResolver` — do not fork provider packages for governance.
299
+ - Enterprise cloud adapters (`azure` / `bedrock` / `vertex`) stay separate from consumer Anthropic/Google packages and authenticate only through host credential callbacks.
261
300
 
262
301
  ## Manifest declarations
263
302
 
@@ -281,6 +320,8 @@ Manifest declarations are inert. The host must later resolve them through regist
281
320
 
282
321
  ## Related APIs
283
322
 
323
+ - [Model routing](model-routing.md): optional governance router over `ProviderResolver`.
324
+ - [Azure OpenAI / Foundry](providers/azure.md) / [Amazon Bedrock](providers/bedrock.md) / [Google Vertex AI](providers/vertex.md): enterprise workload-identity packages.
284
325
  - [Provider layer](provider-layer.md): provider/model registries and provider events.
285
326
  - [Provider conformance](provider-conformance.md): reusable network-free checks for provider adapters.
286
327
  - [Contribution registries](contribution-registries.md): registry bundle and extension contribution points.
@@ -104,9 +104,11 @@ 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
108
 
108
109
  ## Related APIs
109
110
 
111
+ - [Model routing](model-routing.md): governance facade that emits a chainable OpenRouter routing gate policy.
110
112
  - [Provider caching](provider-caching.md): structured cache hints and helpers.
111
113
  - [Provider packages](provider-packages.md): registering policies from extension packages.
112
114
  - [Provider layer](provider-layer.md): provider request flow and `AIProvider.generate()`.
@@ -4,7 +4,16 @@
4
4
 
5
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.
6
6
 
7
- Supported specification: `@ai-sdk/provider` **v4** (`specificationVersion: "v4"`). Core `@arnilo/prism` does not depend on the AI SDK.
7
+ Core `@arnilo/prism` does not depend on the AI SDK.
8
+
9
+ ### Supported-version matrix
10
+
11
+ | `@ai-sdk/provider` | `LanguageModel` ABI | Status |
12
+ | --- | --- | --- |
13
+ | `4.0.3` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
14
+ | `4.0.4` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
15
+
16
+ The peer dependency is intentionally exact. `createAiSdkProvider()` reads its resolved `@ai-sdk/provider/package.json` version during setup and throws typed `AiSdkProviderError { code: "unsupported_version" }` for an unlisted version; it does not infer compatibility from a matching `"v4"` string.
8
17
 
9
18
  ## When to use it
10
19
 
@@ -19,6 +28,7 @@ import { createAiSdkProvider } from "@arnilo/prism-provider-ai-sdk";
19
28
 
20
29
  createAiSdkProvider(options: {
21
30
  model: LanguageModelV4;
31
+ redactor?: SecretRedactor;
22
32
  id?: string;
23
33
  }): AIProvider
24
34
  ```
@@ -26,6 +36,7 @@ createAiSdkProvider(options: {
26
36
  | Field | Type | Purpose |
27
37
  | --- | --- | --- |
28
38
  | `model` | `LanguageModelV4` | Host-owned AI SDK language model. |
39
+ | `redactor` | `SecretRedactor` | Optional direct-provider error redactor; agent runs use their active redactor. |
29
40
  | `id` | `string` | Prism provider id. Defaults to `ai-sdk:<model.provider>` or `ai-sdk`. |
30
41
 
31
42
  Mapped request surfaces:
@@ -34,7 +45,7 @@ Mapped request surfaces:
34
45
  | --- | --- |
35
46
  | `messages` | `LanguageModelV4Prompt` |
36
47
  | `tools` | `LanguageModelV4FunctionTool[]` with JSON Schema `inputSchema` |
37
- | `options.structuredOutput` | `responseFormat: { type: "json", name, schema }` |
48
+ | `options.structuredOutput` | `responseFormat: { type: "json", name, schema }`; `strict` fails explicitly (V4 has no equivalent) |
38
49
  | `model.parameters` | `maxOutputTokens`, `temperature`, `topP`, `topK`, penalties, `seed`, `stopSequences` |
39
50
  | `request.signal` | `abortSignal` (always wins over adapter options) |
40
51
  | `options.headers` | extension headers only; model owns auth |
@@ -45,16 +56,22 @@ Unsupported content fails before `doStream` (for example unresolved `resourceUri
45
56
 
46
57
  | AI SDK stream part | Prism event |
47
58
  | --- | --- |
59
+ | `response-metadata.id` | `message_start.messageId` |
48
60
  | `text-delta` | `content_delta` text |
49
61
  | `reasoning-delta` | `content_delta` thinking |
50
62
  | `tool-input-start` / `tool-input-delta` | `tool_call_delta` |
51
- | `tool-call` (client-executed) | `tool_call` |
63
+ | `tool-call` | `tool_call`; `providerExecuted` becomes `authority: "provider-hosted"` |
52
64
  | `finish` usage | `usage` then `done` |
53
65
  | `error` / thrown / abort | redacted `error` |
66
+ | `stream-start`, boundaries, raw diagnostics | intentionally not emitted: no normalized safe payload |
67
+ | provider-executed `tool-result` | remains provider-side; no host result or dispatch |
68
+ | file / reasoning-file / source / custom / approval request | typed `unsupported_mapping` error |
69
+
70
+ `response-metadata.modelId`/timestamp and opaque `providerMetadata` have no normalized Prism counterpart and are not emitted, preventing provider-private metadata from entering prompt, event, or telemetry paths.
54
71
 
55
72
  `finish.usage.inputTokens.cacheRead` / `cacheWrite` map to Prism `Usage.cacheReadTokens` / `cacheWriteTokens`. The adapter does not invent cache request fields; prompt caching is owned by the host `LanguageModelV4` and its upstream provider.
56
73
 
57
- Provider-executed tool calls, files/sources/custom parts, warnings, and raw chunks are ignored rather than silently converted into unsupported Prism content.
74
+ No AI SDK stream part is silently coerced into Prism content: the table above maps safe normalized semantics, deliberately withholds provider-private diagnostics/results, and fails unsupported output types explicitly.
58
75
 
59
76
  ## Request/response example
60
77
 
@@ -127,7 +144,7 @@ Official evidence: [Custom providers / LanguageModelV4](https://ai-sdk.dev/provi
127
144
 
128
145
  ## Extension and configuration notes
129
146
 
130
- - Peer dependency: `@ai-sdk/provider@^4.0.0`. Upgrade policy tracks one specification major at a time.
147
+ - Peer dependency: `@ai-sdk/provider@4.0.4` (matrix also lists `4.0.3`). Upgrade policy adds a matrix row and offline conformance fixture before accepting any new version.
131
148
  - First-party HTTP providers remain independent; this adapter is available directly, through `@arnilo/prism-providers`, or through `@arnilo/prism-all`. Installation does not select a model or invoke AI SDK.
132
149
  - `options.compat` / `options.extra` pass through as AI SDK `providerOptions.prism`.
133
150
  - Export helpers `toAiSdkCallOptions`, `toAiSdkPrompt`, and `mapAiSdkStream` for tests and custom hosts.
@@ -137,8 +154,8 @@ Official evidence: [Custom providers / LanguageModelV4](https://ai-sdk.dev/provi
137
154
  - Host credentials stay inside the supplied AI SDK model. The adapter never reads env keys or credential stores.
138
155
  - Abort and resource limits come from Prism `request.signal`; adapter options cannot replace that bound.
139
156
  - Stream parts are translated incrementally with no full-response buffering and no duplicate model call.
140
- - Unsupported content fails closed before model invocation. Errors use Prism `providerError` redaction.
141
- - Provider metadata/warnings are not emitted as prompt or tool content.
157
+ - Unsupported content and stream parts fail closed before/at mapping; `structuredOutput.strict` is rejected because V4 cannot carry it.
158
+ - Pass `redactor` for direct use; agent runs apply their active redactor. Provider metadata/warnings never become prompt, tool, event, or telemetry content.
142
159
 
143
160
  ## Related APIs
144
161
 
@@ -0,0 +1,179 @@
1
+ # Alibaba Cloud provider package
2
+
3
+ ## What it does
4
+
5
+ `@arnilo/prism-provider-alibaba` is a side-effect-free adapter for Alibaba Cloud
6
+ Model Studio / DashScope (including the Coding Plan) over the **OpenAI-compatible**
7
+ `POST {base}/chat/completions` endpoint.
8
+
9
+ - **Dynamic model discovery** — `listAlibabaModels()` calls the OpenAI-compatible
10
+ `GET {base}/models`. No model catalog is hard-coded in the package: available
11
+ models vary by region, workspace, and billing plan, so discovery is the source of
12
+ truth. Package setup never fetches.
13
+ - **Context cache** — DashScope implicit prefix caching is automatic. Explicit
14
+ caching is opt-in via Anthropic-style `cache_control: {"type":"ephemeral"}`
15
+ markers (at most 4 per request). Cache hits are accounted from
16
+ `usage.prompt_tokens_details.cached_tokens` (read) and
17
+ `cache_creation_input_tokens` (write).
18
+ - **Qwen thinking** — `enable_thinking` passthrough toggles reasoning on Qwen models.
19
+
20
+ The API key is region/plan-scoped: it must match the base URL's billing plan
21
+ (pay-as-you-go regional, workspace-dedicated, or Coding Plan).
22
+
23
+ ## When to use it
24
+
25
+ Use it when a host app wants Alibaba Cloud Qwen models (Model Studio / DashScope or
26
+ the Coding Plan) through Prism's `AgentSession` runtime with OpenAI-compatible
27
+ serialization, dynamic model discovery, and explicit/implicit cache accounting.
28
+
29
+ Do not use it for automatic credential discovery, setup-time catalog fetches, or
30
+ real-network tests (live tests stay opt-in).
31
+
32
+ ## Inputs / request
33
+
34
+ ```ts
35
+ import {
36
+ createAlibabaProviderPackage,
37
+ createAlibabaProvider,
38
+ listAlibabaModels,
39
+ defineAlibabaModel,
40
+ alibabaBaseUrl,
41
+ } from "@arnilo/prism-provider-alibaba";
42
+
43
+ createAlibabaProviderPackage(options: AlibabaProviderPackageOptions): ProviderPackage
44
+ createAlibabaProvider(options?: AlibabaProviderOptions): AIProvider
45
+ listAlibabaModels(options?: ListAlibabaModelsOptions): Promise<ModelConfig[]>
46
+ defineAlibabaModel(config: AlibabaModelConfig): ModelConfig
47
+ alibabaBaseUrl(options?: { baseUrl?: string; preset?: AlibabaBasePreset }): string
48
+ ```
49
+
50
+ | Field | Type | Purpose |
51
+ | --- | --- | --- |
52
+ | `apiKey` | `CredentialValueSource` | DashScope API key (`DASHSCOPE_API_KEY`), region/plan-scoped. |
53
+ | `baseUrl` | `string` | Explicit OpenAI-compatible base URL (wins over `preset`). |
54
+ | `preset` | `AlibabaBasePreset` | `"singapore"` (default) / `"beijing"` / `"us"` / `"coding-plan"`. |
55
+ | `fetch` | `typeof fetch` | Optional fetch implementation for tests/hosts. |
56
+ | `id` | `string` | Provider id (default `alibaba`). |
57
+ | `models` | `readonly ModelConfig[]` | Host-supplied models (from `listAlibabaModels`) to register. |
58
+
59
+ Base URLs resolved by preset:
60
+
61
+ | Preset | Base URL |
62
+ | --- | --- |
63
+ | `singapore` | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` |
64
+ | `beijing` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
65
+ | `us` | `https://dashscope-us.aliyuncs.com/compatible-mode/v1` |
66
+ | `coding-plan` | `https://coding-intl.dashscope.aliyuncs.com/v1` |
67
+
68
+ Workspace-dedicated endpoints
69
+ (`https://{workspaceId}.{region}.maas.aliyuncs.com/compatible-mode/v1`) are supplied
70
+ verbatim via `baseUrl`.
71
+
72
+ ## Outputs / response / events
73
+
74
+ | Surface | Behavior |
75
+ | --- | --- |
76
+ | Stream | Prism text deltas, `delta.reasoning_content` → thinking deltas, tool-call delta/final, `usage`, `done`, redacted `error`. |
77
+ | Usage | `prompt_tokens`/`completion_tokens`/`total_tokens`; `prompt_tokens_details.cached_tokens` → `cacheReadTokens`, `cache_creation_input_tokens` → `cacheWriteTokens`. |
78
+ | Discovery | `listAlibabaModels()` maps `GET {base}/models` entries → `ModelConfig` (reasoning/vision inferred from id). |
79
+ | Auth methods | `api_key` for `alibaba`. |
80
+
81
+ The stream parser emits `done` only on completion evidence (`[DONE]` plus a terminal
82
+ `finish_reason` with no dangling tool calls). Truncated streams terminate with an
83
+ `error` event instead. Unsupported block placements or unclaimed images fail before
84
+ fetch.
85
+
86
+ ## Request/response example
87
+
88
+ ```bash
89
+ curl 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions' \
90
+ -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
91
+ -H 'Content-Type: application/json' \
92
+ -d '{
93
+ "model": "qwen-plus",
94
+ "messages": [{ "role": "user", "content": "Hello" }],
95
+ "stream": true,
96
+ "stream_options": { "include_usage": true }
97
+ }'
98
+ ```
99
+
100
+ Usage in the final streamed chunk:
101
+
102
+ ```json
103
+ {
104
+ "usage": {
105
+ "prompt_tokens": 100,
106
+ "completion_tokens": 5,
107
+ "total_tokens": 105,
108
+ "prompt_tokens_details": { "cached_tokens": 80, "cache_creation_input_tokens": 10 }
109
+ }
110
+ }
111
+ ```
112
+
113
+ ## Implementation example
114
+
115
+ ```ts
116
+ import { createExtensionKernel } from "@arnilo/prism";
117
+ import {
118
+ createAlibabaProviderPackage,
119
+ listAlibabaModels,
120
+ } from "@arnilo/prism-provider-alibaba";
121
+
122
+ const kernel = createExtensionKernel();
123
+
124
+ // Caller-gated discovery — never runs during setup.
125
+ const models = await listAlibabaModels({ apiKey: process.env.DASHSCOPE_API_KEY });
126
+
127
+ await kernel.load([
128
+ createAlibabaProviderPackage({
129
+ apiKey: process.env.DASHSCOPE_API_KEY,
130
+ preset: "singapore", // or "coding-plan" with a Coding Plan key
131
+ models,
132
+ }),
133
+ ]);
134
+ ```
135
+
136
+ ## Extension and configuration notes
137
+
138
+ - Hosts choose base URL/preset, provider id, model list, credential source, and
139
+ `fetch` impl. Nothing is hard-coded; register discovered models via `models:`.
140
+ - Qwen thinking: `compat.enable_thinking` (request wins over model default) maps to
141
+ the top-level `enable_thinking` wire field; omitted unless explicitly boolean.
142
+ - Provider-owned compat keys (`route`, `enable_thinking`, `alibaba`) are stripped
143
+ before the opaque `compat` spread so they never leak into wire bodies.
144
+
145
+ ### Cache behavior
146
+
147
+ - **Implicit** prefix caching is automatic upstream and sends no markers.
148
+ - **Explicit** caching is opt-in: when `ModelConfig.cache.kind === "cache_control"`
149
+ (or `cache.mode === "on"`) and the caller supplies
150
+ `ProviderRequestOptions.cache.breakpoints`, `cache_control: {"type":"ephemeral"}`
151
+ markers land on the last content block of each selected message, capped at
152
+ `ALIBABA_MAX_CACHE_BREAKPOINTS` (4). Each cached prefix needs ≥1024 tokens and
153
+ lives ~5 minutes upstream.
154
+ - Usage accounting: `cached_tokens` → `Usage.cacheReadTokens`,
155
+ `cache_creation_input_tokens` → `Usage.cacheWriteTokens`.
156
+
157
+ ## Security and performance notes
158
+
159
+ - SSE streams and HTTP error bodies use bounded `@arnilo/prism/providers/transport`
160
+ helpers (`readSseData`, `readBoundedResponseText`).
161
+ - No network calls during import, setup, build, or default tests.
162
+ - No automatic environment, file, keychain, or shell credential lookup.
163
+ - The API key is resolved per request via `resolveCredentialValue` and sent only as
164
+ `Authorization: Bearer`; keys are redacted from all thrown errors (including
165
+ discovery failures). No local filesystem paths enter request payloads.
166
+ - Caller-supplied `ProviderRequest.options.headers` can add non-owned headers, but
167
+ provider-owned headers (`content-type`, `authorization`) are applied last and
168
+ cannot be overridden.
169
+ - Model discovery is caller-gated and never invoked in the provider hot path.
170
+ - Live tests stay opt-in; default tests are network-free.
171
+
172
+ ## Related APIs
173
+
174
+ - [Provider packages](../provider-packages.md): `defineProviderPackage`,
175
+ caller-gated discovery, OpenAI-compatible routes.
176
+ - [Provider caching](../provider-caching.md): explicit/implicit matrix.
177
+ - [Credentials and redaction](../credentials-and-redaction.md):
178
+ `resolveCredentialValue`, `redactSecrets`.
179
+ - [Provider conformance](../provider-conformance.md): network-free adapter tests.
@@ -0,0 +1,93 @@
1
+ # Anthropic provider package
2
+
3
+ ## What it does
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).
6
+
7
+ ## When to use it
8
+
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
+
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.
12
+
13
+ ## Inputs / request
14
+
15
+ ```ts
16
+ import {
17
+ createAnthropicProviderPackage,
18
+ createAnthropicMessagesProvider,
19
+ listAnthropicModels,
20
+ defineAnthropicModel,
21
+ } from "@arnilo/prism-provider-anthropic";
22
+
23
+ createAnthropicProviderPackage(options?: AnthropicProviderPackageOptions): ProviderPackage
24
+ createAnthropicMessagesProvider(options?): AIProvider
25
+ listAnthropicModels(options?: ListAnthropicModelsOptions): Promise<ModelConfig[]>
26
+ ```
27
+
28
+ | Field | Type | Purpose |
29
+ | --- | --- | --- |
30
+ | `apiKey` | `CredentialValueSource` | Host-owned Anthropic API key (late-bound). |
31
+ | `fetch` | `typeof fetch` | Optional fetch for tests/hosts. |
32
+ | `baseUrl` | `string` | Override default `https://api.anthropic.com`. |
33
+ | `id` | `string` | Provider id (default `anthropic`). |
34
+ | `userAgent` | `string` | Optional User-Agent. |
35
+ | `models` | `readonly ModelConfig[]` | Override featured offline models. |
36
+
37
+ Featured offline aliases: `claude-opus-4-8`, `claude-sonnet-5`, `claude-haiku-4-5`, `claude-fable-5`. Caller-gated discovery: `listAnthropicModels()` — never during setup.
38
+
39
+ ## Outputs / response / events
40
+
41
+ | Surface | Behavior |
42
+ | --- | --- |
43
+ | Stream | Prism text, thinking deltas, tool-call delta/final, usage (incl. cache read/create when present), `done`, redacted `error`. |
44
+ | Cache | Featured models use `cache.kind: "cache_control"`; markers on selected breakpoints (`long` → `ttl: "1h"`). |
45
+ | Thinking | Model-family aware (`adaptive` vs `enabled`+`budget_tokens`); helpers `anthropicThinking` / `anthropicEffort` / `anthropicPreserveThinking`. |
46
+ | Auth | `api_key` for provider id; provider-owned `content-type`, `x-api-key`, `anthropic-version` win over caller headers. No OAuth descriptor or subscription adapter is registered. |
47
+
48
+ ## Request/response example
49
+
50
+ ```json
51
+ {
52
+ "model": "claude-sonnet-5",
53
+ "messages": [{ "role": "user", "content": [{ "type": "text", "text": "Hello" }] }],
54
+ "stream": true,
55
+ "max_tokens": 1024
56
+ }
57
+ ```
58
+
59
+ ## Implementation example
60
+
61
+ ```ts
62
+ import { createProviderRegistry, createModelRegistry } from "@arnilo/prism";
63
+ import { createAnthropicProviderPackage, listAnthropicModels } from "@arnilo/prism-provider-anthropic";
64
+
65
+ const api = /* ExtensionAPI or host registries */;
66
+ api.registerProviderPackage(createAnthropicProviderPackage({ apiKey: hostKey }));
67
+
68
+ // Optional: caller-gated catalog refresh
69
+ const models = await listAnthropicModels({ apiKey: hostKey });
70
+ api.registerProviderPackage(createAnthropicProviderPackage({ apiKey: hostKey, models }));
71
+ ```
72
+
73
+ ## Extension and configuration notes
74
+
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.
77
+ - Live smoke: `PRISM_LIVE_PROVIDER_TESTS=1` + `ANTHROPIC_API_KEY`.
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
+
80
+ ## Security and performance notes
81
+
82
+ - No network during import/setup/default tests; credentials host-owned and late-bound.
83
+ - Provider-owned auth headers cannot be overridden by caller headers.
84
+ - Media/SSRF bounds reuse `@arnilo/prism/providers/media` / transport helpers.
85
+ - Offline conformance: `@arnilo/prism/testing/provider-conformance`.
86
+
87
+ ## Related APIs
88
+
89
+ - [Provider packages](../provider-packages.md): package setup + discovery contract.
90
+ - [Provider caching](../provider-caching.md): `cache_control` breakpoints.
91
+ - [Thinking and reasoning](../thinking-and-reasoning.md): portable thinking helpers.
92
+ - [Provider conformance](../provider-conformance.md): network-free assertions.
93
+ - Package README: [`packages/provider-anthropic/README.md`](../../packages/provider-anthropic/README.md)
@@ -0,0 +1,74 @@
1
+ # Azure OpenAI / Foundry
2
+
3
+ ## What it does
4
+
5
+ `@arnilo/prism-provider-azure` registers an Azure OpenAI / Foundry Chat Completions provider that uses host-supplied Entra workload identity (Bearer) or Azure resource keys (`api-key`). Deployment URLs keep the configured endpoint host (custom subdomain, private endpoint, or VNet FQDN).
6
+
7
+ ## When to use it
8
+
9
+ Use it for enterprise Azure OpenAI / Foundry deployments with Managed Identity or host token providers. Do not fold this into consumer OpenAI packages. Do not embed static keys in fixtures.
10
+
11
+ ## Inputs / request
12
+
13
+ ```ts
14
+ import { createAzureOpenAIProviderPackage } from "@arnilo/prism-provider-azure";
15
+
16
+ createAzureOpenAIProviderPackage({
17
+ endpoint: "https://my-resource.openai.azure.com",
18
+ deployment: "gpt-4o",
19
+ apiVersion: "2024-10-21",
20
+ credential: hostEntraToken, // late-bound
21
+ authStyle: "bearer",
22
+ models: [{ provider: "azure", model: "gpt-4o" }],
23
+ });
24
+ ```
25
+
26
+ | Field | Meaning |
27
+ | --- | --- |
28
+ | `endpoint` | Absolute https resource URL; host preserved |
29
+ | `deployment` | Deployment name (defaults to `model.model`) |
30
+ | `apiVersion` | Query `api-version` (default `2024-10-21`) |
31
+ | `credential` | `CredentialValueSource` — Entra token or resource key |
32
+ | `authStyle` | `bearer` (default) or `api-key` |
33
+
34
+ ## Outputs / response / events
35
+
36
+ Reuses `@arnilo/prism/providers/openai-compatible` streaming events (text, tool deltas, usage, done, redacted errors). Missing credentials fail closed before `fetch`.
37
+
38
+ ## Request/response example
39
+
40
+ ```http
41
+ POST https://my-resource.privatelink.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-10-21
42
+ Authorization: Bearer <entra-token>
43
+ ```
44
+
45
+ ## Implementation example
46
+
47
+ ```ts
48
+ const provider = createAzureOpenAIProvider({
49
+ endpoint: process.env.AZURE_OPENAI_ENDPOINT!,
50
+ deployment: "gpt-4o",
51
+ credential: () => entra.getToken("https://cognitiveservices.azure.com/.default").then((t) => t.token),
52
+ });
53
+ ```
54
+
55
+ Opt-in live canaries: inject real `fetch` + host credential behind host CI secrets — no secrets in repo.
56
+
57
+ ## Extension and configuration notes
58
+
59
+ Register via `createExtensionKernel().load([createAzureOpenAIProviderPackage(...)])`. Pair with `@arnilo/prism-model-router` for residency allow-lists on Azure regions/endpoints.
60
+
61
+ ## Security and performance notes
62
+
63
+ - No credential prefetch at import; resolve per request.
64
+ - Endpoint host is never rewritten to public DNS.
65
+ - Errors redact credential values via shared transport helpers.
66
+ - No Azure SDK dependency.
67
+
68
+ ## Related APIs
69
+
70
+ - [OpenAI-compatible provider](openai-compatible.md)
71
+ - [Provider packages](../provider-packages.md)
72
+ - [Model routing](../model-routing.md)
73
+ - [Credential storage](../credential-storage.md)
74
+ - Package README: [`@arnilo/prism-provider-azure`](../../packages/provider-azure/README.md)
@@ -0,0 +1,72 @@
1
+ # Amazon Bedrock
2
+
3
+ ## What it does
4
+
5
+ `@arnilo/prism-provider-bedrock` registers an Amazon Bedrock Runtime OpenAI-compatible Chat Completions provider. Hosts supply IAM/IRSA/assumed-role credentials; the package signs requests with SigV4 (no AWS SDK). Region and optional PrivateLink endpoint URLs are preserved.
6
+
7
+ ## When to use it
8
+
9
+ Use it for enterprise Bedrock access under workload identity. Do not embed long-lived keys in fixtures. Use model-router residency policy to deny disallowed regions.
10
+
11
+ ## Inputs / request
12
+
13
+ ```ts
14
+ import { createBedrockProviderPackage } from "@arnilo/prism-provider-bedrock";
15
+
16
+ createBedrockProviderPackage({
17
+ region: "eu-west-1",
18
+ // endpoint: "https://vpce-….bedrock-runtime.eu-west-1.vpce.amazonaws.com",
19
+ credential: () => hostAwsCredentials(),
20
+ models: [{ provider: "bedrock", model: "anthropic.claude-3-haiku-20240307-v1:0" }],
21
+ });
22
+ ```
23
+
24
+ | Field | Meaning |
25
+ | --- | --- |
26
+ | `region` | AWS region for signing + default endpoint |
27
+ | `endpoint` | Optional https PrivateLink / VPC interface base URL |
28
+ | `credential` | `{ accessKeyId, secretAccessKey, sessionToken? }` or async callback |
29
+ | `signRequest` | Optional host SigV4 override |
30
+
31
+ Default public base: `https://bedrock-runtime.{region}.amazonaws.com` → `/openai/v1/chat/completions`.
32
+
33
+ ## Outputs / response / events
34
+
35
+ OpenAI-compatible SSE mapped to Prism provider events. Missing credentials fail closed before network I/O.
36
+
37
+ ## Request/response example
38
+
39
+ ```http
40
+ POST https://bedrock-runtime.eu-west-1.amazonaws.com/openai/v1/chat/completions
41
+ Authorization: AWS4-HMAC-SHA256 Credential=…/eu-west-1/bedrock/aws4_request, …
42
+ X-Amz-Security-Token: …
43
+ ```
44
+
45
+ ## Implementation example
46
+
47
+ ```ts
48
+ const provider = createBedrockProvider({
49
+ region: "us-east-1",
50
+ credential: async () => fromNodeProviderChain()(),
51
+ });
52
+ ```
53
+
54
+ Live canaries stay opt-in behind host credentials; default tests are network-free.
55
+
56
+ ## Extension and configuration notes
57
+
58
+ Uses Bedrock’s OpenAI-compatible runtime route (not Converse eventstream). Hosts needing Converse-only models should supply a custom provider or AI SDK bridge.
59
+
60
+ ## Security and performance notes
61
+
62
+ - No AWS SDK; package-local SigV4 only for `bedrock` service.
63
+ - Private endpoint hosts are not rewritten to public DNS.
64
+ - Credential secrets are redacted from provider errors.
65
+ - No credential prefetch at import.
66
+
67
+ ## Related APIs
68
+
69
+ - [OpenAI-compatible provider](openai-compatible.md)
70
+ - [Model routing](../model-routing.md)
71
+ - [Provider packages](../provider-packages.md)
72
+ - Package README: [`@arnilo/prism-provider-bedrock`](../../packages/provider-bedrock/README.md)