@arnilo/prism 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -1
- package/README.md +42 -62
- package/dist/agent-run-lifecycle.js +4 -0
- package/dist/agent-run-state.d.ts +5 -2
- package/dist/agent-run-state.js +18 -8
- package/dist/agent-session/session/assemble.d.ts +6 -0
- package/dist/agent-session/session/assemble.js +391 -0
- package/dist/agent-session/session/persist.d.ts +28 -0
- package/dist/agent-session/session/persist.js +166 -0
- package/dist/agent-session/session/provider-round.d.ts +6 -0
- package/dist/agent-session/session/provider-round.js +231 -0
- package/dist/agent-session/session/tool-round.d.ts +31 -0
- package/dist/agent-session/session/tool-round.js +473 -0
- package/dist/agent-session/session/types.d.ts +115 -0
- package/dist/agent-session/session/types.js +5 -0
- package/dist/agent-session/session.d.ts +54 -41
- package/dist/agent-session/session.js +23 -1132
- package/dist/capture.d.ts +63 -0
- package/dist/capture.js +67 -0
- package/dist/cli-dev.d.ts +29 -0
- package/dist/cli-dev.js +52 -0
- package/dist/cli-init.d.ts +34 -3
- package/dist/cli-init.js +192 -24
- package/dist/cli-runner.d.ts +6 -2
- package/dist/cli-runner.js +57 -10
- package/dist/content.d.ts +3 -3
- package/dist/content.js +3 -1
- package/dist/contracts-core/agent.d.ts +8 -0
- package/dist/contracts-core/batch.d.ts +97 -0
- package/dist/contracts-core/batch.js +65 -0
- package/dist/contracts-core/content.d.ts +72 -1
- package/dist/contracts-core/embeddings.d.ts +30 -0
- package/dist/contracts-core/embeddings.js +17 -0
- package/dist/contracts-core/images.d.ts +60 -0
- package/dist/contracts-core/images.js +17 -0
- package/dist/contracts-core/moderation.d.ts +46 -0
- package/dist/contracts-core/moderation.js +34 -0
- package/dist/contracts-core/speech.d.ts +39 -0
- package/dist/contracts-core/speech.js +17 -0
- package/dist/contracts-core/transcription.d.ts +48 -0
- package/dist/contracts-core/transcription.js +17 -0
- package/dist/contracts-core/video.d.ts +61 -0
- package/dist/contracts-core/video.js +17 -0
- package/dist/contracts-core.d.ts +7 -0
- package/dist/contracts-core.js +7 -0
- package/dist/contracts-protocol.d.ts +18 -0
- package/dist/contracts-run-state.d.ts +1 -2
- package/dist/index.d.ts +7 -3
- package/dist/index.js +5 -3
- package/dist/input.d.ts +8 -0
- package/dist/input.js +4 -0
- package/dist/node/agent-definitions.d.ts +1 -8
- package/dist/node/agent-definitions.js +0 -34
- package/dist/node/settings.d.ts +0 -1
- package/dist/node/settings.js +0 -5
- package/dist/pinned-fetch.js +29 -3
- package/dist/provider-events.js +3 -4
- package/dist/providers/media.d.ts +1 -2
- package/dist/providers/media.js +1 -4
- package/dist/rpc.d.ts +1 -1
- package/dist/rpc.js +4 -4
- package/dist/testing/persistence-schema.d.ts +1 -1
- package/dist/testing/persistence-schema.js +32 -28
- package/dist/testing/provider-conformance.d.ts +114 -5
- package/dist/testing/provider-conformance.js +342 -0
- package/dist/testing/tool-conformance.d.ts +25 -0
- package/dist/testing/tool-conformance.js +128 -1
- package/dist/testing/tool-effect-store-conformance.d.ts +0 -1
- package/dist/testing/tool-effect-store-conformance.js +0 -3
- package/dist/thinking.d.ts +48 -9
- package/dist/thinking.js +134 -8
- package/dist/tool-search.d.ts +76 -0
- package/dist/tool-search.js +199 -0
- package/docs/0.1.0-readiness.md +3 -3
- package/docs/a2a.md +2 -2
- package/docs/acp-agent.md +1 -1
- package/docs/acp.md +3 -3
- package/docs/ag-ui-adoption.md +1 -1
- package/docs/ag-ui.md +1 -2
- package/docs/agent-definitions.md +1 -1
- package/docs/agent-events.md +5 -5
- package/docs/agent-identity.md +13 -2
- package/docs/audit-export.md +3 -3
- package/docs/batch-jobs.md +120 -0
- package/docs/browser-automation.md +5 -5
- package/docs/caveman.md +2 -2
- package/docs/cli-rpc.md +43 -9
- package/docs/coding-agent-tools.md +19 -19
- package/docs/coding-review-and-diagnostics.md +2 -2
- package/docs/coding-security.md +5 -5
- package/docs/coding-tools.md +82 -0
- package/docs/coding-workspaces.md +2 -2
- package/docs/compaction-and-retry.md +2 -2
- package/docs/compaction-llm.md +4 -4
- package/docs/compaction-observational-memory.md +3 -3
- package/docs/computer-use-linux.md +13 -2
- package/docs/context-and-skills.md +3 -1
- package/docs/conversations.md +4 -4
- package/docs/core.md +85 -0
- package/docs/credential-storage.md +12 -8
- package/docs/credentials-and-redaction.md +1 -1
- package/docs/data-classification.md +1 -1
- package/docs/database-persistence.md +7 -3
- package/docs/dev-inspector.md +103 -0
- package/docs/device-adapters.md +2 -2
- package/docs/diagrams.md +247 -0
- package/docs/document-reader.md +6 -6
- package/docs/documents.md +214 -0
- package/docs/embeddings.md +112 -0
- package/docs/enterprise-postgres-state.md +7 -7
- package/docs/evaluations.md +41 -7
- package/docs/extensions.md +3 -3
- package/docs/forge-integration.md +3 -3
- package/docs/graft.md +5 -5
- package/docs/guardrails.md +2 -2
- package/docs/host-security.md +16 -15
- package/docs/image-generation.md +129 -0
- package/docs/impeccable.md +7 -5
- package/docs/index.md +84 -46
- package/docs/indexed-code-search.md +2 -2
- package/docs/language-intelligence.md +4 -4
- package/docs/live-testing.md +126 -0
- package/docs/mcp-tools.md +44 -13
- package/docs/middleware-hooks.md +1 -1
- package/docs/migrate-to-0.4.md +312 -0
- package/docs/migrate-to-0.5.md +122 -0
- package/docs/migration.md +51 -1
- package/docs/model-registry.md +38 -0
- package/docs/model-routing.md +6 -6
- package/docs/moderation.md +117 -0
- package/docs/multi-agent-patterns.md +177 -0
- package/docs/multimodal-content.md +27 -3
- package/docs/obscura.md +12 -12
- package/docs/observability.md +32 -7
- package/docs/openapi-tools.md +14 -4
- package/docs/operations.md +11 -0
- package/docs/performance.md +30 -10
- package/docs/persistence-credentials-multimodality-primitives.md +7 -7
- package/docs/policy-and-audit.md +18 -8
- package/docs/ponytail.md +3 -3
- package/docs/postgres-persistence.md +5 -5
- package/docs/process-sessions.md +2 -2
- package/docs/prompt-registry.md +106 -0
- package/docs/provider-caching.md +36 -32
- package/docs/provider-conformance.md +24 -2
- package/docs/provider-packages.md +58 -22
- package/docs/provider-primitives.md +5 -5
- package/docs/provider-request-policies.md +1 -1
- package/docs/providers/ai-sdk.md +18 -6
- package/docs/providers/alibaba.md +10 -6
- package/docs/providers/anthropic.md +10 -6
- package/docs/providers/azure.md +20 -4
- package/docs/providers/bedrock.md +18 -3
- package/docs/providers/clinepass.md +7 -3
- package/docs/providers/commandcode.md +253 -0
- package/docs/providers/deepseek.md +7 -3
- package/docs/providers/google.md +8 -4
- package/docs/providers/hyper.md +284 -0
- package/docs/providers/kimi.md +7 -3
- package/docs/providers/neuralwatt.md +12 -8
- package/docs/providers/ollama.md +18 -3
- package/docs/providers/openai-compatible.md +5 -1
- package/docs/providers/openai.md +9 -5
- package/docs/providers/opencode-go.md +8 -4
- package/docs/providers/openrouter.md +8 -4
- package/docs/providers/vertex.md +21 -5
- package/docs/providers/xai.md +7 -3
- package/docs/providers/zai.md +7 -3
- package/docs/rag.md +31 -9
- package/docs/release-and-install.md +181 -76
- package/docs/resource-loading.md +1 -1
- package/docs/runs-and-usage.md +28 -3
- package/docs/server.md +94 -5
- package/docs/settings-auth-trust-security.md +7 -5
- package/docs/sheets.md +229 -0
- package/docs/speech.md +126 -0
- package/docs/sqlite-persistence.md +4 -4
- package/docs/supervisors.md +4 -3
- package/docs/thinking-and-reasoning.md +93 -60
- package/docs/tool-conformance.md +28 -3
- package/docs/tool-execution-primitives.md +8 -8
- package/docs/tools.md +32 -5
- package/docs/web-tools.md +3 -3
- package/docs/wiki.md +7 -7
- package/docs/work-artifacts-and-review.md +17 -6
- package/docs/work-connectors.md +4 -4
- package/docs/work-tools.md +5 -5
- package/docs/workflow-orchestration-primitives.md +35 -11
- package/docs/workflows.md +74 -13
- package/docs/working-and-semantic-memory.md +53 -5
- package/package.json +14 -31
- package/templates/README.md +23 -0
- package/templates/deep-research/README.md.tmpl +47 -0
- package/templates/deep-research/env.example.tmpl +12 -0
- package/templates/deep-research/gitignore.tmpl +7 -0
- package/templates/deep-research/manifest.json +12 -0
- package/templates/deep-research/package.json.tmpl +23 -0
- package/templates/deep-research/src/agent.ts.tmpl +81 -0
- package/templates/deep-research/src/index.ts.tmpl +53 -0
- package/templates/deep-research/src/tests/research.test.ts.tmpl +114 -0
- package/templates/deep-research/src/tools.ts.tmpl +86 -0
- package/templates/deep-research/src/types.ts.tmpl +45 -0
- package/templates/deep-research/src/workflow.ts.tmpl +156 -0
- package/templates/deep-research/tsconfig.json.tmpl +15 -0
- package/templates/init/manifest.json +5 -0
- package/templates/init/package.json.tmpl +2 -1
- package/templates/init/providers.json +40 -24
- package/docs/antigravity-agent.md +0 -207
|
@@ -2,100 +2,133 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
Prism
|
|
5
|
+
Prism gives hosts one portable way to set thinking/reasoning effort per model and per turn, and guarantees the level actually reaches the wire on every provider Prism ships. The single entry point is **`applyThinkingLevelForModel`**: it resolves the model's compat family, snaps the requested level to the model's **declared levels** (`capabilities.thinkingLevels`), and merges the family's compat patch into your base options. Every first-party provider catalog stamps the family and declares the per-model level set; provider resolvers translate the patch into official wire fields. Model defaults live on `ModelConfig.compat`; per-turn overrides live on `ProviderRequestOptions.compat` and win through the existing `mergeProviderRequestOptions` merge.
|
|
6
6
|
|
|
7
7
|
## When to use it
|
|
8
8
|
|
|
9
|
-
- Session runs: pass `providerOptions
|
|
10
|
-
- Use-case workers (LLM compaction, observational memory): pass `thinkingLevel`;
|
|
11
|
-
-
|
|
9
|
+
- Session runs: pass `providerOptions` from `applyThinkingLevelForModel` on `RunOptions` — one call, no per-provider branching.
|
|
10
|
+
- Use-case workers (LLM compaction, observational memory): pass `thinkingLevel`; workers call `applyThinkingLevelForModel` with the bound model.
|
|
11
|
+
- Hosts building UI: read `model.capabilities.thinkingLevels` (when declared) to render a legal level picker; `isSupportedThinkingLevel` tells you whether a value is declared before sending.
|
|
12
|
+
- Provider authors: read official wire fields from the compat patches below; keep unique knobs package-local.
|
|
12
13
|
|
|
13
|
-
##
|
|
14
|
+
## Inputs / request
|
|
14
15
|
|
|
15
|
-
|
|
|
16
|
-
| --- | --- |
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
| Helpers | `thinkingCompatFor`, `applyThinkingLevel`, `thinkingFamilyForModel`, `isThinkingLevel`, `normalizeThinkingLevel`, `THINKING_LEVELS` |
|
|
21
|
-
| Not used | Inert `options.extra.thinkingLevel` — providers do not read `extra` for effort |
|
|
16
|
+
| Input | Type | Notes |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `base` | `ProviderRequestOptions \| undefined` | Existing options; the patch is merged on top |
|
|
19
|
+
| `level` | `string \| undefined` | Portable `ThinkingLevel` (`none` \| `minimal` \| `low` \| `medium` \| `high` \| `xhigh` \| `max`) or an opaque provider-specific string (forward-compat passthrough) |
|
|
20
|
+
| `model` | `Pick<ModelConfig, "provider" \| "compat" \| "capabilities">` | Model view used for family resolution, declared levels, and reasoning gating |
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
import { applyThinkingLevel, thinkingCompatFor, thinkingFamilyForModel } from "@arnilo/prism";
|
|
22
|
+
## Outputs / response / events
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
Returns the merged `ProviderRequestOptions` (a new object when a patch applies; `base` unchanged when there is nothing to do — non-reasoning model, `noop` family, or `level` undefined).
|
|
25
|
+
|
|
26
|
+
## Request/response example
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{ "compat": { "reasoning_effort": "high" } }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Implementation example
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { applyThinkingLevelForModel } from "@arnilo/prism";
|
|
30
36
|
|
|
31
|
-
//
|
|
37
|
+
// Per-turn override on a session run
|
|
32
38
|
await session.run(input, {
|
|
33
|
-
providerOptions:
|
|
34
|
-
// → { reasoning: { effort: "low" } }
|
|
39
|
+
providerOptions: applyThinkingLevelForModel(base, "high", model),
|
|
35
40
|
});
|
|
36
41
|
|
|
37
|
-
//
|
|
38
|
-
const
|
|
39
|
-
await runObserver({
|
|
40
|
-
...,
|
|
41
|
-
providerOptions: applyThinkingLevel(base, "low", family === "noop" ? "reasoning_effort" : family),
|
|
42
|
-
});
|
|
42
|
+
// Declared-level-aware UI
|
|
43
|
+
const levels = model.capabilities?.thinkingLevels; // e.g. ["low","medium","high","xhigh","max"]
|
|
43
44
|
```
|
|
44
45
|
|
|
46
|
+
## Contract
|
|
47
|
+
|
|
48
|
+
| Layer | Surface |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| Adapter (use this) | `applyThinkingLevelForModel(base, level, model)` — family resolution + snap + merge in one call |
|
|
51
|
+
| Model default | `ModelConfig.compat` (+ `capabilities.reasoning`, `capabilities.thinkingLevels` when declared) |
|
|
52
|
+
| Per-turn override | `ProviderRequestOptions.compat` (request wins over model via merge) |
|
|
53
|
+
| Portable level | `ThinkingLevel`: `none` \| `minimal` \| `low` \| `medium` \| `high` \| `xhigh` \| `max` |
|
|
54
|
+
| Parse / validate | `parseThinkingLevel` (known level → canonical; other non-empty string → opaque passthrough; empty/non-string → `undefined`), `isSupportedThinkingLevel(model, level)`, `thinkingLevelsForModel(model)`, `snapThinkingLevel(model, level)` |
|
|
55
|
+
| Legacy helpers | `thinkingCompatFor`, `applyThinkingLevel`, `thinkingFamilyForModel`, `isThinkingLevel`, `normalizeThinkingLevel`, `THINKING_LEVELS` (still exported; prefer the adapter) |
|
|
56
|
+
| Not used | Inert `options.extra.thinkingLevel` — providers do not read `extra` for effort |
|
|
57
|
+
|
|
45
58
|
## Compat families
|
|
46
59
|
|
|
47
|
-
Core maps only shapes shared by ≥2 packages (or an explicit no-op). Unique knobs stay package-local.
|
|
60
|
+
Core maps only shapes shared by ≥2 packages (or an explicit no-op). Unique knobs stay package-local. Family inference is **stamp-first**: `compat.thinkingFamily` set by the catalog wins, then compat-shape heuristics, then provider-id heuristics, then `capabilities.reasoning`.
|
|
48
61
|
|
|
49
|
-
| Family | Compat patch | Used by (official fields) |
|
|
62
|
+
| Family | Compat patch | Used by (official wire fields) |
|
|
50
63
|
| --- | --- | --- |
|
|
51
64
|
| `openai_reasoning` | `{ reasoning: { effort } }` | OpenAI Responses `reasoning.effort`; OpenRouter `reasoning.effort` |
|
|
52
|
-
| `reasoning_effort` | `{ reasoning_effort }` | Z.AI
|
|
53
|
-
| `thinking_type` | `{ thinking: { type: "enabled" \| "disabled" } }` | Z.AI `thinking.type`; Kimi K2.x
|
|
65
|
+
| `reasoning_effort` | `{ reasoning_effort }` | Z.AI, NeuralWatt, Kimi K3, DeepSeek, xAI, ClinePass, Hyper, Ollama, gateways (OpenAI routes) |
|
|
66
|
+
| `thinking_type` | `{ thinking: { type: "enabled" \| "disabled" } }` | Z.AI `thinking.type`; Kimi K2.x; DeepSeek toggle; Qwen `enable_thinking` (via `alibabaEnableThinking`) |
|
|
67
|
+
| `google` | `{ thinkingLevel }` | Google `generationConfig.thinkingConfig.thinkingLevel` (3.x) / `thinkingBudget` (2.5) |
|
|
68
|
+
| `output_config_effort` | `{ output_config: { effort } }` | Anthropic Messages `output_config.effort`; DeepSeek anthropic-format endpoint |
|
|
54
69
|
| `noop` | `{}` | AI SDK / host-owned adapters — effort is host-model settings |
|
|
55
70
|
|
|
56
|
-
|
|
71
|
+
**Removed guidance:** do not use the `thinking_type` family to carry effort on Anthropic-routed providers — `thinking.type` is a toggle, and `enabled` without `budget_tokens` is rejected by current Anthropic APIs. Anthropic effort travels in `output_config.effort` (`output_config_effort` family).
|
|
57
72
|
|
|
58
|
-
###
|
|
73
|
+
### First-party packages
|
|
59
74
|
|
|
60
|
-
| Package |
|
|
61
|
-
| --- | --- |
|
|
62
|
-
| `@arnilo/prism-
|
|
63
|
-
| `@arnilo/prism-
|
|
64
|
-
| `@arnilo/prism-
|
|
65
|
-
| `@arnilo/prism-
|
|
66
|
-
| `@arnilo/prism-
|
|
67
|
-
| `@arnilo/prism-
|
|
68
|
-
| `@arnilo/prism-
|
|
69
|
-
| `@arnilo/prism-
|
|
70
|
-
| `@arnilo/prism-
|
|
71
|
-
| `@arnilo/prism-
|
|
75
|
+
| Package | Family / behavior |
|
|
76
|
+
| --- | --- |
|
|
77
|
+
| `@arnilo/prism-providers/openai` | `openai_reasoning`; per-family effort tables, Responses-side clamp, `summary` preserved |
|
|
78
|
+
| `@arnilo/prism-providers/openrouter` | `openai_reasoning`; API-derived `supported_efforts` levels; `preserveThinking` replays as body `reasoning` / `reasoning_content` |
|
|
79
|
+
| `@arnilo/prism-providers/anthropic` | `output_config_effort`; generation-aware `adaptive`/legacy thinking |
|
|
80
|
+
| `@arnilo/prism-providers/google` | `google`; 3.x `thinkingLevel` sets, 2.5 budget ranges |
|
|
81
|
+
| `@arnilo/prism-providers/zai` | `reasoning_effort` (GLM-5.2/5.3 snap tables) + `thinking_type` toggle; Preserved Thinking via `reasoning_content` |
|
|
82
|
+
| `@arnilo/prism-providers/kimi` | K3: `reasoning_effort` (`low/high/max`); K2.x: `thinking_type` |
|
|
83
|
+
| `@arnilo/prism-providers/deepseek` | `reasoning_effort` (`low/high/max`) + `thinking_type` toggle; thinking on by default; tool turns must replay `reasoning_content` or the API returns 400 |
|
|
84
|
+
| `@arnilo/prism-providers/xai` | `reasoning_effort` with declared per-model ladders; `reasoning_content` replay still required |
|
|
85
|
+
| `@arnilo/prism-providers/clinepass` | `reasoning_effort` through per-model slot maps (`compat.thinkingLevelMap`); GLM `xhigh` passthrough, never `max` |
|
|
86
|
+
| `@arnilo/prism-providers/neuralwatt` | `reasoning_effort` (`low/medium/high/max`); budgets + preserve/clear thinking stay package-local |
|
|
87
|
+
| `@arnilo/prism-providers/hyper` | `reasoning_effort` derived from live `effort_levels`; snap instead of drop; Anthropic route emits `output_config.effort` |
|
|
88
|
+
| `@arnilo/prism-providers/commandcode` / `@arnilo/prism-providers/opencode-go` | Gateway level tables (`claude-*` → `output_config_effort`, `gpt-5.6*` → `openai_reasoning`, K3/DeepSeek/GLM → `reasoning_effort`, K2.x/MiniMax/Qwen → `thinking_type`) |
|
|
89
|
+
| `@arnilo/prism-providers/alibaba` | `thinking_type` mapped onto Qwen `enable_thinking` (toggle, no effort levels) |
|
|
90
|
+
| `@arnilo/prism-providers/ollama` | `reasoning_effort`; `gpt-oss*` declares `low/medium/high`; native `think` field never mixed in |
|
|
91
|
+
| `@arnilo/prism-providers/azure` / `.../vertex` / `.../bedrock` | OpenAI-compat sanitized forwarder (`reasoning_effort` / `reasoning` object), snapped to declared levels |
|
|
92
|
+
| `@arnilo/prism-providers/ai-sdk` | `noop` — host `LanguageModelV4` owns reasoning settings |
|
|
93
|
+
|
|
94
|
+
## Declared levels and snapping
|
|
72
95
|
|
|
73
|
-
|
|
96
|
+
Every reasoning-capable model in a first-party catalog declares its legal level set (`capabilities.thinkingLevels`) and, where meaningful, a `compat.thinkingFamily` stamp. The source of truth is the [thinking coverage evidence matrix](_evidence/thinking-coverage-2026-09-05.md) — generated from the compiled catalogs, with per-model source (API-derived vs doc-pinned) and the wire/live test that pins each row.
|
|
74
97
|
|
|
75
|
-
|
|
98
|
+
Snap semantics (`snapThinkingLevel`, applied by the adapter and by provider resolvers when the model declares a set):
|
|
76
99
|
|
|
77
|
-
1.
|
|
78
|
-
2. `
|
|
79
|
-
3.
|
|
100
|
+
1. The requested level is in the declared set → forwarded unchanged.
|
|
101
|
+
2. Below the declared minimum (typically `none`/`minimal` on a set without them) → snaps **up** to the minimum.
|
|
102
|
+
3. Otherwise → nearest declared level by ladder distance, **ties breaking up**.
|
|
103
|
+
4. Provider-documented tables (DeepSeek, Z.AI GLM-5.2/5.3, ClinePass slot maps, Kimi K3) are wire authority and take precedence over the generic rule.
|
|
104
|
+
5. Undeclared levels (opaque strings) on a reasoning-capable model → passthrough (forward compat); a non-reasoning model → options unchanged.
|
|
80
105
|
|
|
81
|
-
|
|
106
|
+
OpenRouter and Hyper derive their sets from each provider's models API (`supported_efforts` / `effort_levels`); all other catalogs are doc-pinned because those upstreams expose no enumeration API.
|
|
82
107
|
|
|
83
|
-
##
|
|
108
|
+
## Extension and configuration notes
|
|
84
109
|
|
|
85
|
-
|
|
110
|
+
- `thinkingFamilyForModel(model)` resolves a family without applying it; hosts that build their own options can use `thinkingCompatFor(family, level)` directly. `compat.thinkingFamily` on a model or request overrides all heuristics.
|
|
111
|
+
- For `openai_reasoning`, an existing `compat.reasoning.summary` (or other reasoning keys) is preserved when merging `effort`.
|
|
112
|
+
- Package-local knobs (`thinking_budget`, `thinking_token_budget`, `chat_template_kwargs`, `cacheRetention`-coupled switches) remain on `compat` — see each provider page.
|
|
113
|
+
|
|
114
|
+
## Security and performance notes
|
|
115
|
+
|
|
116
|
+
- Declared levels prevent 400s from illegal effort values on strict upstreams; snapping is deterministic and ladder-based, never a silent drop.
|
|
117
|
+
- `none` semantics are provider-specific (off, or minimum effort where off is unsupported — e.g. Anthropic Opus 5 cannot disable thinking at `xhigh`/`max`, GLM-5.3 cannot disable thinking at all); the per-provider pages call these out.
|
|
118
|
+
- No secrets or credentials flow through any helper here; patches are plain compat objects.
|
|
86
119
|
|
|
87
120
|
## Non-reasoning models
|
|
88
121
|
|
|
89
|
-
-
|
|
90
|
-
- Helper with a real family on a model that rejects the field: provider/API error — hosts should gate on `capabilities.reasoning` or package docs.
|
|
122
|
+
- The adapter returns options unchanged — no invented body fields.
|
|
91
123
|
- `thinking_type` + `none` sets `{ type: "disabled" }`; other levels set `{ type: "enabled" }` without encoding effort (compose with `reasoning_effort` when the API supports both).
|
|
92
124
|
|
|
93
|
-
## Related
|
|
125
|
+
## Related APIs
|
|
94
126
|
|
|
95
|
-
- [Use-case model selection](use-case-model-selection.md) — session vs worker/summary model binding
|
|
96
|
-
- [Provider packages](provider-packages.md) — package boundaries and discovery
|
|
97
127
|
- [Provider caching](provider-caching.md) — cache retention can disable thinking on some providers (e.g. Z.AI / DeepSeek when `cacheRetention: "none"`)
|
|
98
128
|
- [Provider request policies](provider-request-policies.md) — `mergeProviderRequestOptions`
|
|
129
|
+
- [Use-case model selection](use-case-model-selection.md) — session vs worker/summary model binding (workers take `thinkingLevel`)
|
|
99
130
|
- [Agent/session runtime](agent-session-runtime.md) — prior-reasoning preservation across turns
|
|
100
|
-
-
|
|
101
|
-
-
|
|
131
|
+
- [Provider packages](provider-packages.md) — package boundaries and discovery
|
|
132
|
+
- Per-provider pages under [docs/providers](providers/) — declared levels, wire field, and snapping per provider
|
|
133
|
+
- [Thinking coverage evidence matrix](_evidence/thinking-coverage-2026-09-05.md) — per-model legality, source, and test pins
|
|
134
|
+
- [Review coverage (2026-07-17 provider validation)](_evidence/review-coverage-2026-07-17-provider-validation.md)
|
package/docs/tool-conformance.md
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
Tool conformance helpers are dependency-free assertions for tool-dispatch configuration tests. They exercise the blocked-reason matrix and the success path of `dispatchToolCall` without network or credentials.
|
|
5
|
+
Tool conformance helpers are dependency-free assertions for tool-dispatch configuration tests. They exercise the blocked-reason matrix and the success path of `dispatchToolCall` without network or credentials, and the tool-disclosure contract (progressive tool loading, plan 041) without any provider call.
|
|
6
6
|
|
|
7
7
|
Exported from `@arnilo/prism/testing/tool-conformance`:
|
|
8
8
|
|
|
9
9
|
- `assertToolDispatchConforms(registry, options)`
|
|
10
|
+
- `assertToolDisclosureConforms(options)`
|
|
10
11
|
- `assertToolBlocked(probe, expectedReason)`
|
|
11
12
|
- `dispatchAndCollect(probe)`
|
|
12
|
-
- `ToolConformanceOptions`, `ToolDispatchProbeOptions`
|
|
13
|
+
- `ToolConformanceOptions`, `ToolDispatchProbeOptions`, `ToolDisclosureConformanceOptions`
|
|
13
14
|
|
|
14
15
|
## When to use it
|
|
15
16
|
|
|
@@ -45,6 +46,29 @@ await assertToolDispatchConforms(createToolRegistry(), {
|
|
|
45
46
|
|
|
46
47
|
`assertToolDispatchConforms` returns `Promise<void>` and throws on the first violation. `dispatchAndCollect` returns `{ result, events }` capturing the emitted `AgentEvent`s for custom assertions.
|
|
47
48
|
|
|
49
|
+
`assertToolDispatchConforms` returns `Promise<void>` and throws on the first violation. `dispatchAndCollect` returns `{ result, events }` capturing the emitted `AgentEvent`s for custom assertions.
|
|
50
|
+
|
|
51
|
+
### Disclosure leg (toolsDisclosure "search")
|
|
52
|
+
|
|
53
|
+
`assertToolDisclosureConforms(options)` asserts the progressive tool-loading contract against the same narrowing the runtime applies (`filterTools` allow/deny bounds, then `selectDisclosedTools`):
|
|
54
|
+
|
|
55
|
+
- search mode only narrows: the disclosed set is a subset of the allow/deny-filtered input, never wider, never zero, deterministic order for identical turns; a deny-listed tool is never described to the provider
|
|
56
|
+
- the generated `search_tools` tool is always kept in the disclosed set
|
|
57
|
+
- fail closed: an index over the frozen 1024-tool cap discloses the full eligible list
|
|
58
|
+
- `search_tools` output is inert: names plus byte-truncated (512-char) descriptions only — no JSON structure, no tool schemas — oversized hosts descriptions are truncated, never executed, and configured `secrets` never surface even when a description carries one
|
|
59
|
+
- activation is bounded to topK and only ever selects from the eligible set; activated tools stay disclosed on the next turn
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { assertToolDisclosureConforms } from "@arnilo/prism/testing/tool-conformance";
|
|
63
|
+
|
|
64
|
+
assertToolDisclosureConforms({
|
|
65
|
+
tools: hostTools, // incl. schema-bearing and oversized-description tools
|
|
66
|
+
filter: { deny: ["legacy_tool"] }, // host allow/deny bounds
|
|
67
|
+
search: { topK: 16 },
|
|
68
|
+
secrets: [hostSecret], // secret-scan of model-facing search output
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
48
72
|
## Request/response example
|
|
49
73
|
|
|
50
74
|
```ts
|
|
@@ -77,12 +101,13 @@ await assertToolDispatchConforms(createToolRegistry(), {
|
|
|
77
101
|
## Security and performance notes
|
|
78
102
|
|
|
79
103
|
- No credentials, no network required.
|
|
80
|
-
- Supply `validate` to exercise your policy; use `createJsonSchemaToolArgumentValidator()` from `@arnilo/prism-
|
|
104
|
+
- Supply `validate` to exercise your policy; use `createJsonSchemaToolArgumentValidator()` from `@arnilo/prism-core/validation/json-schema` for standards-based `parameters` validation.
|
|
81
105
|
- The helper uses an allow-all permission policy by default; supply `permission` to validate your fail-closed policy.
|
|
82
106
|
- Blocked calls are proven not to execute by the absence of `tool_execution_started`.
|
|
83
107
|
|
|
84
108
|
## Related APIs
|
|
85
109
|
|
|
86
110
|
- [Tools](tools.md)
|
|
111
|
+
- [Tool effects](tool-effects.md)
|
|
87
112
|
- [Settings, auth, trust, security](settings-auth-trust-security.md)
|
|
88
113
|
- [Provider conformance](provider-conformance.md)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
This page freezes the reusable tool validation, parallel dispatch, MCP bridge, and coding execution-policy designs for Plan 055. It inventories existing `@arnilo/prism` tool harness seams, `@arnilo/prism-coding-agent` behavior, extension/contribution boundaries, and the MCP mapping surface Tasks 1–6 will implement against.
|
|
5
|
+
This page freezes the reusable tool validation, parallel dispatch, MCP bridge, and coding execution-policy designs for Plan 055. It inventories existing `@arnilo/prism` tool harness seams, `@arnilo/prism-coding-tools/agent` behavior, extension/contribution boundaries, and the MCP mapping surface Tasks 1–6 will implement against.
|
|
6
6
|
|
|
7
7
|
Implementation is **shipped** for JSON Schema tool argument validation (Plan 055 Task 1), parallel single-shot tool dispatch (Task 2), the MCP client bridge (Task 3), coding execution policy (Task 4), and bounded image reads (Task 5). Task 6 verification evidence is recorded in [review coverage](_evidence/review-coverage-2026-07-14.md).
|
|
8
8
|
|
|
@@ -40,7 +40,7 @@ All paths converge on normal `ToolResult` values and `tool_execution_*` events.
|
|
|
40
40
|
|
|
41
41
|
```ts
|
|
42
42
|
import { createAgent } from "@arnilo/prism";
|
|
43
|
-
import { createJsonSchemaToolArgumentValidator } from "@arnilo/prism-
|
|
43
|
+
import { createJsonSchemaToolArgumentValidator } from "@arnilo/prism-core/validation/json-schema";
|
|
44
44
|
|
|
45
45
|
const agent = createAgent({
|
|
46
46
|
model,
|
|
@@ -123,7 +123,7 @@ Package performs **no** `PermissionPolicy`, `ToolValidator`, or trust checks of
|
|
|
123
123
|
| --- | --- |
|
|
124
124
|
| `ToolDefinition.parameters` | Stored and forwarded to providers; **not validated** by core |
|
|
125
125
|
| `ToolValidator` | Host function hook; Phase 25 threads through agent runtime |
|
|
126
|
-
| Standards-based schema validation | Optional `@arnilo/prism-
|
|
126
|
+
| Standards-based schema validation | Optional `@arnilo/prism-core/validation/json-schema`; host wires it through `ToolValidator` |
|
|
127
127
|
| Schema compile cache | Adapter-owned finite LRU; core never compiles schemas |
|
|
128
128
|
|
|
129
129
|
### MCP mapping (shipped — Task 3)
|
|
@@ -178,10 +178,10 @@ export function createToolParameterValidator(
|
|
|
178
178
|
): ToolValidator;
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
Optional package `@arnilo/prism-
|
|
181
|
+
Optional package `@arnilo/prism-core/validation/json-schema`:
|
|
182
182
|
|
|
183
183
|
```ts
|
|
184
|
-
import { createJsonSchemaToolArgumentValidator } from "@arnilo/prism-
|
|
184
|
+
import { createJsonSchemaToolArgumentValidator } from "@arnilo/prism-core/validation/json-schema";
|
|
185
185
|
|
|
186
186
|
createAgent({ model, validator: createJsonSchemaToolArgumentValidator() });
|
|
187
187
|
```
|
|
@@ -271,7 +271,7 @@ export async function assertExecutionAllowed(
|
|
|
271
271
|
): Promise<ExecutionAction>;
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
-
`@arnilo/prism-coding-agent` tools call `executionPolicy.check()` **inside** `execute` before side effects (after dispatch permission + argument validation). Optional `@arnilo/prism-coding-security` supplies `createCodingApprovalPolicy({ roots, approve, readOnly, commandRules })` with realpath containment, default deny patterns, metacharacter approval, approval caching, and `createSandboxBashOperations()` for pluggable sandbox backends.
|
|
274
|
+
`@arnilo/prism-coding-tools/agent` tools call `executionPolicy.check()` **inside** `execute` before side effects (after dispatch permission + argument validation). Optional `@arnilo/prism-coding-tools/security` supplies `createCodingApprovalPolicy({ roots, approve, readOnly, commandRules })` with realpath containment, default deny patterns, metacharacter approval, approval caching, and `createSandboxBashOperations()` for pluggable sandbox backends.
|
|
275
275
|
|
|
276
276
|
**Permission vs execution policy:** `PermissionPolicy` remains `tool:<name>:execute` at dispatch. `ExecutionPolicy` adds command/path context for coding tools only — no MCP-specific branches in core.
|
|
277
277
|
|
|
@@ -366,9 +366,9 @@ Core remains dependency-free: validators, MCP bridges, coding policy, sandboxes,
|
|
|
366
366
|
|
|
367
367
|
| Finding / capability | Plan 055 task | Primitive / doc |
|
|
368
368
|
| --- | --- | --- |
|
|
369
|
-
| C-001 JSON Schema tool validation | 1 | **shipped** — `ToolArgumentValidator`, `createToolParameterValidator`, `@arnilo/prism-
|
|
369
|
+
| C-001 JSON Schema tool validation | 1 | **shipped** — `ToolArgumentValidator`, `createToolParameterValidator`, `@arnilo/prism-core/validation/json-schema` |
|
|
370
370
|
| C-003 MCP client bridge | 3 | **shipped** — `@arnilo/prism-mcp` |
|
|
371
|
-
| C-006 Approval/sandbox for coding tools | 4 | **shipped** — `ExecutionPolicy`, `@arnilo/prism-coding-security` |
|
|
371
|
+
| C-006 Approval/sandbox for coding tools | 4 | **shipped** — `ExecutionPolicy`, `@arnilo/prism-coding-tools/security` |
|
|
372
372
|
| C-007 Parallel tool execution | 2 | **shipped** — `toolConcurrency`, `dispatchToolCallsInOrder`, `resolveToolConcurrency` |
|
|
373
373
|
| R-011 Image size / resize option | 5 | **shipped** — `maxImageBytes`, `transformImage`, `DEFAULT_MAX_IMAGE_BYTES` on read tool |
|
|
374
374
|
| Phase verification | 6 | **verified** — `npm run sdk:ready` + audit + threat-model fixtures; evidence in review coverage |
|
package/docs/tools.md
CHANGED
|
@@ -198,11 +198,11 @@ Core exposes schema-agnostic adapters that wrap into the same `ToolValidator` se
|
|
|
198
198
|
- `ToolArgumentValidator` — `validate(schema, value)` with structured errors
|
|
199
199
|
- `createToolParameterValidator(adapter, { missingSchema?: "allow" | "reject" })` — maps `tool.parameters` through the adapter
|
|
200
200
|
|
|
201
|
-
For standards-based validation install `@arnilo/prism-
|
|
201
|
+
For standards-based validation install `@arnilo/prism-core/validation/json-schema`:
|
|
202
202
|
|
|
203
203
|
```ts
|
|
204
204
|
import { createAgent } from "@arnilo/prism";
|
|
205
|
-
import { createJsonSchemaToolArgumentValidator } from "@arnilo/prism-
|
|
205
|
+
import { createJsonSchemaToolArgumentValidator } from "@arnilo/prism-core/validation/json-schema";
|
|
206
206
|
|
|
207
207
|
const agent = createAgent({
|
|
208
208
|
model,
|
|
@@ -242,7 +242,7 @@ await session.run(input, {
|
|
|
242
242
|
|
|
243
243
|
## JSON Schema validator limits
|
|
244
244
|
|
|
245
|
-
Core stores `ToolDefinition.parameters` but does not compile schemas. Hosts that install `@arnilo/prism-
|
|
245
|
+
Core stores `ToolDefinition.parameters` but does not compile schemas. Hosts that install `@arnilo/prism-core/validation/json-schema` receive pre-Ajv schema limits: 256 KiB bytes, depth 64, 10,000 properties/keywords, 128 refs, and a 256-entry LRU compiled cache by default. All reject invalid values and have finite hard ceilings. Only fragment-local `$ref` values are accepted; non-local refs, cycles, forbidden keys, and non-finite schema numbers fail before tool execution.
|
|
246
246
|
|
|
247
247
|
```ts
|
|
248
248
|
createJsonSchemaToolArgumentValidator({
|
|
@@ -251,13 +251,40 @@ createJsonSchemaToolArgumentValidator({
|
|
|
251
251
|
});
|
|
252
252
|
```
|
|
253
253
|
|
|
254
|
+
## Tool disclosure (progressive tool loading)
|
|
255
|
+
|
|
256
|
+
`toolsDisclosure` on `AgentConfig` / `RunOptions` (run wins; default `"all"`) controls how active tools reach the provider request. Default `"all"` sends every active tool schema — byte-identical to releases before the option existed. Opt-in `"search"` surfaces a bounded top-k subset per turn (scored lexically against the turn input over name and description) plus the generated `search_tools` tool; the model requests more by calling it.
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
const agent = createAgent({
|
|
260
|
+
model, provider,
|
|
261
|
+
tools, // host-active ToolDefinitions (or registry)
|
|
262
|
+
toolsDisclosure: "search", // default "all"
|
|
263
|
+
toolsSearch: { topK: 16 }, // optional; clamped to the hard cap
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Limits (mirroring the skill-disclosure DEFAULT/HARD cap pattern):
|
|
268
|
+
|
|
269
|
+
| Limit | Default | Hard cap |
|
|
270
|
+
| --- | --- | --- |
|
|
271
|
+
| Disclosed tools per turn (`topK`) | 16 | 64 |
|
|
272
|
+
| Indexed tools | — | 1024 (fail closed to full disclosure) |
|
|
273
|
+
| Search query bytes | 4096 | 65536 |
|
|
274
|
+
|
|
275
|
+
- `search_tools({ query, k? })` returns inert `name: short description [matched: …]` lines — no schemas or tool bodies — and marks returned tools active for the session. Activation is names-only in run persistence (`sessionState.activatedToolNames`, capped at 128 names) and inert for tools absent from the current registry; a host can reset it with `session.clearActivatedTools()`.
|
|
276
|
+
- Fail closed: any index or scoring error discloses the full input list — never zero tools, never wider than the input list. Exhausting the frozen 1024-tool index cap is surfaced the same way.
|
|
277
|
+
- Disclosure never grants access: dispatch re-checks registry membership and allow/deny (`unknown_tool` / `tool_denied`) on every call regardless of what was described. Search results are intersected with the disclosed list structurally — searched tools are only ever selected from that list, never widened.
|
|
278
|
+
- Scoring is BM25-lite lexical (name tokens weigh ×3, IDF from the registry): bounded, dependency-free, deterministic tie-breaks. ponytail ceiling: embedder-backed scoring via `@arnilo/prism-memory/rag` if accuracy fixtures fall short.
|
|
279
|
+
- Cross-link: skills apply the same discipline to prompt text — see [Context and skills](context-and-skills.md).
|
|
280
|
+
|
|
254
281
|
## Guardrails
|
|
255
282
|
|
|
256
283
|
`DispatchToolCallOptions.guardrails` evaluates `tool_input` after `tool_call` middleware normalization and before lookup, permission, validation, execution policy, or side effect. `tool_output` evaluates raw completed results before redaction, event emission, ledger rows, and transcript append. A block returns a blocked result; tripwire fails the enclosing run. See [Guardrails](guardrails.md).
|
|
257
284
|
|
|
258
285
|
## Related APIs
|
|
259
286
|
|
|
260
|
-
- [OpenAPI tools adapter](openapi-tools.md): optional `@arnilo/prism-
|
|
287
|
+
- [OpenAPI tools adapter](openapi-tools.md): optional `@arnilo/prism-coding-tools/openapi` `createOpenApiTools` — compile host-selected OpenAPI 3.1 operationIds into bounded `ToolDefinition`s (allow-list only, pinned origin, resolved/bounded schemas, approval + effect-store idempotency on mutations, bounded body/response/retries/pagination, host credential resolver, untrusted output).
|
|
261
288
|
- [Agent/session runtime](agent-session-runtime.md): dispatches complete provider tool calls through the host-active tool harness and returns tool results on the next provider turn.
|
|
262
289
|
- [Public contracts](public-contracts.md): `ToolDefinition`, `ToolRegistry`, `ToolExecutionContext`, `ToolResult`, and tool `AgentEvent` contracts.
|
|
263
290
|
- [Contribution registries](contribution-registries.md): inert extension/package tool contribution storage.
|
|
@@ -270,6 +297,6 @@ createJsonSchemaToolArgumentValidator({
|
|
|
270
297
|
- [MCP client bridge](mcp-tools.md): optional remote tool mapping plus separate bounded resource/prompt facades; non-tool MCP capabilities never bypass tool dispatch by masquerading as `ToolDefinition`.
|
|
271
298
|
- [Recoverable tool effects](tool-effects.md): optional `tool.effect` + `effectStore` claim/CAS recovery around dispatch.
|
|
272
299
|
- [Recoverable tool effects](tool-effects.md): optional `tool.effect` + `effectStore` claim/CAS recovery around dispatch.
|
|
273
|
-
- [Coding agent tools](coding-agent-tools.md): optional first-party `@arnilo/prism-coding-agent` `shell`/`read`/`write`/`edit` tools a host registers into this harness.
|
|
300
|
+
- [Coding agent tools](coding-agent-tools.md): optional first-party `@arnilo/prism-coding-tools/agent` `shell`/`read`/`write`/`edit` tools a host registers into this harness.
|
|
274
301
|
|
|
275
302
|
`DispatchToolCallOptions.trust` and `.permission` run before validation or `execute()`; denial emits `tool_execution_blocked`. Middleware cannot bypass either guard. `AgentConfig.validator`/`RunOptions.validate` run after these guards; their output is redacted through the active `SecretRedactor`. `createSecureAgent()` requires all three seams plus non-empty schemas and durable pre-tool approval. Prism does not sandbox tools. See [Security/auth/trust](settings-auth-trust-security.md).
|
package/docs/web-tools.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
Use when agent needs explicit public-web discovery or host-approved document retrieval/extraction. Keep search separate from fetch/extract so model cannot select provider, credential, API origin, extraction schema, or cost path.
|
|
10
10
|
|
|
11
|
-
**Obscura-backed alternative**: the optional
|
|
11
|
+
**Obscura-backed alternative**: the optional `@arnilo/prism-web-tools/obscura` subpath ([Obscura](obscura.md)) provides `web_search`/`web_fetch` behavior backed by a host-installed Obscura headless browser through its CLI (one replaceable HTML search profile instead of an API key), plus explicit native `obscura_fetch`/`obscura_scrape` batch tools. It reuses this package's normalized citation/untrusted shapes (`provider: "obscura"`) but does not require credentials; the API-backed Brave/Exa/Firecrawl adapters here remain the preferred path when an API key is available.
|
|
12
12
|
|
|
13
13
|
## Inputs / request
|
|
14
14
|
|
|
@@ -44,7 +44,7 @@ Fetch returns bounded Markdown and selected attribution. Extract validates host
|
|
|
44
44
|
|
|
45
45
|
```ts
|
|
46
46
|
import { createEnvCredentialResolver } from "@arnilo/prism";
|
|
47
|
-
import { createJsonSchemaArgumentValidator } from "@arnilo/prism-
|
|
47
|
+
import { createJsonSchemaArgumentValidator } from "@arnilo/prism-core/validation/json-schema";
|
|
48
48
|
import { createBraveSearch, createFirecrawlExtractor, createFirecrawlFetch, createWebTools } from "@arnilo/prism-web-tools";
|
|
49
49
|
|
|
50
50
|
const credentials = createEnvCredentialResolver(process.env, {
|
|
@@ -69,7 +69,7 @@ Default/hard limits: query 4/16 KiB; results 10/20; URLs 5/20; request 256 KiB/1
|
|
|
69
69
|
|
|
70
70
|
Provider credentials never enter tool schemas/results, prompts, telemetry, URLs, or errors. Error text excludes remote bodies. Search snippets, Markdown, and extracted JSON are prompt-injection-capable data: never concatenate them into system instructions or use them to modify tools, permissions, credentials, trust, routing, or schemas. Firecrawl fetches target URLs remotely; Prism cannot claim target DNS pinning after handoff. Use controlled host fetch when that guarantee is required.
|
|
71
71
|
|
|
72
|
-
Default tests use injected fake fetch and make no public request. Restricted smoke: `PRISM_LIVE_WEB=1 npm run test:live -w @arnilo/prism-web-tools` plus least-privilege provider environment credential. Prefer
|
|
72
|
+
Default tests use injected fake fetch and make no public request. Restricted smoke: `PRISM_LIVE_WEB=1 npm run test:live -w @arnilo/prism-web-tools` plus least-privilege provider environment credential. Prefer the [`browser`](browser-automation.md) subpath over ordinary public retrieval; use browser automation only for interactive/authenticated/JavaScript-heavy work behind a host egress proxy. Arbitrary HTML execution, model-selected providers, automatic OAuth forwarding, and generic web/MCP passthrough are unsupported.
|
|
73
73
|
|
|
74
74
|
## Related APIs
|
|
75
75
|
|
package/docs/wiki.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# LLM Wiki (@arnilo/prism-wiki)
|
|
1
|
+
# LLM Wiki (@arnilo/prism-memory/wiki)
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
`@arnilo/prism-wiki` implements Andrej Karpathy's **LLM Wiki Pattern** for the Prism agent ecosystem. It acts as a knowledge compiler that transforms raw, immutable sources (source code, AST symbols, notes, markdown clips, transcripts, journal entries) into a persistent, compounding, cross-linked Markdown knowledge base (`.wiki/`).
|
|
5
|
+
The `@arnilo/prism-memory/wiki` subpath implements Andrej Karpathy's **LLM Wiki Pattern** for the Prism agent ecosystem. It acts as a knowledge compiler that transforms raw, immutable sources (source code, AST symbols, notes, markdown clips, transcripts, journal entries) into a persistent, compounding, cross-linked Markdown knowledge base (`.wiki/`).
|
|
6
6
|
|
|
7
7
|
It integrates Tobias Lütke's [`qmd`](https://github.com/tobi/qmd) on-device hybrid search engine (BM25, vector search, and LLM reranking) and hydrates search results with Context7-inspired hierarchical breadcrumbs (`# Category > ## Topic`) and live clickable source line anchors (`file:///path/to/file#Lxx-Lyy` format), enabling agents and humans to navigate code and notes directly without blind regex loops (`grep`/`rg`).
|
|
8
8
|
|
|
@@ -98,7 +98,7 @@ The authentication layer uses asymmetric Ed25519 JWT verification in middleware,
|
|
|
98
98
|
|
|
99
99
|
```ts
|
|
100
100
|
import { createExtensionKernel } from "@arnilo/prism";
|
|
101
|
-
import { createWikiExtension, initWiki, refreshWiki, lintWiki } from "@arnilo/prism-wiki";
|
|
101
|
+
import { createWikiExtension, initWiki, refreshWiki, lintWiki } from "@arnilo/prism-memory/wiki";
|
|
102
102
|
|
|
103
103
|
const kernel = createExtensionKernel();
|
|
104
104
|
|
|
@@ -112,7 +112,7 @@ await kernel.load([wiki]);
|
|
|
112
112
|
|
|
113
113
|
## Skills and Auto-Deployment
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
The wiki subpath includes two specialized skills formatted according to `.agents/skills/skill-creator`:
|
|
116
116
|
|
|
117
117
|
1. **`wiki-maintainer`**: Ingestion, compilation, line-anchor validation, and contradiction reconciliation rules.
|
|
118
118
|
2. **`wiki-searcher`**: Context7 hierarchical breadcrumb query resolution, zero-grep instructions, and compounding insight recording.
|
|
@@ -135,7 +135,7 @@ Emitted `.wiki/` trees are [OKF v0.2](https://github.com/GoogleCloudPlatform/ope
|
|
|
135
135
|
|
|
136
136
|
## Extension and configuration notes
|
|
137
137
|
|
|
138
|
-
-
|
|
138
|
+
- The wiki subpath registers tools (`wiki_search`, `wiki_read_page`, `wiki_record_insight`), commands (`wiki-init`, `wiki-refresh`, `wiki-lint`), skills (`wiki-maintainer`, `wiki-searcher`), and instruction injectors (`wiki-guidance`) into Prism registries.
|
|
139
139
|
- It operates with zero core modifications and can be used with any `@arnilo/prism` agent.
|
|
140
140
|
- `qmd` is optional but recommended. When `@tobilu/qmd` is not installed, the search engine falls back to catalog matching against `index.md`.
|
|
141
141
|
|
|
@@ -148,7 +148,7 @@ Emitted `.wiki/` trees are [OKF v0.2](https://github.com/GoogleCloudPlatform/ope
|
|
|
148
148
|
|
|
149
149
|
## Related APIs
|
|
150
150
|
|
|
151
|
-
- [`@arnilo/prism-rag`](rag.md): Bounded document chunking and vector context injection.
|
|
151
|
+
- [`@arnilo/prism-memory/rag`](rag.md): Bounded document chunking and vector context injection.
|
|
152
152
|
- [`@arnilo/prism-memory`](working-and-semantic-memory.md): Embedder and VectorStore primitives.
|
|
153
|
-
- [`@arnilo/prism-coding-agent`](coding-agent-tools.md): Code manipulation and reading tools.
|
|
153
|
+
- [`@arnilo/prism-coding-tools/agent`](coding-agent-tools.md): Code manipulation and reading tools.
|
|
154
154
|
- [`Contribution registries`](contribution-registries.md): Extension contribution model.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
`@arnilo/prism-server` ships a durable artifact co-work review service (Phase 9 / 0.0.14): authorized attach of source/output references with MIME/hash/version, producer-run attribution, citations/data sources, and preview metadata; revision comparison; reviewer approve/reject (request-changes) with last-validated recovery; and authorized, expiring delivery links. Core (`@arnilo/prism`) exports artifact **types only** (`ArtifactRecord`, `ArtifactRevision`, `ArtifactApproval`, `ArtifactDeliveryToken`, approval state `pending | approved | rejected`). Prism persists bounded metadata, revisions, approvals, and delivery references over the existing versioned checkpoint store — **never file bodies**; hosts own blob storage and rendering.
|
|
5
|
+
`@arnilo/prism-core/runtime/server` ships a durable artifact co-work review service (Phase 9 / 0.0.14): authorized attach of source/output references with MIME/hash/version, producer-run attribution, citations/data sources, and preview metadata; revision comparison; reviewer approve/reject (request-changes) with last-validated recovery; and authorized, expiring delivery links. Core (`@arnilo/prism`) exports artifact **types only** (`ArtifactRecord`, `ArtifactRevision`, `ArtifactApproval`, `ArtifactDeliveryToken`, approval state `pending | approved | rejected`). Prism persists bounded metadata, revisions, approvals, and delivery references over the existing versioned checkpoint store — **never file bodies**; hosts own blob storage and rendering.
|
|
6
6
|
|
|
7
7
|
## When to use it
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ Not for: storing file content (use host blob storage), local Office preview/rend
|
|
|
22
22
|
| `options.redactor` | yes | `SecretRedactor`; records are redacted before persist and on every response |
|
|
23
23
|
| `options.linkSecret` | yes | Host HMAC key material for signing/verifying delivery links |
|
|
24
24
|
| `options.limits` | no | Frozen caps (below); each clamped to a hard maximum |
|
|
25
|
-
| `options.onDecision` | no | Audit seam (redacted refs) for attach/revise/approve/reject; bridge to `@arnilo/prism-policy` |
|
|
25
|
+
| `options.onDecision` | no | Audit seam (redacted refs) for attach/revise/approve/reject; bridge to `@arnilo/prism-core/governance/policy` |
|
|
26
26
|
|
|
27
27
|
Every operation input carries `ownership` (from host `authorize`, never request JSON) plus optional verified `identity`. `attach` requires `threadId`, `uri`, `mime`, `hash`; `revise` requires `uri`, `hash` (mime defaults to the previous revision); `compare` requires two distinct revision numbers; `approve`/`reject` require a `version`; `deliveryLink` accepts optional `version` (defaults to last validated, else latest) and `ttlSeconds`.
|
|
28
28
|
|
|
@@ -56,8 +56,8 @@ No package-owned agent events are emitted; `onDecision` is the audit seam (redac
|
|
|
56
56
|
|
|
57
57
|
```ts
|
|
58
58
|
import { createSecretRedactor } from "@arnilo/prism";
|
|
59
|
-
import { createSqlitePersistence } from "@arnilo/prism-
|
|
60
|
-
import { createArtifactService, createArtifactHandler } from "@arnilo/prism-server";
|
|
59
|
+
import { createSqlitePersistence } from "@arnilo/prism-core/sessions/sqlite";
|
|
60
|
+
import { createArtifactService, createArtifactHandler } from "@arnilo/prism-core/runtime/server";
|
|
61
61
|
|
|
62
62
|
const persistence = createSqlitePersistence({ filename: "prism.db" });
|
|
63
63
|
const artifacts = createArtifactService(persistence.checkpoints, {
|
|
@@ -79,7 +79,7 @@ export const handler = createArtifactHandler({ service: artifacts, authorize: ho
|
|
|
79
79
|
- Artifact records are versioned checkpoint values (namespace `prism.artifact`, key `threadId:artifactId`). The checkpoint `version` is the CAS counter for concurrent reviewers, distinct from revision numbers. Any `CheckpointStore` works; sqlite/postgres persistence already expose `.checkpoints`, so there is no separate artifact schema or migration.
|
|
80
80
|
- `createArtifactHandler` mounts attach/list/get/revise/compare/approve/reject/last-validated/delivery-link plus `GET /prism/artifacts/download?link=…`. Download verifies the link signature + expiry, then **reauthorizes** against the token's ownership (mismatch fails closed), and returns the authorized revision reference only — the host fetches the body.
|
|
81
81
|
- Delivery links are `base64url(payload).base64url(HMAC-SHA256)` over `{ artifactId, threadId, version, ownership, issuedAt, expiresAt }`; they are reauthorized per download and are not bearer secrets.
|
|
82
|
-
- **Blob storage (0.0.28)**: `createArtifactService` accepts an optional `bodies: ArtifactBodyStore` (core contract in `src/artifacts.ts`: `put`/`get`/`delete`/`presign` by opaque, ownership-scoped `ArtifactBodyRef`). When wired, `deliveryLink` resolves through `bodies.presign` and returns an additional `url` (bounded-TTL, single-object presigned URL) beside the signed link/token; revisions must carry a recorded `size` (optional on attach/revise) or delivery fails closed. The reference adapter is `@arnilo/prism-server/artifact-bodies` `createS3ArtifactBodyStore` (hand-rolled SigV4 over native fetch + WebCrypto, path-style, single-chunk PUT with verified `x-amz-content-sha256`; works with AWS S3, MinIO, Cloudflare R2). Hosts may substitute any store; the contract is storage-free in core.
|
|
82
|
+
- **Blob storage (0.0.28)**: `createArtifactService` accepts an optional `bodies: ArtifactBodyStore` (core contract in `src/artifacts.ts`: `put`/`get`/`delete`/`presign` by opaque, ownership-scoped `ArtifactBodyRef`). When wired, `deliveryLink` resolves through `bodies.presign` and returns an additional `url` (bounded-TTL, single-object presigned URL) beside the signed link/token; revisions must carry a recorded `size` (optional on attach/revise) or delivery fails closed. The reference adapter is `@arnilo/prism-core/runtime/server/artifact-bodies` `createS3ArtifactBodyStore` (hand-rolled SigV4 over native fetch + WebCrypto, path-style, single-chunk PUT with verified `x-amz-content-sha256`; works with AWS S3, MinIO, Cloudflare R2). Hosts may substitute any store; the contract is storage-free in core.
|
|
83
83
|
- Body stores verify ownership on every operation, verify size/SHA-256/MIME on put and get (fail closed), refuse delete under legal hold (host `isHeld` callback), and are idempotent on delete (retention sweeps delete bodies with metadata). Credentials come only from the host resolver; bucket/path/key never appear in errors, telemetry, or artifact records (the object key is derived from the ref).
|
|
84
84
|
- Review loops driven by an agent consume the shared `RunLimits` at the host's agent layer; the artifact service itself is a passive, bounded record store.
|
|
85
85
|
|
|
@@ -93,7 +93,18 @@ export const handler = createArtifactHandler({ service: artifacts, authorize: ho
|
|
|
93
93
|
|
|
94
94
|
## Coding patch review composition (0.2.6, plan 026)
|
|
95
95
|
|
|
96
|
-
`@arnilo/prism-coding-agent` composes over this service for the coding patch review workflow: `createCodingPatchReviewManifest` builds a bounded manifest (repository/worktree identity, base/head, patch digest, changed paths, diffstat, check and diagnostic summaries) and returns a structural `ArtifactAttachInput` whose `preview.review` embeds the manifest and whose `hash` is the patch SHA-256; `assertCodingPatchAccepted` derives `pending|accepted|rejected|superseded` from the returned `ArtifactRecord` by binding to the exact artifact revision, digest, and identity — any patch/repository/worktree/base/head change supersedes a prior acceptance (a newer revision attached after approval makes the old acceptance stale and refused). Decisions never apply/commit/push/merge; the manifest never embeds a raw patch body. Full contract: [Coding review and diagnostics](coding-review-and-diagnostics.md).
|
|
96
|
+
`@arnilo/prism-coding-tools/agent` composes over this service for the coding patch review workflow: `createCodingPatchReviewManifest` builds a bounded manifest (repository/worktree identity, base/head, patch digest, changed paths, diffstat, check and diagnostic summaries) and returns a structural `ArtifactAttachInput` whose `preview.review` embeds the manifest and whose `hash` is the patch SHA-256; `assertCodingPatchAccepted` derives `pending|accepted|rejected|superseded` from the returned `ArtifactRecord` by binding to the exact artifact revision, digest, and identity — any patch/repository/worktree/base/head change supersedes a prior acceptance (a newer revision attached after approval makes the old acceptance stale and refused). Decisions never apply/commit/push/merge; the manifest never embeds a raw patch body. Full contract: [Coding review and diagnostics](coding-review-and-diagnostics.md).
|
|
97
|
+
|
|
98
|
+
## Live probe (plans/064 Task 9)
|
|
99
|
+
|
|
100
|
+
The S3 artifact-body store has an operator-gated live probe against a real S3-compatible endpoint (use a throwaway bucket):
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
PRISM_TEST_S3_ENDPOINT=https://s3.us-east-1.amazonaws.com PRISM_TEST_S3_KEY=<key> \
|
|
104
|
+
PRISM_TEST_S3_SECRET=<secret> PRISM_TEST_S3_BUCKET=prism-throwaway npm test -w @arnilo/prism-core -- artifact-bodies-live
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Probes: put → get (hash + size verified), presigned delivery URL with `X-Amz-Signature`, and an idempotent double delete. Bounded to ≤ 3 real requests. Registered in `scripts/live-matrix.json` as `core/artifact-bodies-s3-live`.
|
|
97
108
|
|
|
98
109
|
## Related APIs
|
|
99
110
|
|
package/docs/work-connectors.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Work connectors
|
|
2
2
|
|
|
3
|
-
Least-privilege Microsoft 365 and Google Workspace connectors live in `@arnilo/prism-work
|
|
3
|
+
Least-privilege Microsoft 365 and Google Workspace connectors live in `@arnilo/prism-core/integrations/work`.
|
|
4
4
|
|
|
5
5
|
## Principles
|
|
6
6
|
|
|
@@ -13,19 +13,19 @@ Least-privilege Microsoft 365 and Google Workspace connectors live in `@arnilo/p
|
|
|
13
13
|
|
|
14
14
|
## Microsoft 365
|
|
15
15
|
|
|
16
|
-
See [Work tools](work-tools.md). Adapter: `createMicrosoft365CliAdapter` / subpath `@arnilo/prism-work
|
|
16
|
+
See [Work tools](work-tools.md). Adapter: `createMicrosoft365CliAdapter` / subpath `@arnilo/prism-core/integrations/work/microsoft365`.
|
|
17
17
|
|
|
18
18
|
Uses [@pnp/cli-microsoft365](https://pnp.github.io/cli-microsoft365/) commands such as `outlook message list|get`, `outlook mail send`, `outlook event list|add`, `file list|add`, `spo file sharinglink add`. To Do / Planner / Teams remain capability-gated.
|
|
19
19
|
|
|
20
20
|
## Google Workspace
|
|
21
21
|
|
|
22
|
-
See [Work tools](work-tools.md). Adapter: `createGoogleWorkspaceCliAdapter` / subpath `@arnilo/prism-work
|
|
22
|
+
See [Work tools](work-tools.md). Adapter: `createGoogleWorkspaceCliAdapter` / subpath `@arnilo/prism-core/integrations/work/google-workspace`.
|
|
23
23
|
|
|
24
24
|
Uses [`@googleworkspace/cli` (`gws`)](https://github.com/googleworkspace/cli): `gmail users messages list|get`, `gmail +send`, `calendar events list|insert`, `drive files list|create`, `drive permissions create`, `tasks tasks *`. Docs/Sheets/Slides create remain capability-gated. Discovery `schema` and `auth`/`login`/`setup` are forbidden from Prism argv.
|
|
25
25
|
|
|
26
26
|
## Scoped OAuth establishment (0.0.14)
|
|
27
27
|
|
|
28
|
-
Hosts establish, refresh, and revoke scoped OAuth credentials for these workloads through the existing `OAuthProvider` / credential-store seams (`@arnilo/prism-credentials
|
|
28
|
+
Hosts establish, refresh, and revoke scoped OAuth credentials for these workloads through the existing `OAuthProvider` / credential-store seams (`@arnilo/prism-core/credentials/node`): `createMicrosoft365OAuthProvider` / `createGoogleWorkspaceOAuthProvider` (PKCE + device code), least-privilege scope bundles per capability (`resolveMicrosoft365Scopes` / `resolveGoogleWorkspaceScopes`, read vs mutation). Connectors consume a per-identity token via a late-bound `tokenProvider` injected as an env var — never argv, never model context; revocation fails closed. See [Credential storage](credential-storage.md) and [Work tools](work-tools.md).
|
|
29
29
|
|
|
30
30
|
## Out of scope
|
|
31
31
|
|