@arnilo/prism 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +23 -2
  2. package/README.md +9 -2
  3. package/dist/agent-loops.d.ts +4 -0
  4. package/dist/agent-loops.js +16 -3
  5. package/dist/artifacts.d.ts +78 -0
  6. package/dist/artifacts.js +24 -0
  7. package/dist/contracts.d.ts +86 -0
  8. package/dist/contracts.js +8 -0
  9. package/dist/conversations.d.ts +50 -0
  10. package/dist/conversations.js +97 -0
  11. package/dist/credentials.d.ts +14 -0
  12. package/dist/credentials.js +9 -0
  13. package/dist/devices.d.ts +94 -0
  14. package/dist/devices.js +138 -0
  15. package/dist/index.d.ts +12 -6
  16. package/dist/index.js +7 -4
  17. package/dist/provider-events.d.ts +1 -0
  18. package/dist/provider-events.js +3 -0
  19. package/dist/providers/openai-primitives.js +5 -2
  20. package/docs/ag-ui.md +5 -0
  21. package/docs/browser-automation.md +3 -0
  22. package/docs/conversations.md +135 -0
  23. package/docs/credential-storage.md +28 -1
  24. package/docs/credentials-and-redaction.md +2 -0
  25. package/docs/database-persistence.md +5 -1
  26. package/docs/device-adapters.md +97 -0
  27. package/docs/host-security.md +7 -2
  28. package/docs/index.md +24 -19
  29. package/docs/migration.md +50 -1
  30. package/docs/multimodal-content.md +8 -5
  31. package/docs/performance.md +36 -0
  32. package/docs/policy-and-audit.md +1 -0
  33. package/docs/provider-caching.md +12 -0
  34. package/docs/provider-conformance.md +29 -5
  35. package/docs/provider-packages.md +26 -2
  36. package/docs/providers/ai-sdk.md +23 -7
  37. package/docs/providers/alibaba.md +179 -0
  38. package/docs/providers/ollama.md +166 -0
  39. package/docs/providers/openai.md +22 -3
  40. package/docs/rag.md +41 -12
  41. package/docs/release-and-install.md +135 -17
  42. package/docs/resource-loading.md +3 -0
  43. package/docs/review-coverage-2026-07-25-phase-9.md +256 -0
  44. package/docs/review-coverage-2026-07-26-phase-10.md +132 -0
  45. package/docs/server.md +4 -0
  46. package/docs/work-artifacts-and-review.md +100 -0
  47. package/docs/work-connectors.md +5 -1
  48. package/docs/work-tools.md +3 -0
  49. package/docs/workflows.md +4 -0
  50. package/docs/working-and-semantic-memory.md +40 -7
  51. package/package.json +1 -1
  52. package/templates/init/providers.json +22 -0
package/docs/workflows.md CHANGED
@@ -18,6 +18,7 @@ Primary exports:
18
18
  | `createWorkflowCommands` | Optional `CommandDefinition[]` for direct/background/replay/status/list/cancel/resume and, when selected, schedule control |
19
19
  | `enqueueWorkflow` / `startWorkflowBackground` / `createWorkflowCoordinator` | Persist queued work and atomically claim/renew/execute it across processes using `LeaseStore` |
20
20
  | `createWorkflowSchedules` | Explicit ownership-scoped one-time/interval/host-calculated schedules over existing checkpoint/lease stores |
21
+ | `createProactiveScheduleCapabilities` | Scoped, expiring, revocable capability tokens that enable proactive schedules; revocation stops firing fail-closed |
21
22
 
22
23
  Included through `@arnilo/prism-sdk` and `@arnilo/prism-all`; installing either profile does not start workflows. Interactive TUI is out of scope (C-012 deferred).
23
24
 
