@arnilo/prism 0.1.3 → 0.1.5

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 (43) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/agent-approval.d.ts +49 -0
  3. package/dist/agent-approval.js +178 -0
  4. package/dist/agent-run-lifecycle.d.ts +5 -1
  5. package/dist/agent-run-lifecycle.js +211 -3
  6. package/dist/agent-session.d.ts +98 -0
  7. package/dist/agent-session.js +1811 -0
  8. package/dist/agent-tool-dispatch.d.ts +13 -0
  9. package/dist/agent-tool-dispatch.js +92 -0
  10. package/dist/agents.d.ts +16 -9
  11. package/dist/agents.js +14 -2267
  12. package/dist/cli-init.d.ts +0 -2
  13. package/dist/cli-init.js +0 -2
  14. package/dist/cli-runner.js +1 -1
  15. package/dist/contracts-core.d.ts +1396 -0
  16. package/dist/contracts-core.js +119 -0
  17. package/dist/contracts-protocol.d.ts +594 -0
  18. package/dist/contracts-protocol.js +2 -0
  19. package/dist/contracts-run-state.d.ts +285 -0
  20. package/dist/contracts-run-state.js +77 -0
  21. package/dist/contracts.d.ts +7 -2269
  22. package/dist/contracts.js +7 -192
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/rpc.js +2 -1
  26. package/docs/agent-loops.md +1 -1
  27. package/docs/agent-session-runtime.md +4 -2
  28. package/docs/browser-automation.md +13 -9
  29. package/docs/coding-agent-tools.md +1 -2
  30. package/docs/compaction-observational-memory.md +5 -6
  31. package/docs/index.md +4 -4
  32. package/docs/migration.md +114 -1
  33. package/docs/performance.md +10 -0
  34. package/docs/provider-conformance.md +2 -2
  35. package/docs/provider-layer.md +1 -1
  36. package/docs/provider-packages.md +1 -1
  37. package/docs/provider-primitives.md +1 -1
  38. package/docs/public-contracts.md +4 -2
  39. package/docs/release-and-install.md +64 -0
  40. package/docs/tool-execution-primitives.md +3 -3
  41. package/docs/tools.md +2 -2
  42. package/docs/use-case-model-selection.md +12 -11
  43. package/package.json +2 -2
@@ -17,7 +17,7 @@ Exported from `@arnilo/prism/testing/provider-conformance`:
17
17
 
18
18
  ## When to use it
19
19
 
20
- Use these helpers in provider package tests to check event order, terminal events, abort propagation via `ProviderRequest.signal`, streamed tool-call deltas, usage/cache accounting, request body content preservation, protected header ownership, and secret redaction. Do not treat deprecated `ProviderRequestOptions.timeoutMs`/`maxRetries`/`maxRetryDelayMs` as conformance requirements; first-party providers use runtime abort signals and `AgentConfig.retry`/`RunOptions.retry` instead.
20
+ Use these helpers in provider package tests to check event order, terminal events, abort propagation via `ProviderRequest.signal`, streamed tool-call deltas, usage/cache accounting, request body content preservation, protected header ownership, and secret redaction. Provider-level timeout/retry hints were removed in 0.1.5; first-party providers use runtime abort signals and `AgentConfig.retry`/`RunOptions.retry` instead.
21
21
 
22
22
  Do not use them as a live integration runner, provider simulator, retry framework, credential loader, or test framework replacement.
23
23
 
@@ -65,7 +65,7 @@ Helpers accept normal `AIProvider`, `ProviderRequest`, `ProviderEvent`, `Usage`,
65
65
 
66
66
  - `collectProviderEvents()` returns provider events in stream order.
67
67
  - `assertProviderStreamConforms()` returns collected events after verifying the stream ends with `done` or `error`, terminal events are last, and optional text/usage expectations match.
