stitchkit 0.112.3 → 0.113.1

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 (54) 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/harness.js +5 -5
  16. package/dist/entrypoints/agent-runtime/sqlite/bun.js +3 -3
  17. package/dist/entrypoints/agent-runtime/sqlite/node.js +3 -3
  18. package/dist/entrypoints/agent-runtime/testing.js +34 -3
  19. package/dist/entrypoints/agent-runtime.js +10 -10
  20. package/dist/entrypoints/cli.js +6 -6
  21. package/dist/entrypoints/tools/connections.js +3 -3
  22. package/dist/entrypoints/tools/contract.js +2 -2
  23. package/dist/entrypoints/tools/invoker.js +5 -5
  24. package/dist/entrypoints/tools/mcp.js +6 -6
  25. package/dist/entrypoints/tools.js +9 -9
  26. package/dist/{index-54q2mghq.js → index-8jjzfts8.js} +3 -3
  27. package/dist/{index-epmnrnth.js → index-dsa676h8.js} +24 -7
  28. package/dist/{index-eddzs589.js → index-emrmgq3s.js} +1 -1
  29. package/dist/{index-jna0ejsa.js → index-fggxgbrk.js} +2 -1
  30. package/dist/{index-gpbk7yse.js → index-fytsnhzj.js} +5 -5
  31. package/dist/{index-c9vpsxw4.js → index-gz9jf461.js} +22 -3
  32. package/dist/{index-kenvdagc.js → index-k0zfcxf5.js} +19 -3
  33. package/dist/{index-b9yqb9e7.js → index-mhrtwttb.js} +5 -5
  34. package/dist/{index-4dh3hfs7.js → index-nn6607y3.js} +2 -2
  35. package/dist/{index-jy9wq8tp.js → index-rbzq0q16.js} +1 -1
  36. package/dist/{index-5jjda9a4.js → index-sjww6myv.js} +3 -3
  37. package/dist/{index-z4ga1fa1.js → index-tg2q89ps.js} +2 -2
  38. package/dist/{index-zm1k7hhv.js → index-v6mzw27b.js} +1 -1
  39. package/dist/{index-f2p949ax.js → index-yjnmac9b.js} +41 -7
  40. package/dist/tools/connections/runtime.d.ts +1 -1
  41. package/dist/tools/schema/json-schema-origin.d.ts +6 -5
  42. package/dist/tools/schema/json-schema-origin.d.ts.map +1 -1
  43. package/llms/agent-runtime.2.txt +25 -0
  44. package/llms/agent-runtime.3.txt +1 -1
  45. package/llms/agent-runtime.txt +6 -0
  46. package/llms/cli.2.txt +14 -3
  47. package/llms/stitchkit.txt +3 -3
  48. package/llms/tools-connections.txt +1 -1
  49. package/llms/{upgrading-0.103.0-0.112.0.txt → upgrading-0.103.13-0.113.0.txt} +22 -32
  50. package/llms/{upgrading-0.75.0-0.102.0.txt → upgrading-0.75.0-0.103.0.txt} +32 -3
  51. package/llms/upgrading.txt +2 -2
  52. package/llms-full.txt +69 -8
  53. package/llms.txt +5 -5
  54. package/package.json +1 -1
package/llms/cli.2.txt CHANGED
@@ -149,9 +149,10 @@ One unconvertible schema does not take the connection down. The tool
149
149
  is skipped and **named** (`onSkippedTool`, or a stderr line by default), so a
150
150
  surface of two hundred tools is not lost to one.
151
151
 
152
- **A discovered schema is checked locally, except for its unions.** The arguments are
153
- coerced and parsed against the schema the server advertised, so a missing field or a
154
- wrong scalar is refused before anything is sent. A union in that schema is not judged
152
+ **A discovered schema leaves unions and string formats to its server.** The arguments are
153
+ coerced and parsed against the schema the server advertised. Reported structural failures
154
+ (a missing field, wrong scalar type, unknown key or enum value) and bounds stay local.
155
+ A union in that schema is not judged
155
156
  here: a server's presentation may join a discriminated union into one object whose
156
157
  shared field is an unlabelled `anyOf` (a stitchkit server with `flattenUnionInput`
157
158
  does), and judged against that, a wrong value could only be refused with every branch
@@ -159,6 +160,16 @@ listed. The value goes to the server, which holds the original schema, and its r
159
160
  names the one wrong field — `blocks.0.data.artifactId: expected string` rather than
160
161
  `No union branch matched — branch 1 … and 6 more branches`.
161
162
 
