@godspeedai/cognate-runtime-bun 0.1.1 → 0.1.2

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 (2) hide show
  1. package/README.md +158 -38
  2. package/package.json +12 -12
package/README.md CHANGED
@@ -1,40 +1,160 @@
1
1
  # @godspeedai/cognate-runtime-bun
2
2
 
3
- Bun reference runtime implementing `RuntimeService` (ADR-0011) in-process.
4
-
5
- ## Architecture
6
- - `runtime.ts` composes: SQLite store (or a supplied `DurableStore`), Cordis kernel with mounted components,
7
- `ContinuationService`, `ArtifactService`, `ProjectionRunner`s (user projections + cognitive indexer), background loop.
8
- - `service.ts` authorizes (`actions` policy), enforces tenancy (other tenants see `not_found`), maps typed errors.
9
- - `executor.ts` runs agents by replay; `fold.ts` derives `RunView` from the run stream; `inspect.ts` rebuilds causal chains.
10
- - `invoker.ts` wraps the kernel policy (AsyncLocalStorage) to pass the caller tenant and capture each decision.
11
-
12
- ## Run model
13
- A run is stream `run-<id>`: `run.started` (input in payload; agent/startedBy in metadata) → recorded steps →
14
- `run.completed | run.failed | run.cancelled`. Each event's `causationId` is the previous run event. A `runs`
15
- record holds ids only; views are folds over events, so erased payloads vanish from `getRun`.
16
-
17
- ## Replay rules
18
- Every execution re-reads the stream and re-enters the agent from the top. Calls get deterministic step ids
19
- (`step:<id>`, `emit:<n>`, `invoke:<n>`, `artifact:<n>`, `recall:<id>`, `wait:<id>`) kept in event metadata; a
20
- recorded result is returned instead of re-executing. `waitFor` opens continuation `<runId>.wait.<id>` (handler
21
- `run.resume@1`), records `run.waiting`, and suspends; re-entry records `run.resumed` (returns input) or
22
- `run.wait.closed` (throws `ContinuationClosedError`). Appends are CAS on the stream version; losing a race
23
- (e.g. to `cancelRun`) re-runs the replay, which then sees the terminal state.
24
-
25
- ## Background loop
26
- Every `tickMs` (and on kicks): expire due continuations, deliver `continuation.resume` (handler re-executes the
27
- run), drain `run.execute` outbox intents (committed with `run.started`), re-enter queued runs. Executions of one
28
- run are serialized. `idle()` polls until no tick, execution, available outbox item, or projection lag remains.
29
-
30
- ## Limits
31
- - Single process, single writer; executions within a tick run sequentially (a slow agent delays others).
32
- - Polling loop (default 10 ms), including `expireDue` scans over open continuations.
33
- - Kernel is single-tenant; the tenant reaches `Policy` via the invoker wrapper only.
34
- - Continuation records/idempotency snapshots and `run.recall` results hold copies of content that
35
- erasing run events does not remove.
36
- - Default cognition indexes run output only.
37
- - Public projections must key state `<tenant>/<key>`; `readProjection` returns only the caller's prefix
38
- (stripped, key order), `[]` for an empty partition, `not_found` for unknown names.
39
- - Denied artifacts return `not_found` deliberately, hiding whether the artifact exists (spec §32).
40
- - Steps are at-least-once: a step running at a crash re-executes on restart; put external effects in `CommitmentService`.
3
+ The Cognate reference runtime for Bun: durable agent runs, human-in-the-loop continuations,
4
+ artifacts, projections, and optional cognition, composed in-process behind a single
5
+ `RuntimeService`. Point it at a SQLite file and your application's history survives restarts.
6
+
7
+ **When to use this package:** to run agents for real — in a server, a worker, or a script. Pair it
8
+ with [`@godspeedai/cognate-client`](https://www.npmjs.com/package/@godspeedai/cognate-client) to
9
+ consume it from the same process, or with a transport adapter to serve it over the network.
10
+
11
+ ## Installation
12
+
13
+ ```sh
14
+ bun add @godspeedai/cognate-runtime-bun
15
+ ```
16
+
17
+ Requires [Bun](https://bun.sh) >= 1.4.0 (the default store uses Bun's built-in `bun:sqlite`).
18
+
19
+ ## Quick start
20
+
21
+ ```ts
22
+ import { createRuntime } from "@godspeedai/cognate-runtime-bun";
23
+ import type { AgentDefinition } from "@godspeedai/cognate-runtime-api";
24
+
25
+ const agent: AgentDefinition = {
26
+ id: "agent.order",
27
+ version: "1.0.0",
28
+ async run(_input, ctx) {
29
+ // Shared state: a snapshot, then JSON Patch deltas — clients derive the same state.
30
+ await ctx.emit("state.changed", { snapshot: { order: { id: "o-1", status: "open", total: 0 } } });
31
+ await ctx.emit("state.changed", { patch: [{ op: "replace", path: "/order/status", value: "paid" }] });
32
+ await ctx.emit("state.changed", { patch: [{ op: "replace", path: "/order/total", value: 42 }] });
33
+ return { done: true };
34
+ },
35
+ };
36
+
37
+ const caller = { actor: { id: "alice", kind: "user" }, tenant: "tenant-a" } as const;
38
+
39
+ const runtime = await createRuntime({
40
+ store: "./app.sqlite", // a durable file; use ":memory:" for an ephemeral runtime
41
+ // policy authorizes capability invocations; actions authorizes run/continuation actions.
42
+ policy: { authorize: () => ({ allow: true, policyId: "p", reason: "allowed" }) },
43
+ actions: { authorize: () => ({ allow: true, reason: "allowed" }) },
44
+ agents: [agent],
45
+ });
46
+
47
+ const started = await runtime.service.startRun(caller, {
48
+ agent: "agent.order",
49
+ input: {},
50
+ idempotencyKey: "order-1", // repeating the key returns the same run, never a duplicate
51
+ });
52
+
53
+ await runtime.idle(); // background work queued so far has been processed
54
+
55
+ const run = await runtime.service.getRun(caller, { runId: started.runId });
56
+ console.log(run.status, run.output); // completed { done: true }
57
+
58
+ await runtime.close();
59
+ ```
60
+
61
+ ## Suspending on a durable continuation
62
+
63
+ `ctx.waitFor` suspends the run until someone resolves the continuation it opens. The run's progress
64
+ is durable: it can sit waiting through restarts.
65
+
66
+ ```ts
67
+ const refundAgent: AgentDefinition = {
68
+ id: "agent.refund",
69
+ version: "1.0.0",
70
+ async run(input, ctx) {
71
+ const { amount } = input as { amount: number };
72
+ const decision = (await ctx.waitFor("approve", {
73
+ type: "refund-approval",
74
+ condition: { kind: "human_approval" },
75
+ payload: { amount },
76
+ })) as { approved: boolean };
77
+ return { amount, approved: decision.approved };
78
+ },
79
+ };
80
+
81
+ const waiting = await runtime.service.startRun(caller, {
82
+ agent: "agent.refund",
83
+ input: { amount: 75 },
84
+ idempotencyKey: "refund-1",
85
+ });
86
+
87
+ // Meanwhile — from a webhook, an admin UI, a shell — list and resolve open continuations.
88
+ const [continuation] = await runtime.service.listContinuations(caller, {
89
+ runId: waiting.runId,
90
+ status: "OPEN",
91
+ });
92
+ await runtime.service.resolveContinuation(caller, {
93
+ continuationId: continuation!.id,
94
+ action: "resume",
95
+ input: { approved: true },
96
+ idempotencyKey: "approve-1",
97
+ });
98
+ ```
99
+
100
+ The run re-enters the agent from the top, receives the recorded decision, and completes. Replays
101
+ never repeat recorded work: every `ctx.step`, `emit`, `invoke`, `artifact`, and `waitFor` result is
102
+ an event on the run's stream, and re-entry returns those results instead of re-executing.
103
+
104
+ ## What you get from `createRuntime`
105
+
106
+ The returned `Runtime` exposes:
107
+
108
+ - `service` — the full `RuntimeService`: start/get/cancel/list runs, a reconnectable event stream
109
+ (`service.events(caller, { follow: true })`), continuations, direct capability `invoke`,
110
+ `getArtifact`, public projection reads, and shared run/thread state reads and updates.
111
+ - `store` — the underlying `DurableStore`, if you need direct access to the event log.
112
+ - `kernel` — the embedded capability kernel.
113
+ - `inspect(correlationId)` — the causal chain for a correlation id: runs, events, invocations,
114
+ artifacts, observations.
115
+ - `erase(eventId, reason, actor)` — erase an event's payload; derived views and the cognitive index
116
+ drop it too.
117
+ - `rebuildCognition()`, `pollApprovals()`, `idle(timeoutMs?)`, and `close()`.
118
+
119
+ Notable options beyond the quick start: `components` (capability-providing kernel components your
120
+ agents can `ctx.invoke`), `projections` ([`@godspeedai/cognate-projections`](https://www.npmjs.com/package/@godspeedai/cognate-projections)
121
+ kept current automatically), `cognition` (index completed runs and recall them via `ctx.recall`),
122
+ `outboxFor` (extra outbox intents committed atomically with each run event), `governance`, and
123
+ `tickMs` (background loop interval, default 10 ms).
124
+
125
+ ## Limitations
126
+
127
+ - **One process, one writer.** All runs live in the process that opened the store; executions
128
+ within a tick run sequentially, so a slow agent delays others. To scale out, split runtimes per
129
+ store file.
130
+ - **Steps are at-least-once.** A step that was in flight during a crash re-executes after restart.
131
+ Keep steps idempotent, and put irreversible external calls behind a `ctx.waitFor` continuation so
132
+ they happen once, resolved deliberately.
133
+ - **Polling, not pushing, inside the process.** Background work (run execution, resume delivery,
134
+ continuation expiry) runs on a loop every `tickMs`.
135
+ - **Erasure has copies.** `runtime.erase` removes an event's payload from the log, derived views,
136
+ and the cognitive index — but content copied into continuation payloads, idempotency snapshots,
137
+ or recall results stays.
138
+ - **Public projections are tenant-partitioned.** Register projections that key their state
139
+ `<tenant>/<key>`; `service.readProjection` returns only the caller's tenant partition.
140
+ - **Denied means invisible.** Reading an artifact you are not allowed to see returns the same
141
+ "not found" as a missing one.
142
+ - **Recall degrades gracefully.** Without a `cognition` configuration, `ctx.recall` returns
143
+ `{ status: "degraded" }` instead of failing the run.
144
+
145
+ ## Related packages
146
+
147
+ - [`@godspeedai/cognate-client`](https://www.npmjs.com/package/@godspeedai/cognate-client) — the
148
+ headless client for consuming this runtime; derives live run state for you.
149
+ - [`@godspeedai/cognate-runtime-api`](https://www.npmjs.com/package/@godspeedai/cognate-runtime-api) —
150
+ the service and agent-authoring contract this package implements.
151
+ - [`@godspeedai/cognate-store-sqlite`](https://www.npmjs.com/package/@godspeedai/cognate-store-sqlite) —
152
+ the durable store behind `store: "<path>"`.
153
+ - [`@godspeedai/cognate-store-memory`](https://www.npmjs.com/package/@godspeedai/cognate-store-memory) —
154
+ bring your own ephemeral store via `store: { store }`.
155
+ - [`@godspeedai/cognate`](https://www.npmjs.com/package/@godspeedai/cognate) — the SDK umbrella;
156
+ one install for the runtime and the client together.
157
+
158
+ ## License
159
+
160
+ Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godspeedai/cognate-runtime-bun",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Bun reference runtime: composes kernel, durable store, runs, continuations, commitments, artifacts, and cognition behind RuntimeService.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -22,17 +22,17 @@
22
22
  ".": "./src/index.ts"
23
23
  },
24
24
  "dependencies": {
25
- "@godspeedai/cognate-artifacts": "^0.1.1",
26
- "@godspeedai/cognate-capabilities": "^0.1.1",
27
- "@godspeedai/cognate-cognitive-api": "^0.1.1",
28
- "@godspeedai/cognate-continuations": "^0.1.1",
29
- "@godspeedai/cognate-events": "^0.1.1",
30
- "@godspeedai/cognate-kernel-api": "^0.1.1",
31
- "@godspeedai/cognate-kernel-cordis": "^0.1.1",
32
- "@godspeedai/cognate-projections": "^0.1.1",
33
- "@godspeedai/cognate-runtime-api": "^0.1.1",
34
- "@godspeedai/cognate-store-memory": "^0.1.1",
35
- "@godspeedai/cognate-store-sqlite": "^0.1.1"
25
+ "@godspeedai/cognate-artifacts": "^0.1.2",
26
+ "@godspeedai/cognate-capabilities": "^0.1.2",
27
+ "@godspeedai/cognate-cognitive-api": "^0.1.2",
28
+ "@godspeedai/cognate-continuations": "^0.1.2",
29
+ "@godspeedai/cognate-events": "^0.1.2",
30
+ "@godspeedai/cognate-kernel-api": "^0.1.2",
31
+ "@godspeedai/cognate-kernel-cordis": "^0.1.2",
32
+ "@godspeedai/cognate-projections": "^0.1.2",
33
+ "@godspeedai/cognate-runtime-api": "^0.1.2",
34
+ "@godspeedai/cognate-store-memory": "^0.1.2",
35
+ "@godspeedai/cognate-store-sqlite": "^0.1.2"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@godspeedai/cognate-cognitive-memory": "workspace:*"