68
- - `assertAbortIsObserved()` passes an already-aborted signal and expects provider generation to reject. This is the supported timeout primitive; use a host abort controller or `RunOptions.signal` rather than deprecated provider-level `timeoutMs`.
68
+ - `assertAbortIsObserved()` passes an already-aborted signal and expects provider generation to reject. This is the supported timeout primitive; use a host abort controller or `RunOptions.signal`.
69
69
  - `assertToolCallDeltasReconstruct()` rebuilds streamed `tool_call_delta` fragments into tool calls and validates expected id/name/arguments. Malformed JSON with id+name present yields `argumentsError` (no throw); missing id/name throws typed `incomplete_delta`. The runtime uses the same reconstruction before tool execution when a provider streams deltas.
70
70
  - `assertUsageAccounting()` finds `usage` or `done.usage` and checks selected token fields including `cacheReadTokens` and `cacheWriteTokens`. This is the provider-neutral check for normalized cache read/write token extraction; every first-party provider package exercises it against server-specific fields (`cached_tokens`, `cache_read_input_tokens`, etc.).
71
71
  - `assertSerializedRequestCoversContent()` scans a serialized provider request body for primitive canaries from each Prism content block and fails if any supported block type is silently dropped. Provider-valid transcripts place assistant `tool_call` messages before matching role `tool` `tool_result` messages; runtime, cache-aware input layout, and observational-memory worker loops preserve that order before serialization.
