stitchkit 0.104.2 → 0.105.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.
- package/CHANGELOG.md +372 -13
- package/darwin-native.cjs +4 -2
- package/dist/agent-runtime/browser-control-contract.d.ts +32 -2
- package/dist/agent-runtime/browser-control-contract.d.ts.map +1 -1
- package/dist/agent-runtime/browser-controller.d.ts +21 -3
- package/dist/agent-runtime/browser-controller.d.ts.map +1 -1
- package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-refusals.d.ts +1 -0
- package/dist/agent-runtime/coding-tool-refusals.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-shell.d.ts.map +1 -1
- package/dist/agent-runtime/compaction.d.ts.map +1 -1
- package/dist/agent-runtime/contained-write.d.ts.map +1 -1
- package/dist/agent-runtime/control-schema.d.ts +48 -1
- package/dist/agent-runtime/control-schema.d.ts.map +1 -1
- package/dist/agent-runtime/deferred-tool-search.d.ts +3 -2
- package/dist/agent-runtime/deferred-tool-search.d.ts.map +1 -1
- package/dist/agent-runtime/harness-control.d.ts.map +1 -1
- package/dist/agent-runtime/harness-realtime.d.ts +34 -4
- package/dist/agent-runtime/harness-realtime.d.ts.map +1 -1
- package/dist/agent-runtime/runtime-recovery.d.ts.map +1 -1
- package/dist/agent-runtime/runtime-state.d.ts.map +1 -1
- package/dist/agent-runtime/sandbox-contract.d.ts.map +1 -1
- package/dist/agent-runtime/sandbox-process-owner.d.ts +9 -1
- package/dist/agent-runtime/sandbox-process-owner.d.ts.map +1 -1
- package/dist/agent-runtime/sandbox.d.ts +32 -1
- package/dist/agent-runtime/sandbox.d.ts.map +1 -1
- package/dist/agent-runtime/schedule-records.d.ts.map +1 -1
- package/dist/agent-runtime/schedules.d.ts.map +1 -1
- package/dist/agent-runtime/store-events.d.ts +9 -4
- package/dist/agent-runtime/store-events.d.ts.map +1 -1
- package/dist/agent-runtime/testing.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-contract.d.ts +50 -0
- package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-generations.d.ts +24 -0
- package/dist/application/diagnostic-journal-generations.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-manager.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-open.d.ts +10 -0
- package/dist/application/diagnostic-journal-open.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-quarantine.d.ts +28 -0
- package/dist/application/diagnostic-journal-quarantine.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-read-contract.d.ts +73 -3
- package/dist/application/diagnostic-journal-read-contract.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-reader.d.ts +17 -2
- package/dist/application/diagnostic-journal-reader.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-recovery.d.ts +18 -2
- package/dist/application/diagnostic-journal-recovery.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-storage.d.ts +6 -2
- package/dist/application/diagnostic-journal-storage.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-tail.d.ts +12 -0
- package/dist/application/diagnostic-journal-tail.d.ts.map +1 -0
- package/dist/application/diagnostic-journal.d.ts +3 -0
- package/dist/application/diagnostic-journal.d.ts.map +1 -1
- package/dist/application/directory-inbox-accept.d.ts +3 -3
- package/dist/application/directory-inbox-accept.d.ts.map +1 -1
- package/dist/application/directory-inbox-contract.d.ts +38 -10
- package/dist/application/directory-inbox-contract.d.ts.map +1 -1
- package/dist/application/directory-inbox-delivery.d.ts +3 -3
- package/dist/application/directory-inbox-delivery.d.ts.map +1 -1
- package/dist/application/directory-inbox-files.d.ts +17 -2
- package/dist/application/directory-inbox-files.d.ts.map +1 -1
- package/dist/application/directory-inbox-state.d.ts +1 -1
- package/dist/application/directory-inbox-state.d.ts.map +1 -1
- package/dist/application/directory-inbox.d.ts +1 -1
- package/dist/application/directory-inbox.d.ts.map +1 -1
- package/dist/application/file-state-store.d.ts +21 -1
- package/dist/application/file-state-store.d.ts.map +1 -1
- package/dist/application/grammy.d.ts.map +1 -1
- package/dist/application/kernel-contract.d.ts.map +1 -1
- package/dist/application/revision-signal.d.ts.map +1 -1
- package/dist/application/state-store.d.ts +3 -0
- package/dist/application/state-store.d.ts.map +1 -1
- package/dist/browser/api-error.d.ts +38 -0
- package/dist/browser/api-error.d.ts.map +1 -0
- package/dist/browser/chunked-upload.d.ts.map +1 -1
- package/dist/browser/client-executors.d.ts.map +1 -1
- package/dist/browser/client-url.d.ts.map +1 -1
- package/dist/browser/contract-stream.d.ts.map +1 -1
- package/dist/browser/http.d.ts +0 -25
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/resumable.d.ts.map +1 -1
- package/dist/contract/define-validation.d.ts +0 -1
- package/dist/contract/define-validation.d.ts.map +1 -1
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/errors-factory.d.ts.map +1 -1
- package/dist/contract/errors.d.ts +15 -18
- package/dist/contract/errors.d.ts.map +1 -1
- package/dist/contract/normalize.d.ts.map +1 -1
- package/dist/durability/effect.d.ts.map +1 -1
- package/dist/durability/scheduler.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/browser.js +29 -18
- package/dist/entrypoints/agent-runtime/coding-tools.js +8 -7
- package/dist/entrypoints/agent-runtime/harness.js +15 -14
- package/dist/entrypoints/agent-runtime/realtime.d.ts +1 -1
- package/dist/entrypoints/agent-runtime/realtime.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/realtime.js +119 -54
- package/dist/entrypoints/agent-runtime/sandbox.js +23 -17
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +4 -3
- package/dist/entrypoints/agent-runtime/sqlite/node.js +4 -3
- package/dist/entrypoints/agent-runtime/testing.js +8 -6
- package/dist/entrypoints/agent-runtime.js +37 -38
- package/dist/entrypoints/application/diagnostic-journal.js +305 -111
- package/dist/entrypoints/application/directory-inbox.js +174 -77
- package/dist/entrypoints/application/grammy.js +5 -2
- package/dist/entrypoints/application/opentelemetry.js +2 -2
- package/dist/entrypoints/application.d.ts +2 -2
- package/dist/entrypoints/application.d.ts.map +1 -1
- package/dist/entrypoints/application.js +17 -8
- package/dist/entrypoints/cli/publish.d.ts +16 -0
- package/dist/entrypoints/cli/publish.d.ts.map +1 -0
- package/dist/entrypoints/cli/publish.js +527 -0
- package/dist/entrypoints/cli.d.ts +1 -2
- package/dist/entrypoints/cli.d.ts.map +1 -1
- package/dist/entrypoints/cli.js +59 -966
- package/dist/entrypoints/contract.js +3 -3
- package/dist/entrypoints/files/packaging.js +153 -64
- package/dist/entrypoints/files.d.ts +1 -0
- package/dist/entrypoints/files.d.ts.map +1 -1
- package/dist/entrypoints/files.js +17 -10
- package/dist/entrypoints/index.d.ts +2 -1
- package/dist/entrypoints/index.d.ts.map +1 -1
- package/dist/entrypoints/index.js +31 -60
- package/dist/entrypoints/node.js +8 -8
- package/dist/entrypoints/observability.js +3 -3
- package/dist/entrypoints/primitives.js +67 -83
- package/dist/entrypoints/process.d.ts +1 -1
- package/dist/entrypoints/process.d.ts.map +1 -1
- package/dist/entrypoints/process.js +2 -2
- package/dist/entrypoints/react.js +4 -2
- package/dist/entrypoints/remote.js +37 -13
- package/dist/entrypoints/server.js +18 -16
- package/dist/entrypoints/telegram/screens.js +5 -3
- package/dist/entrypoints/telegram.js +31 -46
- package/dist/entrypoints/testing.d.ts +1 -1
- package/dist/entrypoints/testing.d.ts.map +1 -1
- package/dist/entrypoints/testing.js +444 -448
- package/dist/entrypoints/tools/connections.js +268 -105
- package/dist/entrypoints/tools/contract.js +2 -2
- package/dist/entrypoints/tools/invoker.js +8 -7
- package/dist/entrypoints/tools/mcp.d.ts +2 -2
- package/dist/entrypoints/tools/mcp.d.ts.map +1 -1
- package/dist/entrypoints/tools/mcp.js +10 -9
- package/dist/entrypoints/tools.d.ts +0 -1
- package/dist/entrypoints/tools.d.ts.map +1 -1
- package/dist/entrypoints/tools.js +118 -53
- package/dist/entrypoints/tracking.js +2 -3
- package/dist/files/boundary.d.ts +2 -2
- package/dist/files/boundary.d.ts.map +1 -1
- package/dist/files/chunk-spool.d.ts.map +1 -1
- package/dist/files/file-io.d.ts +2 -2
- package/dist/files/file-io.d.ts.map +1 -1
- package/dist/files/native-packaging-layout.d.ts +50 -4
- package/dist/files/native-packaging-layout.d.ts.map +1 -1
- package/dist/files/native-packaging.d.ts +78 -17
- package/dist/files/native-packaging.d.ts.map +1 -1
- package/dist/{index-r5hsgkz5.js → index-0gs4ymfj.js} +6 -3
- package/dist/{index-zax7resm.js → index-0gxvns6s.js} +1 -13
- package/dist/index-0s4xebbg.js +8 -0
- package/dist/{index-r4r70zmh.js → index-12zsej7b.js} +5 -2
- package/dist/{index-kemm0ej5.js → index-1pwwan01.js} +65 -22
- package/dist/{index-vgkbcnkc.js → index-299sm5tr.js} +1 -1
- package/dist/{index-2vnh05w4.js → index-2k91mewf.js} +31 -74
- package/dist/{index-269zqj8m.js → index-2rc6jd9n.js} +28 -12
- package/dist/{index-wh0ecvyk.js → index-37asdw3a.js} +1 -1
- package/dist/index-3h0ztg0z.js +285 -0
- package/dist/{index-g95fk660.js → index-4vsby8n8.js} +8 -15
- package/dist/index-556g5hsh.js +17 -0
- package/dist/{index-adhgd4pe.js → index-5p55xreg.js} +2 -2
- package/dist/index-5w6t91ze.js +47 -0
- package/dist/{index-9pw0a51a.js → index-6yxhe58g.js} +40 -7
- package/dist/{index-6d9xaxw1.js → index-8ks9b85e.js} +33 -5
- package/dist/{index-bhb950qs.js → index-916yh4e2.js} +25 -12
- package/dist/index-9tqbxv5p.js +44 -0
- package/dist/{index-5csmzesf.js → index-azx12jgv.js} +4 -3
- package/dist/{index-mbnnw3f2.js → index-b0kddvzw.js} +15 -5
- package/dist/{index-n5yqxd3d.js → index-b0w7rbpt.js} +23 -2
- package/dist/index-b56nnscm.js +132 -0
- package/dist/{index-0ndk4555.js → index-c0hffcmj.js} +2 -2
- package/dist/{index-pptyv13k.js → index-c17xcx4k.js} +42 -6
- package/dist/{index-g2j7pnak.js → index-cmzvhhtd.js} +5 -2
- package/dist/index-cq59agna.js +51 -0
- package/dist/{index-ssmd41kh.js → index-d2h99n7d.js} +1 -1
- package/dist/{index-z94wht4y.js → index-dky0dcmf.js} +34 -5
- package/dist/{index-za6j7nwy.js → index-dsnjzb62.js} +104 -51
- package/dist/index-eemvahkc.js +21 -0
- package/dist/index-ef8gdaq0.js +105 -0
- package/dist/{index-fa4wg312.js → index-f199nfq5.js} +10 -6
- package/dist/{index-ck71tbcf.js → index-fsw1ybf3.js} +11 -15
- package/dist/{index-f330qqyg.js → index-g2vfg7ak.js} +217 -63
- package/dist/{index-fk18k56k.js → index-gr5g3xfw.js} +11 -18
- package/dist/{index-jn9g8xdt.js → index-hjvje0pf.js} +6 -4
- package/dist/{index-x928baz2.js → index-j9gxbztg.js} +18 -14
- package/dist/index-kfjkb396.js +37 -0
- package/dist/{index-6drst9sg.js → index-ksfagmyz.js} +45 -345
- package/dist/index-m616f0yz.js +120 -0
- package/dist/{index-fm1c1a08.js → index-m6w6jtda.js} +40 -21
- package/dist/{index-ptn0g0gj.js → index-ma963wz7.js} +21 -20
- package/dist/{index-bakgedh8.js → index-msfpyy2f.js} +2 -4
- package/dist/{index-ywppsaby.js → index-n1nszyk0.js} +23 -34
- package/dist/{index-v14qqmys.js → index-n4689krb.js} +1 -1
- package/dist/{index-a0zzh8ak.js → index-pz3y6b6g.js} +3 -3
- package/dist/{index-43p08g7t.js → index-pzb63z66.js} +12 -8
- package/dist/{index-h97tqqp1.js → index-qaet40b2.js} +5 -3
- package/dist/{index-t1sr4aks.js → index-qaqbdm7s.js} +52 -6
- package/dist/{index-77nxk6ay.js → index-r393tnfp.js} +16 -10
- package/dist/{index-kb8styz3.js → index-rpzewktb.js} +15 -5
- package/dist/{index-27a2pj09.js → index-sj28htvf.js} +1 -1
- package/dist/index-szybbezc.js +455 -0
- package/dist/{index-2hyavjjj.js → index-wbhdzxar.js} +3 -3
- package/dist/{index-4e0ah203.js → index-wdy68sh6.js} +47 -24
- package/dist/{index-hbd32c6a.js → index-wqmvtnkp.js} +38 -89
- package/dist/{index-hp9d77wk.js → index-x7w1z6pf.js} +15 -4
- package/dist/{index-20yvtn9a.js → index-yt7gyg5x.js} +1 -1
- package/dist/{index-cvda079a.js → index-yvfk3y36.js} +12 -2
- package/dist/{index-5z6jn897.js → index-z23rfxhj.js} +1 -1
- package/dist/internal/abort-race.d.ts +8 -2
- package/dist/internal/abort-race.d.ts.map +1 -1
- package/dist/internal/atomic-file.d.ts +55 -9
- package/dist/internal/atomic-file.d.ts.map +1 -1
- package/dist/internal/atomic-publication.d.ts +39 -4
- package/dist/internal/atomic-publication.d.ts.map +1 -1
- package/dist/internal/atomic-staging.d.ts +46 -0
- package/dist/internal/atomic-staging.d.ts.map +1 -0
- package/dist/internal/bounded-file-read.d.ts +19 -11
- package/dist/internal/bounded-file-read.d.ts.map +1 -1
- package/dist/internal/bounded-lines.d.ts.map +1 -1
- package/dist/internal/close-after.d.ts +11 -0
- package/dist/internal/close-after.d.ts.map +1 -0
- package/dist/internal/deadline.d.ts +10 -0
- package/dist/internal/deadline.d.ts.map +1 -1
- package/dist/internal/exclusive-lock-read.d.ts +10 -12
- package/dist/internal/exclusive-lock-read.d.ts.map +1 -1
- package/dist/internal/exclusive-lock.d.ts +2 -2
- package/dist/internal/exclusive-lock.d.ts.map +1 -1
- package/dist/internal/file-observation.d.ts +14 -0
- package/dist/internal/file-observation.d.ts.map +1 -0
- package/dist/internal/json-data.d.ts +22 -5
- package/dist/internal/json-data.d.ts.map +1 -1
- package/dist/internal/positive-integer.d.ts +9 -0
- package/dist/internal/positive-integer.d.ts.map +1 -0
- package/dist/internal/process-instance.d.ts +35 -5
- package/dist/internal/process-instance.d.ts.map +1 -1
- package/dist/internal/secure-fetch.d.ts.map +1 -1
- package/dist/internal/timers.d.ts +11 -0
- package/dist/internal/timers.d.ts.map +1 -0
- package/dist/internal/with-exclusive-lock.d.ts +5 -4
- package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
- package/dist/observability/bounded-sink.d.ts.map +1 -1
- package/dist/primitives/canonical-json.d.ts +23 -2
- package/dist/primitives/canonical-json.d.ts.map +1 -1
- package/dist/primitives/delivery.d.ts.map +1 -1
- package/dist/primitives/index.d.ts +1 -1
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/money.d.ts.map +1 -1
- package/dist/process/cleanup.d.ts +6 -1
- package/dist/process/cleanup.d.ts.map +1 -1
- package/dist/process/command-lifetime.d.ts +4 -0
- package/dist/process/command-lifetime.d.ts.map +1 -1
- package/dist/process/command-owner.d.ts.map +1 -1
- package/dist/process/command.d.ts +4 -0
- package/dist/process/command.d.ts.map +1 -1
- package/dist/process/contract.d.ts +67 -2
- package/dist/process/contract.d.ts.map +1 -1
- package/dist/process/group.d.ts +40 -3
- package/dist/process/group.d.ts.map +1 -1
- package/dist/process/launch.d.ts +12 -1
- package/dist/process/launch.d.ts.map +1 -1
- package/dist/process/terminate.d.ts +39 -0
- package/dist/process/terminate.d.ts.map +1 -0
- package/dist/react/query-client.d.ts.map +1 -1
- package/dist/realtime/rejection.d.ts.map +1 -1
- package/dist/server/contract-stream.d.ts.map +1 -1
- package/dist/server/handler-state.d.ts.map +1 -1
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/request-body.d.ts +0 -1
- package/dist/server/request-body.d.ts.map +1 -1
- package/dist/server/unix-client.d.ts.map +1 -1
- package/dist/telegram/broadcast-delivery.d.ts.map +1 -1
- package/dist/telegram/broadcast-failure.d.ts +10 -2
- package/dist/telegram/broadcast-failure.d.ts.map +1 -1
- package/dist/telegram/operator-channel.d.ts.map +1 -1
- package/dist/telegram/screens/outcome.d.ts.map +1 -1
- package/dist/testing/surface-conformance.d.ts +1 -1
- package/dist/testing/surface-conformance.d.ts.map +1 -1
- package/dist/testing/surface-manifest.d.ts +0 -6
- package/dist/testing/surface-manifest.d.ts.map +1 -1
- package/dist/tools/agent.d.ts +1 -1
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/cli/args.d.ts +1 -1
- package/dist/tools/cli/args.d.ts.map +1 -1
- package/dist/tools/cli/help.d.ts.map +1 -1
- package/dist/tools/cli/invoke.d.ts +2 -2
- package/dist/tools/cli/invoke.d.ts.map +1 -1
- package/dist/tools/cli/profile.d.ts.map +1 -1
- package/dist/tools/cli/publication-assets.d.ts.map +1 -1
- package/dist/tools/cli/publication-contract.d.ts +8 -0
- package/dist/tools/cli/publication-contract.d.ts.map +1 -1
- package/dist/tools/cli/publication-control.d.ts.map +1 -1
- package/dist/tools/cli/publication-storage.d.ts +23 -2
- package/dist/tools/cli/publication-storage.d.ts.map +1 -1
- package/dist/tools/cli/publication.d.ts +8 -1
- package/dist/tools/cli/publication.d.ts.map +1 -1
- package/dist/tools/connections/errors.d.ts +18 -6
- package/dist/tools/connections/errors.d.ts.map +1 -1
- package/dist/tools/connections/limits.d.ts +8 -2
- package/dist/tools/connections/limits.d.ts.map +1 -1
- package/dist/tools/connections/mcp-client.d.ts.map +1 -1
- package/dist/tools/connections/mcp-envelope.d.ts.map +1 -1
- package/dist/tools/connections/openapi.d.ts.map +1 -1
- package/dist/tools/connections/schema-budget.d.ts +1 -1
- package/dist/tools/connections/schema-budget.d.ts.map +1 -1
- package/dist/tools/connections/sse-session.d.ts.map +1 -1
- package/dist/tools/execute-args.d.ts.map +1 -1
- package/dist/tools/execute-result.d.ts.map +1 -1
- package/dist/tools/internal/surface-projector.d.ts +17 -3
- package/dist/tools/internal/surface-projector.d.ts.map +1 -1
- package/dist/tools/internal/tool-error-projection.d.ts +16 -0
- package/dist/tools/internal/tool-error-projection.d.ts.map +1 -0
- package/dist/tools/internal/tool-view.d.ts.map +1 -1
- package/dist/tools/invoker.d.ts.map +1 -1
- package/dist/tools/list-names.d.ts +3 -2
- package/dist/tools/list-names.d.ts.map +1 -1
- package/dist/tools/manifest.d.ts +3 -2
- package/dist/tools/manifest.d.ts.map +1 -1
- package/dist/tools/mcp/handler.d.ts +7 -0
- package/dist/tools/mcp/handler.d.ts.map +1 -1
- package/dist/tools/mcp/mount.d.ts +18 -2
- package/dist/tools/mcp/mount.d.ts.map +1 -1
- package/dist/tools/mcp/prepare.d.ts +3 -3
- package/dist/tools/mcp/prepare.d.ts.map +1 -1
- package/dist/tools/mcp/register.d.ts.map +1 -1
- package/dist/tools/mcp/runtime-tools.d.ts.map +1 -1
- package/dist/tools/mcp/stdio-signals.d.ts +14 -0
- package/dist/tools/mcp/stdio-signals.d.ts.map +1 -1
- package/dist/tools/mcp/stdio.d.ts +7 -0
- package/dist/tools/mcp/stdio.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-runtime-tools.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-runtime-types.d.ts +3 -3
- package/dist/tools/operations/async-operation-runtime-types.d.ts.map +1 -1
- package/dist/tools/operations/define-wait-tool.d.ts +1 -1
- package/dist/tools/operations/define-wait-tool.d.ts.map +1 -1
- package/dist/tools/operations/wait-core.d.ts +0 -6
- package/dist/tools/operations/wait-core.d.ts.map +1 -1
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/remote.d.ts +1 -1
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/{runtime-tool-execution.d.ts → runtime-tool-declaration.d.ts} +32 -9
- package/dist/tools/runtime-tool-declaration.d.ts.map +1 -0
- package/dist/tools/runtime-tool-mcp.d.ts +6 -15
- package/dist/tools/runtime-tool-mcp.d.ts.map +1 -1
- package/dist/tools/runtime-tool.d.ts +14 -12
- package/dist/tools/runtime-tool.d.ts.map +1 -1
- package/dist/tools/schema/coerce.d.ts +4 -0
- package/dist/tools/schema/coerce.d.ts.map +1 -1
- package/dist/tools/schema/flatten-join.d.ts.map +1 -1
- package/dist/tools/surface.d.ts +7 -11
- package/dist/tools/surface.d.ts.map +1 -1
- package/dist/tools/transfer/define-download-tool.d.ts +1 -1
- package/dist/tools/transfer/define-download-tool.d.ts.map +1 -1
- package/dist/tools/transfer/define-upload-tool.d.ts +1 -1
- package/dist/tools/transfer/define-upload-tool.d.ts.map +1 -1
- package/dist/tools/transfer/define-view-file-tool.d.ts +1 -1
- package/dist/tools/transfer/define-view-file-tool.d.ts.map +1 -1
- package/dist/tools/transfer/managed-file-error.d.ts.map +1 -1
- package/dist/tools/transfer/view-file-contract.d.ts.map +1 -1
- package/dist/tools/transfer/view-file.d.ts +1 -1
- package/dist/tools/transfer/view-file.d.ts.map +1 -1
- package/dist/tools/transports.d.ts +3 -2
- package/dist/tools/transports.d.ts.map +1 -1
- package/llms/agent-runtime-browser.txt +10 -4
- package/llms/agent-runtime-harness.txt +32 -31
- package/llms/agent-runtime-react.txt +1 -1
- package/llms/agent-runtime-realtime.txt +14 -5
- package/llms/agent-runtime-sandbox.txt +3 -11
- package/llms/agent-runtime.3.txt +2 -2
- package/llms/agent-runtime.txt +0 -9
- package/llms/application.2.txt +3 -12
- package/llms/application.3.txt +7 -4
- package/llms/application.txt +44 -15
- package/llms/cli-publish.txt +29 -0
- package/llms/cli.2.txt +9 -11
- package/llms/cli.txt +26 -14
- package/llms/declaration.txt +0 -9
- package/llms/files-packaging.txt +16 -8
- package/llms/files.txt +4 -2
- package/llms/geo.txt +0 -9
- package/llms/live.txt +4 -13
- package/llms/observability.txt +31 -5
- package/llms/primitives.txt +38 -20
- package/llms/process.txt +287 -157
- package/llms/react-keyboard.txt +0 -9
- package/llms/react.txt +0 -18
- package/llms/server.4.txt +1 -1
- package/llms/server.5.txt +1 -1
- package/llms/server.txt +1 -1
- package/llms/stitchkit.txt +6 -7
- package/llms/telegram-screens.txt +2 -2
- package/llms/testing.txt +0 -1
- package/llms/tools-mcp.txt +2 -3
- package/llms/tools.2.txt +12 -0
- package/llms/tools.3.txt +5 -6
- package/llms/tools.txt +6 -4
- package/llms/upgrading-0.37.0-0.50.0.txt +947 -0
- package/llms/{upgrading-0.44.0-0.61.0.txt → upgrading-0.53.0-0.67.0.txt} +576 -506
- package/llms/{upgrading-0.62.0-0.80.0.txt → upgrading-0.68.0-0.94.0.txt} +562 -576
- package/llms/{upgrading-0.81.0-0.104.0.txt → upgrading-0.95.0-0.105.0.txt} +452 -567
- package/llms/upgrading.txt +4 -4
- package/llms-full.txt +1029 -409
- package/llms.txt +24 -24
- package/native-assets.json +11 -3
- package/package.json +6 -6
- package/dist/agent-runtime/harness-tools.d.ts +0 -11
- package/dist/agent-runtime/harness-tools.d.ts.map +0 -1
- package/dist/entrypoints/agent-runtime/harness-tools.d.ts +0 -2
- package/dist/entrypoints/agent-runtime/harness-tools.d.ts.map +0 -1
- package/dist/entrypoints/agent-runtime/harness-tools.js +0 -32
- package/dist/index-1a6jtnd9.js +0 -88
- package/dist/index-8a9ksm91.js +0 -95
- package/dist/index-a3wma1hk.js +0 -48
- package/dist/index-jd470k6q.js +0 -109
- package/dist/index-n1dqr7gf.js +0 -20
- package/dist/index-nggfa2yn.js +0 -34
- package/dist/index-s4evrmp5.js +0 -98
- package/dist/index-ze1eph1k.js +0 -20
- package/dist/tools/connections/error-projection.d.ts +0 -4
- package/dist/tools/connections/error-projection.d.ts.map +0 -1
- package/dist/tools/runtime-tool-execution.d.ts.map +0 -1
- package/llms/agent-runtime-harness-tools.txt +0 -25
- package/llms/upgrading-0.37.0-0.44.0.txt +0 -444
|
@@ -1,14 +1,573 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.68.0 → 0.94.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.
|
|
6
|
+
Contains: Guide: Upgrading, 0.68.0 → 0.94.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.68.0 → 0.94.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.94.0
|
|
13
|
+
|
|
14
|
+
One breaking minor that consolidates: tool options move into one group, and
|
|
15
|
+
names that were exported from two entrypoints keep only their owner. Every step
|
|
16
|
+
is an edit a type checker or `defineContract` points at; the few behaviour
|
|
17
|
+
changes that need no edit are under Changed and Fixed in the changelog.
|
|
18
|
+
|
|
19
|
+
1. **Move endpoint tool options into `tool`.** **Who must act:** every project
|
|
20
|
+
with an endpoint that sets `toolName`, `ui`, `annotations` or `mcp`. Run the
|
|
21
|
+
codemod from a checkout of this repository, then typecheck:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bun packages/core/scripts/codemod-tool-group.ts --check path/to/your/src # list
|
|
25
|
+
bun packages/core/scripts/codemod-tool-group.ts path/to/your/src # rewrite
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
// before
|
|
30
|
+
{ method: 'GET', path: '/', desc: 'List', toolName: 'user_list', mcp: { inputRequired } }
|
|
31
|
+
// after
|
|
32
|
+
{ method: 'GET', path: '/', desc: 'List', tool: { name: 'user_list', mcp: { inputRequired } } }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The codemod leaves two kinds of endpoint for a person and prints where: one
|
|
36
|
+
built with a spread (`{ ...base, toolName }`), and one exposed on HTTP only,
|
|
37
|
+
whose tool options never reached a tool — delete them there. Anything left
|
|
38
|
+
over fails at startup, by name — a key moved into the group under its old
|
|
39
|
+
name (`tool: { toolName }`) included:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
Contract "users": endpoint "list" sets `toolName` — tool options live in `tool` since 0.94.0: use tool.name
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`expose` does not move. `MethodDef` — what hooks and runtime tools see — keeps
|
|
46
|
+
`toolName`, `ui`, `annotations` and `mcp` at the top level, so hook code does
|
|
47
|
+
not change. A tool view is declared only with `withToolView`, which now puts
|
|
48
|
+
it in `tool.view`.
|
|
49
|
+
|
|
50
|
+
2. **Change imports of moved names.** **Who must act:** projects importing any
|
|
51
|
+
of these; the compiler lists every site.
|
|
52
|
+
|
|
53
|
+
| Name | From | To |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `RuntimeToolTransport`, `ToolSurfaceTransport`, `ToolInvokerTransport` | `stitchkit/tools`, `stitchkit/tools/invoker`, `stitchkit/tools/connections` | `ToolTransport` from `stitchkit/contract` |
|
|
56
|
+
| `createCli`, `defineCliCommand`, `CliConfig`, `CliSurfaceSource`, `CliPresentationPolicyConfig`, `CliWaitConfig`, `ExitCodeMap`, `CliCommand*` | `stitchkit/tools` | `stitchkit/cli` |
|
|
57
|
+
| `parseSSE`, `ParseSSEOptions` | `stitchkit/server` | `stitchkit` |
|
|
58
|
+
| `runAgentStoreConformance`, `AgentStoreConformance*`, `createAgentRace*`, `AgentRace*` | `stitchkit/testing` | `stitchkit/agent-runtime/testing` |
|
|
59
|
+
| `createLocalStepDurability`, `LocalStepDurability`, `LocalStepDurabilityOptions`, `StepDurabilityLedger` | `stitchkit/agent-runtime` | `stitchkit/tools` |
|
|
60
|
+
|
|
61
|
+
3. **Regenerate a surface snapshot only if it reports drift.** **Who must act:**
|
|
62
|
+
a project whose committed snapshot has an object with integer-like keys
|
|
63
|
+
(`"9"`, `"10"`) — they are now sorted like every other key. Every other
|
|
64
|
+
snapshot, CLI manifest signature and agent-store archive is byte-identical.
|
|
65
|
+
|
|
66
|
+
## Released migration: 0.93.0
|
|
67
|
+
|
|
68
|
+
1. **Regenerate every committed surface snapshot, once.** `manifestVersion` is
|
|
69
|
+
`3` and each operation row gained `mcp` — the rounds it declares before it
|
|
70
|
+
runs. Most rows get `null`, so the first diff is large and mechanical.
|
|
71
|
+
**Who must act:** anyone with a committed snapshot. A snapshot on the older
|
|
72
|
+
version is refused by name rather than failing a schema literal:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
Surface snapshot is manifestVersion 2; this build writes 3. Regenerate it
|
|
76
|
+
and review the diff — the format changed, so the first regeneration is
|
|
77
|
+
expected to be large.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// before — a declared round left no trace, so declaring or removing one
|
|
82
|
+
// passed review invisibly
|
|
83
|
+
manifest.operations[0]
|
|
84
|
+
// after
|
|
85
|
+
manifest.operations[0].mcp
|
|
86
|
+
// null | { inputRequired: [{ key, message, schema }] }
|
|
87
|
+
// | { inputRequired: 'resolved-per-call' }
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
A project that kept its own test for "declared `inputRequired` implies a
|
|
91
|
+
configured state key" can drop it: the snapshot holds that link now.
|
|
92
|
+
|
|
93
|
+
2. **Nothing else to do.** Native commands that declare `output` became
|
|
94
|
+
invokable in process; a name that answered `NOT_FOUND` from
|
|
95
|
+
`createCliInvoker` in 0.92.0 may now resolve. If an application relied on
|
|
96
|
+
native commands being unreachable there, stop passing them to the invoker.
|
|
97
|
+
|
|
98
|
+
## Released migration: 0.92.0
|
|
99
|
+
|
|
100
|
+
1. **`RequestEvent.method`, `path` and `statusCode` are optional.** Work that did
|
|
101
|
+
not arrive over a transport now records their **absence** instead of inventing
|
|
102
|
+
values — a background loop used to write `method: 'AGENT'`, which is not a
|
|
103
|
+
verb. **Who must act:** anyone whose `RequestEventSinkConfig.write` puts these
|
|
104
|
+
into NOT NULL columns, or whose filter reads `event.method`.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
// before
|
|
108
|
+
write: (event) => db.audit.create({ data: { method: event.method, path: event.path, status: event.statusCode } })
|
|
109
|
+
// after — a job has none of the three; `kind` says which kind of row it is
|
|
110
|
+
write: (event) => db.audit.create({ data: {
|
|
111
|
+
kind: event.kind,
|
|
112
|
+
name: event.name ?? null,
|
|
113
|
+
method: event.method ?? null,
|
|
114
|
+
path: event.path ?? null,
|
|
115
|
+
status: event.statusCode ?? null,
|
|
116
|
+
} })
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
A filter written as `event.method !== 'GET'` keeps jobs (`undefined !== 'GET'`),
|
|
120
|
+
which is usually what you want. To exclude them deliberately:
|
|
121
|
+
`event.kind === 'request' && event.method !== 'GET'`.
|
|
122
|
+
|
|
123
|
+
2. **`applyCliUpdate` needs the manifest when given a trust root.** The signature
|
|
124
|
+
covers the manifest and every asset digest together, so an asset alone cannot
|
|
125
|
+
be verified. **Who must act:** only callers adopting signature verification;
|
|
126
|
+
the unsigned call is unchanged.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
// before
|
|
130
|
+
await applyCliUpdate({ asset })
|
|
131
|
+
// after
|
|
132
|
+
await applyCliUpdate({ asset, manifest: check.manifest, trust })
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
3. **An MCP continuation minted before this release is refused once.** The signed
|
|
136
|
+
round state now carries a fingerprint of the question plan, checked on every
|
|
137
|
+
round, so a plan that moved between rounds is a refusal rather than a
|
|
138
|
+
different question asked under the previous one's key. A conversation already
|
|
139
|
+
in flight at deploy time has no fingerprint and gets
|
|
140
|
+
`INVALID_REQUEST_STATE`; the host re-asks and the second attempt succeeds.
|
|
141
|
+
**Who must act:** nobody — but expect a small number of these in the minutes
|
|
142
|
+
after a deploy, and do not read them as tampering.
|
|
143
|
+
|
|
144
|
+
## Released migration: 0.91.0
|
|
145
|
+
|
|
146
|
+
1. `STITCH_ERROR_STATUS` gained `NOT_IMPLEMENTED` (501). An **exhaustive** error
|
|
147
|
+
vocabulary must name it — without the row `defineErrors({ mapping: { exhaustive:
|
|
148
|
+
true } })` stops compiling and then throws at startup. Nothing else in this
|
|
149
|
+
release requires action.
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
// before
|
|
153
|
+
map: { …, WAIT_TIMEOUT: 'timeout' }
|
|
154
|
+
// after
|
|
155
|
+
map: { …, NOT_IMPLEMENTED: 'not_implemented', WAIT_TIMEOUT: 'timeout' }
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The code is thrown only by the new dev-only `onMissingHandler: 'stub'` policy;
|
|
159
|
+
a vocabulary that is not exhaustive is unaffected.
|
|
160
|
+
|
|
161
|
+
## Released migration: 0.90.0
|
|
162
|
+
|
|
163
|
+
1. `stitchkit.watch.value` is a discriminated union on `kind` — `full`, `delta`,
|
|
164
|
+
`unchanged` — and every frame carries `fingerprint`. **Both ends must come from
|
|
165
|
+
the same major.** A client older than this release reads a `delta` frame as a
|
|
166
|
+
value of `undefined`, silently; upgrade the hub and the pages that talk to it
|
|
167
|
+
together, or set `deltaMemoryBytes: 0` on the hub until they are.
|
|
168
|
+
|
|
169
|
+
Applications using `createWatchClient` need no code change: it rebuilds the
|
|
170
|
+
value and hands the listener the whole answer as before. Code that reads
|
|
171
|
+
`WatchValueFrame.value` directly — a hand-written subscriber, a test double —
|
|
172
|
+
narrows on `kind` first.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
// before: frame.value
|
|
176
|
+
// after:
|
|
177
|
+
if (frame.kind === 'full') hold(frame.value);
|
|
178
|
+
else if (frame.kind === 'delta') hold(applyWatchDelta(held, frame.delta));
|
|
179
|
+
// 'unchanged' leaves what you hold standing
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
2. `AttachedWatcher.open` takes an optional third argument, `have`. A custom
|
|
183
|
+
server binding that forwards `stitchkit.watch.open` should pass the payload's
|
|
184
|
+
`have` through; omitting it costs a whole value on every reconnection and is
|
|
185
|
+
otherwise harmless.
|
|
186
|
+
|
|
187
|
+
## Released migration: 0.89.0
|
|
188
|
+
|
|
189
|
+
1. Custom `AgentRuntimeStore` adapters implement `seedConversationInput`; custom
|
|
190
|
+
`AgentRuntimeStoreDriver` adapters implement `seeds.load` and `seeds.create` together
|
|
191
|
+
with atomic, ordered history insertion. Use the maintained Prisma example and run
|
|
192
|
+
`runAgentStoreConformance` against the adapter. Built-in memory and SQLite
|
|
193
|
+
stores already implement the contract; SQLite migrates to schema version 3.
|
|
194
|
+
2. OpenRouter usage normalization consumes each completed SDK step's `usage`, including
|
|
195
|
+
`raw`, rather than aggregate usage. Missing counters stay `unavailable`.
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
// before: normalizeOpenRouterUsage(await result.usage, metadata)
|
|
199
|
+
// after:
|
|
200
|
+
for (const step of await result.steps) {
|
|
201
|
+
const usage = normalizeOpenRouterUsage(step.usage, step.providerMetadata);
|
|
202
|
+
// Persist the step's measured usage with its provenance.
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
3. Durable step bodies return lossless JSON. Convert dates explicitly, reject invalid
|
|
207
|
+
numbers upstream, and return `null` after an effect-only operation.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
await context.step('send', async () => {
|
|
211
|
+
await sendIdempotently();
|
|
212
|
+
return null;
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
First execution, replay and concurrent callers receive detached values. Persistence
|
|
217
|
+
does not make external effects transactional; the host retains idempotency and recovery.
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
How to move a consuming project from one stitchkit version to another — including
|
|
221
|
+
across many versions at once (a project frozen on an old version, then jumped
|
|
222
|
+
forward). The process is mechanical: stitchkit marks every breaking change in one
|
|
223
|
+
place and one format, so you can recover the full migration from the version diff.
|
|
224
|
+
|
|
225
|
+
## Released migration: 0.88.0
|
|
226
|
+
|
|
227
|
+
Two mechanical edits, and only if your project builds these values rather than only reading them.
|
|
228
|
+
|
|
229
|
+
A completed step event now carries the provider's response identity, and the field is required:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
// before
|
|
233
|
+
{ type: 'step-finished', step: 0, usage }
|
|
234
|
+
|
|
235
|
+
// after
|
|
236
|
+
{ type: 'step-finished', step: 0, usage, response: { id: generationId } }
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Every event the runtime emits already has it, so a sink that only reads them needs no change. A
|
|
240
|
+
fixture, a test double or a pipeline that re-validates events persisted by an earlier version does:
|
|
241
|
+
give the older records a response identity, or keep parsing them with the schema they were written
|
|
242
|
+
under.
|
|
243
|
+
|
|
244
|
+
If you implement the whole `AgentRuntime` interface — usually a mock — add the new method:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
// before
|
|
248
|
+
const fake: AgentRuntime = { submit, interrupt, recover, close }
|
|
249
|
+
|
|
250
|
+
// after
|
|
251
|
+
const fake: AgentRuntime = { submit, interrupt, abandon, recover, close }
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
No data migration is involved, and nothing in the store changes shape.
|
|
255
|
+
|
|
256
|
+
## Released migration: 0.87.0
|
|
257
|
+
|
|
258
|
+
Only if your project implements `AgentConversationReader` itself. A message page
|
|
259
|
+
now names which of its messages compaction removed:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
// before
|
|
263
|
+
return { items, ...(nextCursor && { nextCursor }) }
|
|
264
|
+
|
|
265
|
+
// after
|
|
266
|
+
return { items, compacted: [], ...(nextCursor && { nextCursor }) }
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
An empty array is the honest answer for a reader that pages only the active
|
|
270
|
+
history; it is what the SQLite reader returns unless the caller asks for
|
|
271
|
+
`includeCompacted`. Calling the reader needs no change, and no data migration is
|
|
272
|
+
involved.
|
|
273
|
+
|
|
274
|
+
## Released migration: 0.86.0
|
|
275
|
+
|
|
276
|
+
Only if you branch on `AgentTerminalReason` or show it to a person. Three
|
|
277
|
+
failures that used to arrive as `provider_failure` now arrive as themselves:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
// before
|
|
281
|
+
if (run.terminalReason === 'provider_failure') showOutage()
|
|
282
|
+
|
|
283
|
+
// after
|
|
284
|
+
switch (run.terminalReason) {
|
|
285
|
+
case 'provider_failure':
|
|
286
|
+
showOutage()
|
|
287
|
+
break
|
|
288
|
+
case 'storage_conflict':
|
|
289
|
+
// Another writer took this run's revision, or the store refused the write.
|
|
290
|
+
retryOrReport()
|
|
291
|
+
break
|
|
292
|
+
case 'output_rejected':
|
|
293
|
+
// Your own `protocol.acceptTerminal` refused the finished message.
|
|
294
|
+
reportRejectedAnswer()
|
|
295
|
+
break
|
|
296
|
+
case 'runtime_failure':
|
|
297
|
+
// The runtime, or a check the SDK ran on what it was handed, failed
|
|
298
|
+
// before the provider was reached.
|
|
299
|
+
reportInternal()
|
|
300
|
+
break
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
A run that never reached the provider can no longer report `provider_failure`,
|
|
305
|
+
so an alert keyed on that value stops firing for causes that were never the
|
|
306
|
+
provider's.
|
|
307
|
+
|
|
308
|
+
If you implement `AgentRuntimeStore` directly, add the event-ledger surface:
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
const store: AgentRuntimeStore = {
|
|
312
|
+
// existing normalized operations
|
|
313
|
+
appendEvent,
|
|
314
|
+
readEvents,
|
|
315
|
+
exportConversation,
|
|
316
|
+
importConversation,
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
If you implement an `AgentRuntimeStoreDriver` (Prisma, Postgres, any external
|
|
321
|
+
database), the ledger is yours to keep: `events` is a required member, and it
|
|
322
|
+
needs a table.
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
// before
|
|
326
|
+
const driver: AgentRuntimeStoreDriver<Tx> = { transaction, head, runs, admissions, history, scanRecoverable }
|
|
327
|
+
|
|
328
|
+
// after
|
|
329
|
+
const driver: AgentRuntimeStoreDriver<Tx> = {
|
|
330
|
+
transaction, head, runs, admissions, history, scanRecoverable,
|
|
331
|
+
events: {
|
|
332
|
+
// One row per event; `seq` is per conversation, starts at 1, and is
|
|
333
|
+
// assigned inside the caller's transaction so concurrent appends cannot
|
|
334
|
+
// share or skip a number.
|
|
335
|
+
append: async (tx, draft) => {
|
|
336
|
+
// Two transactions that both read max(seq) and both insert max + 1
|
|
337
|
+
// collide on the primary key; under SERIALIZABLE the snapshot predates
|
|
338
|
+
// any lock you take here. Treat a unique violation on this table as a
|
|
339
|
+
// serialization conflict and re-run the whole transaction — see
|
|
340
|
+
// `runTransaction` in examples/agent-store-prisma/adapter.ts.
|
|
341
|
+
const seq = (await tx.event.aggregate({ _max: { seq: true }, where: { conversationId: draft.conversationId } }))._max.seq ?? 0
|
|
342
|
+
await tx.event.create({ data: { ...draft, seq: seq + 1, payload: JSON.stringify(draft.payload) } })
|
|
343
|
+
return { ...draft, seq: seq + 1 }
|
|
344
|
+
},
|
|
345
|
+
// Ordered by `seq`, bounded by `fromSeq`/`toSeq`/`limit`; `nextSeq` when
|
|
346
|
+
// more remain.
|
|
347
|
+
list: async (tx, input) => { /* see examples/agent-store-prisma/adapter.ts */ },
|
|
348
|
+
},
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
The table carries `eventId` (unique), `conversationId`, `seq`, `schemaVersion`,
|
|
353
|
+
`kind`, `occurredAt`, `ignorable` and `payload`. `runAgentStoreConformance`
|
|
354
|
+
from `stitchkit/testing` now exercises it — contiguous `seq` under twenty
|
|
355
|
+
concurrent appends, bounded reads, the `ignorable` flag, a byte-stable export
|
|
356
|
+
— so run it against your driver before deploying. Expect one more insert per
|
|
357
|
+
run operation (`runtime/transition`) and one per model step
|
|
358
|
+
(`provider/request`) on the hot path; there is no opt-out.
|
|
359
|
+
|
|
360
|
+
If you operate a built-in SQLite store file:
|
|
361
|
+
|
|
362
|
+
1. Back the file up. The first open by 0.86.0 migrates it to schema 2 in one
|
|
363
|
+
transaction and there is no way back: a 0.85.x package refuses a migrated
|
|
364
|
+
file with `Unsupported Stitchkit agent-runtime SQLite schema version 2`.
|
|
365
|
+
2. Check the build for FTS5 before deploying:
|
|
366
|
+
|
|
367
|
+
```sql
|
|
368
|
+
SELECT sqlite_compileoption_used('ENABLE_FTS5');
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
A build without it is refused at open with `requires FTS5 support`. On the
|
|
372
|
+
machine this was verified, Bun 1.3 `bun:sqlite` and Node 24.18 `node:sqlite`
|
|
373
|
+
both carry it; verify your own build rather than assuming — the table of
|
|
374
|
+
supported runtimes says Node ≥ 22.5, and FTS5 there is not verified here.
|
|
375
|
+
3. Know what the migration wrote. Each existing conversation becomes one
|
|
376
|
+
`runtime/baseline` event at `seq 1`, dated when the migration ran, with
|
|
377
|
+
`asOf` inside the payload naming the last message it describes. Event
|
|
378
|
+
search and projections address that conversation's pre-migration history as
|
|
379
|
+
one snapshot at `seq 1`; event-level precision begins with the first event
|
|
380
|
+
after the migration.
|
|
381
|
+
|
|
382
|
+
If you subscribe to `AgentRuntimeEvent` and switch over `event.type`
|
|
383
|
+
exhaustively, add the transient `attempt-reset` case — drop the run's
|
|
384
|
+
transient text — or the reducer stops compiling; a reducer that ignores it
|
|
385
|
+
keeps a failed attempt's partial text on screen.
|
|
386
|
+
|
|
387
|
+
New in this release, not a migration: child runs cascade only when the manager
|
|
388
|
+
is given to the runtime —
|
|
389
|
+
`createAgentRuntime({ ...config, children: createSqliteAgentChildManager({ sqlite, spawn }) })`
|
|
390
|
+
— and the SQLite companions take the store handle (`{ sqlite }`), whose
|
|
391
|
+
`database` and `transaction` they share.
|
|
392
|
+
|
|
393
|
+
## Released migration: 0.85.0
|
|
394
|
+
|
|
395
|
+
Only if you implement `AgentRuntimeStore` directly. Add the new durable
|
|
396
|
+
operation mutation beside the existing run mutations:
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
// before
|
|
400
|
+
const store: AgentRuntimeStore = {
|
|
401
|
+
checkpointRunAssistant,
|
|
402
|
+
commitRunTerminal,
|
|
403
|
+
// ...
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// after
|
|
407
|
+
const store: AgentRuntimeStore = {
|
|
408
|
+
checkpointRunAssistant,
|
|
409
|
+
recordRunOperation,
|
|
410
|
+
commitRunTerminal,
|
|
411
|
+
// ...
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
It must atomically replace `AgentRun.lastOperation`, increment the run revision
|
|
416
|
+
and conversation snapshot version, and enforce the supplied owner, fencing
|
|
417
|
+
token and expected revision. Adapters built with `createAgentRuntimeStore`
|
|
418
|
+
already receive the reference implementation; no driver method is added.
|
|
419
|
+
|
|
420
|
+
## Released migration: 0.84.0
|
|
421
|
+
|
|
422
|
+
Only if you call `createAgentCodingTools`.
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
rg -n "createAgentCodingTools"
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**1. Backslashes are refused.** If anything in your system hands the tools a Windows-style path,
|
|
429
|
+
it now gets `FORBIDDEN`. Convert to `/` at the boundary:
|
|
430
|
+
|
|
431
|
+
```ts
|
|
432
|
+
// before: read_file({ path: 'src\\index.ts' }) // reached openat as two segments
|
|
433
|
+
// after: read_file({ path: 'src/index.ts' })
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
This is the half that matters most: until now a backslash bypassed your **required**
|
|
437
|
+
`authorize({ operation, path })` callback, not just `authorizePath`. A rule denying
|
|
438
|
+
`credentials/token.txt` refused that spelling and served — and overwrote — the same file spelled
|
|
439
|
+
`credentials\token.txt`. If your policy denies specific files, re-read your audit logs for
|
|
440
|
+
backslash spellings.
|
|
441
|
+
|
|
442
|
+
**2. Denying a directory now denies everything under it — and a policy must admit every directory
|
|
443
|
+
on the way to a file**, the way POSIX needs `+x` on each directory in a path.
|
|
444
|
+
|
|
445
|
+
If your policy is a DENY-list, it now does what it read as:
|
|
446
|
+
|
|
447
|
+
```ts
|
|
448
|
+
authorizePath: ({ path }) => path !== 'credentials'
|
|
449
|
+
// before: hid `credentials` from glob, served `credentials/token.txt` to read_file
|
|
450
|
+
// after: refuses `credentials/token.txt`, `credentials/nested/deep.txt` and writes under it
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
If you relied on the old behaviour — a directory hidden from discovery but readable directly — you
|
|
454
|
+
were relying on a defect, and the two halves of one callback disagreeing. Name the paths you
|
|
455
|
+
actually want reachable instead.
|
|
456
|
+
|
|
457
|
+
If your policy is an ALLOW-list, widen it to the directories it leads through, or nothing under
|
|
458
|
+
them is reachable:
|
|
459
|
+
|
|
460
|
+
```ts
|
|
461
|
+
// before: allowed src/index.ts, because only the leaf was ever asked
|
|
462
|
+
authorizePath: ({ path }) => path.startsWith('src/')
|
|
463
|
+
// after: `src` itself is asked first and refused, so the file is refused too
|
|
464
|
+
authorizePath: ({ path }) => path === 'src' || path.startsWith('src/')
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
The workspace root is not asked about — it is the boundary the tools already own.
|
|
468
|
+
|
|
469
|
+
**3. The policy is called more often.** A path of depth N costs N+1 calls (`.`, then each ancestor,
|
|
470
|
+
then the leaf), outermost first, stopping at the first refusal. A policy that logs or meters will
|
|
471
|
+
see a different sequence, and will no longer see the leaf once an ancestor has refused.
|
|
472
|
+
|
|
473
|
+
## Released migration: 0.83.0
|
|
474
|
+
|
|
475
|
+
Two things, both mechanical, and only if you touch an observability sink.
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
rg -n "createObservability|createApplicationEventSink|createApplicationSnapshotSink|createAgentRuntimeEventSink|createAgentObservability"
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**1. `flush()` returns `Promise<boolean>`.** `await sink.flush()` needs no
|
|
482
|
+
change. Only a declared type does:
|
|
483
|
+
|
|
484
|
+
```ts
|
|
485
|
+
// before
|
|
486
|
+
const flushAudit: () => Promise<void> = observability.flush
|
|
487
|
+
// after
|
|
488
|
+
const flushAudit: () => Promise<boolean> = observability.flush
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
**2. `ObservabilityDrainReport` carries `drained`.** The framework builds it, so
|
|
492
|
+
reading code is unchanged. A hand-built report — a test double, or one persisted
|
|
493
|
+
and re-parsed through `ObservabilityDrainReportSchema` — needs the field:
|
|
494
|
+
|
|
495
|
+
```ts
|
|
496
|
+
// before
|
|
497
|
+
{ request, tools, total, durationMs }
|
|
498
|
+
// after
|
|
499
|
+
{ request, tools, total, durationMs, drained: true }
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Then take the thing this release exists for. Every drain now accepts
|
|
503
|
+
`{ timeoutMs?, signal? }`, so a shutdown can give the audit drain the same
|
|
504
|
+
deadline it gives every other step:
|
|
505
|
+
|
|
506
|
+
```ts
|
|
507
|
+
const report = await observability.close({ timeoutMs: 5_000 })
|
|
508
|
+
if (!report.drained) {
|
|
509
|
+
logger.warn('audit drain incomplete', {
|
|
510
|
+
unwritten: report.total.received - report.total.filtered - report.total.completed,
|
|
511
|
+
})
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
The bound ends the **waiting**, not the writes: a sink's `write` is handed no
|
|
516
|
+
cancellation, so an outstanding one keeps running against whatever you close
|
|
517
|
+
next. Racing `close()` against your own timer looks equivalent and is not — it
|
|
518
|
+
discards the report along with the wait.
|
|
519
|
+
|
|
520
|
+
## Released migration: 0.82.0
|
|
521
|
+
|
|
522
|
+
One thing, and only if you mount MCP or agent tools from a `createTrackingContract` contract.
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
rg -n "createTrackingContract"
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
The event ingest (`track`, `POST /events`) is now `expose: ['HTTP']`, which is
|
|
529
|
+
what its sibling `bootstrap` always declared. Before, it declared nothing — and
|
|
530
|
+
an endpoint with no `expose` is a tool on MCP and AGENT by default, so the
|
|
531
|
+
mounted surface carried a `track_<prefix>` tool. Since this contract is built
|
|
532
|
+
inside the framework, an application that had made every tool opt-in for the
|
|
533
|
+
endpoints *it* authors could not have opted this one out.
|
|
534
|
+
|
|
535
|
+
**If you pin a tool-surface digest or count**, it moves by one; re-record it.
|
|
536
|
+
**If you assert on tool names**, `track_<prefix>` is gone. **If nothing in your
|
|
537
|
+
project mounts tools from this contract**, there is nothing to do — the HTTP
|
|
538
|
+
routes, the client and the schemas are unchanged.
|
|
539
|
+
|
|
540
|
+
Un-declaring the tool was never the intent, so there is no option to keep it. If
|
|
541
|
+
an agent in your system genuinely needs to record something, give it your own
|
|
542
|
+
endpoint with your own schema: the browser ingest trusts a client-minted event
|
|
543
|
+
id and a visit lease, and an agent holds neither.
|
|
544
|
+
|
|
545
|
+
## Released migration: 0.81.0
|
|
546
|
+
|
|
547
|
+
**Path literals own string params.**
|
|
548
|
+
|
|
549
|
+
An endpoint whose path contains `:id` or a terminal `*rest` no longer needs a
|
|
550
|
+
duplicate `params: z.object({ …string() })` declaration. Remove schemas that do
|
|
551
|
+
nothing beyond repeating path names:
|
|
552
|
+
|
|
553
|
+
```ts
|
|
554
|
+
// before
|
|
555
|
+
{ path: '/projects/:projectId/*filePath',
|
|
556
|
+
params: z.object({ projectId: z.string(), filePath: z.string() }) }
|
|
557
|
+
|
|
558
|
+
// after
|
|
559
|
+
{ path: '/projects/:projectId/*filePath' }
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Keep an explicit schema when it validates or coerces. It must cover every name
|
|
563
|
+
in the path — an explicit schema that misses one now fails at `defineContract`
|
|
564
|
+
with the path and the missing field named. Client calls and handler contexts
|
|
565
|
+
infer the string fields from the literal, so a call that omitted one becomes a
|
|
566
|
+
compile error instead of building a URL with an unresolved segment. Measured
|
|
567
|
+
across three consuming applications before release (373 endpoints with path
|
|
568
|
+
segments), no explicit schema missed a field: the migration is deleting
|
|
569
|
+
schemas that only repeated the path, or nothing.
|
|
570
|
+
|
|
12
571
|
## Released migration: 0.80.0
|
|
13
572
|
|
|
14
573
|
One thing, and only if you parse an async-operation snapshot.
|
|
@@ -598,576 +1157,3 @@ status map needs no change (ADR 0105).
|
|
|
598
1157
|
|
|
599
1158
|
The admission/channel APIs and endpoint `stream` descriptor are additive; raw
|
|
600
1159
|
responses and raw `streamingRoute` remain supported.
|
|
601
|
-
|
|
602
|
-
## Released migration: 0.67.0
|
|
603
|
-
|
|
604
|
-
Three application-kernel changes. Two of them fix silent failures, so the most
|
|
605
|
-
important part of this migration is not what the compiler points at — it is the
|
|
606
|
-
two things that change with no compile error at all: **when your server is
|
|
607
|
-
created**, and **which shutdown budget a signal spends**.
|
|
608
|
-
|
|
609
|
-
### If you gave `managedServerResource` a thunk
|
|
610
|
-
|
|
611
|
-
It is now called during `start`, after the resource's dependencies are ready —
|
|
612
|
-
the reading the type always suggested. Before, it was called on the way *down*,
|
|
613
|
-
so `app.start()` resolved, the snapshot said `healthy` and `ready`, and nothing
|
|
614
|
-
was bound to the port.
|
|
615
|
-
|
|
616
|
-
If your application looked like this, it was never listening:
|
|
617
|
-
|
|
618
|
-
```ts
|
|
619
|
-
// before — resolves clean, listens on nothing
|
|
620
|
-
managedServerResource({ id: 'http', dependsOn: ['database'], server: () => createServer(config) })
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
Nothing to change: the same code now binds the port. Check your startup logs for
|
|
624
|
-
a healthy report you never actually verified with a request.
|
|
625
|
-
|
|
626
|
-
If you used the spread workaround — this resource's phases over your own
|
|
627
|
-
`start` — it keeps working, and you can now delete it:
|
|
628
|
-
|
|
629
|
-
```ts
|
|
630
|
-
// before
|
|
631
|
-
let handle: ManagedServerHandle<T> | null = null
|
|
632
|
-
const shutdown = managedServerResource({ id: 'http', server: () => handle! })
|
|
633
|
-
const http = defineManagedResource({
|
|
634
|
-
...shutdown,
|
|
635
|
-
dependsOn: ['database', 'socket-io'],
|
|
636
|
-
start: () => { handle = createServer(config) },
|
|
637
|
-
})
|
|
638
|
-
|
|
639
|
-
// after
|
|
640
|
-
const http = managedServerResource({
|
|
641
|
-
id: 'http',
|
|
642
|
-
dependsOn: [database, socketIo],
|
|
643
|
-
server: () => createServer(config),
|
|
644
|
-
})
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
An already-created handle is adopted exactly as before.
|
|
648
|
-
|
|
649
|
-
### If you passed `shutdown` to `bindProcessSignals`
|
|
650
|
-
|
|
651
|
-
`bindProcessSignals` used to fill in the schema's defaults for every budget you
|
|
652
|
-
omitted, which made `createApplication({ shutdown })` unreachable on the signal
|
|
653
|
-
path — the one path production stops through. An application declaring five
|
|
654
|
-
seconds took thirty-five.
|
|
655
|
-
|
|
656
|
-
Declare the budget once, on the application, and delete the repetition:
|
|
657
|
-
|
|
658
|
-
```ts
|
|
659
|
-
// before — the same two numbers in two places, and only one of them applied
|
|
660
|
-
const app = createApplication({ id: 'svc', resources, shutdown: SHUTDOWN_BUDGET })
|
|
661
|
-
bindProcessSignals(app, { shutdown: SHUTDOWN_BUDGET })
|
|
662
|
-
|
|
663
|
-
// after
|
|
664
|
-
const app = createApplication({ id: 'svc', resources, shutdown: SHUTDOWN_BUDGET })
|
|
665
|
-
bindProcessSignals(app)
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
**Check this even if you change nothing.** If you declared a budget on the
|
|
669
|
-
application and did not repeat it on the binding, your process has been stopping
|
|
670
|
-
on 30 s / 5 s and will now stop on what you declared. Compare it against the
|
|
671
|
-
supervisor timeout that watches it — `kill_timeout`, `TimeoutStopSec` — because
|
|
672
|
-
that number was probably calculated from the declaration.
|
|
673
|
-
|
|
674
|
-
Passing `shutdown` to the binding still works and still wins, key by key: one
|
|
675
|
-
key overrides that key alone and leaves the other at the declaration.
|
|
676
|
-
|
|
677
|
-
### If you read `resource.dependsOn`
|
|
678
|
-
|
|
679
|
-
Its type widened from `readonly string[]` to `readonly ManagedResourceDependency[]`
|
|
680
|
-
— `string | ManagedResource` — so a dependency can be declared as the resource
|
|
681
|
-
itself. Declaring stays compatible; reading needs one call:
|
|
682
|
-
|
|
683
|
-
```ts
|
|
684
|
-
// before
|
|
685
|
-
const ids: readonly string[] = resource.dependsOn ?? []
|
|
686
|
-
|
|
687
|
-
// after
|
|
688
|
-
import { managedResourceDependencyId } from 'stitchkit/application'
|
|
689
|
-
const ids = (resource.dependsOn ?? []).map(managedResourceDependencyId)
|
|
690
|
-
```
|
|
691
|
-
|
|
692
|
-
### If you thread a handle through a module-local
|
|
693
|
-
|
|
694
|
-
This is the pattern the change exists to remove, and it is opt-in — nothing
|
|
695
|
-
breaks if you keep yours:
|
|
696
|
-
|
|
697
|
-
```ts
|
|
698
|
-
// before
|
|
699
|
-
let socket: SocketHandle | null = null
|
|
700
|
-
const socketIo = defineManagedResource({
|
|
701
|
-
id: 'socket-io',
|
|
702
|
-
start: async () => { socket = await createSocketServer(config) },
|
|
703
|
-
})
|
|
704
|
-
const http = defineManagedResource({
|
|
705
|
-
id: 'http',
|
|
706
|
-
dependsOn: ['socket-io'],
|
|
707
|
-
start: () => {
|
|
708
|
-
if (!socket) throw new Error('socket is not initialized') // unreachable
|
|
709
|
-
server = createServer({ socket })
|
|
710
|
-
},
|
|
711
|
-
})
|
|
712
|
-
|
|
713
|
-
// after
|
|
714
|
-
const socketIo = defineManagedResource({
|
|
715
|
-
id: 'socket-io',
|
|
716
|
-
start: async () => ({ value: await createSocketServer(config) }),
|
|
717
|
-
})
|
|
718
|
-
const http = defineManagedResource({
|
|
719
|
-
id: 'http',
|
|
720
|
-
dependsOn: [socketIo],
|
|
721
|
-
start: (context) => {
|
|
722
|
-
server = createServer({ socket: context.use(socketIo) }) // SocketHandle
|
|
723
|
-
},
|
|
724
|
-
})
|
|
725
|
-
```
|
|
726
|
-
|
|
727
|
-
Declare the dependency with the **resource** when you intend to read from it —
|
|
728
|
-
that is the form `use` can type. `use` refuses a resource missing from
|
|
729
|
-
`dependsOn`, and refuses one that published no value; the second refusal is a
|
|
730
|
-
compile error too.
|
|
731
|
-
|
|
732
|
-
## Released migration: 0.66.0
|
|
733
|
-
|
|
734
|
-
Three changes, and only one of them is a feature. The other two are shapes that
|
|
735
|
-
would have had to break later: a vocabulary that described one fact with two
|
|
736
|
-
words, and a store whose only read was the whole conversation.
|
|
737
|
-
|
|
738
|
-
The compiler points at most of it. Two things change with no compile error —
|
|
739
|
-
what a **total** says about its own provenance, and the fact that token counts
|
|
740
|
-
are now validated where they were not.
|
|
741
|
-
|
|
742
|
-
### An input that joins a run in flight
|
|
743
|
-
|
|
744
|
-
#### If you matched exhaustively on `AgentTerminalReason`
|
|
745
|
-
|
|
746
|
-
`'absorbed'` is new. A run ends this way when a run already in flight took its
|
|
747
|
-
input on and answered it; its state is `'superseded'`, and `absorbedIntoRunId`
|
|
748
|
-
names the run that has the answer.
|
|
749
|
-
|
|
750
|
-
```ts
|
|
751
|
-
// after
|
|
752
|
-
switch (run.terminalReason) {
|
|
753
|
-
// …
|
|
754
|
-
case 'absorbed':
|
|
755
|
-
// no assistant message of its own — follow run.absorbedIntoRunId
|
|
756
|
-
break
|
|
757
|
-
}
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
A run record with `terminalReason: 'absorbed'` and no `absorbedIntoRunId` is
|
|
761
|
-
refused at parse time, and so is `absorbedIntoRunId` on any other reason.
|
|
762
|
-
|
|
763
|
-
#### If you render or export runs
|
|
764
|
-
|
|
765
|
-
An absorbed run has **no assistant message**. Anything that assumes "every
|
|
766
|
-
terminal run has one" needs the `absorbed` case — the answer is on the run
|
|
767
|
-
`absorbedIntoRunId` names, and `store.loadRun` resolves it.
|
|
768
|
-
|
|
769
|
-
#### If you want the policy
|
|
770
|
-
|
|
771
|
-
```ts
|
|
772
|
-
// after
|
|
773
|
-
runs: { inputPolicy: 'inject' }
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
It was withdrawn in 0.65.0 and is back with the ordering corrected: the
|
|
777
|
-
absorption commits with the terminal record, not at the step boundary. Read
|
|
778
|
-
*An input that joins a run in flight* in the agent-runtime guide before turning
|
|
779
|
-
it on — in particular what happens when the absorbing run does not complete, and
|
|
780
|
-
how it composes with `coalescePending`.
|
|
781
|
-
|
|
782
|
-
#### If you implement a store driver
|
|
783
|
-
|
|
784
|
-
Nothing to do, but know what changed underneath: one terminal commit can now
|
|
785
|
-
save **two** run records, and they must land in the same transaction. A driver
|
|
786
|
-
that persists one of the pair fails `runAgentStoreConformance`.
|
|
787
|
-
|
|
788
|
-
### A run read without its conversation
|
|
789
|
-
|
|
790
|
-
#### If you implement `AgentRuntimeStore` by hand
|
|
791
|
-
|
|
792
|
-
Two members to add. **If your adapter is an `AgentRuntimeStoreDriver` passed to
|
|
793
|
-
`createAgentRuntimeStore`, there is nothing to do** — the driver already had
|
|
794
|
-
everything both need.
|
|
795
|
-
|
|
796
|
-
```ts
|
|
797
|
-
// after
|
|
798
|
-
loadRun(input: { conversationId: string; runId: string }): Promise<AgentRunView | undefined>
|
|
799
|
-
listActiveRuns(conversationId: string): Promise<readonly AgentRun[]>
|
|
800
|
-
```
|
|
801
|
-
|
|
802
|
-
`AgentRunView` is `{ snapshotVersion, run, assistant? }`. `assistant` is the
|
|
803
|
-
retained terminal answer, so it is present exactly when the run has ended and
|
|
804
|
-
absent while it is live — a store that returns a live run's draft here lets the
|
|
805
|
-
terminal path resolve a run that has not finished. `listActiveRuns` orders by
|
|
806
|
-
`createdAt` then `id`, and must not report a run that has ended.
|
|
807
|
-
`runAgentStoreConformance` covers both, including the boundary cases.
|
|
808
|
-
|
|
809
|
-
#### If you have a store **double** in your tests
|
|
810
|
-
|
|
811
|
-
The runtime now reads `loadRun` where it used to read `loadSnapshot`. A double
|
|
812
|
-
that simulates a condition — a run drifting to another owner, a stale fencing
|
|
813
|
-
token — must apply it to both reads, or the code under test will not see it.
|
|
814
|
-
This is not hypothetical: it turned one of this repository's own fixtures into
|
|
815
|
-
an infinite retry loop, which is how the bounded retry below was found.
|
|
816
|
-
|
|
817
|
-
#### Nothing else changes
|
|
818
|
-
|
|
819
|
-
`loadSnapshot` behaves exactly as before, and still returns the whole
|
|
820
|
-
conversation — as does every mutation result. What it costs, and what bounds it,
|
|
821
|
-
is now written down in *Reading a conversation* in the agent-runtime guide.
|
|
822
|
-
|
|
823
|
-
### One provenance vocabulary, and integral tokens
|
|
824
|
-
|
|
825
|
-
#### If you match on `'measured'`
|
|
826
|
-
|
|
827
|
-
A **total** now says `computed`, because it is a sum this code performed rather
|
|
828
|
-
than a count it took — the same rule `AgentUsage` has always applied to a run's
|
|
829
|
-
spend. Two values change with no compile error:
|
|
830
|
-
|
|
831
|
-
```ts
|
|
832
|
-
// before
|
|
833
|
-
if (result.totalTokens.provenance === 'measured') { /* exact */ }
|
|
834
|
-
// after
|
|
835
|
-
if (result.totalTokens.provenance === 'computed') { /* exact, and derived */ }
|
|
836
|
-
```
|
|
837
|
-
|
|
838
|
-
It affects `AgentHistoryBudgetResult.totalTokens` and
|
|
839
|
-
`ComposedAgentPrompt.instructionTokens`. A per-message or per-section count is
|
|
840
|
-
still `measured` — only the totals moved. When any part was estimated the total
|
|
841
|
-
is still `estimated`: an estimate survives arithmetic, and that is the weaker
|
|
842
|
-
claim, so it wins.
|
|
843
|
-
|
|
844
|
-
#### If you produce token counts
|
|
845
|
-
|
|
846
|
-
They are validated now, in the places they were not. A fractional count throws
|
|
847
|
-
where it used to flow into the context-window arithmetic:
|
|
848
|
-
|
|
849
|
-
```ts
|
|
850
|
-
// refused from this release on
|
|
851
|
-
estimateTokens: (text) => ({ value: text.length / 4, provenance: 'estimated' })
|
|
852
|
-
// after
|
|
853
|
-
estimateTokens: (text) => ({ value: Math.ceil(text.length / 4), provenance: 'estimated' })
|
|
854
|
-
```
|
|
855
|
-
|
|
856
|
-
The same applies to `ComposeAgentPromptOptions.estimateFallback` and
|
|
857
|
-
`.historyTokens`, to `AgentPromptBudget.toolSchemas` / `.attachments` /
|
|
858
|
-
`.providerOverhead`, and to `AgentPromptBudget.contextWindow` /
|
|
859
|
-
`.reservedOutput`, which must now be non-negative safe integers.
|
|
860
|
-
|
|
861
|
-
`AgentUsageValue.value` is `z.int()` too, which matters if you build usage
|
|
862
|
-
records by hand or in a store double. A figure arriving from a **provider** is
|
|
863
|
-
not thrown — `normalizeSdkUsage` and the OpenRouter adapter turn a non-integer
|
|
864
|
-
into `{ provenance: 'unavailable' }`, so a run that already answered is not
|
|
865
|
-
failed over its own bookkeeping.
|
|
866
|
-
|
|
867
|
-
#### The new export
|
|
868
|
-
|
|
869
|
-
`AgentProvenanceSchema` / `AgentProvenance` is the whole vocabulary:
|
|
870
|
-
`provider-reported`, `measured`, `computed`, `estimated`, `unavailable`. Each
|
|
871
|
-
surface declares its subset, so nothing widened — `AgentUsageValue` still refuses
|
|
872
|
-
`measured` and `AgentTokenCount` still refuses `provider-reported`. Use it when
|
|
873
|
-
you want one switch over the question instead of two.
|
|
874
|
-
|
|
875
|
-
## Released migration: 0.65.0
|
|
876
|
-
|
|
877
|
-
The largest migration of the pre-1.0 line, and most of it is the compiler
|
|
878
|
-
pointing at things. One item is a feature withdrawal and two change behaviour
|
|
879
|
-
with no compile error at all.
|
|
880
|
-
|
|
881
|
-
### A projection a provider accepts, and a policy withdrawn
|
|
882
|
-
|
|
883
|
-
### If you compact, or use `system-note`, you were broken and now are not
|
|
884
|
-
|
|
885
|
-
No code change to adopt the fix — but **check your own code if you call
|
|
886
|
-
`projectAgentHistory` yourself.** System and summary records no longer appear in
|
|
887
|
-
`messages`; they come back in `system` and belong in the provider's instructions
|
|
888
|
-
channel, which is the only place `ai` accepts them:
|
|
889
|
-
|
|
890
|
-
```ts
|
|
891
|
-
// before — the provider refuses this outright
|
|
892
|
-
const messages = await projectAgentHistory(snapshot.messages)
|
|
893
|
-
streamText({ model, messages })
|
|
894
|
-
|
|
895
|
-
// after
|
|
896
|
-
const { messages, system } = await projectAgentHistoryDetailed(snapshot.messages)
|
|
897
|
-
streamText({
|
|
898
|
-
model,
|
|
899
|
-
instructions: system.map((content) => ({ role: 'system', content })),
|
|
900
|
-
messages,
|
|
901
|
-
})
|
|
902
|
-
```
|
|
903
|
-
|
|
904
|
-
If you use `createAgentRuntime`, this is handled for you.
|
|
905
|
-
|
|
906
|
-
### `inputPolicy: 'inject'` is withdrawn
|
|
907
|
-
|
|
908
|
-
```ts
|
|
909
|
-
// before
|
|
910
|
-
runs: { inputPolicy: 'inject' }
|
|
911
|
-
// after
|
|
912
|
-
runs: { inputPolicy: 'queue' }
|
|
913
|
-
```
|
|
914
|
-
|
|
915
|
-
`'absorbed'`, `AgentRun.absorbedIntoRunId` and `AgentRuntimeStore.absorbQueuedRun`
|
|
916
|
-
go with it. A driver built on `AgentRuntimeStoreDriver` needs no change.
|
|
917
|
-
|
|
918
|
-
### Records must agree with themselves
|
|
919
|
-
|
|
920
|
-
If you construct `AgentRun` values — a store double, a fixture, a migration —
|
|
921
|
-
derive the state instead of setting it:
|
|
922
|
-
|
|
923
|
-
```ts
|
|
924
|
-
// after
|
|
925
|
-
import { runStateForTerminalReason } from 'stitchkit/agent-runtime'
|
|
926
|
-
AgentRunSchema.parse({ …run, terminalReason: reason, state: runStateForTerminalReason(reason) })
|
|
927
|
-
```
|
|
928
|
-
|
|
929
|
-
A terminal state with no reason, a queued run carrying one, and `policy_stop`
|
|
930
|
-
without a `terminalPolicyName` are now all refused at parse time.
|
|
931
|
-
|
|
932
|
-
### Enum and field changes the compiler will point at
|
|
933
|
-
|
|
934
|
-
- `AgentTerminalReason`: `'tool_failure'` removed (never produced),
|
|
935
|
-
`'context_overflow'` added — this runtime's own refusal when the prompt does
|
|
936
|
-
not fit, which used to report `provider_failure`.
|
|
937
|
-
- `AgentRunState`: `'absorbed'` removed.
|
|
938
|
-
- `AgentRunMetrics.usage` is required.
|
|
939
|
-
- `AgentHistoryBudgetDecision['reason']`: `'superseded'` → `'unspeakable'`.
|
|
940
|
-
|
|
941
|
-
### Two behaviour changes with no compile error
|
|
942
|
-
|
|
943
|
-
- **`loop.idleTimeoutMs` now defaults to 60 000.** A run whose provider stream
|
|
944
|
-
goes quiet for a minute ends as `timeout` instead of holding the lane forever.
|
|
945
|
-
Pass `null` for the old behaviour, and think about why you want it.
|
|
946
|
-
- **`advanceAgentRuntimeEventCursor` stops returning `gap` for durable events.**
|
|
947
|
-
If you reload a conversation on `gap`, you were reloading after essentially
|
|
948
|
-
every run. Transient events still report it, and there it is real.
|
|
949
|
-
|
|
950
|
-
## Released migration: 0.64.0
|
|
951
|
-
|
|
952
|
-
Two changes, and only one of them can break a build. Nothing was removed.
|
|
953
|
-
|
|
954
|
-
### An event that says which kind it is
|
|
955
|
-
|
|
956
|
-
### Narrow `AgentRunEvent` on `type`
|
|
957
|
-
|
|
958
|
-
```ts
|
|
959
|
-
// before
|
|
960
|
-
for (const event of events) record(event.usage?.cost?.value ?? 0)
|
|
961
|
-
|
|
962
|
-
// after — and the compiler will point at every site
|
|
963
|
-
for (const event of events) {
|
|
964
|
-
if (event.type !== 'run-terminal') continue
|
|
965
|
-
record(event.usage.cost.value ?? null) // `usage` is present; unknown says so
|
|
966
|
-
}
|
|
967
|
-
```
|
|
968
|
-
|
|
969
|
-
`step` is now required on `step-finished`, `terminalReason` on `run-terminal`,
|
|
970
|
-
and `usage` on both. `queueWaitMs` exists only on `run-started`. Nothing was
|
|
971
|
-
removed — the fields that were optional because a *different* kind of event
|
|
972
|
-
lacked them are now simply on the kinds that have them.
|
|
973
|
-
|
|
974
|
-
Import `AgentRunTerminalEventSchema` (or the sibling schemas) if you construct
|
|
975
|
-
events in tests.
|
|
976
|
-
|
|
977
|
-
### If you implement `AgentRuntimeStore` directly, move to the driver
|
|
978
|
-
|
|
979
|
-
Not urgent and nothing breaks today — but the aggregate is no longer the
|
|
980
|
-
supported target, so its future growth will not be announced as breaking
|
|
981
|
-
(→ ADR 0111). The supported shape is one line:
|
|
982
|
-
|
|
983
|
-
```ts
|
|
984
|
-
const driver: AgentRuntimeStoreDriver<TransactionClient> = { /* six primitives */ }
|
|
985
|
-
export const store = createAgentRuntimeStore(driver)
|
|
986
|
-
```
|
|
987
|
-
|
|
988
|
-
Run `runAgentStoreConformance` against your adapter before and after any bump —
|
|
989
|
-
see *Before you bump, if you implement an agent store* above.
|
|
990
|
-
|
|
991
|
-
## Released migration: 0.63.0
|
|
992
|
-
|
|
993
|
-
Four changes to what a running system reports and how an input reaches a run
|
|
994
|
-
in flight. Nothing moves an export except one added store member, and only an
|
|
995
|
-
application implementing `AgentRuntimeStore` directly has to touch code.
|
|
996
|
-
|
|
997
|
-
### A spend figure that survives, and an input that joins
|
|
998
|
-
|
|
999
|
-
### `AgentRuntimeStore` has a ninth member
|
|
1000
|
-
|
|
1001
|
-
Only if you implement the aggregate interface directly — an adapter built on
|
|
1002
|
-
`AgentRuntimeStoreDriver` needs no change, and the public conformance kit covers
|
|
1003
|
-
the new operation.
|
|
1004
|
-
|
|
1005
|
-
```ts
|
|
1006
|
-
// after
|
|
1007
|
-
absorbQueuedRun(input: AbsorbQueuedRun): Promise<AgentStoreMutationResult>
|
|
1008
|
-
```
|
|
1009
|
-
|
|
1010
|
-
It moves a queued successor's inputs into the run already answering, in one
|
|
1011
|
-
mutation, and marks the successor `absorbed`. Two run records change in one
|
|
1012
|
-
transaction — if your driver persists them one at a time, persist both.
|
|
1013
|
-
|
|
1014
|
-
### A provider failure says so
|
|
1015
|
-
|
|
1016
|
-
```ts
|
|
1017
|
-
// before — an upstream error arrived as a policy stop with no policy
|
|
1018
|
-
if (terminal.reason === 'policy_stop') retryLater()
|
|
1019
|
-
|
|
1020
|
-
// after
|
|
1021
|
-
if (terminal.reason === 'provider_failure') retryLater()
|
|
1022
|
-
if (terminal.reason === 'provider_stop') { /* a length cap or content filter */ }
|
|
1023
|
-
```
|
|
1024
|
-
|
|
1025
|
-
`policy_stop` now always carries the `policyName` that caused it. If you switch
|
|
1026
|
-
exhaustively on `AgentTerminalReason` or `AgentRunState`, add `'provider_stop'`
|
|
1027
|
-
and `'absorbed'`.
|
|
1028
|
-
|
|
1029
|
-
### `partial` changed meaning
|
|
1030
|
-
|
|
1031
|
-
It used to tell you which event kind you were holding. It now tells you whether
|
|
1032
|
-
the figure beside it is a confirmed total:
|
|
1033
|
-
|
|
1034
|
-
```ts
|
|
1035
|
-
// after — true when the provider never reported the run finished
|
|
1036
|
-
if (metrics.partial) treatAsFloor(metrics.usage)
|
|
1037
|
-
```
|
|
1038
|
-
|
|
1039
|
-
Terminal events for runs that were superseded, interrupted, timed out or failed
|
|
1040
|
-
before the provider finished now report `partial: true` where they reported
|
|
1041
|
-
`false`.
|
|
1042
|
-
|
|
1043
|
-
### Checkpoint metrics are a running total
|
|
1044
|
-
|
|
1045
|
-
```ts
|
|
1046
|
-
// wrong, and now wrong by more than it used to be
|
|
1047
|
-
const spent = checkpoints.reduce((total, c) => total + (c.metrics.usage?.cost?.value ?? 0), 0)
|
|
1048
|
-
// right
|
|
1049
|
-
const spent = checkpoints.at(-1)?.metrics.usage?.cost?.value
|
|
1050
|
-
```
|
|
1051
|
-
|
|
1052
|
-
### You can read a run's spend back from the store
|
|
1053
|
-
|
|
1054
|
-
`AgentRun.usage` is written at every checkpoint and with the terminal record, so
|
|
1055
|
-
a dropped observability event no longer loses the number, and a process that dies
|
|
1056
|
-
mid-stream leaves behind what it had already spent.
|
|
1057
|
-
|
|
1058
|
-
## Released migration: 0.62.0
|
|
1059
|
-
|
|
1060
|
-
Two groups of behaviour changes. Nothing moves an export — the surface is
|
|
1061
|
-
strictly additive — and every item changes what a running system reports or
|
|
1062
|
-
sends, which is what this heading is for. One of them changes a number you may
|
|
1063
|
-
already be billing against.
|
|
1064
|
-
|
|
1065
|
-
### A run reports what it spent
|
|
1066
|
-
|
|
1067
|
-
Three changes to what the runtime says about cost and tokens. Nothing moves an
|
|
1068
|
-
export; all three change numbers a running system reports, and one of them
|
|
1069
|
-
changes a number you may already be billing against.
|
|
1070
|
-
|
|
1071
|
-
#### Multi-step cost was under-reported and is now summed
|
|
1072
|
-
|
|
1073
|
-
No code change is needed to get the fix — but check any predicate that reads
|
|
1074
|
-
`provenance`:
|
|
1075
|
-
|
|
1076
|
-
```ts
|
|
1077
|
-
// before — accepted a number that was one step's cost, not the run's
|
|
1078
|
-
if (usage.cost?.provenance === 'provider-reported') bill(usage.cost.value)
|
|
1079
|
-
|
|
1080
|
-
// after — a sum stitchkit performed says so
|
|
1081
|
-
if (usage.cost && usage.cost.provenance !== 'unavailable') bill(usage.cost.value)
|
|
1082
|
-
```
|
|
1083
|
-
|
|
1084
|
-
`'computed'` means stitchkit added up provider-reported parts. It is not a guess
|
|
1085
|
-
— `'estimated'` is the word for that — but it is deliberately not
|
|
1086
|
-
`'provider-reported'`, because that label is what a caller filters on when it
|
|
1087
|
-
wants a figure it can bill against unchanged, and a sum is not one.
|
|
1088
|
-
|
|
1089
|
-
Token totals moved with it. The AI SDK's `totalUsage` is a sum *it* performed
|
|
1090
|
-
over per-step provider figures — not a run total any provider handed over — so
|
|
1091
|
-
labelling it `provider-reported` was the same overstatement. **A run total on a
|
|
1092
|
-
terminal event is always `computed`.** If you want a figure with the provider's
|
|
1093
|
-
own word on it, read `step-finished`: each step carries what that call reported.
|
|
1094
|
-
|
|
1095
|
-
#### `usage` is always present on a terminal event
|
|
1096
|
-
|
|
1097
|
-
```ts
|
|
1098
|
-
// before — absent when the run ended before the provider's `finish`
|
|
1099
|
-
const spent = event.usage?.cost?.value ?? 0 // silently 0 for a real spend
|
|
1100
|
-
|
|
1101
|
-
// after — present, and it says what it does not know
|
|
1102
|
-
event.usage?.cost?.provenance === 'unavailable' // we spent, and cannot say how much
|
|
1103
|
-
```
|
|
1104
|
-
|
|
1105
|
-
Keep the optional chaining: one `AgentRunEvent` shape covers `run-started`,
|
|
1106
|
-
`step-finished` and `run-terminal`, so `usage` stays optional on the type. The
|
|
1107
|
-
guarantee is about terminal events, and a schema shared with `run-started`
|
|
1108
|
-
cannot express it.
|
|
1109
|
-
|
|
1110
|
-
**Do not read `unavailable` as zero.** A run aborted mid-stream has spent real
|
|
1111
|
-
money that nobody has counted; a run that never reached the provider has not.
|
|
1112
|
-
Both used to look the same and now do not.
|
|
1113
|
-
|
|
1114
|
-
#### A losing executor reports its own spend
|
|
1115
|
-
|
|
1116
|
-
An execution that loses the terminal compare-and-swap now emits an operator
|
|
1117
|
-
`run-terminal` event, because it ran and it spent. If a sink treated those events
|
|
1118
|
-
as "runs this process committed", that is no longer true — `AgentRuntimeResult.metrics`
|
|
1119
|
-
is still `undefined` for a losing executor and remains the way to tell.
|
|
1120
|
-
|
|
1121
|
-
The *delivery* `terminal` event is unchanged and still fires only for the winner,
|
|
1122
|
-
so nothing delivers a turn twice.
|
|
1123
|
-
|
|
1124
|
-
### An interrupted answer stops passing as a finished one
|
|
1125
|
-
|
|
1126
|
-
Two behaviour changes, one shared cause: a run ended by a newer input used to
|
|
1127
|
-
leave its half-written answer in the conversation with no sign that it was cut
|
|
1128
|
-
off, and the next request to the provider carried it as an ordinary assistant
|
|
1129
|
-
turn.
|
|
1130
|
-
|
|
1131
|
-
#### The projection marks an interrupted turn
|
|
1132
|
-
|
|
1133
|
-
Nothing to change to adopt the fix — the default is the fixed behaviour. What to
|
|
1134
|
-
check is whether the marker is the *right* form for your surface, and the
|
|
1135
|
-
question that decides it is not "was the run interrupted" but **"did anyone see
|
|
1136
|
-
what it produced"**.
|
|
1137
|
-
|
|
1138
|
-
```ts
|
|
1139
|
-
// after — pick the form; the default is 'assistant-marked'
|
|
1140
|
-
createAgentRuntime({ history: { interruptedAssistant: 'system-note' } })
|
|
1141
|
-
```
|
|
1142
|
-
|
|
1143
|
-
- **The user pressed stop and the text was on their screen** — keep
|
|
1144
|
-
`'assistant-marked'`. The assistant turn is the truthful record of what the
|
|
1145
|
-
human read, and the model should stay consistent with it.
|
|
1146
|
-
- **The partial never reached anyone** — a surface that sends nothing until the
|
|
1147
|
-
run is done — prefer `'system-note'`. An assistant turn in provider history is
|
|
1148
|
-
a commitment the model stays consistent with; a system line is context.
|
|
1149
|
-
|
|
1150
|
-
If you pass `history.project` you own the projection outright and none of this
|
|
1151
|
-
applies — but the same question does.
|
|
1152
|
-
|
|
1153
|
-
#### A run ended by a newer input can now say so
|
|
1154
|
-
|
|
1155
|
-
```ts
|
|
1156
|
-
// before
|
|
1157
|
-
runs: { inputPolicy: 'interrupt' } // ends the run, keeps its partial answer
|
|
1158
|
-
|
|
1159
|
-
// after — for a surface where a follow-up message invalidates the answer
|
|
1160
|
-
// in flight rather than merely stopping it
|
|
1161
|
-
runs: { inputPolicy: 'supersede' } // ends the run, discards its partial answer
|
|
1162
|
-
```
|
|
1163
|
-
|
|
1164
|
-
`inputPolicy` also accepts `(input) => policy`, which is how one application
|
|
1165
|
-
gives two conversation surfaces different rules without the runtime learning
|
|
1166
|
-
which is which.
|
|
1167
|
-
|
|
1168
|
-
A superseded run terminates with `terminalReason: 'superseded'`, state
|
|
1169
|
-
`'superseded'` and an assistant message of status `'superseded'`. **If you switch
|
|
1170
|
-
exhaustively on any of those enums, add the arm** — that is the part of this
|
|
1171
|
-
release that can break a build rather than a behaviour. The record itself is
|
|
1172
|
-
kept: it is excluded from the projection, not deleted, so an operator can still
|
|
1173
|
-
see what was thrown away.
|