@@ -82,6 +83,8 @@ Every node receives bounded `ctx.state`, `ctx.stateVersion`, and async `ctx.upda
82
83
 
83
84
  `createWorkflowSchedules({ store, leases, checkpoints, workflows, ownership, ownerId, calculators? })` is inert until its host calls `pollOnce()` or `run({ signal })`. Ownership requires `tenantId` plus `accountId` or `userId`. Methods are `create`, `get`, `list`, `pause`, `resume`, `trigger`, `delete`, `pollOnce`, and `run`. A record has one required `nextRunAt`, optional fixed `intervalMs` or registered `calculatorId` (never both), bounded input/metadata, status, version, and last-fire attribution. Manual trigger requires an idempotency key. Scheduled run IDs derive from schedule ID plus fire timestamp, so retry after enqueue-before-advance finds the same queued checkpoint instead of duplicating it. Defaults: page 100/hard 500, due claims 16/hard 256, input 256 KiB/hard 1 MiB, poll 1s, fire lease 30s.
84
85
 
86
+ `createProactiveScheduleCapabilities({ schedules, store, ownership, ownerId, defaultTtlMs?, maxTtlMs?, onCapability? })` wraps a `WorkflowSchedules` facade in explicit user enablement. `enable({ workflowId, scope, actor, nextRunAt, intervalMs?|calculatorId?, input?, ttlMs? })` creates the schedule plus a scoped, expiring `ScheduleCapabilityToken` (default TTL 24h / hard 31d, record ≤ 16 KiB) stamped with redacted actor refs. `revoke(tokenId, actor)` marks the token revoked and pauses the underlying schedule so `pollOnce()` never fires it (fail-closed). `assertActive(tokenId)` is a fail-closed guard for manual trigger paths — it throws on missing/revoked/expired tokens. `onCapability` emits `capability_enabled` / `capability_revoked` / `capability_denied` events (redacted refs only) that hosts bridge to `@arnilo/prism-policy` for an auditable ledger. Tokens are ownership-scoped checkpoint records; no cron expression or secret is persisted.
87
+
85
88
  ## Outputs / response / events
86
89
 
87
90
  `runWorkflow` / `resumeWorkflow` resolve to `WorkflowRunResult`:
@@ -280,6 +283,7 @@ runRpcServer({
280
283
  - Nested workflows inherit host registries/policies and cannot inject broader tools, agents, ownership, or credentials. Nested depth is inherited; child suspension bubbles to the parent review cursor.
281
284
  - Replay source ownership/hash/status/node eligibility are checked before a new checkpoint is created. Source records are immutable, lineage is bounded, and copied approval-bearing paths are rejected.
282
285
  - Schedule services are ownership-scoped and explicitly started. Per-fire leases plus deterministic run IDs/CAS prevent duplicate enqueue across coordinators and crash retry. Host calculator IDs resolve only from the supplied map; no callback or cron expression is persisted.
286
+ - Proactive schedules require an explicit capability grant. Revocation pauses the schedule (never fired by `pollOnce`) and `assertActive` fails closed on missing/revoked/expired tokens; enable/revoke/deny events carry redacted actor refs for the host policy ledger. Capability TTL is capped (default 24h / hard 31d) and the token record is byte-bounded (≤ 16 KiB); tokens are ownership-scoped, so foreign access fails closed rather than leaking existence.
283
287
  - Scheduler stores O(nodes + active outputs + bounded state history); ready-node work uses indegree maps, not repeated full scans.
284
288
  - Lease acquisition is atomic; opaque tokens protect renew/release; monotonically increasing fencing tokens plus checkpoint compare-and-swap prevent expired workers from committing after takeover. Node functions must honor `ctx.signal` for prompt cooperative cancellation.
285
289
 
@@ -23,19 +23,44 @@ Ordinary Prism sessions do not require this package or any vector backend.
23
23
  | `vectorStore` / `workingStore` | no | Defaults to in-memory adapters |
24
24
  | `schema` / `validateWorkingMemory` | no | Working-memory shape checks (JSON Schema subset or host hook) |
25
25
  | `workingMemoryTemplate` | no | `{{path}}` template for context injection |
26
- | `limits` | no | top-K, adjacent range, batch, payload, injected-token caps |
26
+ | `limits` | no | top-K, adjacent range, batch, payload, injected-token, export, and rebuild caps |
27
27
  | `redactor` / `secrets` | no | Redact text/metadata before persist/inject |
28
+ | `requireConsent` | no | Strict mode: recall/injection excludes entries lacking explicit consent |
28
29
 
29
- Semantic indexing:
30
+ Semantic indexing (entries carry `MemoryConsent` source/visibility; unset defaults to `{ source: "user", scope: "thread", visible: true }`):
31
+
32
+ | `MemoryConsent` field | Meaning |
33
+ | --- | --- |
34
+ | `source` | `"user"`, `"agent"`, or `"system"` provenance. |
35
+ | `scope` | `"thread"`, `"profile"`, or `"user"` control scope. |
36
+ | `visible` | `false` immediately excludes the record from recall, injection, export, and telemetry. |
37
+ | `grantedAt` / `revokedAt` | Optional host/audit timestamps; a revocation excludes the record. |
38
+
39
+ ```ts
40
+ await memory.remember({ entries: [{ id, text, metadata?, consent?, sequence? }] }, { wait?: boolean })
41
+ ```
42
+
43
+ Semantic recall (honors consent/visibility at assembly time):
30
44
 
31
45
  ```ts