163
+ String formats and patterns also lose the author's error messages in JSON Schema. A
164
+ restored `date-time`, email, UUID or regex check would substitute Zod's generic wording.
165
+ Those `invalid_format` refusals go to the remote instead: a bare `2026-10-12` reaches
166
+ the original datetime schema, whose answer can explain that a full UTC timestamp such
167
+ as `2026-10-12T00:00:00Z` is required. This also applies inside arrays, objects and
168
+ record keys. A mixed refusal retains only its reported local reasons; a record-key
169
+ wrapper stays local when it contains any of those reasons. A schema authored locally
170
+ keeps its complete verdict, including custom errors and refinements. No second parse
171
+ invents checks that the first parse did not reach. See [ADR 0272](../decisions/0272-a-restored-string-format-is-judged-by-its-server.md).
172
+
162
173
  MCP connection limits follow the operation phase. `initialize`, the initialized
163
174
  notification, `tools/list` and legacy endpoint discovery use `limits.discovery`;
164
175
  `tools/call` uses `limits.call`. A mounted call's handshake still uses discovery
@@ -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 |
@@ -27,7 +27,7 @@ and approval path.
27
27
  | `ConnectionPhase` / `ConnectionOperation` / `ConnectionFailureContext` | _type_ | closed operation/phase vocabulary and measured read context for existing typed connection errors |
28
28
  | `ConnectionTimeoutError` / `ConnectionResponseTooLargeError` | class | bounded operation refusal, with phase, operation and finite observed bytes; safe tool projection retains the raw cause locally |
29
29
  | `defineOpenApiConnection` | function | declare one OpenAPI document (object, JSON text or JSON URL) as a tool surface |
30
- | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent`; a call's arguments are parsed against the discovered schema before sending, except its unions, which the server judges (ADR 0266) |
30
+ | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent`; reported structural failures and bounds stay local, while unions and string-format/pattern refusals (including inside record keys) are judged by the server that owns the original schema (ADR 0266, ADR 0272) |
31
31
  | `ConnectionAuthorizationRequiredError` | class | typed reauthorization signal raised on `401` with credentials resolved again on the next call |
32
32
  | `ConnectionBudgetExceededError` | class | the mount would expose more foreign tools than its declared budget |
33
33
  | `ConnectionRequestError` | class | any non-`2xx` connection response other than the reauthorization signal |
@@ -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.
@@ -10869,9 +10900,10 @@ One unconvertible schema does not take the connection down. The tool
10869
10900
  is skipped and **named** (`onSkippedTool`, or a stderr line by default), so a
10870
10901
  surface of two hundred tools is not lost to one.
10871
10902
 
10872
- **A discovered schema is checked locally, except for its unions.** The arguments are
10873
- coerced and parsed against the schema the server advertised, so a missing field or a
10874
- wrong scalar is refused before anything is sent. A union in that schema is not judged
10903
+ **A discovered schema leaves unions and string formats to its server.** The arguments are
10904
+ coerced and parsed against the schema the server advertised. Reported structural failures
10905
+ (a missing field, wrong scalar type, unknown key or enum value) and bounds stay local.
10906
+ A union in that schema is not judged
10875
10907
  here: a server's presentation may join a discriminated union into one object whose
10876
10908
  shared field is an unlabelled `anyOf` (a stitchkit server with `flattenUnionInput`
10877
10909
  does), and judged against that, a wrong value could only be refused with every branch
@@ -10879,6 +10911,16 @@ listed. The value goes to the server, which holds the original schema, and its r
10879
10911
  names the one wrong field — `blocks.0.data.artifactId: expected string` rather than
10880
10912
  `No union branch matched — branch 1 … and 6 more branches`.
10881
10913
 
10914
+ String formats and patterns also lose the author's error messages in JSON Schema. A
10915
+ restored `date-time`, email, UUID or regex check would substitute Zod's generic wording.
10916
+ Those `invalid_format` refusals go to the remote instead: a bare `2026-10-12` reaches
10917
+ the original datetime schema, whose answer can explain that a full UTC timestamp such
10918
+ as `2026-10-12T00:00:00Z` is required. This also applies inside arrays, objects and
10919
+ record keys. A mixed refusal retains only its reported local reasons; a record-key
10920
+ wrapper stays local when it contains any of those reasons. A schema authored locally
10921
+ keeps its complete verdict, including custom errors and refinements. No second parse
10922
+ invents checks that the first parse did not reach. See [ADR 0272](../decisions/0272-a-restored-string-format-is-judged-by-its-server.md).
10923
+
10882
10924
  MCP connection limits follow the operation phase. `initialize`, the initialized
10883
10925
  notification, `tools/list` and legacy endpoint discovery use `limits.discovery`;
10884
10926
  `tools/call` uses `limits.call`. A mounted call's handshake still uses discovery
@@ -16276,6 +16318,25 @@ analytics policy belong to the application.
16276
16318
 
16277
16319
  # Upgrading stitchkit
16278
16320
 
