stitchkit 0.112.2 → 0.113.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/agent-runtime/run-model-attempts.d.ts.map +1 -1
  3. package/dist/agent-runtime/runtime.d.ts +8 -3
  4. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  5. package/dist/agent-runtime/sqlite-history.d.ts.map +1 -1
  6. package/dist/agent-runtime/store-driver-contract.d.ts +94 -1
  7. package/dist/agent-runtime/store-driver-contract.d.ts.map +1 -1
  8. package/dist/agent-runtime/store-events.d.ts +8 -0
  9. package/dist/agent-runtime/store-events.d.ts.map +1 -1
  10. package/dist/agent-runtime/store-memory.d.ts.map +1 -1
  11. package/dist/agent-runtime/store-reduce-history.d.ts +1 -1
  12. package/dist/agent-runtime/store-reduce-history.d.ts.map +1 -1
  13. package/dist/agent-runtime/store.d.ts +8 -2
  14. package/dist/agent-runtime/store.d.ts.map +1 -1
  15. package/dist/entrypoints/agent-runtime/coding-tools.js +3 -3
  16. package/dist/entrypoints/agent-runtime/harness.js +5 -5
  17. package/dist/entrypoints/agent-runtime/sandbox.js +3 -3
  18. package/dist/entrypoints/agent-runtime/sqlite/bun.js +6 -6
  19. package/dist/entrypoints/agent-runtime/sqlite/node.js +6 -6
  20. package/dist/entrypoints/agent-runtime/testing.js +37 -6
  21. package/dist/entrypoints/agent-runtime.js +11 -11
  22. package/dist/entrypoints/cli.js +6 -6
  23. package/dist/entrypoints/testing.js +1 -1
  24. package/dist/entrypoints/tools/connections.js +6 -6
  25. package/dist/entrypoints/tools/invoker.js +4 -4
  26. package/dist/entrypoints/tools/mcp.js +6 -6
  27. package/dist/entrypoints/tools.js +9 -9
  28. package/dist/{index-jfk93gja.js → index-4dh3hfs7.js} +3 -3
  29. package/dist/{index-651xsm48.js → index-54q2mghq.js} +4 -4
  30. package/dist/{index-c7h371gr.js → index-5jjda9a4.js} +4 -4
  31. package/dist/{index-n0adphfg.js → index-dsxrcseb.js} +1 -1
  32. package/dist/{index-hvg9hctd.js → index-eddzs589.js} +3 -3
  33. package/dist/{index-jna0ejsa.js → index-fggxgbrk.js} +2 -1
  34. package/dist/{index-bd7spznx.js → index-gpbk7yse.js} +4 -4
  35. package/dist/{index-fh2ht88b.js → index-gz9jf461.js} +22 -3
  36. package/dist/{index-h7accrrv.js → index-jgwqc38k.js} +66 -6
  37. package/dist/{index-d4cnhfdn.js → index-k0zfcxf5.js} +19 -3
  38. package/dist/{index-ff3agzaf.js → index-nk1mh535.js} +1 -1
  39. package/dist/{index-a0vj9edp.js → index-ppf5nerp.js} +5 -5
  40. package/dist/{index-38gvr73z.js → index-yjnmac9b.js} +42 -8
  41. package/dist/{index-02h0dfpr.js → index-z4ga1fa1.js} +1 -1
  42. package/dist/{index-vqdjym30.js → index-zm1k7hhv.js} +2 -2
  43. package/dist/json-schema/dialect.d.ts +12 -10
  44. package/dist/json-schema/dialect.d.ts.map +1 -1
  45. package/dist/tools/schema/presentation.d.ts +4 -3
  46. package/dist/tools/schema/presentation.d.ts.map +1 -1
  47. package/llms/agent-runtime.2.txt +25 -0
  48. package/llms/agent-runtime.3.txt +1 -1
  49. package/llms/agent-runtime.txt +6 -0
  50. package/llms/stitchkit.txt +3 -3
  51. package/llms/{upgrading-0.103.0-0.112.0.txt → upgrading-0.103.13-0.113.0.txt} +22 -32
  52. package/llms/{upgrading-0.75.0-0.102.0.txt → upgrading-0.75.0-0.103.0.txt} +32 -3
  53. package/llms/upgrading.txt +2 -2
  54. package/llms-full.txt +54 -4
  55. package/llms.txt +3 -3
  56. package/package.json +2 -1
