@arnilo/prism 0.0.18 → 0.0.20
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 +28 -0
- package/dist/agents.js +17 -2
- package/dist/context-budget.d.ts +5 -1
- package/dist/context-budget.js +55 -9
- package/dist/contracts.d.ts +16 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +4 -1
- package/dist/input.d.ts +6 -0
- package/dist/input.js +42 -8
- package/dist/skill-disclosure.d.ts +35 -0
- package/dist/skill-disclosure.js +101 -0
- package/dist/skill-load.d.ts +25 -0
- package/dist/skill-load.js +112 -0
- package/dist/tool-result-fold.d.ts +40 -0
- package/dist/tool-result-fold.js +164 -0
- package/docs/0.1.0-readiness.md +10 -8
- package/docs/agent-session-runtime.md +2 -0
- package/docs/compaction-observational-memory.md +52 -8
- package/docs/context-and-skills.md +83 -7
- package/docs/index.md +5 -5
- package/docs/migration.md +35 -0
- package/docs/release-and-install.md +56 -14
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## When to use it
|
|
8
8
|
|
|
9
|
-
Use context resolution when a host wants project/session/context blocks resolved before prompt composition. Use the skill registry when a host wants explicit progressive skill disclosure. Declarative `AgentDefinition.skills` are inactive unless listed; omitted skills means none unless the host uses the migration-only `activateAllCapabilities: true` option.
|
|
9
|
+
Use context resolution when a host wants project/session/context blocks resolved before prompt composition. Use the skill registry when a host wants explicit progressive skill disclosure: catalog `name` + `description` every turn by default, full `instructions` only after `load_skill` or when the host opts into eager mode. Declarative `AgentDefinition.skills` are inactive unless listed; omitted skills means none unless the host uses the migration-only `activateAllCapabilities: true` option.
|
|
10
10
|
|
|
11
11
|
Do not use these helpers as an agent loop, package discovery mechanism, context cache, token budgeter, retrier, credential resolver, semantic skill ranker, tool activator, or permission system.
|
|
12
12
|
|
|
@@ -107,7 +107,8 @@ The agent/session runtime resolves skills per run and wires each active skill's
|
|
|
107
107
|
| Surface | Config shape | Run override | Active skills |
|
|
108
108
|
| --- | --- | --- | --- |
|
|
109
109
|
| Runtime agent | `AgentConfig.skills: SkillRegistry` | `RunOptions.activeSkills: ["brief"]` | Named skills only, resolved with `resolveActiveSkills({ registry, names, tools })`. |
|
|
110
|
-
| Runtime agent | `AgentConfig.skills: SkillRegistry` | no `activeSkills` / no `skills` |
|
|
110
|
+
| Runtime agent | `AgentConfig.skills: SkillRegistry` | no `activeSkills` / no `skills` / no `activateAllSkills` | No skills active (fail-closed default). |
|
|
111
|
+
| Runtime agent | `AgentConfig.skills: SkillRegistry` | `activateAllSkills: true` (run or agent) | All registry skills (`SkillRegistry.list()`), migration opt-in. |
|
|
111
112
|
| Runtime agent | `AgentConfig.skills: Skill[]` | `RunOptions.skills: [...]` | Override array only. |
|
|
112
113
|
| Runtime agent | `AgentConfig.skills: Skill[]` | no `RunOptions.skills` | All configured array skills. |
|
|
113
114
|
| Declarative definition | `AgentDefinition.skills: ["brief"]` | later runtime `activeSkills` optional | Listed names only. |
|
|
@@ -118,13 +119,13 @@ Runtime selection precedence mirrors the other `RunOptions` overrides (`redactor
|
|
|
118
119
|
|
|
119
120
|
1. `AgentConfig.skills` is a `SkillRegistry` and `RunOptions.activeSkills: readonly string[]` (names) is set → the runtime calls `resolveActiveSkills({ registry, names, tools })`.
|
|
120
121
|
2. `RunOptions.skills: readonly Skill[]` is set → that array replaces `AgentConfig.skills` for the run. This override exists for the case where `AgentConfig.skills` is a plain `Skill[]` (no registry), so name resolution is impossible.
|
|
121
|
-
3. Neither set →
|
|
122
|
+
3. Neither set → no skills active when `AgentConfig.skills` is a `SkillRegistry` (fail-closed). Use `activateAllSkills: true` on the run or agent to restore prior list-all behavior (`SkillRegistry.list()`). Plain `Skill[]` configs still activate every configured array skill. This is not the declarative default.
|
|
122
123
|
|
|
123
124
|
names win when a registry exists. `RunOptions.activeSkills` cannot be used against a plain-array `AgentConfig.skills` — use `RunOptions.skills` instead. Use `RunOptions.skills: []` for an explicit no-skills runtime run.
|
|
124
125
|
|
|
125
|
-
Each active skill contributes two things the runtime
|
|
126
|
+
Each active skill contributes two things the runtime wires together:
|
|
126
127
|
|
|
127
|
-
- `Skill
|
|
128
|
+
- `Skill` prompt text → rendered as system messages by `skillMessages()` / `skillPromptText()` (active set only). Default `skillsDisclosure: "progressive"` sends `Skill <name>: <description>`; full `instructions` appear only when the skill is in the session `LoadedSkillSet` or disclosure is `"eager"`.
|
|
128
129
|
- `Skill.context: ContextProvider[]` → collected across active skills (`activeSkills.flatMap(s => s.context ?? [])`), resolved through the existing `resolveContextProviders(...)`, and merged into the request's `context` **after** host `AgentConfig.context` blocks. Inactive skills contribute neither instructions nor context.
|
|
129
130
|
|
|
130
131
|
`toolNames` enforcement is live: because selection routes through `resolveActiveSkills()`, a skill demanding a host-inactive tool throws with `Skill ${name} requires inactive tool: ${missing}` **before the first provider turn** — no provider call, no store write, no partial side effect. This is the fail-fast contract the docs already claimed; the runtime now honors it.
|
|
@@ -153,7 +154,69 @@ await session.run(input, { skills: [{ name: "verbose", instructions: "Be verbose
|
|
|
153
154
|
await session.run(input, { skills: [] }); // explicit no skills for this run
|
|
154
155
|
```
|
|
155
156
|
|
|
156
|
-
Skill selection grants no tool access and cannot bypass permissions — a skill's `toolNames` can only *require* host-active tools, never activate or grant them. Declarative skills also do not activate themselves by presence in a registry; list names on `AgentDefinition.skills` (or pass runtime `activeSkills`) when wanted.
|
|
157
|
+
Skill selection grants no tool access and cannot bypass permissions — a skill's `toolNames` can only *require* host-active tools, never activate or grant them. Declarative skills also do not activate themselves by presence in a registry; list names on `AgentDefinition.skills` (or pass runtime `activeSkills`) when wanted.
|
|
158
|
+
|
|
159
|
+
### Progressive skill disclosure
|
|
160
|
+
|
|
161
|
+
`skillsDisclosure` on `AgentConfig` / `RunOptions` (`"progressive"` default, `"eager"` opt-in; run wins) controls how active skills render in provider input:
|
|
162
|
+
|
|
163
|
+
| Mode | Provider view per active skill |
|
|
164
|
+
| --- | --- |
|
|
165
|
+
| `"progressive"` (default) | `Skill <name>: <description>` (or `(no description)` when empty) |
|
|
166
|
+
| `"eager"` | `Skill <name>:\n<instructions>` every turn (pre-0.0.20 behavior) |
|
|
167
|
+
|
|
168
|
+
Catalog caps: **64** entries default / **256** hard; descriptions **512 B** default / **4 KiB** hard; instruction bodies **32 KiB** default / **256 KiB** hard on load/eager render. Oversize catalog/description/instruction payloads fail closed (`SkillDisclosureError` / `SkillLoadError`).
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { assembleProviderInput, createLoadedSkillSet } from "@arnilo/prism";
|
|
172
|
+
|
|
173
|
+
const loaded = createLoadedSkillSet(); // session-owned; not checkpoint-persisted in 0.0.20
|
|
174
|
+
const request = await assembleProviderInput({
|
|
175
|
+
model,
|
|
176
|
+
input: "Hi",
|
|
177
|
+
skills: active,
|
|
178
|
+
skillsDisclosure: "progressive",
|
|
179
|
+
loadedSkills: loaded,
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### On-demand skill load (`load_skill`)
|
|
184
|
+
|
|
185
|
+
Hosts opt in by registering `createLoadSkillTool({ registry, loaded })` on the active tool set. The model calls `load_skill { name }` with an exact registry name; success adds the name to the session `LoadedSkillSet` so later turns include `instructions` under progressive mode. The tool does **not** activate tools, widen permissions, or load skills that were not active for the run.
|
|
186
|
+
|
|
187
|
+
Fail-closed cases: unknown name, inactive skill for the run, inactive required `toolNames`, oversize body, duplicate load, missing session loaded-set wiring. Tool output and errors are size-capped; skill text is untrusted host/extension data.
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
import { createAgent, createLoadSkillTool, createSkillRegistry } from "@arnilo/prism";
|
|
191
|
+
|
|
192
|
+
const registry = createSkillRegistry([ponytail, brief]);
|
|
193
|
+
const loadSkill = createLoadSkillTool({ registry }); // session injects loadedSkills at dispatch
|
|
194
|
+
const agent = createAgent({ model, provider, skills: registry, tools: [loadSkill, /* host */] });
|
|
195
|
+
await agent.createSession().run("…", { activeSkills: ["ponytail"] });
|
|
196
|
+
// Turn 1: catalog only. After load_skill({ name: "ponytail" }), later turns include instructions.
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Pure validation without the tool: `resolveSkillLoad({ registry, name, tools, loaded, activeSkillNames })`.
|
|
200
|
+
|
|
201
|
+
### Context budget priority and skill demotion
|
|
202
|
+
|
|
203
|
+
When `assembleProviderInput` runs with `contextBudget`, `applyContextBudget` evicts droppable sections in layout order. Within `context` blocks and skills, victims sort by ascending `ContextBlock.priority` (missing = **0**), then LIFO within the same priority.
|
|
204
|
+
|
|
205
|
+
Under pressure on a skill with a loaded body, eviction may demote to catalog-only first (`ContextBudgetOmissionKind: "skill_body"`), then remove the skill entirely (`"skills"`). Demoted bodies render as description-only even when the name remains in `LoadedSkillSet`. See [Input and prompt assembly](input-and-prompt-assembly.md).
|
|
206
|
+
|
|
207
|
+
### Optional tool-result fold
|
|
208
|
+
|
|
209
|
+
`toolResultFold` on `AgentConfig` / `RunOptions` (run wins) is **off** unless the host supplies a `summarize` callback. When enabled, aged large tool-result messages in the **provider view** become a one-line header plus bounded summary text; session store entries stay raw. Defaults: `minAgeTurns` **2**, `minBytes` **4096**, `maxSummaryBytes` **512** (hard **4096**). Summarizer failure keeps the raw tool result (fail closed). Not a second memory system — use observational memory / compaction for durable recall.
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
await session.run("…", {
|
|
213
|
+
toolResultFold: {
|
|
214
|
+
minAgeTurns: 2,
|
|
215
|
+
minBytes: 4_096,
|
|
216
|
+
summarize: async ({ toolCallId, text }) => `ref:${toolCallId} ${text.slice(0, 80)}`,
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
```
|
|
157
220
|
|
|
158
221
|
### Migration note
|
|
159
222
|
|
|
@@ -164,12 +227,25 @@ For declarative agents, old configs that omitted `skills` should now add explici
|
|
|
164
227
|
resolveAgentDefinition({ name: "doc", model, skills: ["brief"] }, context);
|
|
165
228
|
```
|
|
166
229
|
|
|
167
|
-
|
|
230
|
+
Runtime hosts that relied on `SkillRegistry.list()` when `activeSkills` was omitted must opt in explicitly:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
// Restore pre-0.0.20 list-all activation (still subject to progressive disclosure):
|
|
234
|
+
await session.run("Hi", { activateAllSkills: true });
|
|
235
|
+
|
|
236
|
+
// Or restore full instruction bodies every turn:
|
|
237
|
+
const agent = createAgent({ model, provider, skills: registry, skillsDisclosure: "eager" });
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Use `activateAllCapabilities: true` only as a temporary all-skills/all-tools compatibility opt-in during migration for **declarative** definitions. Runtime `RunOptions.activeSkills` remains the per-run narrowing tool after an agent has a skill registry configured.
|
|
168
241
|
|
|
169
242
|
## Security and performance notes
|
|
170
243
|
|
|
171
244
|
- Context providers run sequentially and deterministically in caller order.
|
|
172
245
|
- Skill registry lookup is `Map`-backed, and selection is linear in requested skills plus active tools. Strict duplicate mode adds one O(1) `Map.has()` check during registration only.
|
|
246
|
+
- Progressive catalog render is O(active skills) with byte/count caps; `load_skill` lookup is O(1). Budget eviction over context/skills is O(n log n) worst case.
|
|
247
|
+
- `load_skill` cannot grant tools; loaded instructions are untrusted text bounded by hard caps. `toolResultFold` summarizer output is untrusted and capped; failures keep raw tool results.
|
|
248
|
+
- Loaded-skill names are session-scoped in memory only in 0.0.20 — not checkpoint-persisted; new sessions start catalog-only until reload.
|
|
173
249
|
- These helpers perform no provider calls, tool execution, resource loading, package discovery, filesystem/network access, retries, timers, or watchers by themselves.
|
|
174
250
|
- Context and skill output is host/extension data. Do not include secrets unless the host explicitly accepts that prompt exposure.
|
|
175
251
|
- Active tools remain host-supplied; skills and middleware do not activate tools or grant permissions. Use `duplicate: "error"` when loading third-party skills to prevent silent name shadowing.
|
package/docs/index.md
CHANGED
|
@@ -25,7 +25,7 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
|
|
|
25
25
|
## Compaction/session memory
|
|
26
26
|
- [Compaction and retry policies](compaction-and-retry.md): summarize branch history and retry transient provider failures with host-replaceable policies.
|
|
27
27
|
- [LLM compaction package](compaction-llm.md): optional provider-backed strategy with finite summary/reserve/error caps, bounded redacted streaming retention, mandatory finite post-policy `model.parameters.maxTokens`, and `createCodingCompactionStrategy()` for coding handoff focus.
|
|
28
|
-
- [Observational memory compaction package](compaction-observational-memory.md): optional source-backed memory with
|
|
28
|
+
- [Observational memory compaction package](compaction-observational-memory.md): optional source-backed memory with explicit `attach()` lifecycle — **Recent exact messages**, **Observation log**, **Reflections**, **Raw-source retrieval** (exact-id recall + cursor paging); dual coverage, nested settings with legacy map, branch-isolated `appendEntry`, secrets redaction, and inert import/extension.
|
|
29
29
|
- [Working and semantic memory](working-and-semantic-memory.md): optional `@arnilo/prism-memory` working-memory store, semantic recall, finite Embedder/VectorStore contracts, PostgreSQL/pgvector path, consent lifecycle, identity-bound redacted export, and resumable bounded rebuild.
|
|
30
30
|
- [Session stores](session-stores.md): `SessionStore` contract, `SessionAppendOptions`, `SessionAppendConflictError`, branch handles, `readBranchPath`, optional bounded `searchSessions` / `SessionIndex` (memory linear|unsupported), and dev-vs-production branch reads — start here for session persistence.
|
|
31
31
|
- [Conversations](conversations.md): durable user-scoped conversation threads (create/list/continue/branch/archive/export/delete) on session + event-ledger seams, thread-bound reconnectable replay, frozen caps, and legal-hold-aware deletion.
|
|
@@ -34,7 +34,7 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
|
|
|
34
34
|
- [Database persistence](database-persistence.md): production persistence contracts, shared checksummed migration/full-shape catalog primitives (`@arnilo/prism/testing/persistence-schema`), conditional append, indexes, `readBranchPath`, reference relational schema, retention/legal-hold/quota lifecycle (`lifecycle`), and NoSQL mapping.
|
|
35
35
|
- [SQLite persistence](sqlite-persistence.md): optional `better-sqlite3` adapter with session/run storage, checkpoints/leases, feedback, FTS `searchSessions` (migration-v4), and transactionally verified/backfilled migration metadata.
|
|
36
36
|
- [PostgreSQL persistence](postgres-persistence.md): optional pooled `pg` adapter with session/run/checkpoint/lease/feedback storage, FTS `searchSessions` (migration-v4), advisory-locked checksummed/full-shape migrations, and opt-in live conformance.
|
|
37
|
-
- [Migration guide](migration.md): **0.0.15** OpenAI hosted tools/continuation/Realtime, exact AI SDK v4 matrix, RAG lifecycle/reranking/trust/status, and memory export/rebuild; **0.0.14** conversations, memory consent/lifecycle, artifact co-work review, AG-UI co-work events, scoped M365/GWS OAuth connectors, browser checkpoints, device contracts, and Alibaba/Ollama providers; plus prior release migrations.
|
|
37
|
+
- [Migration guide](migration.md): **0.0.20** progressive skill disclosure, empty registry default, `load_skill`, priority budget demotion, optional tool-result fold; **0.0.19** observational memory lifecycle; **0.0.15** OpenAI hosted tools/continuation/Realtime, exact AI SDK v4 matrix, RAG lifecycle/reranking/trust/status, and memory export/rebuild; **0.0.14** conversations, memory consent/lifecycle, artifact co-work review, AG-UI co-work events, scoped M365/GWS OAuth connectors, browser checkpoints, device contracts, and Alibaba/Ollama providers; plus prior release migrations.
|
|
38
38
|
- [Node JSONL session store](node-jsonl-session-store.md): development-only JSONL file adapter for single-process Node hosts; no cross-process safety; `searchSessions` throws `SessionSearchUnsupportedError`.
|
|
39
39
|
- [Persistence, credentials, and multimodality primitives](persistence-credentials-multimodality-primitives.md): Plan 056 inventory — session/run-ledger/persistence contracts, credential/OAuth seams, content/resource/model capabilities, package dependency matrix, conformance matrix, and threat model for production adapters.
|
|
40
40
|
|
|
@@ -58,7 +58,7 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
|
|
|
58
58
|
- [Multimodal content](multimodal-content.md): complete-request media resolution and aggregate bounds, DNS-classified/address-pinned URLs, SSRF/MIME policy, `ModelCapabilities.input` tags, and first-party content-type mapping.
|
|
59
59
|
- [System prompts](system-prompts.md): compose explicit user/package/app/run system prompt layers, auto-load the standard `AGENTS.md` (workspace) / `SYSTEM.md` prompt files via the Node `loadSystemPromptFiles` loader (trust-gated for `AGENTS.md`), and append `SYSTEM.md` → per-agent `AGENT.md` body → repo `AGENTS.md` layers from a discovered agent bundle via `resolveAgentBundle`.
|
|
60
60
|
- [Instruction injection](instruction-injection.md): register package injectors that layer redacted instructions/context blocks without granting tools, permissions, or resource escapes.
|
|
61
|
-
- [Context and skills](context-and-skills.md): resolve ordered context providers
|
|
61
|
+
- [Context and skills](context-and-skills.md): resolve ordered context providers; progressive skill catalog (`skillsDisclosure`, default catalog-only), `load_skill` on-demand bodies, fail-closed registry activation (`activateAllSkills` migration opt-in), `toolNames` fail closed before provider turns, priority-aware budget demotion, and optional `toolResultFold`.
|
|
62
62
|
- [Retrieval-augmented generation](rag.md): optional bounded source lifecycle, document adapters, host reranking, ingestion status, attributable citations, and inert context injection.
|
|
63
63
|
|
|
64
64
|
## Tools
|
|
@@ -117,8 +117,8 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
|
|
|
117
117
|
- `examples/`: compile-checked typed examples and runnable mock demos (SDK basics, provider registration, auth, tools, [`examples/ag-ui-server.ts`](../examples/ag-ui-server.ts), [`examples/enterprise-identity.ts`](../examples/enterprise-identity.ts), [`examples/enterprise-policy-audit.ts`](../examples/enterprise-policy-audit.ts), [`examples/enterprise-work-connectors.ts`](../examples/enterprise-work-connectors.ts), [`examples/conversation-durable-replay.ts`](../examples/conversation-durable-replay.ts), [`examples/artifact-review-delivery.ts`](../examples/artifact-review-delivery.ts), [`examples/server-deployment-seams.ts`](../examples/server-deployment-seams.ts), cache-aware prompt assembly, NeuralWatt agent run ([`examples/neuralwatt-agent-run.ts`](../examples/neuralwatt-agent-run.ts)), [`examples/coding-compaction.ts`](../examples/coding-compaction.ts), stores/branching, structured-output/artifact-loop, CLI, RPC, workflow orchestration).
|
|
118
118
|
|
|
119
119
|
## Release and install
|
|
120
|
-
- [Release and install](release-and-install.md): current **0.0.
|
|
121
|
-
- [0.1.0 / 1.0 readiness gates](0.1.0-readiness.md): command-per-gate 1.0 readiness table — frozen API surface + compat gate, migration/docs tripwires, budget table, live-suite matrix, security matrix, current-line status (**0.0.
|
|
120
|
+
- [Release and install](release-and-install.md): current **0.0.19** 44-package graph (Phase 2 observational memory lifecycle; plan 002), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates.
|
|
121
|
+
- [0.1.0 / 1.0 readiness gates](0.1.0-readiness.md): command-per-gate 1.0 readiness table — frozen API surface + compat gate, migration/docs tripwires, budget table, live-suite matrix, security matrix, current-line status (**0.0.19** published target), signed-publication/live-canary prerequisites for 1.0, and Phase 12 demand-evidence entry criteria.
|
|
122
122
|
- [Review coverage (2026-07-26 Phase 11)](review-coverage-2026-07-26-phase-11.md): Plan 079 evidence freeze — baseline size/startup/benchmark budgets, hotspot domain extraction table, confirmed duplication survivors (redactor/cleanJson/row-codecs/checkpoints/exec-runner/approval/ownership), profile adoption recommendations, and tarball artifact-diet findings for 0.0.16.
|
|
123
123
|
- [Review coverage (2026-07-26 Phase 10)](review-coverage-2026-07-26-phase-10.md): Plan 078 evidence freeze — OpenAI hosted tools/continuation/realtime, AI SDK version matrix, remaining provider metadata parity, RAG replaceSource/loaders/parsers/reranker/provenance/ingestion-status, memory export/rebuild/conformance, and 0.0.15 (43 → 43 manifests; no new package) release gates.
|
|
124
124
|
- [Review coverage (2026-07-25 Phase 9)](review-coverage-2026-07-25-phase-9.md): Plan 077 evidence freeze — conversation service, memory consent/lifecycle, artifact co-work review, AG-UI co-work events, scoped M365/GWS OAuth, browser checkpoint composition, and deny-by-default device contracts for 0.0.14 (41 → 43 manifests; only the two provider packages are new).
|
package/docs/migration.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Migration guide
|
|
2
2
|
|
|
3
|
+
## 0.0.19 → 0.0.20 skills and context progressive disclosure (small intentional breaks)
|
|
4
|
+
|
|
5
|
+
Release **0.0.20** completes Phase 3 progressive skill disclosure in core `@arnilo/prism`:
|
|
6
|
+
|
|
7
|
+
1. **Default skill prompt is catalog-only.** Active skills render `Skill <name>: <description>` every turn (`skillsDisclosure: "progressive"` default). Full `instructions` appear only after a successful `load_skill` for that session or when the host sets `skillsDisclosure: "eager"`.
|
|
8
|
+
2. **Runtime `SkillRegistry` without activation is empty.** When `AgentConfig.skills` is a `SkillRegistry` and neither `RunOptions.activeSkills` nor `RunOptions.skills` is set, **zero** skills activate (was `SkillRegistry.list()`). Migration: `activateAllSkills: true` on the run or agent restores list-all activation (still subject to disclosure rules). Plain `Skill[]` configs are unchanged.
|
|
9
|
+
3. **`load_skill` is host-opt-in.** Export `createLoadSkillTool({ registry, loaded })` from `@arnilo/prism`; register on the active tool set. Unknown names, inactive required tools, oversize bodies, and duplicate loads fail closed; load cannot widen tools or permissions.
|
|
10
|
+
4. **Context budget honors `ContextBlock.priority`.** Within `context` and `skills` victims, lower priority drops first (missing = 0), then LIFO. Skills with loaded bodies may demote to description-only (`skill_body` omission) before full removal.
|
|
11
|
+
5. **Optional `toolResultFold`.** Off by default; host `summarize` + thresholds fold aged large tool results in provider view only (session store untouched). Summarizer failure keeps raw results.
|
|
12
|
+
|
|
13
|
+
Example: `node examples/skills-progressive-disclosure.ts` (network-free).
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
// Migration for hosts that relied on activate-all registry behavior:
|
|
17
|
+
await session.run("Hi", { activateAllSkills: true });
|
|
18
|
+
|
|
19
|
+
// Migration for hosts that want full bodies every turn without load_skill:
|
|
20
|
+
const agent = createAgent({ model, provider, skills: registry, skillsDisclosure: "eager" });
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Declarative `activateAllCapabilities: true` is unchanged and does **not** set runtime `activateAllSkills`.
|
|
24
|
+
|
|
25
|
+
## 0.0.18 → 0.0.19 observational memory lifecycle (small intentional breaks)
|
|
26
|
+
|
|
27
|
+
Release **0.0.19** completes Phase 2 observational memory in `@arnilo/prism-compaction-observational-memory` only; core `@arnilo/prism` runtime behavior is unchanged.
|
|
28
|
+
|
|
29
|
+
1. **Preferred host path: `createObservationalMemory().attach()`.** Post-run observe/reflect/drop and `compactAfterTokens` compaction run automatically after proxied `run`/`prompt`/`stream`/`compact` (and via `wrapResumeRun` / `wrapResumeStream`). Manual `createObservationalMemoryRuntime().flush()` remains on `attached.runtime` for advanced hosts.
|
|
30
|
+
2. **Nested settings replace flat keys.** Use `observation` / `reflection` / `dropper` / `context` / `retrieval` groups from `resolveObservationalMemorySettings()`. Legacy flat keys still map (`observeAfterTokens` → `observation.messageTokens`, `reflectAfterTokens` → `reflection.observationTokens`, `compactAfterTokens` → `context.compactAfterTokens`, `keepRecentEntries` → `context.recentMessages`, flat `workerModel` → all workers when nested models absent). **Throw** if flat and nested values conflict.
|
|
31
|
+
3. **Separate observer/reflector/dropper models.** Pass per-worker `provider` / `model` / `instruction` / `thinkingLevel` under `observation`, `reflection`, and `dropper`. `dropper.policy: "lowest-relevance"` drops without a model; default is `"model"`.
|
|
32
|
+
4. **Reflection recall reads the full ledger.** Supporting observations dropped from the active pool still resolve in `recallObservationalMemory()` with `dropped` / `missingSourceEntryIds` status instead of being invisible.
|
|
33
|
+
5. **Recall tool adds current-branch paging.** `createRecallMemoryTool()` accepts either `{ id }` or `{ cursor, limit?, direction?, detail? }` (default limit 20, hard cap 100). Both `id` and `cursor` together fail closed.
|
|
34
|
+
6. **Coverage and eligibility fixes.** Observer input is eligible `user`/`assistant`/`tool` messages only; bookkeeping/compaction/custom OM entries advance scan coverage without entering the prompt. Empty observer passes still append `coversUpToId`. Compaction `fullFold` actively trims lowest-relevance observations to hard byte caps.
|
|
35
|
+
|
|
36
|
+
Example: `node examples/observational-memory-lifecycle.ts` (network-free). Live worker canary: `PRISM_LIVE_OBSERVATIONAL_MEMORY_TESTS=1` (Task 7 gate).
|
|
37
|
+
|
|
3
38
|
## 0.0.17 → 0.0.18 restore integrity (small intentional break)
|
|
4
39
|
|
|
5
40
|
Release **0.0.18** removes model-facing regex from `repo_search`:
|
|
@@ -8,7 +8,7 @@ Core package:
|
|
|
8
8
|
|
|
9
9
|
- `@arnilo/prism` — the runtime, contracts, registries, streaming events, CLI (including `prism init`), and the `/docs` hub. `files`: `dist` (with `!dist/__tests__` and `!dist/**/*.map` negations), `docs`, `templates`, `CHANGELOG.md`. `bin`: `prism` -> `dist/cli.js`. `sideEffects`: `["dist/cli.js"]`.
|
|
10
10
|
|
|
11
|
-
First-party workspace packages (each has non-optional `@arnilo/prism@0.0.
|
|
11
|
+
First-party workspace packages (each has non-optional `@arnilo/prism@0.0.20` peer and `sideEffects: false`; RAG also peers on memory, and server also peers on workflows):
|
|
12
12
|
|
|
13
13
|
- `@arnilo/prism-provider-anthropic`, `@arnilo/prism-provider-google`, `@arnilo/prism-provider-openai`, `@arnilo/prism-provider-openrouter`, `@arnilo/prism-provider-kimi`, `@arnilo/prism-provider-zai`, `@arnilo/prism-provider-opencode-go`, `@arnilo/prism-provider-neuralwatt` — provider adapters.
|
|
14
14
|
- `@arnilo/prism-provider-azure`, `@arnilo/prism-provider-bedrock`, `@arnilo/prism-provider-vertex` — optional enterprise-cloud adapters (Entra/IAM/ADC; separate from consumer Anthropic/Google).
|
|
@@ -36,7 +36,7 @@ First-party workspace packages (each has non-optional `@arnilo/prism@0.0.18` pee
|
|
|
36
36
|
|
|
37
37
|
### 0.0.12 AG-UI package boundary
|
|
38
38
|
|
|
39
|
-
`@arnilo/prism-ag-ui` is a publishable optional code package with root AG-UI exports and stable `./acp` sibling, peer `@arnilo/prism@0.0.
|
|
39
|
+
`@arnilo/prism-ag-ui` is a publishable optional code package with root AG-UI exports and stable `./acp` sibling, peer `@arnilo/prism@0.0.20`, pinned `@ag-ui/core@0.0.57` / `@agentclientprotocol/sdk@1.3.0`, and no import-time network/listener/run. It is included by `@arnilo/prism-all` only—not `@arnilo/prism-code` or `@arnilo/prism-sdk`—so coding and SDK profiles stay free of UI protocol dependencies.
|
|
40
40
|
|
|
41
41
|
Family/profile packages (pure manifests, no code or `dist`; ship `README.md` and `CHANGELOG.md`; use exact hard `dependencies`):
|
|
42
42
|
|
|
@@ -78,9 +78,9 @@ Consumers install the core package for the runtime and add first-party packages
|
|
|
78
78
|
| Run the default (network-free) test suite | `npm test` |
|
|
79
79
|
| Dry-run pack core + every package | `npm run pack:dry-run` |
|
|
80
80
|
| Local mirror of the release verify gate | `npm run release:dry-run` |
|
|
81
|
-
| Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.
|
|
82
|
-
| Preview deterministic publish order | `npm run release:publish -- --version 0.0.
|
|
83
|
-
| Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.
|
|
81
|
+
| Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.20` |
|
|
82
|
+
| Preview deterministic publish order | `npm run release:publish -- --version 0.0.20 --dry-run --allow-dirty --allow-untagged` |
|
|
83
|
+
| Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.20 --resume --report release-artifacts/publish-report.json` |
|
|
84
84
|
| Full SDK readiness gate (typecheck + offline tests + pack) | `npm run sdk:ready` |
|
|
85
85
|
|
|
86
86
|
Public core import specifiers (from the root `exports` map):
|
|
@@ -117,7 +117,7 @@ A packed tarball contains only public compiled output and release files:
|
|
|
117
117
|
- Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
|
|
118
118
|
- The core tarball additionally ships the full `docs/` directory (the docs hub) and `templates/init/` used by `prism init`.
|
|
119
119
|
- `dist/cli.js` and the `bin` link in core.
|
|
120
|
-
- **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.
|
|
120
|
+
- **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.20.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.20.tgz` / `arnilo-prism-compaction-<name>-0.0.20.tgz` / `arnilo-prism-coding-agent-0.0.20.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.0.20.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
|
|
121
121
|
|
|
122
122
|
Excluded from every tarball by `files` negation:
|
|
123
123
|
|
|
@@ -136,9 +136,9 @@ Excluded from every tarball by `files` negation:
|
|
|
136
136
|
"name": "host-app",
|
|
137
137
|
"type": "module",
|
|
138
138
|
"dependencies": {
|
|
139
|
-
"@arnilo/prism": "0.0.
|
|
140
|
-
"@arnilo/prism-provider-openai": "0.0.
|
|
141
|
-
"@arnilo/prism-compaction-observational-memory": "0.0.
|
|
139
|
+
"@arnilo/prism": "0.0.20",
|
|
140
|
+
"@arnilo/prism-provider-openai": "0.0.20",
|
|
141
|
+
"@arnilo/prism-compaction-observational-memory": "0.0.20"
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
```
|
|
@@ -181,11 +181,11 @@ For SDK readiness, run the same one-command gate directly. It composes existing
|
|
|
181
181
|
npm run sdk:ready
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
-
Release publication derives all **44** manifests from the workspace once, validates exact `0.0.
|
|
184
|
+
Release publication derives all **44** manifests from the workspace once, validates exact `0.0.20` manifest/lockfile/internal ranges, then uses deterministic dependency order. `release:check` requires a clean commit tagged `v0.0.20` and rejects any existing registry version. `release:publish --resume` skips only registry versions whose internal dependency fingerprint matches the local manifest; conflicting versions fail closed. Each attempted package is written immediately to the JSON report, so a failed job can rerun safely. `--dry-run` performs registry availability checks and invokes `npm publish --dry-run` with explicit public access, provenance, and `latest` tag, but does not publish.
|
|
185
185
|
|
|
186
186
|
```bash
|
|
187
|
-
npm run release:check -- --version 0.0.
|
|
188
|
-
npm run release:publish -- --version 0.0.
|
|
187
|
+
npm run release:check -- --version 0.0.20
|
|
188
|
+
npm run release:publish -- --version 0.0.20 --dry-run --allow-dirty --allow-untagged
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
`--allow-dirty` and `--allow-untagged` exist only for local preview; real publication and CI never pass them. npm registry calls occur only in these release preflight/publication commands, never build/test/package discovery.
|
|
@@ -196,6 +196,48 @@ Optional live smoke tests stay separate from SDK readiness because they require
|
|
|
196
196
|
PRISM_LIVE_PROVIDER_TESTS=1 npm run test --workspaces --if-present
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
+
### 0.0.20 publish handoff
|
|
200
|
+
|
|
201
|
+
**Decision: GO after protected operator prerequisites below.** Release **0.0.20** (Phase 3 skills and context progressive disclosure, plan 003) ships progressive skill catalog assembly (`skillsDisclosure`), session `load_skill`, empty `SkillRegistry` default with `activateAllSkills` migration opt-in, priority-aware context budget demotion, and optional `toolResultFold`. The exact graph stays **44 publishable manifests**; no package added or retired. Intentional pre-1.0 breaks are documented in [migration](migration.md) under `0.0.19 → 0.0.20 skills and context progressive disclosure`.
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
git diff --check
|
|
205
|
+
npm ci
|
|
206
|
+
npm run sdk:ready
|
|
207
|
+
node --test scripts/budget-gate.test.mjs
|
|
208
|
+
node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
|
|
209
|
+
npm audit --audit-level=moderate
|
|
210
|
+
npm run release:gate
|
|
211
|
+
npm run release:check -- --version 0.0.20 --allow-dirty --allow-untagged --report /tmp/prism-0.0.20-preflight.json
|
|
212
|
+
npm run release:publish -- --version 0.0.20 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.20-dry-run.json
|
|
213
|
+
git tag -s v0.0.20 -m "Prism 0.0.20"
|
|
214
|
+
git verify-tag v0.0.20
|
|
215
|
+
git push origin v0.0.20
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The dry-run checks every registry collision and executes npm's non-publishing tarball validation for each dependency-ordered manifest. The protected tag workflow alone publishes through `npm run release:publish -- --version "${GITHUB_REF_NAME#v}" --resume --report release-artifacts/publish-report.json`; re-run a failed job for the same tag. `npm audit signatures --json --include-attestations` and artifact checksums remain post-publish checks.
|
|
219
|
+
|
|
220
|
+
### 0.0.19 publish handoff
|
|
221
|
+
|
|
222
|
+
**Decision: GO after protected operator prerequisites below.** Release **0.0.19** (Phase 2 observational memory lifecycle, plan 002) ships `@arnilo/prism-compaction-observational-memory` attach lifecycle, four-layer provider context, nested settings with legacy map, source-faithful recall/paging, and hard fold/render caps. Core `@arnilo/prism` runtime is unchanged. The exact graph stays **44 publishable manifests**; no package added or retired. Intentional pre-1.0 breaks are documented in [migration](migration.md) under `0.0.18 → 0.0.19 observational memory lifecycle`.
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
git diff --check
|
|
226
|
+
npm ci
|
|
227
|
+
npm run sdk:ready
|
|
228
|
+
node --test scripts/budget-gate.test.mjs
|
|
229
|
+
node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
|
|
230
|
+
npm audit --audit-level=moderate
|
|
231
|
+
npm run release:gate
|
|
232
|
+
npm run release:check -- --version 0.0.19 --allow-dirty --allow-untagged --report /tmp/prism-0.0.19-preflight.json
|
|
233
|
+
npm run release:publish -- --version 0.0.19 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.19-dry-run.json
|
|
234
|
+
git tag -s v0.0.19 -m "Prism 0.0.19"
|
|
235
|
+
git verify-tag v0.0.19
|
|
236
|
+
git push origin v0.0.19
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The dry-run checks every registry collision and executes npm's non-publishing tarball validation for each dependency-ordered manifest. The protected tag workflow alone publishes through `npm run release:publish -- --version "${GITHUB_REF_NAME#v}" --resume --report release-artifacts/publish-report.json`; re-run a failed job for the same tag. `npm audit signatures --json --include-attestations` and artifact checksums remain post-publish checks.
|
|
240
|
+
|
|
199
241
|
### 0.0.18 publish handoff
|
|
200
242
|
|
|
201
243
|
**Decision: GO after protected operator prerequisites below.** Release **0.0.18** (Phase 1 restore integrity, plan 001) hardens coding tools and release trust without adding packages: `repo_search` is literal-only (ReDoS mitigation), default `write`/`edit` use temp+`rename`, `applyContextBudget` evicts oldest history first, default `inputLayout` is `cache_aware`, `@arnilo/prism-mcp` pins `@modelcontextprotocol/sdk` **1.30.0** (clears moderate `@hono/node-server` advisory), and README/readiness docs match the 14-adapter / optional-browser inventory. The exact graph stays **44 publishable manifests**; no package added or retired. Intentional pre-1.0 breaks are documented in [migration](migration.md) under `0.0.17 → 0.0.18 restore integrity`.
|
|
@@ -793,7 +835,7 @@ npm publication is not transactional and published versions are immutable. Parti
|
|
|
793
835
|
|
|
794
836
|
## Extension and configuration notes
|
|
795
837
|
|
|
796
|
-
- **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.
|
|
838
|
+
- **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.20` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.20` for the current 0.x release and will widen to `^1.0.0` at the 1.x stable release. Inside the workspace each package also declares `"@arnilo/prism": "file:../.."` in `devDependencies` so `npm install` resolves the peer locally; that devDependency is stripped from consumer installs and is not a runtime dependency.
|
|
797
839
|
- **Public access.** All 43 manifests (37 code packages + 6 family/profile packages) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
|
|
798
840
|
- **Map retention knob.** Source maps are emitted locally but stripped from tarballs by `!dist/**/*.map`. Removing that `files` negation ships maps in releases (larger tarballs, better consumer stack traces).
|
|
799
841
|
- **Release workflow.** `.github/workflows/release.yml` has six jobs. `verify` runs network-free SDK readiness on Node 24; `node20-compat` builds/imports every public root `exports` default target on Node 20 for declared `engines.node >=20` (docs examples need Node >=22.6 native TypeScript stripping); `postgres-integration` uses `pgvector/pgvector:pg16`; `supply-chain` runs high-severity audit, SPDX/license policy, and tracked-source secret scanning; and tag-only `codeql-release` runs SAST. Tag-only `publish` needs all five gates, preserves clean exact-tag/version/topological publication, and alone receives `NPM_TOKEN`, `id-token: write`, and `attestations: write`. Before npm publish it packs all current tarballs, generates checksums plus SPDX, scans unpacked public artifacts, creates GitHub attestations for tarballs and SBOM, then retains artifacts for 30 days. Registry state remains the resumable journal. Local `npm run release:dry-run` remains network-free SDK readiness; local PostgreSQL coverage is `PRISM_TEST_POSTGRES_URL=... npm run test:postgres`.
|
|
@@ -815,7 +857,7 @@ npm publication is not transactional and published versions are immutable. Parti
|
|
|
815
857
|
- `PRISM_TEST_DOCKER_SANDBOX=1` — gates `@arnilo/prism-coding-security` protected Docker matrix. Requires host-preloaded digest-pinned `PRISM_TEST_DOCKER_IMAGE` and absolute `PRISM_TEST_DOCKER_BIN` (optional `PRISM_TEST_DOCKER_USER`). Prism never pulls/builds the image during default tests. Missing prerequisites fail closed when the gate is enabled; disabled gate skips safely.
|
|
816
858
|
- `PRISM_LIVE_CANARIES=1` — gates `scripts/live-canary.mjs`, used only by scheduled/manual `.github/workflows/live-canaries.yml` in protected `live-canaries` environment. It requires provider endpoint/key/model, MCP endpoint/token, A2A endpoint/token, and Brave token environment entries; performs four probes plus at most one MCP session DELETE; caps provider output at one token, each response at 64 KiB, each request at 15 seconds (30 seconds hard), and emits only aggregate kind/status/code/duration. Disabled gate skips before network; enabled but incomplete configuration fails closed.
|
|
817
859
|
- `PRISM_LIVE_COMPACTION_TESTS=1` — gates `@arnilo/prism-compaction-llm`'s live summary-provider smoke test (placeholder).
|
|
818
|
-
- `PRISM_LIVE_OBSERVATIONAL_MEMORY_TESTS=1` — gates `@arnilo/prism-compaction-observational-memory`'s live
|
|
860
|
+
- `PRISM_LIVE_OBSERVATIONAL_MEMORY_TESTS=1` — gates `@arnilo/prism-compaction-observational-memory`'s live observer/reflector worker canary. Requires `OPENAI_API_KEY`; gate enabled without key fails closed.
|
|
819
861
|
- `PRISM_TEST_POSTGRES_URL` — gates `@arnilo/prism-session-store-postgres` and `@arnilo/prism-memory` integration tests against a real database (memory path requires pgvector). Local: `PRISM_TEST_POSTGRES_URL=... npm run test:postgres`. CI: `postgres-integration` job with `pgvector/pgvector:pg16`.
|
|
820
862
|
- `PRISM_TEST_KEYCHAIN=1` — gates `@arnilo/prism-credentials-node` system-keychain round-trips (requires a working OS keychain backend; skipped by default).
|
|
821
863
|
- Provider live tests read the API key from the env only when both gates are set; the key is used as a bearer token and never logged. `assertNoSecretLeak` verifies the key value does not appear in any streamed event. The compaction placeholders still carry no real credentials.
|