@arnilo/prism 0.0.23 → 0.0.25
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 +39 -3
- package/dist/agent-event-source.d.ts +11 -0
- package/dist/agent-event-source.js +512 -0
- package/dist/agent-loops.js +37 -5
- package/dist/agent-run-state.d.ts +27 -1
- package/dist/agent-run-state.js +86 -5
- package/dist/agents.js +890 -78
- package/dist/contracts.d.ts +338 -4
- package/dist/contracts.js +53 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +5 -2
- package/dist/testing/agent-event-source-conformance.d.ts +4 -0
- package/dist/testing/agent-event-source-conformance.js +54 -0
- package/dist/testing/persistence-schema.d.ts +2 -2
- package/dist/testing/persistence-schema.js +58 -21
- package/dist/testing/tool-effect-store-conformance.d.ts +9 -0
- package/dist/testing/tool-effect-store-conformance.js +85 -0
- package/dist/tool-effects.d.ts +15 -0
- package/dist/tool-effects.js +338 -0
- package/dist/tools.d.ts +4 -1
- package/dist/tools.js +219 -9
- package/docs/0.1.0-readiness.md +10 -9
- package/docs/a2a.md +6 -2
- package/docs/ag-ui-adoption.md +77 -0
- package/docs/ag-ui.md +77 -42
- package/docs/agent-events.md +5 -1
- package/docs/agent-loops.md +9 -1
- package/docs/agent-session-runtime.md +9 -2
- package/docs/browser-automation.md +2 -0
- package/docs/coding-agent-tools.md +2 -0
- package/docs/coding-security.md +1 -1
- package/docs/database-persistence.md +2 -0
- package/docs/enterprise-postgres-state.md +5 -1
- package/docs/host-security.md +8 -1
- package/docs/index.md +13 -11
- package/docs/mcp-tools.md +19 -2
- package/docs/migration.md +46 -0
- package/docs/performance.md +25 -0
- package/docs/postgres-persistence.md +5 -2
- package/docs/public-contracts.md +2 -0
- package/docs/release-and-install.md +70 -690
- package/docs/server.md +10 -6
- package/docs/sqlite-persistence.md +10 -2
- package/docs/supervisors.md +6 -0
- package/docs/tool-effects.md +95 -0
- package/docs/tools.md +4 -0
- package/docs/work-tools.md +4 -0
- package/docs/workflows.md +1 -1
- package/package.json +11 -3
package/docs/migration.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Migration guide
|
|
2
2
|
|
|
3
|
+
## 0.0.24 → 0.0.25 durable custom loops and human-in-the-loop (intentional pre-1.0 contract changes)
|
|
4
|
+
|
|
5
|
+
Release **0.0.25** makes custom loops durable and replaces sequential binary approvals with one shared pending-decision model. Protocol adapters (AG-UI, ACP, MCP, coding `ask_user_decision`, server resume, supervisor nesting) map onto that model. Opt-in A2UI painting and standard AG-UI projectors ship in `@arnilo/prism-ag-ui`. Publishable graph stays **47** manifests.
|
|
6
|
+
|
|
7
|
+
1. **Custom loops on durable runs need hooks.** Built-in `single-shot` / `generate-validate-revise` stay durable. A custom `AgentLoopStrategy` on `runState` must expose `snapshot` + `restore` (and usually `revision`) or the run fails closed with `AgentLoopStateError` / `ERR_PRISM_LOOP_NOT_DURABLE` before any provider call. Snapshots must be JSON-compatible and fit the run-state byte/depth caps (`ERR_PRISM_LOOP_SNAPSHOT`).
|
|
8
|
+
2. **Fingerprint loop entry shape changed.** Durable fingerprints now store `{ name, revision }` instead of a bare loop name string. Persisted **0.0.24** runs fail closed on **0.0.25** resume (fingerprint mismatch / `ERR_PRISM_LOOP_REVISION`). Finish or abandon in-flight 0.0.24 durable runs before upgrading, or rebuild from a fresh suspension under 0.0.25.
|
|
9
|
+
3. **Batch resume.** `AgentRunResume` accepts either legacy `{ decision: "approve" | "deny" }` or `{ decisions: RunDecision[] }` — exactly one. Outcomes: `allow_once` / `allow_for_run` / `reject_once` / `reject_for_run`, optional `reason`, `modifiedArguments`, `elicitation`. One CAS transition applies the whole batch; partial batches re-suspend with remaining pendings. Sticky decisions expire at run end and match exact scope (tool/effect/identity/arguments hash + nested attribution path).
|
|
10
|
+
4. **Elicitation.** Tools may declare an `elicitation` hook; coding `ask_user_decision` uses it on durable gates. MCP hosts use `mcpElicitationDecision` / `mcpElicitationResultFromDecision` with required `humanInteraction: true` on accept.
|
|
11
|
+
5. **Nested approvals.** Supervisors with `checkpoints` + `definitionRevision` surface child approvals to the root as hashed attributed ids; `resumeNestedRun` routes decisions without widening child permission. Root sticky decisions are path-scoped.
|
|
12
|
+
6. **AG-UI / ACP / server.** Interrupts carry redacted `pendingDecisions` in metadata; resume may return a batch. ACP permission offers four outcomes (`allow_always` → `allow_for_run`, `reject_always` → `reject_for_run`); cancelled stays terminal deny. Server `/resume` validates the same shapes at the boundary.
|
|
13
|
+
7. **Opt-in generative UI.** `createAgUiHandler({ a2ui })` paints A2UI v0.9 surfaces; A2UI actions return through existing `input.project` (not an automatic tool loopback). Standard projectors (`createMessagesFromSessionProjection`, `createStateFromStoreProjection`, `createActivityFromToolProgressProjection`, `composeAgUiProjections`) are explicit opt-in.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
await resumeAgentRun(checkpoints, {
|
|
17
|
+
runId,
|
|
18
|
+
decisions: [
|
|
19
|
+
{ approvalId: "a1", outcome: "allow_for_run" },
|
|
20
|
+
{ approvalId: "a2", outcome: "reject_once", reason: "external recipient" },
|
|
21
|
+
],
|
|
22
|
+
}, { ownership, expectedVersion });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Examples: `node examples/durable-loops-and-approvals.ts`, `node examples/ag-ui-a2ui.ts`. Hosts that never set `runState` / interrupt gates keep prior behavior aside from the fingerprint shape for any already-persisted durable runs.
|
|
26
|
+
|
|
27
|
+
## 0.0.23 → 0.0.24 distributed events and recoverable tool effects (intentional pre-1.0 contract changes)
|
|
28
|
+
|
|
29
|
+
Release **0.0.24** adds a replaceable durable `AgentEventSource`, recoverable `ToolEffectStore`, full AG-UI 0.0.57 compatibility, and AG-UI fronting for MCP / MCP Apps / remote A2A. Core remains dependency-free; PostgreSQL adapters and effect stores stay opt-in. Delivery is at-least-once with consumer deduplication — not exactly-once.
|
|
30
|
+
|
|
31
|
+
1. **Open persistence for durable events.** `createPostgresPersistence({ pool, eventCursorSecret })` exposes `persistence.events` (`AgentEventSource`). Migration **006** adds `prism_agent_event_streams`; migration **007** adds the exact-owner retention index. Share one HMAC `eventCursorSecret` across replicas. SQLite gains sequence compatibility only (no distributed subscribe). Backup before upgrade; rollback restores both session-store and enterprise migration histories.
|
|
32
|
+
2. **Reconnect through the shared source.** Prefer `events.subscribe({ ownership, sessionId, runId, after })` or transport cursors (`Last-Event-ID` / `?cursor=` / A2A `afterEventId` Prism extension). Live `session.subscribe()` remains process-local. Consumers must dedupe `record.id`; sticky sessions are optional.
|
|
33
|
+
3. **Opt into tool effects.** Pass `effectStore` on the agent/run. Declare `tool.effect` (`kind` + `idempotency`). Core derives `idempotencyKey` — model keys are ignored. Required effects without a store fail closed. Ambiguous post-dispatch outcomes become `unknown` and need `resolveUnknown`; they never auto-replay.
|
|
34
|
+
4. **Enterprise tool effects.** `createPostgresEnterpriseState` applies enterprise migration **002** (`prism_tool_effects`) and exposes `state.toolEffects`. Cleanup remains host-scheduled via `state.cleanup`.
|
|
35
|
+
5. **Package adapters.** Coding/browser/work/MCP/supervisor tools ship effect declarations or host policies. Work mutations require the core key + store. MCP defaults remote tools to unsupported unless the host policy classifies them.
|
|
36
|
+
6. **AG-UI.** Handler accepts full RunAgentInput with host `input.project` / `frontendTools` / interrupt resume; optional `mcp` / `a2a` adapters. Direct Prism MCP/A2A APIs remain independent.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const persistence = await createPostgresPersistence({ pool, eventCursorSecret: secret });
|
|
40
|
+
const enterprise = await createPostgresEnterpriseState({ pool });
|
|
41
|
+
const agent = createAgent({ model, provider, tools, runLedger: persistence, effectStore: enterprise.toolEffects });
|
|
42
|
+
for await (const { record, cursor } of persistence.events.subscribe({ ownership, sessionId, runId, after })) {
|
|
43
|
+
save(cursor); // dedupe record.id; reconnect never reruns completed effects
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Example: `node examples/distributed-events-and-tool-effects.ts` (network-free memory reference). Hosts that never open an event source or effect store keep prior behavior.
|
|
48
|
+
|
|
3
49
|
## 0.0.22 → 0.0.23 production enterprise state adapters (intentional pre-1.0 contract changes)
|
|
4
50
|
|
|
5
51
|
Release **0.0.23** adds `@arnilo/prism-enterprise-postgres` and makes work-mutation idempotency plus durable model-router state explicit. Core agent/session behavior stays unchanged; install/configure this package only when a host needs PostgreSQL coordination.
|
package/docs/performance.md
CHANGED
|
@@ -6,6 +6,31 @@ Evaluation defaults are finite: 100 trace rows × 20 pages and 4 MiB aggregate t
|
|
|
6
6
|
|
|
7
7
|
This page states Prism runtime limits that keep slow consumers and long sessions from becoming unbounded memory or latency problems.
|
|
8
8
|
|
|
9
|
+
## Release 0.0.25 durable loops and human-in-the-loop
|
|
10
|
+
|
|
11
|
+
`node scripts/benchmark-0.0.25.mjs` is network-free (in-memory checkpoint store). Checked `scripts/benchmark-0.0.25.json` (Node v24.18.0/Linux x64): 20 warmups, 100 measured ops, 32 pending decisions, ~250 KiB snapshot, 64 A2UI ops/message.
|
|
12
|
+
|
|
13
|
+
| Scenario | Recorded p95 ms | Ceiling |
|
|
14
|
+
| --- | ---: | ---: |
|
|
15
|
+
| Decision apply (batch CAS) | 3.913 | 5 |
|
|
16
|
+
| Sticky match | 0.407 | 5 |
|
|
17
|
+
| Snapshot capture/restore | 6.742 | 20 |
|
|
18
|
+
| A2UI paint | 0.348 | 10 |
|
|
19
|
+
|
|
20
|
+
Conformance: `scripts/phase8-conformance.test.mjs` (8 network-free cases). Values are environment evidence, not universal SLOs.
|
|
21
|
+
|
|
22
|
+
## Release 0.0.24 distributed events and tool effects
|
|
23
|
+
|
|
24
|
+
`node scripts/benchmark-0.0.24.mjs` is an explicit protected PostgreSQL benchmark behind `PRISM_TEST_POSTGRES_URL`. Checked `scripts/benchmark-0.0.24.json` (Node v24.18.0/Linux x64, PostgreSQL 16.14): 10 tenants × 10 principals × 1,000 events/owner, 16 producers/subscribers, 100 warmups, 1,000 measured ops, 10,000-event sustained replay, 100-row cleanup.
|
|
25
|
+
|
|
26
|
+
| Scenario | Recorded p95 ms | Ceiling |
|
|
27
|
+
| --- | ---: | ---: |
|
|
28
|
+
| Event append / page | 1.502 / 3.103 | 50 / 100 |
|
|
29
|
+
| Effect claim+transition / cleanup | 3.084 / 3.242 | 50 / 100 |
|
|
30
|
+
| Event cleanup / reconnect catch-up | 1.370 / 7.883 | 100 / 2000 |
|
|
31
|
+
|
|
32
|
+
Sustained replay delivered 160,000 subscriber-events at 101.34 events/s. Five `EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)` plans used named indexes with no sequential scans. Process conformance (`scripts/phase7-conformance.test.mjs`) covers 16-process producers, `LISTEN` backend kill + poll catch-up, and pending/dispatched effect crash windows. Values are environment evidence, not universal SLOs.
|
|
33
|
+
|
|
9
34
|
## Release 0.0.23 enterprise PostgreSQL evidence
|
|
10
35
|
|
|
11
36
|
`node scripts/benchmark-0.0.23.mjs` is an explicit protected PostgreSQL benchmark, not part of `npm test` or `sdk:ready`. It requires `PRISM_TEST_POSTGRES_URL`, creates/drops an isolated schema, and checks frozen p95 ceilings from `scripts/budgets.json`. The checked `scripts/benchmark-0.0.23.json` evidence was recorded on Node v24.18.0/Linux x64 with `postgres:16-alpine`: 10 tenants × 10 principals × 1,000 policy/evaluation rows, 10,000 router keys, 16 pool clients, 100 warmups, 1,000 measured operations, and 100-row cleanup batches.
|
|
@@ -40,6 +40,8 @@ import { createPostgresPersistence } from "@arnilo/prism-session-store-postgres"
|
|
|
40
40
|
| `schema` | `string` | PostgreSQL schema for Prism tables. Defaults to `"prism"`. Validated and double-quoted. |
|
|
41
41
|
| `poolMax` | `number` | Maximum pool size for adapter-owned pools. Defaults to `10`. |
|
|
42
42
|
| `feedbackRedactor` | `SecretRedactor` | Optional redaction for feedback comment/tags/metadata before insert. |
|
|
43
|
+
| `eventSource` | `AgentEventSourceOptions` | Bounds durable event pages, subscribers, polling, reconnects, and cleanup. |
|
|
44
|
+
| `eventCursorSecret` | `string \| Uint8Array` | Stable HMAC secret shared by replicas that resume durable event cursors. |
|
|
43
45
|
| `poolConfig` | `PoolConfig` | Additional `pg` options (TLS, idle timeout, application name, etc.). |
|
|
44
46
|
|
|
45
47
|
Hosts own TLS (`ssl` in `poolConfig`), credentials, connection limits, and backup/retention enforcement.
|
|
@@ -54,12 +56,13 @@ Hosts own TLS (`ssl` in `poolConfig`), credentials, connection limits, and backu
|
|
|
54
56
|
| `SessionStore.list` / `get` | Indexed reads by `session_id` and primary key. |
|
|
55
57
|
| `SessionStore.readBranchPath` | Recursive ancestor query from `leafId` (or latest leaf) in root→leaf order. |
|
|
56
58
|
| `RunLedger.append*` | Inserts run/event/tool/usage rows; events receive monotonic per-run `sequence` values. |
|
|
59
|
+
| `events` | Durable `AgentEventSource`; `LISTEN`/`NOTIFY` only wakes exact owned indexed reads, while polling remains recovery fallback. |
|
|
57
60
|
| `ProductionPersistenceStore.query*` | Parameterized cursor pagination on indexed columns with tenant/account/user filters. |
|
|
58
61
|
| `checkpoints` | Generic versioned `CheckpointStore` backed by `prism_checkpoints`; ownership, CAS/fencing checks, bounded pagination, and workflow suspended/denied/schedule/state/replay values without a schema migration. |
|
|
59
62
|
| `leases` | Atomic `LeaseStore` backed by `prism_leases`; database-clock expiry, opaque renew/release token, monotonic takeover fence. |
|
|
60
63
|
| `close()` | Ends the pool when the adapter created it from `connectionString`. |
|
|
61
64
|
|
|
62
|
-
Migrations run automatically on open and are idempotent across reopen. Concurrent setup uses per-schema advisory transaction locks. While holding that lock, startup verifies ordered contract name/version/SHA-256 rows and full schema-
|
|
65
|
+
Migrations run automatically on open and are idempotent across reopen. Concurrent setup uses per-schema advisory transaction locks. While holding that lock, startup verifies ordered contract name/version/SHA-256 rows and full schema-v7 `information_schema`/catalog shape (all required tables, columns/types/nullability/defaults, PK/unique/FK keys, and named indexes) before any runtime write. A complete legacy 0.0.5 history with all `checksum` values `NULL` is shape-verified then backfilled transactionally once. Unknown, duplicate, out-of-order, partial-legacy, checksum, or shape drift rejects open; restore or apply reviewed DDL rather than editing migration rows.
|
|
63
66
|
|
|
64
67
|
## Request/response example
|
|
65
68
|
|
|
@@ -116,7 +119,7 @@ PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres --workspace @arnil
|
|
|
116
119
|
- The package is optional and workspace-local; `@arnilo/prism` core has no PostgreSQL dependency.
|
|
117
120
|
- Schema names must match `^[a-zA-Z_][a-zA-Z0-9_]*$`; the adapter quotes them and never interpolates user values into identifier positions.
|
|
118
121
|
- `SessionAppendOptions` idempotency rows are durable in `prism_session_append_idempotency` and survive reopen.
|
|
119
|
-
- Schema version **
|
|
122
|
+
- Schema version **6** applies `001_init`, `002_usage_scope`, `003_run_feedback`, `004_session_search`, `005_lifecycle_hold_quota`, and `006_agent_event_source`. Migration 006 backfills `prism_agent_event_streams`, then replaces the former non-unique run sequence index with unique `(run_id, sequence)` allocation enforced in the event append transaction. `LISTEN` registration commits before initial catch-up; notifications carry only a constant wake token, so dropped/coalesced notifications affect latency rather than delivery. Migration 003 adds immutable `prism_run_feedback` rows with run FK/cascade deletion and owner/run/trace cursor indexes. Migration 004 adds session search FTS (Postgres `tsvector` FTS table dual-written on append) plus `prism_sessions(updated_at, id)` cursor index; existing entries are backfilled once. `persistence.feedback` validates exact run ownership, bounds/redacts through optional `feedbackRedactor`, queries bounded pages, and deletes only exact-owned IDs. Search hits never include credentials; ownership filters apply when present. SQLite shares sequence compatibility only; it does not provide distributed subscriptions.
|
|
120
123
|
- Pass an existing `pg` `Pool` when your host already manages pooling, TLS, and credential rotation.
|
|
121
124
|
|
|
122
125
|
## Security and performance notes
|
package/docs/public-contracts.md
CHANGED
|
@@ -429,6 +429,8 @@ void credentials;
|
|
|
429
429
|
- `createAgent()` and `createAgentSession()` implement the session runtime. They use explicit providers only; no hidden provider registry is created. Store-backed sessions use explicit `SessionStore` values and branch methods on `AgentSession`. `AgentSession.compact()` and `AgentConfig`/`RunOptions.compaction` provide manual and opt-in auto-compaction. `AgentConfig`/`RunOptions.retry` provide bounded provider-turn retry before observable output.
|
|
430
430
|
- `createMemorySessionStore()` is the built-in in-memory `SessionStore`. Node hosts can opt into file durability with `@arnilo/prism/node/session-store-jsonl`. `createSessionEntry()`, `getSessionBranchEntries()`, `listSessionBranches()`, and `rebuildSessionContext()` are pure helpers for branch-aware session entries. `rebuildSessionContext()` understands compaction entries produced by `createDefaultCompactionStrategy()`, reducing provider-context messages while keeping raw entries. They do not read files or call providers.
|
|
431
431
|
|
|
432
|
+
Phase 7 contracts: `AgentEventSource`, `ToolEffectDeclaration`/`ToolEffectStore`, and related error codes. Opt-in only; hosts without stores keep prior dispatch behavior.
|
|
433
|
+
|
|
432
434
|
## Security and performance notes
|
|
433
435
|
|
|
434
436
|
- Type-only imports have no runtime side effects.
|