@@ -4,7 +4,7 @@ import {
4
4
  AgentSandboxRestrictionSchema2,
5
5
  AgentSandboxGradeSchema2,
6
6
  AGENT_CODING_TOOL_NAMES
7
- } from "./index-n0adphfg.js";
7
+ } from "./index-dsxrcseb.js";
8
8
  import {
9
9
  AgentRecordIdSchema2,
10
10
  AgentRecordVersionSchema2,
@@ -39,7 +39,7 @@ import {
39
39
  ProviderJournalMessageSchema,
40
40
  ProviderJournalRequestSchema,
41
41
  ProviderJournalResponseSchema
42
- } from "./index-jna0ejsa.js";
42
+ } from "./index-fggxgbrk.js";
43
43
  import {
44
44
  StepEventPayloadSchema,
45
45
  ParkEventPayloadSchema,
@@ -154,6 +154,11 @@ var AgentHistoryMutationSchema2 = z3.discriminatedUnion("type", [
154
154
  z3.object({
155
155
  type: z3.literal("seed"),
156
156
  message: AgentMessageSchema2
157
+ }),
158
+ z3.object({
159
+ type: z3.literal("insert"),
160
+ message: AgentMessageSchema2,
161
+ beforeMessageId: AgentRecordIdSchema2.optional()
157
162
  })
158
163
  ]);
159
164
  var ACTIVE_AGENT_RUN_STATES2 = [
@@ -362,22 +367,51 @@ function reduceAccept(current, input) {
362
367
  historyMutations: [{ type: "admit", input: input.input }]
363
368
  });
364
369
  }