16321
+ ## Released migration: 0.113.0
16322
+
16323
+ **Who must act:** custom `AgentRuntimeStoreDriver` adapters and custom `AgentRuntimeStore` implementations of `seedConversationInput`. The built-in memory and SQLite stores already implement the contract.
16324
+
16325
+ `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:
16326
+
16327
+ ```ts
16328
+ // after: one more branch in history.apply
16329
+ if (mutation.type === 'insert') {
16330
+ if (await exists(mutation.message.id)) return replaceInPlace(mutation.message)
16331
+ if (mutation.beforeMessageId === undefined) return appendAtEnd(mutation.message)
16332
+ const anchor = await activePosition(mutation.beforeMessageId) // refuse when missing
16333
+ await shiftPositionsFrom(anchor) // every row at or after it moves one down
16334
+ return insertAt(anchor, mutation.message)
16335
+ }
16336
+ ```
16337
+
16338
+ 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.
16339
+
16279
16340
  ## Released migration: 0.112.0
16280
16341
 
16281
16342
  **Who must act:** scripts using an array option together with bare positional arguments without a declared `positionals` policy, including calls to `parseCliArgs`.
@@ -22193,7 +22254,7 @@ Server-only optional application runtime. See the
22193
22254
  | `selectCompactableHistory` | function | which oldest whole complete turns may be summarised away — the half of compaction that needs no store (→ ADR 0142) |
22194
22255
  | `SelectCompactableHistoryOptions` / `CompactableHistory` | _type_ | message list, retained-turn count and evidence policy in; `leadingSummary`, `compactable` and `retained` out |
22195
22256
  | `createAgentSessionCoordinator` | function | strict process-local queue/interrupt/supersede lifecycle |
22196
- | `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
22257
+ | `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
22258
  | `AgentRuntimePrepareStep` | _type_ | per-run controlled step callback with typed domain context and managed run signal/fence |
22198
22259
  | `AgentContextOverflowError` | class | deliberate application budget refusal thrown from `loop.prepareStep`; terminalizes as `context_overflow` without classifying arbitrary error text |
22199
22260
  | `AgentRuntimeRecordIds` | _type_ | optional caller-provided input, run and assistant IDs for stable application records |
@@ -23053,7 +23114,7 @@ and approval path.
23053
23114
  | `ConnectionPhase` / `ConnectionOperation` / `ConnectionFailureContext` | _type_ | closed operation/phase vocabulary and measured read context for existing typed connection errors |
23054
23115
  | `ConnectionTimeoutError` / `ConnectionResponseTooLargeError` | class | bounded operation refusal, with phase, operation and finite observed bytes; safe tool projection retains the raw cause locally |
23055
23116
  | `defineOpenApiConnection` | function | declare one OpenAPI document (object, JSON text or JSON URL) as a tool surface |
23056
- | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent`; a call's arguments are parsed against the discovered schema before sending, except its unions, which the server judges (ADR 0266) |
23117
+ | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent`; reported structural failures and bounds stay local, while unions and string-format/pattern refusals (including inside record keys) are judged by the server that owns the original schema (ADR 0266, ADR 0272) |
23057
23118
  | `ConnectionAuthorizationRequiredError` | class | typed reauthorization signal raised on `401` with credentials resolved again on the next call |
23058
23119
  | `ConnectionBudgetExceededError` | class | the mount would expose more foreign tools than its declared budget |
23059
23120
  | `ConnectionRequestError` | class | any non-`2xx` connection response other than the reauthorization signal |
package/llms.txt CHANGED
@@ -17,15 +17,15 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
17
17
  - **stitchkit/tools/mcp**: [llms/tools-mcp.txt](llms/tools-mcp.txt) 1.8 KB
18
18
  - **stitchkit/tools/contract**: [llms/tools-contract.txt](llms/tools-contract.txt) 0.2 KB
19
19
  - **stitchkit/tools/invoker**: [llms/tools-invoker.txt](llms/tools-invoker.txt) 0.2 KB
20
- - **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.8 KB
21
- - **stitchkit/cli**: [llms/cli.txt](llms/cli.txt) 45.3 KB → [llms/cli.2.txt](llms/cli.2.txt) 21.4 KB
20
+ - **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.9 KB
21
+ - **stitchkit/cli**: [llms/cli.txt](llms/cli.txt) 45.3 KB → [llms/cli.2.txt](llms/cli.2.txt) 22.3 KB
22
22
  - **stitchkit/cli/publish**: [llms/cli-publish.txt](llms/cli-publish.txt) 1.5 KB
23
23
  - **stitchkit/remote**: [llms/remote.txt](llms/remote.txt) 1.0 KB
24
24
  - **stitchkit/contract**: [llms/contract.txt](llms/contract.txt) 31.9 KB
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.3",
3
+ "version": "0.113.1",
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",