32
- await memory.remember({ entries: [{ id, text, metadata?, sequence? }] }, { wait?: boolean })
46
+ await memory.recall(query, { topK?, messageRange?, requireConsent?, signal? })
33
47
  ```
34
48
 
35
- Semantic recall:
49
+ Consent + lifecycle (real grant/correct/delete/retention on stored entries):
36
50
 
37
51
  ```ts
38
- await memory.recall(query, { topK?, messageRange?, signal? })
52
+ await memory.setConsent(entryId, { visible?: boolean, source?, scope? }) // grant/revoke; no re-embed
53
+ await memory.correct(entryId, text) // re-embeds, preserves consent
54
+ await memory.forget({ ids? }) // real delete (whole thread if no ids)
55
+ await memory.applyRetention({ maxAgeDays?, maxEntries?, batchSize? }) // bounded real-delete sweep
56
+
57
+ const page = await memory.exportMemory({
58
+ identity: { tenantId, resourceId, threadId }, // exact host-verified owner
59
+ cursor?, limit?, maxBytes?, maxMs?, signal?,
60
+ }); // visible, explicitly consented, redacted records only
61
+
62
+ const rebuilt = await memory.rebuildIndex({ cursor?, batchSize?, maxMs?, signal? });
63
+ // re-embeds one page; save rebuilt.nextCursor and call again to resume
39
64
  ```
40
65
 
41
66
  ## Outputs / response / events
@@ -44,7 +69,12 @@ await memory.recall(query, { topK?, messageRange?, signal? })
44
69
  | --- | --- |
45
70
  | `updateWorking` / `getWorking` | Versioned `WorkingMemoryRecord` |
46
71
  | `remember` | `{ accepted, pending, done }` — default `wait: false` indexes asynchronously |
47
- | `recall` | `{ hits, adjacent }` tenant/thread scoped |
72
+ | `recall` | `{ hits, adjacent }` tenant/thread scoped; invisible/revoked entries excluded |
73
+ | `setConsent` / `correct` | Updated `MemoryVectorRecord` with stamped grant/revoke times |
74
+ | `forget` | Removed count (real delete) |
75
+ | `applyRetention` | `{ deleted, scanned }` bounded real-delete sweep |
76
+ | `exportMemory` | `{ entries, bytes, nextCursor? }` redacted, explicitly consented, identity-bound page |
77
+ | `rebuildIndex` | `{ rebuilt, nextCursor? }` re-embedded bounded page; caller owns resume scheduling |
48
78
  | `createContextProvider()` | Inert `ContextProvider` blocks for working and/or semantic text |
49
79
  | `createWorkingMemoryProcessor({ extract })` | Explicit host-invoked updater; never auto-runs |
50
80
 
@@ -131,6 +161,8 @@ const memory = createMemory({
131
161
  - The working-memory processor is opt-in and host-invoked; middleware is not required.
132
162
  - `createHashEmbedder()` is for tests/demos only; production hosts supply a real `Embedder`.
133
163
  - Observational memory (`@arnilo/prism-compaction-observational-memory`) remains unchanged and composable.
164
+ - Consent is enforced at the single `recall()` gate, so both direct recall and `createContextProvider()` injection honor it; `visible: false` (or a revoked grant) keeps an entry out of prompts, events, exports, and telemetry. `setConsent`/`correct` re-upsert in place (consent change does not re-embed); `forget`/`applyRetention` are real deletes, not tombstones. Retention uses indexed oldest-first pages plus a scoped count, deleting one default-500/hard-5000 batch without reading a corpus into memory. The PostgreSQL adapter persists consent in a `consent JSONB` column added by `buildMemoryDdl`.
165
+ - `exportMemory()` requires an exact `{ tenantId, resourceId, threadId }` identity equal to its `createMemory()` scope. It excludes legacy consent-less, invisible, and revoked records even when normal recall allows legacy entries. It returns a stable sequence cursor page, redacted before response, with defaults/hard caps of 100/200 entries, 4/32 MiB, and 10/60 seconds. `rebuildIndex()` uses the same stable cursor shape to re-embed one 32/128-record page under a 10/60-second cap; save the cursor durably to resume. Both APIs require a store implementing bounded `listByThread()`; retention also requires `countByThread()`. PostgreSQL/pgvector and the in-memory reference adapter conform; SQLite persistence stores sessions, not semantic vectors.
134
166
  - Profile bundles do not include this package yet.
135
167
 
136
168
  Shared conformance:
@@ -149,10 +181,11 @@ await runMemoryConformance(() => ({
149
181
 
150
182
  - Every write/query/delete requires `tenantId` + `resourceId`; semantic paths also require `threadId`.
151
183
  - Cross-tenant and cross-thread access is denied.
184
+ - Revoked/invisible/non-consented memories never enter prompts, events, exports, or telemetry; `requireConsent: true` additionally drops consent-less (legacy) entries. Consent checks are O(hits) at recall, within the existing injected-token cap.
152
185
  - Configure `secrets` / `redactor` so memory text and metadata cannot persist or inject raw canaries.
153
186
  - Injected context is inert text — it cannot grant tools or permissions.
154
187
  - Hard caps: top-K ≤ 32, messageRange ≤ 4, embed batch ≤ 128, injected tokens ≤ 8000, payload/working-memory byte limits enforced.
155
- - Every embedding is a non-empty finite number vector. `embedBatched()`, in-memory `VectorStore` upserts/queries, and PostgreSQL/pgvector parameters reject NaN, ±Infinity, non-numbers, and wrong configured dimensions before similarity scoring or SQL. Custom adapters can call `assertFiniteVector(vector, label, expectedLength?)` at their trust boundary.
188
+ - Every embedding is a non-empty finite number vector. `embedBatched()`, in-memory `VectorStore` upserts/queries, PostgreSQL/pgvector parameters, and export/rebuild page boundaries reject NaN, ±Infinity, non-numbers, and wrong configured dimensions before similarity scoring, SQL, response, or re-indexing. Custom adapters can call `assertFiniteVector(vector, label, expectedLength?)` at their trust boundary.
156
189
  - Default `remember()` does not block agent completion; pass `{ wait: true }` when indexing must finish first.
157
190
  - PostgreSQL live suite is gated by `PRISM_TEST_POSTGRES_URL` and requires the `vector` extension.
158
191
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -72,5 +72,27 @@
72
72
  "imports": "import { createAgent } from \"@arnilo/prism\";\nimport {\n createNeuralWattProvider,\n defineNeuralWattModel,\n} from \"@arnilo/prism-provider-neuralwatt\";",
73
73
  "providerExpression": "createNeuralWattProvider({\n apiKey: () => process.env.NEURALWATT_API_KEY,\n })",
74
74
  "modelExpression": "defineNeuralWattModel({\n model: \"glm-5.2\",\n cache: { kind: \"implicit\" },\n })"
75
+ },
76
+ "alibaba": {
77
+ "id": "alibaba",
78
+ "packageName": "@arnilo/prism-provider-alibaba",
79
+ "envKey": "DASHSCOPE_API_KEY",
80
+ "envPlaceholder": "sk-...",
81
+ "modelProvider": "alibaba",
82
+ "modelName": "qwen-plus",
83
+ "imports": "import { createAgent } from \"@arnilo/prism\";\nimport {\n createAlibabaProvider,\n defineAlibabaModel,\n} from \"@arnilo/prism-provider-alibaba\";",
84
+ "providerExpression": "createAlibabaProvider({\n apiKey: () => process.env.DASHSCOPE_API_KEY,\n })",
85
+ "modelExpression": "defineAlibabaModel({ model: \"qwen-plus\" })"
86
+ },
87
+ "ollama": {
88
+ "id": "ollama",
89
+ "packageName": "@arnilo/prism-provider-ollama",
90
+ "envKey": "OLLAMA_API_KEY",
91
+ "envPlaceholder": "your-ollama-api-key",
92
+ "modelProvider": "ollama",
93
+ "modelName": "gpt-oss:20b",
94
+ "imports": "import { createAgent } from \"@arnilo/prism\";\nimport {\n createOllamaProvider,\n defineOllamaModel,\n} from \"@arnilo/prism-provider-ollama\";",
95
+ "providerExpression": "createOllamaProvider({\n apiKey: () => process.env.OLLAMA_API_KEY,\n })",
96
+ "modelExpression": "defineOllamaModel({ model: \"gpt-oss:20b\" })"
75
97
  }
76
98
  }