@@ -129,7 +129,7 @@ const agent = createAgent({ model: { provider: own.id, model: "demo" }, provider
129
129
  - Provider event helpers return plain `ProviderEvent` objects.
130
130
  - `providerError()` converts unknown errors to redacted `ErrorInfo` through `errorToErrorInfo()` and preserves safe string/number `code` fields for retry classification.
131
131
  - `createMockProvider()` returns an `AIProvider` whose `generate()` yields the scripted events in order and checks `request.signal?.aborted` before each event.
132
- - The agent/session runtime passes its per-run abort signal as `ProviderRequest.signal`. `ProviderRequestOptions.structuredOutput` requests provider-native JSON-schema output when the model declares `capabilities.structuredOutput`; unsupported models fail before fetch. `ProviderRequestOptions.timeoutMs`, `maxRetries`, and `maxRetryDelayMs` are deprecated inert hints in first-party providers; use `RunOptions.signal`/host abort controllers for timeouts and `AgentConfig.retry`/`RunOptions.retry` for retry.
132
+ - The agent/session runtime passes its per-run abort signal as `ProviderRequest.signal`. `ProviderRequestOptions.structuredOutput` requests provider-native JSON-schema output when the model declares `capabilities.structuredOutput`; unsupported models fail before fetch. Timeouts are host-owned: pass `RunOptions.signal`/host abort controllers; retries are runtime-owned via `AgentConfig.retry`/`RunOptions.retry`. Provider-level timeout/retry hints were removed in 0.1.5.
133
133
 
134
134
  ## Request/response example
135
135
 
@@ -68,7 +68,7 @@ api.registerSystemPromptContribution({ id: "demo-prompt", source: "package", mod
68
68
 
69
69
  Hosts decide which credential resolvers, env objects, OAuth stores, request policies, and prompt contributions become active. Request policies can set generic `ProviderRequest.options` such as `sessionId`, `cacheRetention`, `headers`, `compat`, and opaque `extra`; provider adapters decide how to map those options to provider payloads. Caller headers are extension headers only: provider adapters must apply provider-owned headers (auth, content type, session/cache/security, attribution) after caller headers so requests cannot override credentials or provider policy.
70
70
 
71
- Deprecated provider request options: `timeoutMs`, `maxRetries`, and `maxRetryDelayMs` are inert in first-party providers. Use `RunOptions.signal`/host abort controllers for timeouts and `AgentConfig.retry`/`RunOptions.retry` for retry. Provider packages should not add provider-specific retry loops unless the vendor protocol requires it and runtime retry cannot cover the failure mode.
71
+ Provider request options: `ProviderRequestOptions` carries session/cache/header/compat/extra hints only. Timeouts are host-owned (`RunOptions.signal`/host abort controllers); retries are runtime-owned (`AgentConfig.retry`/`RunOptions.retry`). Provider-level timeout/retry hints were removed in 0.1.5. Provider packages should not add provider-specific retry loops unless the vendor protocol requires it and runtime retry cannot cover the failure mode.
72
72
 
73
73
  First-party providers map generic `ModelConfig.parameters.maxTokens` to real output-token request fields instead of sending `maxTokens` on the wire: OpenAI Responses uses `max_output_tokens`; OpenRouter, OpenCode Go OpenAI-compatible, OpenCode Go Anthropic-style, Z.AI, Kimi, and NeuralWatt use `max_tokens`. Other `model.parameters` values pass through unchanged unless the provider docs say otherwise.
74
74
 
@@ -33,7 +33,7 @@ Static scan of root `src/providers/` and `packages/provider-*/src/` before Plan
33
33
  | Surface | Owner | Behavior today |
34
34
  | --- | --- | --- |
35
35
  | Runtime retry | `@arnilo/prism` `AgentConfig.retry` / `RunOptions.retry` | Classifies `ErrorInfo.code`; provider packages set numeric HTTP `code` on errors |
36
- | `ProviderRequestOptions.maxRetries` / `timeoutMs` | Contracts | **Deprecated / inert** in first-party providers |
36
+ | `ProviderRequestOptions.maxRetries` / `timeoutMs` | Contracts | **Removed in 0.1.5**; use `RunOptions.signal` / `AgentConfig.retry` / `RunOptions.retry` |
37
37
  | NeuralWatt `classifyNeuralWattError` | `packages/provider-neuralwatt` | Parses `Retry-After`, `error.retry_after`, `retry_strategy`; no extra network calls |
38
38
  | Quota endpoint throttling | `packages/provider-neuralwatt/quota.ts` | Documents 1 rps limit; caller-owned cache |
39
39
 
@@ -117,7 +117,7 @@ Important request shapes:
117
117
  | `PromptCacheHints` / `PromptCacheBreakpoint` | Structured provider cache intent and reusable prompt anchors. See [Provider caching](provider-caching.md). |
118
118
  | `ProviderPackage` | Inert provider package definition with docs metadata and explicit `setup(api)` registration. |
119
119
  | `ProviderRequest` | Normalized provider input: `model`, `messages`, optional `tools`, `context`, generic `options`, `metadata`, and `signal`. |
120
- | `ProviderRequestOptions` | Generic provider adapter hints: session id, legacy `cacheKey`/`cacheRetention`, structured `cache?: PromptCacheHints`, headers, compat, and opaque `extra`; `timeoutMs`, `maxRetries`, and `maxRetryDelayMs` are deprecated inert hints in first-party providers. |
120
+ | `ProviderRequestOptions` | Generic provider adapter hints: session id, legacy `cacheKey`/`cacheRetention`, structured `cache?: PromptCacheHints`, headers, compat, and opaque `extra`. Provider-level timeout/retry hints were removed in 0.1.5; timeouts are host-owned (`RunOptions.signal`) and retries are runtime-owned (`AgentConfig.retry`/`RunOptions.retry`). |
121
121
  | `ProviderRequestPolicy` | Ordered pre-provider hook that can patch the request and return exact secrets for provider-error redaction. |
122
122
  | `ToolRegistry` | Host active tool registry shape: `register()`, `get()`, `resolve()`, and `list()`. |
123
123
  | `ToolExecutionContext` | Host tool execution context: session/run ids, tool call id, optional abort signal, metadata, and progress callback. |
@@ -131,7 +131,7 @@ Important request shapes:
131
131
  | `CredentialRequest` | Credential lookup request: credential `name`, optional provider id, and metadata. |
132
132
  | `OAuthProvider` | Host/package OAuth callbacks for login, optional refresh, and conversion to a `Credential`. |
133
133
  | `AgentSessionConfig` | Session creation input: optional id, agent, store, leaf id, and metadata. |
134
- | `RunOptions` | Per-run overrides: optional abort signal, model, input layout, max tool rounds, provider options/request policies, system prompt layers, compaction, retry, metadata, skill selection, validate, redactor, and loop. |
134
+ | `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. |
135
135
  | `SubscribeOptions` / `SubscriberOverflowPolicy` | Live `AgentEvent` subscriber queue limit and overflow policy: `maxQueuedEvents`, `overflow: "close" \| "drop_oldest" \| "drop_newest"`. |
136
136
  | `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. |
137
137
  | `AgentConfig.loop` / `RunOptions.loop` | Replaceable per-run control loop: `singleShotLoop` default, `generate-validate-revise` options, or a custom `AgentLoopStrategy`. `RunOptions.loop` wins. See [Agent loops](agent-loops.md). |
@@ -417,6 +417,8 @@ void credentials;
417
417
 
418
418
  ## Extension and configuration notes
419
419
 
420
+ **Internal file structure (0.1.4).** Since 0.1.4 the contract declarations are spread across sibling modules behind the `src/contracts.ts` barrel: `src/contracts-core.ts` (JSON/content/core agent contracts plus the `SESSION_ENTRY_KINDS`/`session-store` values), `src/contracts-run-state.ts` (run-state and agent-session contracts including `AgentRunStatus` through `AgentSession`, decision/steer constants, and the error classes), and `src/contracts-protocol.ts` (pure protocol-payload types). The 295-name public surface is unchanged; this page groups the frozen contract by functionality rather than source file.
421
+
420
422
  - Contracts are host-owned and package-friendly. External packages can implement `AIProvider`, `ToolDefinition`, `CommandDefinition`, `AgentDefinition`, `InputBuilder`, `PromptBuilder`, `Middleware`, `ContextProvider`, `Skill`, `Extension`, config providers, data-only manifests, compaction strategies, store factories, resource loaders, settings providers, and credential resolvers.
421
423
  - `ExtensionAPI` is implemented by the extension kernel. It exposes explicit registries, ordered middleware registration, ordered event subscription/emission, and registration methods for Phase 2 contribution categories.
422
424
  - `AgentConfig.provider` can hold a direct provider instance for simple host wiring. Hosts that need config-driven selection should use `ModelConfig.provider` with explicit `createProviderRegistry()` / `createModelRegistry()` objects; Prism does not create a hidden global provider registry.
@@ -274,6 +274,70 @@ git push origin v0.1.2 # tag push triggers release.yml publish job (prove
274
274
 
275
275
  **Rollback notes.** `release:publish --version 0.1.2 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.2` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.2` is store-compatible with `0.1.1` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback.
276
276
 
277
+ ### 0.1.5 publish handoff (plan 017 Task 4)
278
+
279
+ **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.5** (plan 017) is the **documented breaking cut** on the frozen 0.1.x line — deprecated-option removal, with the removed-symbols list, replacements, before/after examples, dynamic-config refusal behavior, store compatibility, and rollback in the top `docs/migration.md` `0.1.4 → 0.1.5` section. Removed: `ProviderRequestOptions.timeoutMs`/`maxRetries`/`maxRetryDelayMs` (inert in first-party providers; abort/retry lives at the host layer — replacements `RunOptions.signal`/`AgentConfig.retry`/`RunOptions.retry`), `RunOptions.maxToolRounds` (→ `limits.maxToolRounds`; CLI `--max-tool-rounds` unchanged), `ObservationalMemorySettingsInput` pre-0.0.19 flat keys and top-level `workerProvider`/`workerModel` aliases (→ nested `observation`/`reflection`/`dropper` configs; `sessionModel` fallback unchanged), `ReadToolOptions.autoResizeImages` (→ `transformImage`), and `INIT_PROVIDERS` (→ `listInitProviders()`). Every removal **fails closed** for untyped callers with a `TypeError` naming the replacement before any provider call, tool call, filesystem access, compaction, or session append. Compat baselines were regenerated only after the reviewed `--allow-break` break report: `arnilo__prism.txt` (removed `INIT_PROVIDERS` const + `maxToolRounds`/provider-knob member lines — interface members are not baseline text, so the delta is the `INIT_PROVIDERS` line), `arnilo__prism-coding-agent.txt` (`autoResizeImages` is an interface member — baseline delta limited to statement/re-export text if any), `arnilo__prism-compaction-observational-memory.txt` (flat keys and worker aliases are interface members — no baseline line delta expected). Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.5**. Store compatibility with 0.1.4: **compatible, no migration** (removed options were inert aliases; nested replacements resolve to the same active values; `DEFAULT_RUN_LIMITS.maxToolRounds` 8 / hard cap 64 unchanged); zero new dependencies (lockfile name-set unchanged).
280
+
281
+ ```bash
282
+ # Operator prerequisites (each a named blocked gate — none may be skipped):
283
+ # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
284
+ # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
285
+ # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
286
+ # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
287
+
288
+ git diff --check
289
+ npm ci
290
+ npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
291
+ npm run security:threat-suites
292
+ PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
293
+ npm audit --audit-level=moderate
294
+ npm run release:check -- --version 0.1.5 --report /tmp/prism-0.1.5-preflight.json
295
+ npm run release:publish -- --version 0.1.5 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.5-dry-run.json
296
+ # run the dry-run twice and diff the reports: deterministic, byte-identical
297
+
298
+ # Sign the release on the clean tagged tree (operator GPG key):
299
+ git tag -s v0.1.5 -m "Prism 0.1.5 — documented breaking cut: deprecated-option removal"
300
+ git verify-tag v0.1.5
301
+ git push origin v0.1.5 # tag push triggers release.yml publish job (provenance, attestations)
302
+
303
+ # Real publication never bypasses the gates: release.mjs refuses
304
+ # --allow-dirty/--allow-untagged without --dry-run.
305
+ ```
306
+
307
+ **Rollback notes.** `release:publish --version 0.1.5 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.5` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.5` is store-compatible with `0.1.4` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the cut without a database rollback; code/config using removed keys must be migrated first (removed keys fail closed on 0.1.5).
308
+
309
+ ### 0.1.4 publish handoff (plan 016 Task 6)
310
+
311
+ **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.4** (plan 016) is the internal god-module split, compat-preserving on the frozen 0.1.x line: `src/agents.ts` and `src/contracts.ts` reorganized by concern behind barrel re-exports (`contracts-core`/`contracts-run-state`/`contracts-protocol`; `agent-session`/`agent-run-lifecycle`/`agent-approval`/`agent-tool-dispatch` reusing `agent-run-state`/`agent-loops`/`compaction`) with a **byte-identical public entry surface** (0 added/0 removed/0 changed vs the 0.1.3 baseline; the 14 additive union-surface helpers are internal cross-module exports, not consumer-importable — deviation #1), measured tree-shaking improvement (111,049 → 982 B `dist/agents.js`, 9,420 → 418 B `dist/contracts.js`, module count 64 → 70; evidence in `scripts/phase16-baseline.json`), and additive **`@arnilo/prism-browser` Chrome DevTools Protocol capabilities** (Tasks 4-5): `browser_evaluate`, `browser_observe`, `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions, and `{ css }`/`{ xpath }` targets on Chromium hosts — 41 added / 0 removed / 18 changed declaration texts (15 re-export-statement artifacts + 3 optional-member/signature widenings), the documented deviation #2 carve-out; root `arnilo__prism.txt` regenerated with zero breaking deltas. Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.4**. Store compatibility with 0.1.3: **compatible, no migration**; zero new dependencies (lockfile name-set unchanged).
312
+
313
+ ```bash
314
+ # Operator prerequisites (each a named blocked gate — none may be skipped):
315
+ # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
316
+ # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
317
+ # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
318
+ # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
319
+
320
+ git diff --check
321
+ npm ci
322
+ npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
323
+ npm run security:threat-suites
324
+ PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
325
+ npm audit --audit-level=moderate
326
+ npm run release:check -- --version 0.1.4 --report /tmp/prism-0.1.4-preflight.json
327
+ npm run release:publish -- --version 0.1.4 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.4-dry-run.json
328
+ # run the dry-run twice and diff the reports: deterministic, byte-identical
329
+
330
+ # Sign the release on the clean tagged tree (operator GPG key):
331
+ git tag -s v0.1.4 -m "Prism 0.1.4"
332
+ git verify-tag v0.1.4
333
+ git push origin v0.1.4 # tag push triggers release.yml publish job (provenance, attestations)
334
+
335
+ # Real publication never bypasses the gates: release.mjs refuses
336
+ # --allow-dirty/--allow-untagged without --dry-run.
337
+ ```
338
+
339
+ **Rollback notes.** `release:publish --version 0.1.4 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.4` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.4` is store-compatible with `0.1.3` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback. The next line, **0.1.5**, is the documented breaking cut (deprecated-option removal) with its removed-symbols list landing in `docs/migration.md`.
340
+
277
341
  ### 0.1.3 publish handoff (plan 015 Task 5)
278
342
 
279
343
  **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.3** (plan 015) is the dead-code and deprecation hygiene patch on the frozen 0.1.x line: one parameterized benchmark runner `scripts/benchmark.mjs --scenario <name>` replaces the per-version runners (16 orphaned `benchmark-0.0.{8..16}` runner/test files removed, evidence JSON kept; the CI schema leg runs `scripts/benchmark.test.mjs`), the 12 `docs/review-coverage-2026-07-*.md` evidence files moved to the tarball-excluded `docs/_evidence/` archive, a non-blocking unused-code sweep (`npm run sweep:unused` — tsc `noUnusedLocals`/`noUnusedParameters` over core + all workspace tsconfigs plus a zero-dep dead-export scan; always exits 0, report to `scripts/unused-sweep-report.txt`), and opt-in checkpoint persistence (`persistSessionState: true` on durable run/resume options — loaded-skill name catalog ≤64 names rides the run-state checkpoint and restores on resume, bodies re-resolve from the live registry; `createReadPathSetPersistence` in `@arnilo/prism-coding-agent` persists the read-before-write path set through the host `CheckpointStore`, ≤1024 paths, ownership-scoped). Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.3**. Store compatibility with 0.1.2: **compatible, no migration**; declaration surface additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.3 with zero breaking deltas).
@@ -91,7 +91,7 @@ Blocked reasons today: `unknown_tool`, `tool_denied`, `invalid_arguments`, `perm
91
91
  | Surface | Location | Behavior today |
92
92
  | --- | --- | --- |
93
93
  | `singleShotLoop` | `src/agent-loops.ts` | Sequential `for (const call of calls) await dispatchToolCall(call)` per provider turn |
94
- | `maxToolRounds` | `AgentConfig` / `RunOptions` → `LoopContext` | Default `1` in `RuntimeAgentSession.run()` |
94
+ | `maxToolRounds` | `AgentConfig.limits` / `RunOptions.limits` → `LoopContext` | Default `1` in `RuntimeAgentSession.run()` |
95
95
  | Transcript ordering | `src/agent-loops.ts` | Tool results appended in call order (Plan 053 R-002 fix shipped) |
96
96
  | Parallelism | — | **None** — models may emit multiple calls; runtime executes one at a time |
97
97
 
@@ -290,11 +290,11 @@ export type TransformImage = (input: TransformImageInput) => Promise<Buffer>;
290
290
  export interface ReadToolOptions {
291
291
  readonly maxImageBytes?: number; // default DEFAULT_MAX_IMAGE_BYTES
292
292
  readonly transformImage?: TransformImage;
293
- /** @deprecated Use transformImage instead; ignored when transformImage is absent. */
294
- readonly autoResizeImages?: boolean;
295
293
  }
296
294
  ```
297
295
 
296
+ `autoResizeImages` was removed in 0.1.5; the supported `transformImage` callback is the only resize path. Untyped callers passing the old key fail closed before any filesystem access.
297
+
298
298
  Reject oversize images by `stat` before full read where possible; re-check `buffer.length` after read and after `transformImage`. MIME from magic bytes only (existing behavior). `transformImage` is host-owned; base package stays free of image-processing deps. Implemented in `packages/coding-agent/src/read.ts`.
299
299
 
300
300
  ## Conformance and threat-model matrix
package/docs/tools.md CHANGED
@@ -161,7 +161,7 @@ Need different tools for one request? Build a short-lived agent/session with a n
161
161
 
162
162
  ### Artifact-loop tools
163
163
 
164
- `generate-validate-revise` treats provider tools as inert by default. Set `loop.toolCalls: "bounded"` and `RunOptions.maxToolRounds` only when an artifact needs a host-owned lookup before its next candidate. Each response with one-or-more calls consumes one shared round, dispatches calls sequentially through this exact `dispatchToolCall()` path, persists assistant-call then result transcript rows, and skips artifact parsing/validation for that response. A post-limit call executes nothing; the loop emits `artifact_failed` with `metadata.reason: "tool_round_limit"`. Tools do not consume `maxRevisions`, and tool schemas/context never grant authority.
164
+ `generate-validate-revise` treats provider tools as inert by default. Set `loop.toolCalls: "bounded"` and `RunOptions.limits.maxToolRounds` only when an artifact needs a host-owned lookup before its next candidate. Each response with one-or-more calls consumes one shared round, dispatches calls sequentially through this exact `dispatchToolCall()` path, persists assistant-call then result transcript rows, and skips artifact parsing/validation for that response. A post-limit call executes nothing; the loop emits `artifact_failed` with `metadata.reason: "tool_round_limit"`. Tools do not consume `maxRevisions`, and tool schemas/context never grant authority.
165
165
 
166
166
  ### Runtime-supplied validators
167
167
 
@@ -220,7 +220,7 @@ Opt in through `loop.toolConcurrency` on `AgentConfig` / `RunOptions` (single-sh
220
220
 
221
221
  ```ts
222
222
  await session.run(input, {
223
- maxToolRounds: 3,
223
+ limits: { maxToolRounds: 3 },
224
224
  loop: { strategy: "single-shot", toolConcurrency: 4 },
225
225
  });
226
226
  ```
@@ -24,11 +24,11 @@ Prism separates the **session chat model** (`AgentConfig.model` / `RunOptions.mo
24
24
  ```ts
25
25
  import { resolveUseCaseModel, applyThinkingLevel, thinkingFamilyForModel } from "@arnilo/prism";
26
26
 
27
- // Prefer an explicit worker; otherwise inherit the session/agent model.
27
+ // Prefer an explicit worker model; otherwise inherit the session/agent model.
28
28
  const resolved = resolveUseCaseModel({
29
- configured: settings.workerModel, // optional use-case ModelConfig
30
- sessionModel: agent.config.model, // host-supplied; AgentSession does not expose agent
31
- thinkingLevel: settings.thinkingLevel,
29
+ configured: settings.observation?.model, // optional per-worker ModelConfig
30
+ sessionModel: agent.config.model, // host-supplied; AgentSession does not expose agent
31
+ thinkingLevel: settings.observation?.thinkingLevel,
32
32
  });
33
33
  if (!resolved) {
34
34
  // skip — neither configured nor session model (or requireExplicitModel)
@@ -52,7 +52,7 @@ Resolution is O(1) and network-free. It does not mutate session history.
52
52
 
53
53
  | Site | How hosts bind | Session fallback |
54
54
  | --- | --- | --- |
55
- | Observational memory | `workerModel` / settings `workerModel` + runtime `sessionModel` | Yes — pass `sessionModel: agent.config.model`; `requireExplicitModel` restores skip |
55
+ | Observational memory | `observation.model` / `reflection.model` / `dropper.model` + runtime `sessionModel` | Yes — pass `sessionModel: agent.config.model`; `requireExplicitModel` restores skip |
56
56
  | LLM compaction | `summaryModel` with `model` as fallback slot | Yes — `resolveUseCaseModel({ configured: summaryModel, sessionModel: model })` |
57
57
  | `RunOptions.model` | Per-run override on the **session** | N/A — this *is* the session/run model (writes `model_change`) |
58
58
  | Declarative `AgentDefinition` | Definition `model` / registry resolve | Definition-scoped (independent agent) |
@@ -67,17 +67,18 @@ Resolution is O(1) and network-free. It does not mutate session history.
67
67
  createObservationalMemoryRuntime({
68
68
  session,
69
69
  appendEntry: (entry) => store.append(entry),
70
- workerProvider,
71
- sessionModel: agent.config.model, // enables fallback when workerModel unset
72
- // workerModel: { provider: "neuralwatt", model: "glm-5.2-fast" }, // optional override
73
- overrides: { thinkingLevel: "low", observeAfterTokens: 1 },
70
+ observation: { provider: workerProvider }, // optional per-worker model override below
71
+ sessionModel: agent.config.model, // enables fallback when no worker model is configured
72
+ // observation: { provider: workerProvider, model: { provider: "neuralwatt", model: "glm-5.2-fast" } },
73
+ overrides: { observation: { thinkingLevel: "low", messageTokens: 1 } },
74
74
  });
75
75
  ```
76
76
 
77
- - Default: no `workerModel` + `sessionModel` set → workers use the session model.
78
- - Explicit `workerModel` (or settings `workerModel`) always wins.
77
+ - Default: no worker `model` + `sessionModel` set → workers use the session model.
78
+ - Explicit per-worker `model` (or settings `observation.model` / `reflection.model` / `dropper.model`) always wins.
79
79
  - `requireExplicitModel: true` (runtime or settings) → `skipped: "missing_model"` when no worker model, even if `sessionModel` is set.
80
80
  - Neither worker nor session model → `skipped: "missing_model"`.
81
+ - Top-level `workerProvider` / `workerModel` aliases were removed in 0.1.5; workers resolve only from the nested `observation` / `reflection` / `dropper` configs.
81
82
  - Default credential request uses the **resolved** model's `provider` id.
82
83
 
83
84
  ## LLM compaction
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -142,7 +142,7 @@
142
142
  "build": "npm run build:core && npm run build --workspaces --if-present",
143
143
  "typecheck": "npm run build && npm run typecheck --workspaces --if-present && tsc -p examples --noEmit",
144
144
  "sweep:unused": "node scripts/sweep-unused.mjs",
145
- "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/phase14-freeze.test.mjs scripts/phase15-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/sweep-unused.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs && npm run test --workspaces --if-present",
145
+ "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/phase14-freeze.test.mjs scripts/phase15-freeze.test.mjs scripts/phase16-freeze.test.mjs scripts/phase17-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/sweep-unused.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs && npm run test --workspaces --if-present",
146
146
  "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=70 --test-coverage-branches=75 --test-coverage-exclude='**/__tests__/**' --test-coverage-exclude='**/node_modules/**' --test-coverage-exclude='**/scripts/**' --test-coverage-exclude='**/packages/**' --test-coverage-exclude='**/examples/**' dist/__tests__/*.test.js && node scripts/coverage-summary.mjs",
147
147
  "coverage:summary": "node scripts/coverage-summary.mjs",
148
148
  "lint": "biome lint .",