370
+ function seedReceipt(input) {
371
+ return AgentSeedReceiptSchema2.parse({
372
+ schemaVersion: 1,
373
+ conversationId: input.conversationId,
374
+ seedKey: input.seedKey,
375
+ messageIds: input.inputs.map((message) => message.id)
376
+ });
377
+ }
378
+ function reduceSettledSeed(current, input) {
379
+ for (const message of input.inputs) {
380
+ if (message.conversationId !== input.conversationId || message.runId !== undefined || !(message.role === "user" && message.status === "committed" || message.role === "assistant" && message.status === "completed")) {
381
+ throw new TypeError("A settled exchange must be committed user and completed assistant messages no run owns");
382
+ }
383
+ }
384
+ const activeMessageIds = new Set(current.runs.filter((run) => isActiveRunState(run.state)).flatMap((run) => [...run.inputMessageIds, run.assistantMessageId]));
385
+ const anchor = current.messages.find((message) => activeMessageIds.has(message.id));
386
+ const at = anchor ? current.messages.indexOf(anchor) : current.messages.length;
387
+ return applied(current, {
388
+ messages: [
389
+ ...current.messages.slice(0, at),
390
+ ...input.inputs,
391
+ ...current.messages.slice(at)
392
+ ]
393
+ }, {
394
+ seedReceipt: seedReceipt(input),
395
+ historyMutations: input.inputs.map((message) => ({
396
+ type: "insert",
397
+ message,
398
+ ...anchor && { beforeMessageId: anchor.id }
399
+ }))
400
+ });
401
+ }
365
402
  function reduceSeed(current, input) {
366
403
  const conversationId = input.conversationId;
367
404
  if (current.conversationId !== conversationId)
368
405
  return { outcome: "not_found" };
406
+ if (input.placement === "after-settled")
407
+ return reduceSettledSeed(current, input);
369
408
  for (const message of input.inputs) {
370
409
  if (message.conversationId !== conversationId || message.role !== "user" || message.status !== "committed" || message.runId !== undefined) {
371
410
  throw new TypeError("Seeded conversation input must be committed unowned user messages");
372
411
  }
373
412
  }
374
413
  return applied(current, { messages: [...input.inputs, ...current.messages] }, {
375
- seedReceipt: AgentSeedReceiptSchema2.parse({
376
- schemaVersion: 1,
377
- conversationId,
378
- seedKey: input.seedKey,
379
- messageIds: input.inputs.map((message) => message.id)
380
- }),
414
+ seedReceipt: seedReceipt(input),
381
415
  historyMutations: [...input.inputs].reverse().map((message) => ({
382
416
  type: "seed",
383
417
  message
@@ -12,7 +12,7 @@ import {
12
12
  applyToolViewDefaults,
13
13
  projectToolView,
14
14
  objectShapeKeys
15
- } from "./index-h7accrrv.js";
15
+ } from "./index-jgwqc38k.js";
16
16
  import {
17
17
  runWithRequestContext2,
18
18
  getRequestContext2
@@ -3,11 +3,11 @@ import {
3
3
  mergeSchemas,
4
4
  assertToolExtensionCompatible,
5
5
  projectToolSurface
6
- } from "./index-h7accrrv.js";
6
+ } from "./index-jgwqc38k.js";
7
7
  import {
8
8
  toolErrorFromResult,
9
9
  executeToolMethod
10
- } from "./index-02h0dfpr.js";
10
+ } from "./index-z4ga1fa1.js";
11
11
  import {
12
12
  isRetryableStatus2
13
13
  } from "./index-j9gxbztg.js";
@@ -1,17 +1,19 @@
1
1
  /** True when a document says, in its own `$schema`, that it is draft-07. */
2
2
  export declare function declaresDraft07(dialect: unknown): boolean;
3
3
  /**
4
- * Move a document's top-level `definitions` to `$defs`, carrying its pointers.
4
+ * Write a document in the keywords of 2020-12, the dialect an MCP client reads
5
+ * tool schemas in. Two draft-07 keywords mean something else there or nothing:
6
+ * reusable subschemas move from `definitions` to `$defs` with their pointers,
7
+ * and a tuple's `items` list becomes `prefixItems`.
5
8
  *
6
- * A JSON Schema document that names one dialect and uses another's keyword is
7
- * not a style question: a reader registers reusable subschemas from the keyword
8
- * the dialect declares and then cannot resolve `#/definitions/x` at all. Both
9
- * halves of this framework met that document — the MCP SDK stamps 2020-12 onto
10
- * the metadata it is handed, and our own MCP client obeyed the stamp.
9
+ * A document that names one dialect and uses another's keyword is not a style
10
+ * question: a reader registers subschemas from the keyword its dialect declares
11
+ * and cannot resolve `#/definitions/x`, and a reader that validates the schema
12
+ * itself refuses an `items` list and drops the whole tool.
11
13
  *
12
- * Only the top level moves. A `definitions` deeper in the document may be a
13
- * property literally called "definitions", and guessing which is worse than
14
- * leaving it where the author put it.
14
+ * Only the top-level `definitions` moves. A `definitions` deeper in the
15
+ * document may be a property literally called "definitions", and guessing which
16
+ * is worse than leaving it where the author put it.
15
17
  */
16
- export declare function withDefsDialect(schema: Record<string, unknown>): Record<string, unknown>;
18
+ export declare function withDraft2020Keywords(schema: Record<string, unknown>): Record<string, unknown>;
17
19
  //# sourceMappingURL=dialect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../../src/json-schema/dialect.ts"],"names":[],"mappings":"AAQA,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEzD;AAeD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUxF"}
1
+ {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../../src/json-schema/dialect.ts"],"names":[],"mappings":"AAiCA,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEzD;AAmDD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB"}
@@ -16,9 +16,10 @@ export declare function isObjectPresentationSchema(schema: ToolPresentationSchem
16
16
  * Metadata passed to the Zod identity carrier.
17
17
  *
18
18
  * The SDK supplies its own dialect and it is 2020-12, so the document has to
19
- * speak 2020-12: a draft-07 `definitions` block under a 2020-12 `$schema` is a
20
- * document that says one thing and does another, and a client that believes the
21
- * stamp cannot resolve a single `#/definitions/...` pointer in it.
19
+ * speak 2020-12: draft-07 `definitions` under a 2020-12 `$schema` leave every
20
+ * `#/definitions/...` pointer unresolvable, and a tuple's draft-07 `items` list
21
+ * is not a schema there, so a client that validates tool schemas drops the tool.
22
+ * → ADR 0185, ADR 0268.
22
23
  */
23
24
  export declare function presentationMetadata(schema: ToolPresentationSchema): ToolPresentationSchema;
24
25
  //# sourceMappingURL=presentation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../../../src/tools/schema/presentation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAClC,uFAAuF;IACvF,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9C;AA+KD,+EAA+E;AAC/E,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,sBAAsB,GAC7B,sBAAsB,CAkDxB;AAoCD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAElF;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,sBAAsB,GAAG,sBAAsB,CAE3F"}
1
+ {"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../../../src/tools/schema/presentation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAClC,uFAAuF;IACvF,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9C;AA+KD,+EAA+E;AAC/E,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,sBAAsB,GAC7B,sBAAsB,CAkDxB;AAoCD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAElF;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,sBAAsB,GAAG,sBAAsB,CAE3F"}
@@ -256,6 +256,31 @@ implement the smaller `AgentRuntimeStoreDriver` rather than these eleven members
256
256
  calls this and nothing else, so an adapter that implements the interface has
257
257
  everything recovery needs
258
258
 
259
+ ### Writing history no run owns
260
+
261
+ `seedConversationInput` writes messages no run owns, exactly once per `seedKey`; the key is
262
+ recorded beside the history, so compaction or replacement of the messages never brings them
263
+ back. It places them by `placement`:
264
+
265
+ - absent or `'lead'` — committed user instructions ahead of the whole conversation;
266
+ - `'after-settled'` — an exchange that already happened without a model (a confirmed voice
267
+ command and its receipt): committed `user` and completed `assistant` messages. They land after
268
+ the settled history and ahead of the first message of any run still active, so an active run's
269
+ input and answer stay adjacent and the next run reads the exchange before the input queued
270
+ behind it. With no active run they are the tail.
271
+
272
+ ```ts
273
+ await store.seedConversationInput({
274
+ conversationId,
275
+ seedKey: `voice:${commandId}`,
276
+ placement: 'after-settled',
277
+ inputs: [ownerMessage, receiptMessage],
278
+ })
279
+ ```
280
+
281
+ The pair is ordinary history: it is in `loadSnapshot`, compaction may summarize it, and the next
282
+ provider request carries it. No model is called and no run is created.
283
+
259
284
  ### Reading a conversation
260
285
 
261
286
  Two shapes of read, and the difference matters as a conversation grows.
@@ -181,7 +181,7 @@ Server-only optional application runtime. See the
181
181
  | `selectCompactableHistory` | function | which oldest whole complete turns may be summarised away — the half of compaction that needs no store (→ ADR 0142) |
182
182
  | `SelectCompactableHistoryOptions` / `CompactableHistory` | _type_ | message list, retained-turn count and evidence policy in; `leadingSummary`, `compactable` and `retained` out |
183
183
  | `createAgentSessionCoordinator` | function | strict process-local queue/interrupt/supersede lifecycle |
184
- | `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
184
+ | `AgentRuntimeStopPolicy` | _type_ | named stop rule persisted and published on policy stop; `when` receives the AI SDK `steps` plus the run context `prepareStep` gets (`context`, `run`, `signal`, `toolFenceLifecycle`, `contextUsage`) |
185
185
  | `AgentRuntimePrepareStep` | _type_ | per-run controlled step callback with typed domain context and managed run signal/fence |
186
186
  | `AgentContextOverflowError` | class | deliberate application budget refusal thrown from `loop.prepareStep`; terminalizes as `context_overflow` without classifying arbitrary error text |
187
187
  | `AgentRuntimeRecordIds` | _type_ | optional caller-provided input, run and assistant IDs for stable application records |
@@ -165,6 +165,12 @@ await ticket.accepted
165
165
  const terminal = await ticket.result
166
166
  ```
167
167
 
168
+ A stop policy's `when` receives the steps so far together with the same run context
169
+ `prepareStep` gets — `context`, `run`, `signal`, `toolFenceLifecycle` and `contextUsage` —
170
+ typed by the runtime's `CONTEXT`. A rule that depends on its own run (a receipt bound to the
171
+ run's request, a per-tenant limit) reads it there; it needs no map of its own keyed by `runId`.
172
+ The first policy to return `true` ends the run as `policy_stop` with its `name` as `policyName`.
173
+
168
174
  ## Bounded deferred tool catalogs
169
175
 
170
176
  Use `createDeferredAgentToolSurface` when a measured large catalog makes
@@ -85,12 +85,12 @@ own, recorded as an ADR.
85
85
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
86
86
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
87
87
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
88
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 57 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
88
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 58 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
89
89
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, the managed-resource conformance kit and manual time for schedules and retries |
90
90
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
91
91
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
92
92
  | `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
93
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 57 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
93
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 24 of the 58 minors since 0.56.2, most recently 0.113.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
94
94
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
95
95
  | `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
96
96
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -102,7 +102,7 @@ own, recorded as an ADR.
102
102
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
103
103
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
104
104
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
105
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 57 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
105
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 58 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
106
106
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
107
107
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
108
108
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -1,14 +1,33 @@
1
- # Upgrading 0.103.0 → 0.112.0 — stitchkit docs slice
1
+ # Upgrading 0.103.13 → 0.113.0 — stitchkit docs slice
2
2
 
3
3
  > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
4
  > `llms.txt` in this package.
5
5
 
6
- Contains: Guide: Upgrading, 0.103.0 → 0.112.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.103.13 → 0.113.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.103.0 → 0.112.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.103.13 → 0.113.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.113.0
13
+
14
+ **Who must act:** custom `AgentRuntimeStoreDriver` adapters and custom `AgentRuntimeStore` implementations of `seedConversationInput`. The built-in memory and SQLite stores already implement the contract.
15
+
16
+ `seedConversationInput({ placement: 'after-settled' })` emits one `insert` history mutation per message. A driver's `history.apply` places the message ahead of the active row named `beforeMessageId`, or at the end when it is absent, and replaces a message already present in place:
17
+
18
+ ```ts
19
+ // after: one more branch in history.apply
20
+ if (mutation.type === 'insert') {
21
+ if (await exists(mutation.message.id)) return replaceInPlace(mutation.message)
22
+ if (mutation.beforeMessageId === undefined) return appendAtEnd(mutation.message)
23
+ const anchor = await activePosition(mutation.beforeMessageId) // refuse when missing
24
+ await shiftPositionsFrom(anchor) // every row at or after it moves one down
25
+ return insertAt(anchor, mutation.message)
26
+ }
27
+ ```
28
+
29
+ A custom `AgentRuntimeStore` that implements `seedConversationInput` itself places `'after-settled'` messages after the settled history and ahead of the first message of any active run, and keeps `'lead'` (or an absent `placement`) as before. Run `runAgentStoreConformance` against the adapter; `examples/agent-store-prisma/adapter.ts` shows the Prisma form.
30
+
12
31
  ## Released migration: 0.112.0
13
32
 
14
33
  **Who must act:** scripts using an array option together with bare positional arguments without a declared `positionals` policy, including calls to `parseCliArgs`.
@@ -876,32 +895,3 @@ mytool deploy --profile "${PROFILE:-production}" "$@"
876
895
 
877
896
  Dotted leaves such as `--filter.name` follow the same rule as their parent field. Declare a
878
897
  field as an array when repetition is meant.
879
-
880
- ## Released migration: 0.103.0
881
-
882
- ### Diagnostic journal startup preserves torn evidence and inspects archives
883
-
884
- **Who must act:** operators using `maxFiles: 1` who can encounter a torn active
885
- file, or whose retained files are unreadable by the writer. Clean single-file
886
- journals continue to work; successful startup now requires read access to every
887
- retained generation.
888
-
889
- ```ts
890
- import { createDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
891
-
892
- // Before: a torn active file could be discarded during startup.
893
- await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 1 } })
894
- // After: retain the torn file while the fresh writer starts in a new active file.
895
- await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 2 } })
896
- ```
897
-
898
- With single-file retention, a torn active file throws `DiagnosticJournalRecoveryError`
899
- from `stitchkit/application`, carrying `recovery` observations and releasing its lock
900
- without deleting evidence. Inspection I/O errors also fail startup and release the
901
- lock; restore filesystem access rather than treating that failure as a bad JSON row.
902
- Normal rotation retains the configured finite eviction policy.
903
-
904
- For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
905
- from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
906
- missing files, permissions and unsafe paths still throw. See the
907
- [journal guide](application-kernel.md#bounded-local-diagnostic-journal).
@@ -1,14 +1,43 @@
1
- # Upgrading 0.75.0 → 0.102.0 — stitchkit docs slice
1
+ # Upgrading 0.75.0 → 0.103.0 — stitchkit docs slice
2
2
 
3
3
  > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
4
  > `llms.txt` in this package.
5
5
 
6
- Contains: Guide: Upgrading, 0.75.0 → 0.102.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.75.0 → 0.103.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.75.0 → 0.102.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.75.0 → 0.103.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.103.0
13
+
14
+ ### Diagnostic journal startup preserves torn evidence and inspects archives
15
+
16
+ **Who must act:** operators using `maxFiles: 1` who can encounter a torn active
17
+ file, or whose retained files are unreadable by the writer. Clean single-file
18
+ journals continue to work; successful startup now requires read access to every
19
+ retained generation.
20
+
21
+ ```ts
22
+ import { createDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
23
+
24
+ // Before: a torn active file could be discarded during startup.
25
+ await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 1 } })
26
+ // After: retain the torn file while the fresh writer starts in a new active file.
27
+ await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 2 } })
28
+ ```
29
+
30
+ With single-file retention, a torn active file throws `DiagnosticJournalRecoveryError`
31
+ from `stitchkit/application`, carrying `recovery` observations and releasing its lock
32
+ without deleting evidence. Inspection I/O errors also fail startup and release the
33
+ lock; restore filesystem access rather than treating that failure as a bad JSON row.
34
+ Normal rotation retains the configured finite eviction policy.
35
+
36
+ For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
37
+ from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
38
+ missing files, permissions and unsafe paths still throw. See the
39
+ [journal guide](application-kernel.md#bounded-local-diagnostic-journal).
40
+
12
41
  ## Released migration: 0.102.0
13
42
 
14
43
  ### `view_file` receives an array, not an array encoded as text
@@ -11,8 +11,8 @@ Contains: Guide: Upgrading, general (docs/guide/upgrading.md)
11
11
 
12
12
  Load this slice, then every range slice between your installed version and the target:
13
13
 
14
- - 0.103.0 → 0.112.0: `llms/upgrading-0.103.0-0.112.0.txt`
15
- - 0.75.0 → 0.102.0: `llms/upgrading-0.75.0-0.102.0.txt`
14
+ - 0.103.13 → 0.113.0: `llms/upgrading-0.103.13-0.113.0.txt`
15
+ - 0.75.0 → 0.103.0: `llms/upgrading-0.75.0-0.103.0.txt`
16
16
  - 0.61.0 → 0.74.0: `llms/upgrading-0.61.0-0.74.0.txt`
17
17
  - 0.44.0 → 0.60.0: `llms/upgrading-0.44.0-0.60.0.txt`
18
18
  - 0.37.0 → 0.37.0: `llms/upgrading-0.37.0.txt`
package/llms-full.txt CHANGED
@@ -77,12 +77,12 @@ own, recorded as an ADR.
77
77
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
78
78
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
79
79
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
80
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 57 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
80
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 58 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
81
81
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, the managed-resource conformance kit and manual time for schedules and retries |
82
82
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
83
83
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
84
84
  | `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
85
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 57 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
85
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 24 of the 58 minors since 0.56.2, most recently 0.113.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
86
86
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
87
87
  | `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
88
88
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -94,7 +94,7 @@ own, recorded as an ADR.
94
94
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
95
95
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
96
96
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
97
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 57 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
97
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 58 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
98
98
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
99
99
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
100
100
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -5518,6 +5518,12 @@ await ticket.accepted
5518
5518
  const terminal = await ticket.result
5519
5519
  ```
5520
5520
 
5521
+ A stop policy's `when` receives the steps so far together with the same run context
5522
+ `prepareStep` gets — `context`, `run`, `signal`, `toolFenceLifecycle` and `contextUsage` —
5523
+ typed by the runtime's `CONTEXT`. A rule that depends on its own run (a receipt bound to the
5524
+ run's request, a per-tenant limit) reads it there; it needs no map of its own keyed by `runId`.
5525
+ The first policy to return `true` ends the run as `policy_stop` with its `name` as `policyName`.
5526
+
5521
5527
  ## Bounded deferred tool catalogs
5522
5528
 
5523
5529
  Use `createDeferredAgentToolSurface` when a measured large catalog makes
@@ -6365,6 +6371,31 @@ implement the smaller `AgentRuntimeStoreDriver` rather than these eleven members
6365
6371
  calls this and nothing else, so an adapter that implements the interface has
6366
6372
  everything recovery needs
6367
6373
 
6374
+ ### Writing history no run owns
6375
+
6376
+ `seedConversationInput` writes messages no run owns, exactly once per `seedKey`; the key is
6377
+ recorded beside the history, so compaction or replacement of the messages never brings them
6378
+ back. It places them by `placement`:
6379
+
6380
+ - absent or `'lead'` — committed user instructions ahead of the whole conversation;
6381
+ - `'after-settled'` — an exchange that already happened without a model (a confirmed voice
6382
+ command and its receipt): committed `user` and completed `assistant` messages. They land after
6383
+ the settled history and ahead of the first message of any run still active, so an active run's
6384
+ input and answer stay adjacent and the next run reads the exchange before the input queued
6385
+ behind it. With no active run they are the tail.
6386
+
6387
+ ```ts
6388
+ await store.seedConversationInput({
6389
+ conversationId,
6390
+ seedKey: `voice:${commandId}`,
6391
+ placement: 'after-settled',
6392
+ inputs: [ownerMessage, receiptMessage],
6393
+ })
6394
+ ```
6395
+
6396
+ The pair is ordinary history: it is in `loadSnapshot`, compaction may summarize it, and the next
6397
+ provider request carries it. No model is called and no run is created.
6398
+
6368
6399
  ### Reading a conversation
6369
6400
 
6370
6401
  Two shapes of read, and the difference matters as a conversation grows.
@@ -16276,6 +16307,25 @@ analytics policy belong to the application.
16276
16307
 
16277
16308
  # Upgrading stitchkit
16278
16309
 
16310
+ ## Released migration: 0.113.0
16311
+
16312
+ **Who must act:** custom `AgentRuntimeStoreDriver` adapters and custom `AgentRuntimeStore` implementations of `seedConversationInput`. The built-in memory and SQLite stores already implement the contract.
16313
+
16314
+ `seedConversationInput({ placement: 'after-settled' })` emits one `insert` history mutation per message. A driver's `history.apply` places the message ahead of the active row named `beforeMessageId`, or at the end when it is absent, and replaces a message already present in place:
16315
+
16316
+ ```ts
16317
+ // after: one more branch in history.apply
16318
+ if (mutation.type === 'insert') {
16319
+ if (await exists(mutation.message.id)) return replaceInPlace(mutation.message)
16320
+ if (mutation.beforeMessageId === undefined) return appendAtEnd(mutation.message)
16321
+ const anchor = await activePosition(mutation.beforeMessageId) // refuse when missing
16322
+ await shiftPositionsFrom(anchor) // every row at or after it moves one down
16323
+ return insertAt(anchor, mutation.message)
16324
+ }
16325
+ ```
16326
+
16327
+ A custom `AgentRuntimeStore` that implements `seedConversationInput` itself places `'after-settled'` messages after the settled history and ahead of the first message of any active run, and keeps `'lead'` (or an absent `placement`) as before. Run `runAgentStoreConformance` against the adapter; `examples/agent-store-prisma/adapter.ts` shows the Prisma form.
16328
+
16279
16329
  ## Released migration: 0.112.0
16280
16330
 
16281
16331
  **Who must act:** scripts using an array option together with bare positional arguments without a declared `positionals` policy, including calls to `parseCliArgs`.
@@ -22193,7 +22243,7 @@ Server-only optional application runtime. See the
22193
22243
  | `selectCompactableHistory` | function | which oldest whole complete turns may be summarised away — the half of compaction that needs no store (→ ADR 0142) |
22194
22244
  | `SelectCompactableHistoryOptions` / `CompactableHistory` | _type_ | message list, retained-turn count and evidence policy in; `leadingSummary`, `compactable` and `retained` out |
22195
22245
  | `createAgentSessionCoordinator` | function | strict process-local queue/interrupt/supersede lifecycle |
22196
- | `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
22246
+ | `AgentRuntimeStopPolicy` | _type_ | named stop rule persisted and published on policy stop; `when` receives the AI SDK `steps` plus the run context `prepareStep` gets (`context`, `run`, `signal`, `toolFenceLifecycle`, `contextUsage`) |
22197
22247
  | `AgentRuntimePrepareStep` | _type_ | per-run controlled step callback with typed domain context and managed run signal/fence |
22198
22248
  | `AgentContextOverflowError` | class | deliberate application budget refusal thrown from `loop.prepareStep`; terminalizes as `context_overflow` without classifying arbitrary error text |
22199
22249
  | `AgentRuntimeRecordIds` | _type_ | optional caller-provided input, run and assistant IDs for stable application records |
package/llms.txt CHANGED
@@ -25,7 +25,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
25
25
  - **stitchkit/primitives**: [llms/primitives.txt](llms/primitives.txt) 11.7 KB
26
26
  - **stitchkit/server**: [llms/server.txt](llms/server.txt) 44.2 KB → [llms/server.2.txt](llms/server.2.txt) 20.5 KB → [llms/server.3.txt](llms/server.3.txt) 45.6 KB → [llms/server.4.txt](llms/server.4.txt) 38.3 KB → [llms/server.5.txt](llms/server.5.txt) 22.9 KB
27
27
  - **stitchkit/observability**: [llms/observability.txt](llms/observability.txt) 46.9 KB
28
- - **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 42.7 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 44.8 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 42.1 KB
28
+ - **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 43.2 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 45.9 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 42.2 KB
29
29
  - **stitchkit/agent-runtime/testing**: [llms/agent-runtime-testing.txt](llms/agent-runtime-testing.txt) 2.6 KB
30
30
  - **stitchkit/agent-runtime/harness**: [llms/agent-runtime-harness.txt](llms/agent-runtime-harness.txt) 11.0 KB
31
31
  - **stitchkit/agent-runtime/coding-tools**: [llms/agent-runtime-coding-tools.txt](llms/agent-runtime-coding-tools.txt) 5.0 KB
@@ -64,8 +64,8 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
64
64
 
65
65
  ## Upgrading slices
66
66
  - **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 12.7 KB
67
- - **Upgrading 0.103.0 → 0.112.0**: [llms/upgrading-0.103.0-0.112.0.txt](llms/upgrading-0.103.0-0.112.0.txt) 46.6 KB
68
- - **Upgrading 0.75.0 → 0.102.0**: [llms/upgrading-0.75.0-0.102.0.txt](llms/upgrading-0.75.0-0.102.0.txt) 44.8 KB
67
+ - **Upgrading 0.103.13 → 0.113.0**: [llms/upgrading-0.103.13-0.113.0.txt](llms/upgrading-0.103.13-0.113.0.txt) 46.4 KB
68
+ - **Upgrading 0.75.0 → 0.103.0**: [llms/upgrading-0.75.0-0.103.0.txt](llms/upgrading-0.75.0-0.103.0.txt) 46.3 KB
69
69
  - **Upgrading 0.61.0 → 0.74.0**: [llms/upgrading-0.61.0-0.74.0.txt](llms/upgrading-0.61.0-0.74.0.txt) 43.5 KB
70
70
  - **Upgrading 0.44.0 → 0.60.0**: [llms/upgrading-0.44.0-0.60.0.txt](llms/upgrading-0.44.0-0.60.0.txt) 43.9 KB
71
71
  - **Upgrading 0.37.0 → 0.37.0**: [llms/upgrading-0.37.0.txt](llms/upgrading-0.37.0.txt) 6.2 KB
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.112.2",
3
+ "version": "0.113.0",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",
@@ -378,6 +378,7 @@
378
378
  "@types/react-dom": "^19.3.0",
379
379
  "@typescript/typescript6": "^6.0.2",
380
380
  "ai": "^7.0.111",
381
+ "ajv": "^8.20.0",
381
382
  "fake-indexeddb": "^6.2.5",
382
383
  "google-auth-library": "^11.1.0",
383
384
  "grammy": "^1.46.0",