@arnilo/prism 0.5.6 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -5
- package/README.md +10 -10
- package/dist/agent-approval.js +7 -6
- package/dist/agent-definitions.js +1 -0
- package/dist/agent-loops.js +51 -12
- package/dist/agent-run-lifecycle.js +11 -0
- package/dist/agent-run-state.d.ts +6 -0
- package/dist/agent-run-state.js +29 -9
- package/dist/agent-session/session/assemble.js +33 -2
- package/dist/agent-session/session/persist.js +6 -2
- package/dist/agent-session/session/tool-round.js +1 -0
- package/dist/agent-session/session/types.d.ts +10 -0
- package/dist/agent-session/session.d.ts +15 -0
- package/dist/agent-session/session.js +59 -4
- package/dist/agent-tool-dispatch.js +5 -4
- package/dist/artifacts.d.ts +39 -1
- package/dist/artifacts.js +73 -0
- package/dist/attention-compiler.d.ts +121 -0
- package/dist/attention-compiler.js +479 -0
- package/dist/cli-init.js +20 -6
- package/dist/content.d.ts +3 -16
- package/dist/content.js +9 -99
- package/dist/context-budget.d.ts +32 -2
- package/dist/context-budget.js +51 -19
- package/dist/contracts-core/agent.d.ts +18 -0
- package/dist/contracts-core/agent.js +4 -1
- package/dist/contracts-core/attention.d.ts +66 -0
- package/dist/contracts-core/attention.js +2 -0
- package/dist/contracts-core/compaction.d.ts +59 -0
- package/dist/contracts-core/compaction.js +77 -1
- package/dist/contracts-core/provider.d.ts +4 -0
- package/dist/contracts-core.d.ts +1 -0
- package/dist/contracts-core.js +1 -0
- package/dist/contracts-protocol.d.ts +29 -0
- package/dist/contracts-run-state.d.ts +6 -0
- package/dist/host-composition.d.ts +78 -0
- package/dist/host-composition.js +248 -0
- package/dist/index.d.ts +11 -8
- package/dist/index.js +6 -5
- package/dist/input.d.ts +19 -1
- package/dist/input.js +52 -2
- package/dist/media-types.d.ts +34 -0
- package/dist/media-types.js +158 -0
- package/dist/pinned-fetch.d.ts +2 -2
- package/dist/pinned-fetch.js +11 -12
- package/dist/redaction.js +74 -1
- package/dist/secure-agent.d.ts +2 -0
- package/dist/secure-agent.js +6 -1
- package/dist/session-stores.d.ts +11 -0
- package/dist/session-stores.js +23 -8
- package/dist/tool-result-fold.d.ts +12 -0
- package/dist/tool-result-fold.js +13 -6
- package/dist/tools.d.ts +10 -0
- package/dist/tools.js +41 -0
- package/docs/acp-agent.md +42 -11
- package/docs/acp.md +3 -2
- package/docs/ag-ui.md +9 -5
- package/docs/agent-definitions.md +9 -1
- package/docs/agent-events.md +6 -1
- package/docs/agent-loops.md +1 -1
- package/docs/agent-session-runtime.md +9 -7
- package/docs/attention-compiler.md +272 -0
- package/docs/browser-automation.md +5 -2
- package/docs/cli-rpc.md +4 -2
- package/docs/coding-agent-tools.md +1 -1
- package/docs/coding-security.md +5 -3
- package/docs/coding-tools.md +1 -1
- package/docs/coding-workspaces.md +22 -0
- package/docs/compaction-and-retry.md +36 -4
- package/docs/compaction-observational-memory.md +62 -9
- package/docs/context-and-skills.md +4 -2
- package/docs/contributing.md +37 -0
- package/docs/conversations.md +1 -1
- package/docs/core.md +2 -0
- package/docs/dev-inspector.md +4 -0
- package/docs/device-adapters.md +1 -0
- package/docs/document-reader.md +12 -2
- package/docs/documents.md +11 -3
- package/docs/enterprise-postgres-state.md +2 -2
- package/docs/evaluations.md +168 -4
- package/docs/execution-timeline.md +180 -0
- package/docs/graft.md +3 -1
- package/docs/history/0.7.0-primitive-review.md +254 -0
- package/docs/history/migration-0.0.md +2 -2
- package/docs/history/release-handoffs.md +70 -1
- package/docs/host-compositions.md +147 -0
- package/docs/host-security.md +2 -2
- package/docs/hosted-sandboxes.md +94 -0
- package/docs/index.md +73 -41
- package/docs/input-and-prompt-assembly.md +5 -4
- package/docs/knowledge-sync.md +84 -0
- package/docs/language-intelligence.md +2 -2
- package/docs/live-testing.md +4 -1
- package/docs/mcp-tools.md +2 -1
- package/docs/memory-fabric.md +416 -0
- package/docs/migrate-to-0.5.md +8 -3
- package/docs/migrate-to-0.6.md +90 -0
- package/docs/migrate-to-0.7.md +345 -0
- package/docs/migration.md +43 -1
- package/docs/model-registry.md +1 -1
- package/docs/model-routing.md +79 -4
- package/docs/multi-agent-patterns.md +20 -6
- package/docs/multimodal-content.md +1 -1
- package/docs/obscura.md +3 -1
- package/docs/observability.md +52 -1
- package/docs/operations.md +13 -1
- package/docs/options-index.md +298 -0
- package/docs/peer-dependencies.md +96 -0
- package/docs/performance.md +34 -2
- package/docs/ponytail.md +2 -0
- package/docs/postgres-persistence.md +3 -1
- package/docs/process-sessions.md +3 -1
- package/docs/prompt-registry.md +1 -1
- package/docs/provider-caching.md +4 -2
- package/docs/provider-conformance.md +2 -2
- package/docs/provider-packages.md +23 -23
- package/docs/provider-primitives.md +2 -1
- package/docs/providers/ai-sdk.md +5 -2
- package/docs/providers/bedrock.md +71 -7
- package/docs/providers/openai.md +1 -1
- package/docs/public-contracts.md +2 -2
- package/docs/rag.md +24 -8
- package/docs/realtime-voice.md +87 -0
- package/docs/release-and-install.md +78 -56
- package/docs/runs-and-usage.md +3 -2
- package/docs/server.md +6 -4
- package/docs/session-stores.md +3 -1
- package/docs/speech.md +2 -0
- package/docs/sqlite-persistence.md +2 -0
- package/docs/supervisors.md +33 -5
- package/docs/testing.md +38 -0
- package/docs/thinking-and-reasoning.md +3 -1
- package/docs/tools.md +7 -6
- package/docs/web-tools.md +2 -1
- package/docs/wiki.md +1 -1
- package/docs/work-artifacts-and-review.md +14 -4
- package/docs/work-connectors.md +3 -1
- package/docs/work-tools.md +14 -4
- package/docs/workflows.md +69 -1
- package/docs/working-and-semantic-memory.md +25 -14
- package/package.json +5 -5
- package/templates/README.md +2 -0
- package/templates/business-worker/README.md.tmpl +19 -0
- package/templates/business-worker/env.example.tmpl +1 -0
- package/templates/business-worker/gitignore.tmpl +11 -0
- package/templates/business-worker/manifest.json +11 -0
- package/templates/business-worker/package.json.tmpl +23 -0
- package/templates/business-worker/src/agent.ts.tmpl +92 -0
- package/templates/business-worker/src/index.ts.tmpl +13 -0
- package/templates/business-worker/src/tests/agent.test.ts.tmpl +77 -0
- package/templates/business-worker/tsconfig.json.tmpl +15 -0
- package/templates/personal-assistant/README.md.tmpl +18 -0
- package/templates/personal-assistant/env.example.tmpl +1 -0
- package/templates/personal-assistant/gitignore.tmpl +11 -0
- package/templates/personal-assistant/manifest.json +11 -0
- package/templates/personal-assistant/package.json.tmpl +23 -0
- package/templates/personal-assistant/src/agent.ts.tmpl +65 -0
- package/templates/personal-assistant/src/index.ts.tmpl +13 -0
- package/templates/personal-assistant/src/tests/agent.test.ts.tmpl +28 -0
- package/templates/personal-assistant/tsconfig.json.tmpl +15 -0
package/docs/performance.md
CHANGED
|
@@ -85,6 +85,16 @@ Recorded 2026-08-31 on Node v24.19.0 / Linux x64: 5 warmups + 20 measured runs,
|
|
|
85
85
|
node scripts/benchmark.mjs --scenario workflow-loop --out /tmp/prism-workflow-loop.json
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
## Secret redaction (plan 070)
|
|
89
|
+
|
|
90
|
+
`node scripts/benchmark.mjs --scenario redaction` is network-free (in-memory, no credentials). It builds one transcript-scale string (≥ 1 MiB) and one small entry-shaped object, both carrying 16 realistic secret-shaped needles, and measures `redactSecrets` against a local copy of the ordered `needles.reduce(split/join)` loop it replaced for large strings: the two must stay byte-identical and no needle may survive either path. Caps live in `scripts/budgets.json#redaction` (same-process speedup floor 5, transcript p95 ceiling 250 ms, small-entry p95 ceiling 25 ms — sanity bounds, machine-dependent). Schema/caps/network-free gating in `npm test`: `scripts/benchmark-redaction.test.mjs`.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
node scripts/benchmark.mjs --scenario redaction --out /tmp/prism-redaction.json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Recorded 2026-09-11, Node v24.19.0 / Linux x64: 1 MiB transcript × 16 needles **9.39 ms → 0.69 ms p50 (13.7×, floor 5×)**, small entry 0.15 ms p50 / 0.22 ms p95. Strings below 16 KB keep the ordered loop (`src/redaction.ts`): the equivalence check that guards the single scan costs more than the passes it saves below ~4 KB.
|
|
97
|
+
|
|
88
98
|
## Current-line root artifact diet
|
|
89
99
|
|
|
90
100
|
`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.
|
|
@@ -102,10 +112,32 @@ demand gate.
|
|
|
102
112
|
**Pass/fail thresholds.** Network-free rows fail above the frozen ceiling in
|
|
103
113
|
the table below; protected PostgreSQL rows fail above their per-phase
|
|
104
114
|
budgets.json ceilings (50/100 ms per the approved budget contract); startup
|
|
105
|
-
import fails above `startupImportMsCeiling` (250 ms)
|
|
115
|
+
import fails above `startupImportMsCeiling` (250 ms) on a quiet machine — see the
|
|
116
|
+
startup-gate note below for how the in-chain check stays load-tolerant; root
|
|
117
|
+
packed bytes and
|
|
106
118
|
file count fail above baseline × 1.05. Labels: **network-free** = runs in
|
|
107
119
|
`npm test` evidence, no network; **protected** = requires live PostgreSQL.
|
|
108
120
|
|
|
121
|
+
**Startup gate (plan 071 Task 3).** The in-`npm test` check in
|
|
122
|
+
`scripts/budget-gate.test.mjs` asserts a *machine-relative ratio* rather than a raw
|
|
123
|
+
millisecond bound: cold-process `import('./dist/index.js')` wall time (trimmed mean
|
|
124
|
+
of five spawns, min/max dropped) over the median empty `node -e ''` process start
|
|
125
|
+
measured in the same run. External CPU load inflates both numbers, so the ratio held
|
|
126
|
+
at 3.3 idle, 3.5–4.1 with a full `npm test` running concurrently, and up to 7.2 with
|
|
127
|
+
40 competing processes, while the absolute import alone moved 60 ms → 258 ms — the
|
|
128
|
+
same contention that failed the old fixed 250 ms check (273 ms at plan 070 Task 11,
|
|
129
|
+
1104.8 ms at Task 13, both at load average ~25). Off load
|
|
130
|
+
(loadavg-per-CPU < 1.5) the tight ratio ceiling (`importRatioCeiling` 8) and the
|
|
131
|
+
absolute ceiling (250 ms) are both asserted; under load the ratio ceiling widens to
|
|
132
|
+
`importRatioCeilingUnderLoad` (20) and the absolute bound becomes
|
|
133
|
+
evidence-of-record, still measured by `scripts/benchmark-0.1.0.mjs` (39.79 ms in
|
|
134
|
+
`scripts/benchmark-0.1.0.json`) and re-gated by `scripts/benchmark-0.1.0.test.mjs`;
|
|
135
|
+
the current-line scenario runner `scripts/benchmark.mjs` carries the six scenario
|
|
136
|
+
medians and no startup row. Both ceilings live in
|
|
137
|
+
`scripts/budgets.json#startup` with the calibration recorded in their `$comment`;
|
|
138
|
+
freeze deviation `dev-007` records the enforcement change (the frozen 250 ms number
|
|
139
|
+
itself is unchanged).
|
|
140
|
+
|
|
109
141
|
| Envelope | Recorded p95 ms | Ceiling ms | Source leg | Label |
|
|
110
142
|
| --- | ---: | ---: | --- | --- |
|
|
111
143
|
| oidcVerifyCacheHitMs | 0.151 | 5 | enterprise adapters (0.0.28) | network-free |
|
|
@@ -543,7 +575,7 @@ The ledger percentage overhead is intentionally not a threshold: its no-ledger b
|
|
|
543
575
|
|
|
544
576
|
### 0.0.5 Phase 0 baseline (2026-07-15)
|
|
545
577
|
|
|
546
|
-
Scope froze at commit `f5128a816ae204c52f3e2f089de71c99bd5de6d4`. Measurement host: Node v24.18.0, npm 11.16.0, Linux 7.1.3 x86_64, AMD Ryzen 9 PRO 7940HS (16 logical CPUs). Supported package runtime
|
|
578
|
+
Scope froze at commit `f5128a816ae204c52f3e2f089de71c99bd5de6d4`. Measurement host: Node v24.18.0, npm 11.16.0, Linux 7.1.3 x86_64, AMD Ryzen 9 PRO 7940HS (16 logical CPUs). Supported package runtime is Node >=22 (>=20 at the time of this baseline; raised in 0.6.0) and the host measured above is Node 24. These are dated local comparison points, not portable CI wall-clock assertions.
|
|
547
579
|
|
|
548
580
|
| Surface | Workload | Result |
|
|
549
581
|
| --- | --- | --- |
|
package/docs/ponytail.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Ponytail behavior integration
|
|
2
2
|
|
|
3
|
+
> **Optional peer install:** `@dietrichgebert/ponytail` — see [Optional peer dependencies](peer-dependencies.md).
|
|
4
|
+
|
|
3
5
|
## What it does
|
|
4
6
|
|
|
5
7
|
`@arnilo/prism-coding-tools/ponytail` is an optional package that wires [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail) into Prism contribution contracts.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# PostgreSQL persistence
|
|
2
2
|
|
|
3
|
+
> **Optional peer install:** `pg` — see [Optional peer dependencies](peer-dependencies.md).
|
|
4
|
+
|
|
3
5
|
## What it does
|
|
4
6
|
|
|
5
7
|
The optional `@arnilo/prism-core/sessions/postgres` package ships a production-oriented PostgreSQL adapter that implements:
|
|
@@ -14,7 +16,7 @@ Factory:
|
|
|
14
16
|
- `PostgresPersistenceOptions`
|
|
15
17
|
- `PostgresPersistence.close()` (async; ends adapter-owned pools only)
|
|
16
18
|
|
|
17
|
-
The adapter uses `pg@^8.
|
|
19
|
+
The adapter uses `pg@^8.23.0`, applies versioned migrations from the shared Plan 056 schema model inside a transaction guarded by `pg_advisory_xact_lock`, validates/quotes schema identifiers, and passes the full session-store and run-ledger conformance suites when `PRISM_TEST_POSTGRES_URL` is set.
|
|
18
20
|
|
|
19
21
|
## When to use it
|
|
20
22
|
|
package/docs/process-sessions.md
CHANGED
|
@@ -136,7 +136,8 @@ await sessions.dispose();
|
|
|
136
136
|
- Host restart: call `reconcile()` on a new registry for in-memory orphans, or listen for `process_unknown` and wire Phase 7 `ToolEffectStore.markUnknown` in the host.
|
|
137
137
|
- Expiry sweep runs on registry/handle access — no timers at import.
|
|
138
138
|
- Command fingerprint is SHA-256 of `[command, ...args]` only (no env).
|
|
139
|
-
- Docker
|
|
139
|
+
- Docker sandbox (`createDockerSandbox`) implements `startProcess` returning a compliant `SandboxProcessHandle` with durable `ref` for attested reconnect. Process operations (`write`, bounded `onData` output, `wait`, `signal`, `kill`, `release`) compose with `ProcessSessions`. The sandbox `attachProcess(ref)` resolves an opaque `prism-docker-proc:` ref to a live in-memory handle with fail-closed validation (container ID, workspace, command fingerprint). `createDockerProcessRecoveryBackend(sandbox, options?)` provides a ready-made `ProcessRecoveryBackend` with optional `expectedContainerId`, `expectedWorkspace`, and `expectedLabels` assertions. When a sandbox is passed to `createProcessSessions` and has `attachProcess`, the recovery backend is wired automatically.
|
|
140
|
+
- Hosted E2B sandbox (`createE2BSandbox`) also implements `startProcess` / `attachProcess` with opaque `prism-e2b-proc:` refs (sandbox id, pid, command fingerprint, workspace). `createE2BProcessRecoveryBackend` mirrors the Docker backend (`expectedSandboxId` / `expectedWorkspace` / `expectedLabels`). Filesystem-only `pause({ keepMemory: false })` reports process loss: `attachProcess` returns null after that snapshot. `connectE2BSandbox` reconnects by sandbox id without auto-resume; call `resume()` explicitly. See [Hosted sandboxes](hosted-sandboxes.md).
|
|
140
141
|
|
|
141
142
|
## Durable process recovery (plan 026 Task 5)
|
|
142
143
|
|
|
@@ -199,4 +200,5 @@ optionally `recoveryBackend` + `recoveryLimits`. With durability configured:
|
|
|
199
200
|
- [Coding agent tools](coding-agent-tools.md): one-shot `shell` vs long-running sessions.
|
|
200
201
|
- [Language intelligence](language-intelligence.md): LSP servers may later register as managed sessions.
|
|
201
202
|
- [Coding security](coding-security.md): `SandboxProcessHandle` / optional `DisposableSandbox.startProcess`.
|
|
203
|
+
- [Hosted sandboxes](hosted-sandboxes.md): E2B `pause`/`resume` and `prism-e2b-proc:` reconnect refs.
|
|
202
204
|
- [Tool effects](tool-effects.md): unknown-outcome vocabulary mirrored by `markUnknown` / `process_unknown` / `reconcile`.
|
package/docs/prompt-registry.md
CHANGED
|
@@ -90,7 +90,7 @@ const v = await assertPromptPromotion({
|
|
|
90
90
|
if (v.verdict === "promote") await store.put({ ...hostInput, body: v.candidate.body, labels: ["production"] });
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
The verdict carries `promote`/`hold`, per-scorer `wins/losses/ties/failures`, `winRate`, the raw `ComparisonReport`, a redacted bounded `reportJson` (`serializeEvaluationReport`), and `reasons` on hold. The default gate holds unless the candidate wins strictly more scored comparisons than the baseline; `minimumWinRate` and `thresholds` add stricter gates, and threshold equality passes. Requires the optional peer `@arnilo/prism-core/governance/evals` (install it or the helper fails closed with `ERR_PRISM_PROMPT_EVALS_PEER`). Promotion itself stays a host decision: applying the verdict means `put`-ing a new version with labels — the helper never does.
|
|
93
|
+
The verdict carries `promote`/`hold`, per-scorer `wins/losses/ties/failures`, `winRate`, the raw `ComparisonReport`, a redacted bounded `reportJson` (`serializeEvaluationReport`), and `reasons` on hold. The default gate holds unless the candidate wins strictly more scored comparisons than the baseline; `minimumWinRate` and `thresholds` add stricter gates, and threshold equality passes. Requires the optional peer `@arnilo/prism-core/governance/evals` (install it or the helper fails closed with `ERR_PRISM_PROMPT_EVALS_PEER`). Promotion itself stays a host decision: applying the verdict means `put`-ing a new version with labels — the helper never does. When provenance tracking is required, evaluation experiments bind candidate prompt versions via `EvalManifest.promptId` and `promptVersion`; release evidence also calls `validateReleaseEvalManifest` (see [Evaluations](evaluations.md#repeated-trials-and-manifests)).
|
|
94
94
|
|
|
95
95
|
## Limits and security
|
|
96
96
|
|
package/docs/provider-caching.md
CHANGED
|
@@ -166,7 +166,8 @@ Provider request policies can set `ProviderRequestOptions.cache` or the legacy `
|
|
|
166
166
|
| `@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). |
|
|
167
167
|
| `@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. |
|
|
168
168
|
| `@arnilo/prism-providers/azure` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Azure cache policy. |
|
|
169
|
-
| `@arnilo/prism-providers/bedrock` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Bedrock cache policy. |
|
|
169
|
+
| `@arnilo/prism-providers/bedrock` (`compatible`) | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Bedrock cache policy. |
|
|
170
|
+
| `@arnilo/prism-providers/bedrock` (`converse`) | `cache_control` | Prism breakpoints become standalone `cachePoint` blocks in `system`/message content; long retention adds `ttl: "1h"` when the model allows it. `tools` caching stays host-owned. | Stable prefix in the documented order `tools → system → messages`; changing an earlier section invalidates later ones. | `cacheReadInputTokens`/`cacheWriteInputTokens` map to `Usage.cacheReadTokens`/`Usage.cacheWriteTokens`; `inputTokens` is the non-cached remainder and is never folded. |
|
|
170
171
|
| `@arnilo/prism-providers/vertex` | none | No Prism cache mapping. | Endpoint/model-specific. | Host owns Vertex cache policy. |
|
|
171
172
|
|
|
172
173
|
Detailed first-party provider notes:
|
|
@@ -188,7 +189,7 @@ Detailed first-party provider notes:
|
|
|
188
189
|
- 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`.
|
|
189
190
|
- 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`.
|
|
190
191
|
- 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`.
|
|
191
|
-
- 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.
|
|
192
|
+
- 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. Bedrock's native `converse` route is the exception: it is a documented cache-control surface (`cachePoint`, shared `applyCacheControl` markers) and maps cache usage fields instead of leaving them host-owned.
|
|
192
193
|
|
|
193
194
|
### NeuralWatt cache-aware limiter
|
|
194
195
|
|
|
@@ -303,6 +304,7 @@ for (const sample of report.samples) {
|
|
|
303
304
|
## Related APIs
|
|
304
305
|
|
|
305
306
|
- [Input and prompt assembly](input-and-prompt-assembly.md): opt-in cache-aware ordering for stable provider payload prefixes.
|
|
307
|
+
- [Attention compiler](attention-compiler.md): opt-in per-turn shrink that only rewrites rows *behind* the stable prefix, so cache hits survive.
|
|
306
308
|
- [Provider request policies](provider-request-policies.md): set cache hints before provider calls.
|
|
307
309
|
- [Model registry](model-registry.md): register `ModelConfig.cache` capability metadata.
|
|
308
310
|
- [Provider layer](provider-layer.md): provider/model registries and provider events.
|
|
@@ -31,7 +31,7 @@ Offline conformance is mandatory for every package; credentialed probes are not
|
|
|
31
31
|
| Package | Required offline evidence | Restricted live evidence |
|
|
32
32
|
| --- | --- | --- |
|
|
33
33
|
| OpenAI | Responses serialization/stream ordering, provider-hosted authority, continuation cap/cursor, Realtime fake WebSocket caps | Standard API-key smoke; separate protected hosted-tool/Realtime entitlement probe |
|
|
34
|
-
| AI SDK | Exact 4.0.
|
|
34
|
+
| AI SDK | Exact 4.0.13/V4 gate (`4.0.3`, `4.0.4`, `4.0.10` also listed); every mapped stream part; authority, cache usage, redaction, unsupported mapping | Host-created V4 model only; no Prism credential fixture |
|
|
35
35
|
| Anthropic | Messages serialization, cache/thinking/tools, header/redaction/abort assertions | Protected `ANTHROPIC_API_KEY` smoke |
|
|
36
36
|
| Google | `generateContent` serialization, complete tool calls, media/abort/redaction assertions | Protected `GOOGLE_API_KEY` or `GEMINI_API_KEY` smoke |
|
|
37
37
|
| Kimi | Coding/Moonshot route fixtures, thinking/tool reconstruction, headers/redaction | Protected `KIMI_API_KEY` smoke |
|
|
@@ -44,7 +44,7 @@ Offline conformance is mandatory for every package; credentialed probes are not
|
|
|
44
44
|
| Ollama | cloud/local preset, reasoning/image mapping, implicit-cache fixture | Protected cloud or host-local authenticated daemon probe; no daemon starts in tests |
|
|
45
45
|
| NeuralWatt | stream/retry/quota/telemetry fixtures, implicit-cache usage, headers/redaction | Protected `NEURALWATT_API_KEY` smoke |
|
|
46
46
|
| Azure | endpoint preservation, Entra/resource-key header and OpenAI-compatible stream fixture | Protected host workload-identity probe |
|
|
47
|
-
| Bedrock | SigV4/region/PrivateLink
|
|
47
|
+
| Bedrock | SigV4/region/PrivateLink, OpenAI-compatible stream fixture, and native Converse fixtures: body mapping (messages/system/tools/media/reasoning/structured output/cachePoint), canonical event-stream frame bytes with CRC/limit/truncation refusals, capability refusals before network I/O | Protected host IAM/IRSA probe for both routes |
|
|
48
48
|
| Vertex | location/endpoint preservation, ADC header and OpenAI-compatible stream fixture | Protected host ADC/WIF probe |
|
|
49
49
|
|
|
50
50
|
All rows must retain bounded request/response fixtures, abort propagation, provider-owned-header precedence, and fake-secret leak assertions where the package surfaces those values. A successful fake transport proves Prism mapping, not account entitlement or vendor availability.
|
|
@@ -25,26 +25,26 @@ Do not use provider packages as a package manager, credential store, env loader,
|
|
|
25
25
|
|
|
26
26
|
| adapter package | version |
|
|
27
27
|
| --- | --- |
|
|
28
|
-
| `@arnilo/prism-providers/ai-sdk` | 0.
|
|
29
|
-
| `@arnilo/prism-providers/alibaba` | 0.
|
|
30
|
-
| `@arnilo/prism-providers/anthropic` | 0.
|
|
31
|
-
| `@arnilo/prism-providers/azure` | 0.
|
|
32
|
-
| `@arnilo/prism-providers/bedrock` | 0.
|
|
33
|
-
| `@arnilo/prism-providers/clinepass` | 0.
|
|
34
|
-
| `@arnilo/prism-providers/commandcode` | 0.
|
|
35
|
-
| `@arnilo/prism-providers/deepseek` | 0.
|
|
36
|
-
| `@arnilo/prism-providers/google` | 0.
|
|
37
|
-
| `@arnilo/prism-providers/hyper` | 0.
|
|
38
|
-
| `@arnilo/prism-providers/kimi` | 0.
|
|
39
|
-
| `@arnilo/prism-providers/model-discovery` | 0.
|
|
40
|
-
| `@arnilo/prism-providers/neuralwatt` | 0.
|
|
41
|
-
| `@arnilo/prism-providers/ollama` | 0.
|
|
42
|
-
| `@arnilo/prism-providers/openai` | 0.
|
|
43
|
-
| `@arnilo/prism-providers/opencode-go` | 0.
|
|
44
|
-
| `@arnilo/prism-providers/openrouter` | 0.
|
|
45
|
-
| `@arnilo/prism-providers/vertex` | 0.
|
|
46
|
-
| `@arnilo/prism-providers/xai` | 0.
|
|
47
|
-
| `@arnilo/prism-providers/zai` | 0.
|
|
28
|
+
| `@arnilo/prism-providers/ai-sdk` | 0.7.0 |
|
|
29
|
+
| `@arnilo/prism-providers/alibaba` | 0.7.0 |
|
|
30
|
+
| `@arnilo/prism-providers/anthropic` | 0.7.0 |
|
|
31
|
+
| `@arnilo/prism-providers/azure` | 0.7.0 |
|
|
32
|
+
| `@arnilo/prism-providers/bedrock` | 0.7.0 |
|
|
33
|
+
| `@arnilo/prism-providers/clinepass` | 0.7.0 |
|
|
34
|
+
| `@arnilo/prism-providers/commandcode` | 0.7.0 |
|
|
35
|
+
| `@arnilo/prism-providers/deepseek` | 0.7.0 |
|
|
36
|
+
| `@arnilo/prism-providers/google` | 0.7.0 |
|
|
37
|
+
| `@arnilo/prism-providers/hyper` | 0.7.0 |
|
|
38
|
+
| `@arnilo/prism-providers/kimi` | 0.7.0 |
|
|
39
|
+
| `@arnilo/prism-providers/model-discovery` | 0.7.0 |
|
|
40
|
+
| `@arnilo/prism-providers/neuralwatt` | 0.7.0 |
|
|
41
|
+
| `@arnilo/prism-providers/ollama` | 0.7.0 |
|
|
42
|
+
| `@arnilo/prism-providers/openai` | 0.7.0 |
|
|
43
|
+
| `@arnilo/prism-providers/opencode-go` | 0.7.0 |
|
|
44
|
+
| `@arnilo/prism-providers/openrouter` | 0.7.0 |
|
|
45
|
+
| `@arnilo/prism-providers/vertex` | 0.7.0 |
|
|
46
|
+
| `@arnilo/prism-providers/xai` | 0.7.0 |
|
|
47
|
+
| `@arnilo/prism-providers/zai` | 0.7.0 |
|
|
48
48
|
<!-- generated:package-truth:providers end -->
|
|
49
49
|
|
|
50
50
|
|
|
@@ -61,7 +61,7 @@ Do not use provider packages as a package manager, credential store, env loader,
|
|
|
61
61
|
| `@arnilo/prism-providers/hyper` | `api_key` only | No subscription OAuth — Charm Hyper is pay-per-use Hypercredits; host supplies `HYPER_API_KEY` (keys start `sk-hyper-`). |
|
|
62
62
|
| `@arnilo/prism-providers/commandcode` | `api_key` only | No subscription OAuth — Command Code Go/GOAT/Pro/Max coding plans and the Provider plan all authenticate with the same Studio API key; host supplies `COMMAND_CODE_API_KEY`. |
|
|
63
63
|
| `@arnilo/prism-providers/azure` | host Entra token or Azure resource key | Workload identity via `credential` callback; endpoint host preserved ([docs](providers/azure.md)). |
|
|
64
|
-
| `@arnilo/prism-providers/bedrock` | host IAM/IRSA credentials | SigV4 over OpenAI-compatible Bedrock Runtime; region/PrivateLink preserved ([docs](providers/bedrock.md)). |
|
|
64
|
+
| `@arnilo/prism-providers/bedrock` | host IAM/IRSA credentials | SigV4 over either the OpenAI-compatible Bedrock Runtime route (default) or the native model-agnostic Converse/ConverseStream route (`api: "converse"`); region/PrivateLink preserved ([docs](providers/bedrock.md)). |
|
|
65
65
|
| `@arnilo/prism-providers/vertex` | host ADC / workload token | OpenAPI-compatible Vertex endpoint; separate from consumer Google package ([docs](providers/vertex.md)). |
|
|
66
66
|
|
|
67
67
|
A future provider-local OAuth package must first have explicit third-party permission and documented authorize/token/refresh flow. Before it registers an OAuth descriptor, it must add bounded request/response, abort, PKCE/state where required, expiry/refresh, secret-redaction, durable-store round-trip, and offline protocol tests. Do not add a generic OAuth framework, CLI credential scanner, automatic refresh timer, or success stub.
|
|
@@ -123,7 +123,7 @@ Every package remains explicit, setup-zero-fetch, and late-credential-bound. `Mo
|
|
|
123
123
|
| Package | Protocol / model source | Content mapping | Stream, tools, and reasoning | Cache / canary |
|
|
124
124
|
| --- | --- | --- | --- | --- |
|
|
125
125
|
| 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 |
|
|
126
|
-
| 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.
|
|
126
|
+
| 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.13 matrix (`4.0.3`, `4.0.4`, `4.0.10` also listed); protected host integration |
|
|
127
127
|
| Anthropic | Messages; caller-gated list | text, image, PDF document/file | tool deltas, thinking | `cache_control`; protected API-key smoke |
|
|
128
128
|
| Google | Gemini `generateContent`; caller-gated list | text, image, audio, document/file | complete tool calls, thinking | no Prism cache marker; protected API-key smoke |
|
|
129
129
|
| 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 |
|
|
@@ -139,7 +139,7 @@ Every package remains explicit, setup-zero-fetch, and late-credential-bound. `Mo
|
|
|
139
139
|
| xAI | OpenAI-compatible Completions; caller-gated list | text, image | tool deltas, `reasoning_content` replay | implicit + `x-grok-conv-id`; protected API-key smoke; SuperGrok login operator-only |
|
|
140
140
|
| ClinePass | OpenAI-compatible stream-only; static `cline-pass/*` catalog | text | tool deltas, per-model `reasoning_effort` | implicit; protected API-key smoke |
|
|
141
141
|
| Azure | Azure/Foundry OpenAI-compatible; host models | selected endpoint/model capability | normalized OpenAI-compatible tools | no Prism cache mapping; protected host workload-identity probe |
|
|
142
|
-
| Bedrock | Bedrock OpenAI-compatible; host models | selected endpoint/model capability | normalized OpenAI-compatible tools | no Prism cache mapping; protected host IAM/IRSA probe |
|
|
142
|
+
| Bedrock | Bedrock OpenAI-compatible (default) or native Converse/ConverseStream; host models | selected endpoint/model capability; native route refuses denied/unknown capabilities before request | normalized OpenAI-compatible tools or Converse `toolSpec`/`toolUse` deltas | compatible route: no Prism cache mapping; native route maps `cachePoint` breakpoints; protected host IAM/IRSA probe |
|
|
143
143
|
| Vertex | Vertex OpenAPI-compatible; host models | selected endpoint/model capability | normalized OpenAI-compatible tools | no Prism cache mapping; protected host ADC/WIF probe |
|
|
144
144
|
|
|
145
145
|
### First-party cache behavior
|
|
@@ -35,9 +35,10 @@ Static scan of root `src/providers/` and `packages/prism-providers/src/*/` befor
|
|
|
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
37
|
| NeuralWatt `classifyNeuralWattError` | `packages/prism-providers/src/neuralwatt` | Parses `Retry-After`, `error.retry_after`, `retry_strategy`; no extra network calls |
|
|
38
|
+
| Shared retry HTTP plane | `packages/prism-providers/src/shared/retry-http.ts` | **Migrated (plan 070 Task 11)** — `readRetryAfterMs` (header, plus a caller-supplied body field), `parseErrorBody`, the secret-redacting `providerHttpError` builder, and `RETRYABLE_STATUSES`; hyper, NeuralWatt, and Command Code classifiers keep their own status/field decisions |
|
|
38
39
|
| Quota endpoint throttling | `packages/prism-providers/src/neuralwatt/quota.ts` | Documents 1 rps limit; caller-owned cache |
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
The `Retry-After` HTTP plane is shared inside `@arnilo/prism-providers` (`src/shared/retry-http.ts`, plan 070 Task 11), so the three classifiers cannot drift on header reading or on the redaction of provider error text. `x-request-id` extraction and a *core*-level helper for every provider do not exist yet.
|
|
41
42
|
|
|
42
43
|
### Structured output
|
|
43
44
|
|
package/docs/providers/ai-sdk.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# AI SDK provider adapter
|
|
2
2
|
|
|
3
|
+
> **Optional peer install:** `@ai-sdk/provider@4.0.13` (exact pin) — see [Optional peer dependencies](../peer-dependencies.md).
|
|
4
|
+
|
|
3
5
|
## What it does
|
|
4
6
|
|
|
5
7
|
`@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.
|
|
@@ -12,7 +14,8 @@ Core `@arnilo/prism` does not depend on the AI SDK.
|
|
|
12
14
|
| --- | --- | --- |
|
|
13
15
|
| `4.0.3` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
|
|
14
16
|
| `4.0.4` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
|
|
15
|
-
| `4.0.10` | `LanguageModelV4`, `specificationVersion: "v4"` |
|
|
17
|
+
| `4.0.10` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
|
|
18
|
+
| `4.0.13` | `LanguageModelV4`, `specificationVersion: "v4"` | Current peer; supported and offline-tested |
|
|
16
19
|
|
|
17
20
|
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.
|
|
18
21
|
|
|
@@ -145,7 +148,7 @@ Official evidence: [Custom providers / LanguageModelV4](https://ai-sdk.dev/provi
|
|
|
145
148
|
|
|
146
149
|
## Extension and configuration notes
|
|
147
150
|
|
|
148
|
-
- Peer dependency: `@ai-sdk/provider@4.0.
|
|
151
|
+
- Peer dependency: `@ai-sdk/provider@4.0.13` (matrix also lists `4.0.3`, `4.0.4`, and `4.0.10`). Upgrade policy adds a matrix row and offline conformance fixture before accepting any new version.
|
|
149
152
|
- First-party HTTP providers remain independent; this adapter is available directly or through `@arnilo/prism-providers`. Installation does not select a model or invoke AI SDK.
|
|
150
153
|
- `options.compat` / `options.extra` pass through as AI SDK `providerOptions.prism`.
|
|
151
154
|
- Export helpers `toAiSdkCallOptions`, `toAiSdkPrompt`, and `mapAiSdkStream` for tests and custom hosts.
|
|
@@ -2,11 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
`@arnilo/prism-providers/bedrock` registers an Amazon Bedrock Runtime
|
|
5
|
+
`@arnilo/prism-providers/bedrock` registers an Amazon Bedrock Runtime provider with two explicit routes:
|
|
6
|
+
|
|
7
|
+
| Route | Wire API | Select with |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `compatible` (default) | OpenAI-compatible Chat Completions at `/openai/v1/chat/completions` | `createBedrockProvider` / `api: "compatible"` |
|
|
10
|
+
| `converse` | Native model-agnostic `Converse` and `ConverseStream` | `createBedrockConverseProvider` / `api: "converse"` |
|
|
11
|
+
|
|
12
|
+
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
13
|
|
|
7
14
|
## When to use it
|
|
8
15
|
|
|
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.
|
|
16
|
+
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. Use the `converse` route when the model only exists on Converse (tool use, reasoning, prompt caching, and structured output for Anthropic/Nova/OpenAI families), and keep `compatible` when an OpenAI-shaped gateway is what the deployment standardizes on.
|
|
17
|
+
|
|
18
|
+
## Route selection
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { createBedrockConverseProvider, createBedrockProviderPackage } from "@arnilo/prism-providers/bedrock";
|
|
22
|
+
|
|
23
|
+
// Package form: one provider id, selected route, optional non-streaming mode.
|
|
24
|
+
createBedrockProviderPackage({
|
|
25
|
+
region: "eu-west-1",
|
|
26
|
+
credential: () => hostAwsCredentials(),
|
|
27
|
+
api: "converse", // or "compatible" (default)
|
|
28
|
+
stream: true, // native route only: ConverseStream (default) vs one Converse call
|
|
29
|
+
models: [{ provider: "bedrock", model: "eu.anthropic.claude-haiku-4-5-20251001-v1:0" }],
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Factory form (same options, no registry wiring):
|
|
33
|
+
const provider = createBedrockConverseProvider({ region: "us-east-1", credential });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Routes are mutually exclusive per provider id, so a host that needs both registers the second provider under a different `id` and model bindings. The package records the selected route in `ProviderPackage.metadata.route` and in the registered auth method metadata.
|
|
37
|
+
|
|
38
|
+
## Capability matrix
|
|
39
|
+
|
|
40
|
+
| Capability | `compatible` | `converse` |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| Text streaming | yes (OpenAI SSE) | yes (`ConverseStream` event stream) |
|
|
43
|
+
| Non-streaming | n/a (always streams) | yes (`stream: false`, one `Converse` response mapped to deltas + done) |
|
|
44
|
+
| Images | model-dependent OpenAI image parts | `image` blocks (`png`/`jpeg`/`gif`/`webp`); unknown media types refuse before the request |
|
|
45
|
+
| PDF documents | n/a | `document` blocks (`format` from media type); non-PDF files refuse |
|
|
46
|
+
| Tools | OpenAI `tools` | `toolConfig.tools[].toolSpec`, streamed `toolUse` deltas, `toolResult` in the following user turn |
|
|
47
|
+
| Reasoning/thinking | sanitized `reasoning_effort` / `reasoning` object | Anthropic-family `thinking` (`enabled`/`disabled`/`adaptive`, budget validated) and OpenAI-family `reasoning_effort` in `additionalModelRequestFields`; reasoning deltas map to Prism thinking blocks with signatures |
|
|
48
|
+
| Prompt caching | none (no Prism cache fields emitted) | `cachePoint` blocks from Prism cache breakpoints, `ttl: "1h"` for long retention; usage reports `cacheReadTokens` / `cacheWriteTokens` |
|
|
49
|
+
| Structured output | body passthrough only | `outputConfig.textFormat` JSON schema (requires `capabilities.structuredOutput`) |
|
|
50
|
+
| Usage | OpenAI usage | `inputTokens`/`outputTokens`/`totalTokens` + cache read/write |
|
|
51
|
+
|
|
52
|
+
Every feature above is tested offline against recorded frame/body fixtures; the live probe below covers text, tools, and usage. Features are not inferred from compatible endpoints.
|
|
10
53
|
|
|
11
54
|
## Inputs / request
|
|
12
55
|
|
|
@@ -34,6 +77,8 @@ Default public base: `https://bedrock-runtime.{region}.amazonaws.com` → `/open
|
|
|
34
77
|
|
|
35
78
|
OpenAI-compatible SSE mapped to Prism provider events. Missing credentials fail closed before network I/O.
|
|
36
79
|
|
|
80
|
+
Native route: `ConverseStream` frames are decoded from `application/vnd.amazon.eventstream` (prelude/header lengths and both CRC32 checksums validated, 1 MiB default frame ceiling, 24 MiB hard spec ceiling) and mapped to Prism provider events. `:message-type: exception` frames become `error` events with the exception name and message; a stream that ends without `messageStop` or with an incomplete tool block fails loudly instead of returning partial output as success. Credentials are resolved once per request and redacted from provider errors.
|
|
81
|
+
|
|
37
82
|
## Request/response example
|
|
38
83
|
|
|
39
84
|
```http
|
|
@@ -51,11 +96,26 @@ const provider = createBedrockProvider({
|
|
|
51
96
|
});
|
|
52
97
|
```
|
|
53
98
|
|
|
99
|
+
Native route request:
|
|
100
|
+
|
|
101
|
+
```http
|
|
102
|
+
POST https://bedrock-runtime.eu-west-1.amazonaws.com/model/eu.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse-stream
|
|
103
|
+
Accept: application/vnd.amazon.eventstream
|
|
104
|
+
Authorization: AWS4-HMAC-SHA256 Credential=…/eu-west-1/bedrock/aws4_request, …
|
|
105
|
+
|
|
106
|
+
{ "messages": [{ "role": "user", "content": [{ "text": "hi" }] }],
|
|
107
|
+
"inferenceConfig": { "maxTokens": 4096 } }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The `Converse` and `ConverseStream` operations share one request body; `accept` and the URL suffix select the operation. Inference-profile model ids (`eu.`/`us.` prefixes) are percent-encoded into the path, and region/endpoint policy is unchanged from the compatible route.
|
|
111
|
+
|
|
54
112
|
Live canaries stay opt-in behind host credentials; default tests are network-free.
|
|
55
113
|
|
|
56
114
|
## Extension and configuration notes
|
|
57
115
|
|
|
58
|
-
|
|
116
|
+
The compatible route uses Bedrock’s OpenAI-compatible runtime route (not Converse eventstream). The native route (`api: "converse"`) covers Converse-only models and features; both stay explicit, and neither silently falls back to the other.
|
|
117
|
+
|
|
118
|
+
Model-specific fields (for example `top_k`) come from `ModelConfig.parameters` leftovers plus the sanitized `compat.thinking` / `compat.reasoning_effort` keys; opaque `compat` keys are not spread onto the Converse body, and `toolChoice` is only forwarded when it is `auto`/`any`/`required` or `{ tool: { name } }`.
|
|
59
119
|
|
|
60
120
|
## Request construction (0.5.1)
|
|
61
121
|
|
|
@@ -71,12 +131,14 @@ See [Provider request policies](../provider-request-policies.md).
|
|
|
71
131
|
|
|
72
132
|
## Security and performance notes
|
|
73
133
|
|
|
74
|
-
- No AWS SDK; package-local SigV4 only for `bedrock` service.
|
|
134
|
+
- No AWS SDK; package-local SigV4 only for `bedrock` service on both routes.
|
|
75
135
|
- Input headers are normalized once before signing: names are lowercased and duplicate-case keys merge last-wins, so the canonical request always matches the signed header list (no duplicate-case mismatch); query parameters are canonicalized sorted by encoded key then value.
|
|
76
136
|
- Private endpoint hosts are not rewritten to public DNS.
|
|
77
137
|
- Conformance-proven (Task 6): package `setup()` performs zero fetch and zero credential resolution; an already-aborted signal fails fast; a truncated SSE stream (no `data: [DONE]`) ends in an `error` event; native Bedrock caching (`Converse cachePoint`) is intentionally unsupported on the OpenAI-compatible route — no cache wire fields are emitted even when the request carries Prism cache hints.
|
|
138
|
+
- Native route: `ConverseStream` frames are capped at 1 MiB (24 MiB hard spec ceiling) and a non-streaming `Converse` body is read under a 4 MiB ceiling (`BEDROCK_CONVERSE_RESPONSE_MAX_BYTES`), so a hostile or runaway response cannot exhaust memory.
|
|
139
|
+
- Native route: denied/unknown capabilities (`streaming: false` with the streaming route, `tools: false` with tools, `structuredOutput` undeclared, `reasoning: false` with a thinking/effort request, unsupported media types) refuse before any request is sent; corrupt or oversized event-stream frames terminate the stream rather than resyncing.
|
|
78
140
|
- Credential secrets are redacted from provider errors.
|
|
79
|
-
- No credential prefetch at import.
|
|
141
|
+
- No credential prefetch at import on either route.
|
|
80
142
|
|
|
81
143
|
## Live probe
|
|
82
144
|
|
|
@@ -87,11 +149,13 @@ PRISM_LIVE_PROVIDER_TESTS=1 AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_
|
|
|
87
149
|
node --test packages/prism-providers/dist/bedrock/__tests__/live.test.js
|
|
88
150
|
```
|
|
89
151
|
|
|
90
|
-
`PRISM_LIVE_BEDROCK_MODEL` overrides the probed model (default `us.anthropic.claude-haiku-4-5-20251001-v1:0`). Without credentials the suite skips.
|
|
152
|
+
`PRISM_LIVE_BEDROCK_MODEL` overrides the probed model (default `us.anthropic.claude-haiku-4-5-20251001-v1:0`). The same suite also probes the native route (streaming text/tools/usage and one non-streaming `Converse` call). Without credentials the suite skips.
|
|
91
153
|
|
|
92
154
|
## Thinking and reasoning
|
|
93
155
|
|
|
94
|
-
Bedrock OpenAI-compat chat expects snake_case `reasoning_effort` (with `effort`/`reasoningEffort` aliases) or a sanitized `reasoning` object. OpenAI-family models on Bedrock snap effort to their declared levels (gpt-5.1 → `none/low/medium/high`); non-OpenAI models pass through untouched.
|
|
156
|
+
Compatible route: Bedrock OpenAI-compat chat expects snake_case `reasoning_effort` (with `effort`/`reasoningEffort` aliases) or a sanitized `reasoning` object. OpenAI-family models on Bedrock snap effort to their declared levels (gpt-5.1 → `none/low/medium/high`); non-OpenAI models pass through untouched.
|
|
157
|
+
|
|
158
|
+
Native route: Anthropic-family models take `additionalModelRequestFields.thinking` (`{type: "enabled"|"disabled"|"adaptive", budget_tokens?}`); a bare `enabled` gets a default budget so it can never reach the wire without one, and historical thinking blocks replay with signatures when `compat.preserveThinking` is on (default: when the model declares `capabilities.reasoning`). OpenAI-family models take `additionalModelRequestFields.reasoning_effort`, snapped to declared levels. See [Thinking and reasoning](../thinking-and-reasoning.md).
|
|
95
159
|
|
|
96
160
|
## Related APIs
|
|
97
161
|
|
package/docs/providers/openai.md
CHANGED
|
@@ -52,7 +52,7 @@ uses official Responses `reasoning: { effort, summary? }` via
|
|
|
52
52
|
| --- | --- |
|
|
53
53
|
| Provider stream | Prism text, thinking (downgraded to text), host `tool_call` deltas/finals, provider-hosted `tool_call` events (`authority: "provider-hosted"`), `continuation_required`, `usage`, `done`, and redacted `error` events. |
|
|
54
54
|
| Continuation | An incomplete Responses stream self-resumes at most eight HTTP hops using opaque `previous_response_id`; a cursor is at most 4 KiB, is never replayed, and is observable as `continuation_required`. |
|
|
55
|
-
| Realtime | `createOpenAIRealtimeSession()` exposes server-session creation, audio in/out, transcript deltas, provider-hosted calls, interrupt, and idempotent close through the neutral `RealtimeSession` seam. |
|
|
55
|
+
| Realtime | `createOpenAIRealtimeSession()` exposes server-session creation, audio in/out, transcript deltas, host `function_call` items, provider-hosted calls, `usage`, `completeTool`, interrupt, and idempotent close through the neutral `RealtimeSession` seam. Host orchestration is [Realtime voice](../realtime-voice.md). |
|
|
56
56
|
| Block preservation | User/system text → `input_text`; assistant text → `output_text`; assistant host `tool_call` → top-level `function_call` with `call_id`; provider-hosted calls are not replayed; `tool_result` → top-level `function_call_output`; images/files/audio when declared on the model. Bare thinking without an encrypted Responses reasoning item is omitted on replay. |
|
|
57
57
|
| Auth methods | `api_key` for `openai`; host-invoked subscription `oauth` for `openai-codex`. xAI SuperGrok is the other first-party subscription OAuth flow ([xAI](xai.md)). |
|
|
58
58
|
|
package/docs/public-contracts.md
CHANGED
|
@@ -131,7 +131,7 @@ Important request shapes:
|
|
|
131
131
|
| `SkillRegistry` | Host active skill registry shape: `register()`, `get()`, `resolve()`, and `list()`. |
|
|
132
132
|
| `CredentialRequest` | Credential lookup request: credential `name`, optional provider id, and metadata. |
|
|
133
133
|
| `OAuthProvider` | Host/package OAuth callbacks for login, optional refresh, and conversion to a `Credential`. |
|
|
134
|
-
| `AgentSessionConfig` | Session creation input: optional id, agent, store, leaf id, and
|
|
134
|
+
| `AgentSessionConfig` | Session creation input: optional id, agent, store, leaf id, metadata, and `snapshotCacheTtlMs` (branch-cache TTL; `0` disables). |
|
|
135
135
|
| `RunOptions` | Per-run overrides: optional abort signal, model, input layout, run limits (incl. `limits.maxToolRounds`), provider options/request policies, system prompt layers, compaction, retry, metadata, skill selection, validate, redactor, and loop. |
|
|
136
136
|
| `SubscribeOptions` / `SubscriberOverflowPolicy` | Live `AgentEvent` subscriber queue limit and overflow policy: `maxQueuedEvents`, `overflow: "close" \| "drop_oldest" \| "drop_newest"`. |
|
|
137
137
|
| `resumeAgentRunStream` / `AgentRunResumeStreamOptions` | One durable-run event stream: existing checkpoint/resume options plus `signal` and bounded subscriber options. `AgentRunLifecycle.resumeStream()` adds host capability resolution; no protocol types enter core. Runtime resume validation (0.2.0): every resume entrypoint validates the full input in core before any checkpoint write, tool call, or event — unknown legacy decisions and malformed batches fail closed with `AgentDecisionError` and no side effect; see [Agent/session runtime § Durable interruption](agent-session-runtime.md#durable-interruption). |
|
|
@@ -157,7 +157,7 @@ Important request shapes:
|
|
|
157
157
|
| `SessionIndex` / `SessionSearchQuery` / `SessionSearchHit` | Bounded optional session search seam (`search` / `SessionStore.searchSessions?`). Filters: workspace (`metadata.workspaceRoot`), time, provider/model, label/summary, optional FTS `query`, ownership. Hits return `sessionId` + optional `leafId` for resume; never credentials. Caps via `resolveSessionSearchQuery` / `DEFAULT_*` / `HARD_MAX_*` session-search constants. |
|
|
158
158
|
| `contextBudget` / `getContextBudgetReport` / `ContextBudgetError` | Opt-in assembler budget on `AssembleProviderInputOptions`; deterministic eviction; omission report in `ProviderRequest.metadata` (kinds/ids/sizes only). |
|
|
159
159
|
| `AgentSession.steer` / `SteerOptions` / pending-steer caps | Mid-run enqueue into active run; optional `softInterrupt`; default 8 msgs / 64 KiB UTF-8. |
|
|
160
|
-
| `SessionSearchUnsupportedError` / `sessionSearchMode` | Memory opt-out + JSONL; typed throw (not empty success). |
|
|
160
|
+
| `SessionSearchUnsupportedError` / `sessionSearchMode` | Memory opt-out + JSONL; typed throw (not empty success). Memory linear caps are host-overridable via `CreateMemorySessionStoreOptions.search`. |
|
|
161
161
|
| `BranchRecord` / `BranchQuery` | Branch handle/leaf pointer and query filters (session, name, parent branch, leaf presence). |
|
|
162
162
|
| `SessionEntryQuery` | Paginated entry filters: `sessionId`, `runId`, `parentId`, `leafId`, `kind`, timestamp range, ownership. |
|
|
163
163
|
| `RunRecord` / `RunQuery` | Stored run and filters: session, branch, status, timestamps, ownership. |
|
package/docs/rag.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
The `@arnilo/prism-memory/rag` subpath is an optional surface for deterministic text/Markdown chunking (with ATX heading-stack metadata), bounded embedding/vector indexing with embedder-identity drift guards, atomic scoped source replacement/deletion with content-hash skip and generation visibility, hybrid vector+lexical retrieval with reciprocal-rank fusion (one embed / one RRF / one rerank across one or many exact scopes), focused text/Markdown/HTML/PDF parsing, bounded reranking (host seam plus a TEI REST adapter), ingestion status, attributable citations, content-trust metadata, and explicit `ContextProvider` injection. It reuses `Embedder` and `VectorStore` from the memory root entry; Prism core input assembly is unchanged.
|
|
5
|
+
The `@arnilo/prism-memory/rag` subpath is an optional surface for deterministic text/Markdown chunking (with ATX heading-stack metadata), bounded embedding/vector indexing with embedder-identity drift guards, atomic scoped source replacement/deletion with content-hash skip and generation visibility, hybrid vector+lexical retrieval with reciprocal-rank fusion (one embed / one RRF / one rerank across one or many exact scopes), host-verified document authorization on both query legs, paged knowledge-source synchronization with a Drive connector, focused text/Markdown/HTML/PDF parsing, bounded reranking (host seam plus a TEI REST adapter), ingestion status, attributable citations, content-trust metadata, and explicit `ContextProvider` injection. It reuses `Embedder` and `VectorStore` from the memory root entry; Prism core input assembly is unchanged.
|
|
6
6
|
|
|
7
7
|
## When to use it
|
|
8
8
|
|
|
9
|
-
Use it when a host needs bounded replacement of one owned source, focused parsing after a host-authorized resource or host-selected web fetch,
|
|
9
|
+
Use it when a host needs bounded replacement of one owned source, focused parsing after a host-authorized resource or host-selected web fetch, a host-selected reranker over a finite candidate set, or incremental Drive knowledge sync into that same source lifecycle. Do not use it for LaTeX parsing, semantic chunking, metadata extraction agents, a hosted reranker implementation, GraphRAG, crawling, URL fetching outside `@arnilo/prism-web-tools`, or filesystem discovery.
|
|
10
10
|
|
|
11
11
|
## Inputs / request
|
|
12
12
|
|
|
@@ -24,9 +24,11 @@ Document lifecycle:
|
|
|
24
24
|
|
|
25
25
|
| API/field | Meaning |
|
|
26
26
|
| --- | --- |
|
|
27
|
-
| `replaceSource({ sourceId, chunks, store, scope, ... })` | Atomically replaces one source after all bounded embedding succeeds; the store must implement scoped `getBySource()` and `transaction()`. |
|
|
27
|
+
| `replaceSource({ sourceId, chunks, store, scope, ... })` | Atomically replaces one source after all bounded embedding succeeds; the store must implement scoped `getBySource()` and `transaction()`. `advanceGeneration: false` stamps the current generation without moving the scope pointer (multi-source sync). |
|
|
28
28
|
| `deleteSource({ sourceId, store, scope })` | Deletes only matching IDs under exact tenant/resource/corpus scope. |
|
|
29
29
|
| `replaceDocument({ uri, loader, parser, store, scope, ... })` | Loads through a host seam, parses, chunks, and atomically replaces. `sourceId` is required unless loader supplies one. |
|
|
30
|
+
| `syncKnowledge({ connector, checkpoints, checkpoint, store, embedder, scope })` | Paged connector import; cursor CAS only after each committed page. See [Knowledge synchronization](knowledge-sync.md). |
|
|
31
|
+
| `createGoogleDriveConnector({ tokenProvider, resolveAccess })` | Drive `files.list` + `changes.list` connector. Host maps permissions; watch payloads are not authorization. |
|
|
30
32
|
| `DocumentLoader` / `Parser` | Small host-replaceable seams. `@arnilo/prism-memory/rag/loaders` and `/rag/parsers` export reference adapters. |
|
|
31
33
|
| `textParser` / `markdownParser` / `htmlParser` / `pdfParser` | UTF-8 text, Markdown, script/style-stripping HTML, and uncompressed-text PDF parsers. |
|
|
32
34
|
|
|
@@ -40,7 +42,8 @@ Index/retrieve:
|
|
|
40
42
|
| `topK` / `queryCandidates` | retrieval | Returned result count and bounded pre-filter candidates (`queryCandidates` is **per scope**) |
|
|
41
43
|
| `lexical` | no | `"fts"` \| `"bm25"` \| `"off"` (default `"off"`); enables the lexical retrieval leg when the store advertises it |
|
|
42
44
|
| `fusion` / `rrfK` | no | `"rrf"` fusion of vector+lexical legs (default `"rrf"` when `lexical` is on; `rrfK` default 60, hard cap 1,000) |
|
|
43
|
-
| `filter` | no | Shallow JSON metadata equality filter |
|
|
45
|
+
| `filter` | no | Shallow JSON metadata equality filter. **Not authorization.** |
|
|
46
|
+
| `authorization` | no | Host-verified `{ principalId, tenantId, groupIds?, accessVersion? }`. Injected into both vector and lexical legs before ranking; rechecked before rerank and injection. Stores without `authorization: "acl"` fail closed. |
|
|
44
47
|
| `reranker` | no | Host-owned `Reranker` receives redacted bounded `RagHit[]` and must return the same IDs once each, in preferred order. |
|
|
45
48
|
| `maxRerankBytes` / `maxRerankMs` / `rerankConcurrency` | no | Reranker caps; defaults/hard limits are 64/256 KiB, 2/10 s, and 2/8 active calls per reranker object. |
|
|
46
49
|
| `statusStore` | no | `IngestionStatusStore` records per-source pending/indexed/failed/partial byte/chunk progress; use `listIngestionStatus()` for capped exact-scope pages. |
|
|
@@ -56,9 +59,10 @@ Index/retrieve:
|
|
|
56
59
|
- `indexChunks()` returns `{ indexed, sourceIds }` after bounded batch upserts.
|
|
57
60
|
- `replaceSource()` / `deleteSource()` return `{ sourceId, deleted, indexed }`.
|
|
58
61
|
- `replaceDocument()` carries loader parser metadata into chunk metadata; the web loader preserves web-tools citation ID and `untrusted: true`.
|
|
59
|
-
- `retrieveContext()` returns `{ query, trust, text, hits, citations, truncated }`. Every hit/citation carries `{ provenance: { sourceId, chunkId, citationId, provider, tenantId, resourceId, corpusId, retrieval: "vector" | "lexical" | "hybrid", retrievedAt }, trust: { untrusted: true, inert: true, injectionCapable: true } }`; `retrieval` labels the leg(s) that surfaced the hit after RRF fusion, and `retrievalRank` preserves pre-rerank order. Rendered text uses `[citation-id] text` blocks.
|
|
62
|
+
- `retrieveContext()` returns `{ query, trust, text, hits, citations, truncated }`. Every hit/citation carries `{ provenance: { sourceId, chunkId, citationId, provider, tenantId, resourceId, corpusId, retrieval: "vector" | "lexical" | "hybrid", retrievedAt }, trust: { untrusted: true, inert: true, injectionCapable: true } }`; `retrieval` labels the leg(s) that surfaced the hit after RRF fusion, and `retrievalRank` preserves pre-rerank order. Rendered text uses `[citation-id] text` blocks. `evidenceFromRagCitation(citation, { contentHash, revision, excerpt? })` projects a hit into the shared `ArtifactCitation` evidence shape without refetching.
|
|
60
63
|
- `replaceSource()` returns `{ sourceId, deleted, indexed, skipped? }` (skipped when the stored `contentHash` matched and no writes occurred). Records carry `embedderId` (from `Embedder.id`, the Task 2 identity contract) and `generation` (scope-level monotonically bumped index per replacement; `_rag` metadata carries `contentHash` when supplied). `store.getCurrentGeneration(scope)` / `store.setCurrentGeneration(scope, n)` let hosts read and roll back the visible generation; retrieval filters to the current generation while legacy generation-less rows stay visible.
|
|
61
|
-
- `createMemoryIngestionStatusStore()` is a bounded in-memory reference adapter. `listIngestionStatus({ store, scope, limit, cursor })` returns capped status pages; hosts supply durable stores when status must survive process restart.
|
|
64
|
+
- `createMemoryIngestionStatusStore()` is a bounded in-memory reference adapter. `listIngestionStatus({ store, scope, limit, cursor })` returns capped status pages; hosts supply durable stores when status must survive process restart. Optional `freshness` is `current` / `stale` / `unavailable` for synchronized sources.
|
|
65
|
+
- `syncKnowledge()` returns `{ pages, upserted, deleted, skipped, withheld, cursor?, exhausted }`. Unchanged `contentHash` values skip embedding. Invalid Drive page tokens throw `RagSyncCursorError` (default: one bootstrap resync).
|
|
62
66
|
- `createRagContextProvider()` returns one ordinary context provider. Empty queries/results contribute no block.
|
|
63
67
|
- No events, tools, permissions, provider calls, loaders, or network requests are added.
|
|
64
68
|
|
|
@@ -97,12 +101,17 @@ const statusStore = createMemoryIngestionStatusStore();
|
|
|
97
101
|
await indexChunks({ chunks, embedder, store, scope, statusStore });
|
|
98
102
|
// For a replaceable source use `replaceSource`; it keeps previous chunks until embedding succeeds.
|
|
99
103
|
|
|
104
|
+
await store.setSourceAccess(
|
|
105
|
+
{ tenantId: scope.tenantId, resourceId: scope.resourceId, threadId: scope.corpusId },
|
|
106
|
+
[{ sourceId: "security-guide", principalIds: ["alice"], groupIds: ["eng"], accessVersion: 1 }],
|
|
107
|
+
);
|
|
100
108
|
const found = await retrieveContext("approval policy", {
|
|
101
109
|
embedder,
|
|
102
110
|
store,
|
|
103
111
|
scopes: [scope], // or `scope` for one corpus
|
|
104
112
|
topK: 4,
|
|
105
113
|
filter: { category: "security" },
|
|
114
|
+
authorization: { principalId: "alice", tenantId: scope.tenantId, groupIds: ["eng"] },
|
|
106
115
|
reranker: { rerank: async ({ hits }) => [...hits].sort((a, b) => b.score - a.score) },
|
|
107
116
|
});
|
|
108
117
|
console.log(await listIngestionStatus({ store: statusStore, scope }));
|
|
@@ -149,7 +158,8 @@ const found = await retrieveContext("leave balance", {
|
|
|
149
158
|
## Extension and configuration notes
|
|
150
159
|
|
|
151
160
|
- Supply any Phase 7-conforming embedder/vector store, including the in-memory reference or PostgreSQL/pgvector adapter.
|
|
152
|
-
- Metadata filtering is package-local after a bounded candidate query so existing vector contracts/adapters remain unchanged. Increase `queryCandidates` only when selective filters measurably need it.
|
|
161
|
+
- Metadata filtering is package-local after a bounded candidate query so existing vector contracts/adapters remain unchanged. Increase `queryCandidates` only when selective filters measurably need it. `filter` never grants document access.
|
|
162
|
+
- Document ACL is opt-in via `authorization` on `retrieveContext` / `store.query` / `store.lexicalQuery`. Reference memory and PostgreSQL adapters declare `authorization: "acl"` and apply principal/group predicates **before** top-K. `setSourceAccess` replaces grants per source (empty principal+group lists revoke). Access version is independent of embedding generation; an unresolved `accessVersion` denies. Missing grants deny. Stores that omit the capability throw rather than claim protection. Group lists cap at 32.
|
|
153
163
|
- `Reranker` is a host seam, not a provider integration. Return each redacted candidate ID exactly once; Prism retains canonical hit/provenance/trust fields and exposes `retrievalRank` for diagnostics. Add a hosted reranker only when a host owns its credentials, quota, and retry policy.
|
|
154
164
|
- `createTeiReranker({ baseUrl, model?, timeoutMs?, maxResponseBytes?, ssrf?, allowLoopback?, fetch? })` (`CreateTeiRerankerOptions`) adapts a Hugging Face TEI `POST <baseUrl>/rerank` endpoint (`{query, texts, raw_scores:false}` → `{results:[{index,score}]}`) into the `Reranker` seam. It returns a permutation-only reorder of the same hit objects, so provenance/trust move untouched. Response parsing is strict — short/duplicate/out-of-range indices, non-finite scores, HTTP errors, timeouts, and oversized bodies all fail closed; the `rerankHits` caps (`maxRerankBytes`, `maxRerankMs`, `rerankConcurrency`) still apply around it. The default transport is the core DNS-pinned `pinnedFetch` (redirect-free, byte-bounded to 65,536 by default); HTTPS is required unless `allowLoopback: true` (loopback dev/test) or the host supplies `ssrf`/`fetch` for cluster networking. The adapter validates URL shape only — SSRF policy enforcement stays host-side. No credentials are ever sent; there is no SaaS default URL.
|
|
155
165
|
- Hosted rerank adapters over the same seam (plan 062): `createOpenAiCompatibleReranker({ baseUrl, model?, apiKey?, timeoutMs?, maxResponseBytes?, ssrf?, allowLoopback?, fetch? })` speaks the OpenAI-compatible `POST <baseUrl>/rerank` route (`{model, query, documents}` → `{results:[{index,relevance_score}]}`; pass the version segment in `baseUrl`, e.g. `https://api.jina.ai/v1`), and `createVoyageReranker({ baseUrl, model?, apiKey, … })` adapts Voyage AI (`…/v1/rerank` → `{data:[{index,relevance_score}]}`; `apiKey` required). Both send one request per rerank — no adapter-side batching — never send `top_k` (the retrieval seam owns top-K), return the same permutation-only reorder, and fail closed on the same malformed-response/HTTP/timeout/byte-bound cases. `apiKey` rides as `Authorization: Bearer …` and is never logged; errors carry status/host only. No SaaS default URL — hosts own credentials, quota, and retry policy.
|
|
@@ -162,12 +172,13 @@ const found = await retrieveContext("leave balance", {
|
|
|
162
172
|
- `createRagContextProvider()` derives its query from latest user text by default; pass a fixed string or callback for host-controlled query generation.
|
|
163
173
|
- `createResourceDocumentLoader({ loader })` calls one host-owned `ResourceLoader`; it scans nothing and performs no filesystem or network I/O itself. Pass the host's permission/trust context to that loader.
|
|
164
174
|
- `createWebFetchDocumentLoader({ fetcher })` accepts an already-configured `@arnilo/prism-web-tools` fetch adapter. It never opens a socket, rejects file/local/private/IP-literal URLs, and carries normalized citation/trust metadata forward. The fetch adapter still owns DNS/SSRF policy.
|
|
165
|
-
- `pdfParser` is deliberately limited to bounded, uncompressed PDF text. Provide a host parser through `Parser` for compressed, scanned, or complex PDFs; do not silently index partial text.
|
|
175
|
+
- `pdfParser` is deliberately limited to bounded, uncompressed PDF text. Provide a host parser through `Parser` for compressed, scanned, or complex PDFs; do not silently index partial text. Hosts that need OCR wrap `createMistralOcrParser` from `@arnilo/prism-coding-tools/document-reader` — it is never the default parser and never runs unless the host passes it to `replaceDocument({ parser })`.
|
|
166
176
|
- Package is available directly or via the `@arnilo/prism-memory` family tarball; installation does not create an embedder, vector store, loader, parser, or context provider.
|
|
167
177
|
|
|
168
178
|
## Security and performance notes
|
|
169
179
|
|
|
170
180
|
- Every index/query includes exact tenant/resource/corpus scope; returned records are rechecked and malformed/foreign records fail closed. `retrieveContext` accepts `scope` or `scopes` (never both, never neither). Empty `scopes` is the host “no allowed corpora” path — no embed, no search, no rerank. A hit whose stored scope is not in the requested list fails closed. Generation filters stay per scope.
|
|
181
|
+
- When `authorization` is set, unauthorized text, titles, citations, counts, and reranker payloads never leave the store. Recheck runs after fusion (before rerank) and again after rerank before injection, so revocation between those steps drops the candidate. `authorization.tenantId` must match every retrieve scope.
|
|
171
182
|
- Embedding identity is a privacy/consistency boundary: records from a different embedder (or dimension) never silently mingle with new ones — retrieval fails closed and names the re-index path. Generation pointers are scope-scoped: a pointer row belongs to exactly one scope, and visibility is computed inside the store (SQL), never by post-filtering in JS.
|
|
172
183
|
- Source IDs become citation/storage IDs and must be stable non-secret identifiers. Text and user metadata can be redacted before external embedding and persistence.
|
|
173
184
|
- Heading metadata is document text only — it passes through the existing `maxMetadataBytes` cap as chunk metadata; no new content path is introduced.
|
|
@@ -200,12 +211,17 @@ PRISM_TEST_TEI_RERANKER_URL=http://tei.svc:8080 \
|
|
|
200
211
|
| `PRISM_TEST_HOSTED_RERANK_URL` | OpenAI-compatible rerank base URL (`/rerank` appended, include `/v1`) |
|
|
201
212
|
| `PRISM_TEST_HOSTED_RERANK_KEY` | Bearer credential for the hosted endpoint |
|
|
202
213
|
| `PRISM_LIVE_HOSTED_RERANK_MODEL` | optional hosted model name |
|
|
214
|
+
| `PRISM_TEST_DRIVE_ACCESS_TOKEN` | delegated Drive readonly token for `memory/drive-sync-live` |
|
|
215
|
+
| `PRISM_TEST_DRIVE_FOLDER_ID` | optional folder scope |
|
|
216
|
+
| `PRISM_TEST_DRIVE_SHARED_DRIVE_ID` | optional shared drive |
|
|
203
217
|
|
|
204
218
|
Probes send one non-sensitive rerank request per configured endpoint and assert the live response conforms (permutation-only reorder, scores non-increasing, credential never in error transcripts). Registered in `scripts/live-matrix.json` as `memory/rag-rerankers-live`.
|
|
205
219
|
|
|
206
220
|
## Related APIs
|
|
207
221
|
|
|
222
|
+
- [Knowledge synchronization](knowledge-sync.md): paged connector sync, Drive adapter, cursor CAS, source freshness.
|
|
208
223
|
- [Working and semantic memory](working-and-semantic-memory.md): shared `Embedder`/`VectorStore` contracts and adapters.
|
|
224
|
+
- [Work artifacts and review](work-artifacts-and-review.md): `evidenceFromRagCitation` projects retrieved hits into shared citation evidence.
|
|
209
225
|
- [Context and skills](context-and-skills.md): explicit `ContextProvider` injection and inert context semantics.
|
|
210
226
|
- [Resource loading](resource-loading.md): host-owned trusted source loading.
|
|
211
227
|
- [Multimodal content](multimodal-content.md): remote media SSRF/MIME/byte policies before text extraction.
|