stitchkit 0.104.1 → 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 +381 -12
- 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 +196 -56
- 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 +104 -21
- 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 +22 -7
- 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 +305 -154
- 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 +1053 -405
- 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,587 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.53.0 → 0.67.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.53.0 → 0.67.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.53.0 → 0.67.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.67.0
|
|
13
|
+
|
|
14
|
+
Three application-kernel changes. Two of them fix silent failures, so the most
|
|
15
|
+
important part of this migration is not what the compiler points at — it is the
|
|
16
|
+
two things that change with no compile error at all: **when your server is
|
|
17
|
+
created**, and **which shutdown budget a signal spends**.
|
|
18
|
+
|
|
19
|
+
### If you gave `managedServerResource` a thunk
|
|
20
|
+
|
|
21
|
+
It is now called during `start`, after the resource's dependencies are ready —
|
|
22
|
+
the reading the type always suggested. Before, it was called on the way *down*,
|
|
23
|
+
so `app.start()` resolved, the snapshot said `healthy` and `ready`, and nothing
|
|
24
|
+
was bound to the port.
|
|
25
|
+
|
|
26
|
+
If your application looked like this, it was never listening:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
// before — resolves clean, listens on nothing
|
|
30
|
+
managedServerResource({ id: 'http', dependsOn: ['database'], server: () => createServer(config) })
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Nothing to change: the same code now binds the port. Check your startup logs for
|
|
34
|
+
a healthy report you never actually verified with a request.
|
|
35
|
+
|
|
36
|
+
If you used the spread workaround — this resource's phases over your own
|
|
37
|
+
`start` — it keeps working, and you can now delete it:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// before
|
|
41
|
+
let handle: ManagedServerHandle<T> | null = null
|
|
42
|
+
const shutdown = managedServerResource({ id: 'http', server: () => handle! })
|
|
43
|
+
const http = defineManagedResource({
|
|
44
|
+
...shutdown,
|
|
45
|
+
dependsOn: ['database', 'socket-io'],
|
|
46
|
+
start: () => { handle = createServer(config) },
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
// after
|
|
50
|
+
const http = managedServerResource({
|
|
51
|
+
id: 'http',
|
|
52
|
+
dependsOn: [database, socketIo],
|
|
53
|
+
server: () => createServer(config),
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
An already-created handle is adopted exactly as before.
|
|
58
|
+
|
|
59
|
+
### If you passed `shutdown` to `bindProcessSignals`
|
|
60
|
+
|
|
61
|
+
`bindProcessSignals` used to fill in the schema's defaults for every budget you
|
|
62
|
+
omitted, which made `createApplication({ shutdown })` unreachable on the signal
|
|
63
|
+
path — the one path production stops through. An application declaring five
|
|
64
|
+
seconds took thirty-five.
|
|
65
|
+
|
|
66
|
+
Declare the budget once, on the application, and delete the repetition:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// before — the same two numbers in two places, and only one of them applied
|
|
70
|
+
const app = createApplication({ id: 'svc', resources, shutdown: SHUTDOWN_BUDGET })
|
|
71
|
+
bindProcessSignals(app, { shutdown: SHUTDOWN_BUDGET })
|
|
72
|
+
|
|
73
|
+
// after
|
|
74
|
+
const app = createApplication({ id: 'svc', resources, shutdown: SHUTDOWN_BUDGET })
|
|
75
|
+
bindProcessSignals(app)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Check this even if you change nothing.** If you declared a budget on the
|
|
79
|
+
application and did not repeat it on the binding, your process has been stopping
|
|
80
|
+
on 30 s / 5 s and will now stop on what you declared. Compare it against the
|
|
81
|
+
supervisor timeout that watches it — `kill_timeout`, `TimeoutStopSec` — because
|
|
82
|
+
that number was probably calculated from the declaration.
|
|
83
|
+
|
|
84
|
+
Passing `shutdown` to the binding still works and still wins, key by key: one
|
|
85
|
+
key overrides that key alone and leaves the other at the declaration.
|
|
86
|
+
|
|
87
|
+
### If you read `resource.dependsOn`
|
|
88
|
+
|
|
89
|
+
Its type widened from `readonly string[]` to `readonly ManagedResourceDependency[]`
|
|
90
|
+
— `string | ManagedResource` — so a dependency can be declared as the resource
|
|
91
|
+
itself. Declaring stays compatible; reading needs one call:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
// before
|
|
95
|
+
const ids: readonly string[] = resource.dependsOn ?? []
|
|
96
|
+
|
|
97
|
+
// after
|
|
98
|
+
import { managedResourceDependencyId } from 'stitchkit/application'
|
|
99
|
+
const ids = (resource.dependsOn ?? []).map(managedResourceDependencyId)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### If you thread a handle through a module-local
|
|
103
|
+
|
|
104
|
+
This is the pattern the change exists to remove, and it is opt-in — nothing
|
|
105
|
+
breaks if you keep yours:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
// before
|
|
109
|
+
let socket: SocketHandle | null = null
|
|
110
|
+
const socketIo = defineManagedResource({
|
|
111
|
+
id: 'socket-io',
|
|
112
|
+
start: async () => { socket = await createSocketServer(config) },
|
|
113
|
+
})
|
|
114
|
+
const http = defineManagedResource({
|
|
115
|
+
id: 'http',
|
|
116
|
+
dependsOn: ['socket-io'],
|
|
117
|
+
start: () => {
|
|
118
|
+
if (!socket) throw new Error('socket is not initialized') // unreachable
|
|
119
|
+
server = createServer({ socket })
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// after
|
|
124
|
+
const socketIo = defineManagedResource({
|
|
125
|
+
id: 'socket-io',
|
|
126
|
+
start: async () => ({ value: await createSocketServer(config) }),
|
|
127
|
+
})
|
|
128
|
+
const http = defineManagedResource({
|
|
129
|
+
id: 'http',
|
|
130
|
+
dependsOn: [socketIo],
|
|
131
|
+
start: (context) => {
|
|
132
|
+
server = createServer({ socket: context.use(socketIo) }) // SocketHandle
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Declare the dependency with the **resource** when you intend to read from it —
|
|
138
|
+
that is the form `use` can type. `use` refuses a resource missing from
|
|
139
|
+
`dependsOn`, and refuses one that published no value; the second refusal is a
|
|
140
|
+
compile error too.
|
|
141
|
+
|
|
142
|
+
## Released migration: 0.66.0
|
|
143
|
+
|
|
144
|
+
Three changes, and only one of them is a feature. The other two are shapes that
|
|
145
|
+
would have had to break later: a vocabulary that described one fact with two
|
|
146
|
+
words, and a store whose only read was the whole conversation.
|
|
147
|
+
|
|
148
|
+
The compiler points at most of it. Two things change with no compile error —
|
|
149
|
+
what a **total** says about its own provenance, and the fact that token counts
|
|
150
|
+
are now validated where they were not.
|
|
151
|
+
|
|
152
|
+
### An input that joins a run in flight
|
|
153
|
+
|
|
154
|
+
#### If you matched exhaustively on `AgentTerminalReason`
|
|
155
|
+
|
|
156
|
+
`'absorbed'` is new. A run ends this way when a run already in flight took its
|
|
157
|
+
input on and answered it; its state is `'superseded'`, and `absorbedIntoRunId`
|
|
158
|
+
names the run that has the answer.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
// after
|
|
162
|
+
switch (run.terminalReason) {
|
|
163
|
+
// …
|
|
164
|
+
case 'absorbed':
|
|
165
|
+
// no assistant message of its own — follow run.absorbedIntoRunId
|
|
166
|
+
break
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
A run record with `terminalReason: 'absorbed'` and no `absorbedIntoRunId` is
|
|
171
|
+
refused at parse time, and so is `absorbedIntoRunId` on any other reason.
|
|
172
|
+
|
|
173
|
+
#### If you render or export runs
|
|
174
|
+
|
|
175
|
+
An absorbed run has **no assistant message**. Anything that assumes "every
|
|
176
|
+
terminal run has one" needs the `absorbed` case — the answer is on the run
|
|
177
|
+
`absorbedIntoRunId` names, and `store.loadRun` resolves it.
|
|
178
|
+
|
|
179
|
+
#### If you want the policy
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
// after
|
|
183
|
+
runs: { inputPolicy: 'inject' }
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
It was withdrawn in 0.65.0 and is back with the ordering corrected: the
|
|
187
|
+
absorption commits with the terminal record, not at the step boundary. Read
|
|
188
|
+
*An input that joins a run in flight* in the agent-runtime guide before turning
|
|
189
|
+
it on — in particular what happens when the absorbing run does not complete, and
|
|
190
|
+
how it composes with `coalescePending`.
|
|
191
|
+
|
|
192
|
+
#### If you implement a store driver
|
|
193
|
+
|
|
194
|
+
Nothing to do, but know what changed underneath: one terminal commit can now
|
|
195
|
+
save **two** run records, and they must land in the same transaction. A driver
|
|
196
|
+
that persists one of the pair fails `runAgentStoreConformance`.
|
|
197
|
+
|
|
198
|
+
### A run read without its conversation
|
|
199
|
+
|
|
200
|
+
#### If you implement `AgentRuntimeStore` by hand
|
|
201
|
+
|
|
202
|
+
Two members to add. **If your adapter is an `AgentRuntimeStoreDriver` passed to
|
|
203
|
+
`createAgentRuntimeStore`, there is nothing to do** — the driver already had
|
|
204
|
+
everything both need.
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
// after
|
|
208
|
+
loadRun(input: { conversationId: string; runId: string }): Promise<AgentRunView | undefined>
|
|
209
|
+
listActiveRuns(conversationId: string): Promise<readonly AgentRun[]>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
`AgentRunView` is `{ snapshotVersion, run, assistant? }`. `assistant` is the
|
|
213
|
+
retained terminal answer, so it is present exactly when the run has ended and
|
|
214
|
+
absent while it is live — a store that returns a live run's draft here lets the
|
|
215
|
+
terminal path resolve a run that has not finished. `listActiveRuns` orders by
|
|
216
|
+
`createdAt` then `id`, and must not report a run that has ended.
|
|
217
|
+
`runAgentStoreConformance` covers both, including the boundary cases.
|
|
218
|
+
|
|
219
|
+
#### If you have a store **double** in your tests
|
|
220
|
+
|
|
221
|
+
The runtime now reads `loadRun` where it used to read `loadSnapshot`. A double
|
|
222
|
+
that simulates a condition — a run drifting to another owner, a stale fencing
|
|
223
|
+
token — must apply it to both reads, or the code under test will not see it.
|
|
224
|
+
This is not hypothetical: it turned one of this repository's own fixtures into
|
|
225
|
+
an infinite retry loop, which is how the bounded retry below was found.
|
|
226
|
+
|
|
227
|
+
#### Nothing else changes
|
|
228
|
+
|
|
229
|
+
`loadSnapshot` behaves exactly as before, and still returns the whole
|
|
230
|
+
conversation — as does every mutation result. What it costs, and what bounds it,
|
|
231
|
+
is now written down in *Reading a conversation* in the agent-runtime guide.
|
|
232
|
+
|
|
233
|
+
### One provenance vocabulary, and integral tokens
|
|
234
|
+
|
|
235
|
+
#### If you match on `'measured'`
|
|
236
|
+
|
|
237
|
+
A **total** now says `computed`, because it is a sum this code performed rather
|
|
238
|
+
than a count it took — the same rule `AgentUsage` has always applied to a run's
|
|
239
|
+
spend. Two values change with no compile error:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
// before
|
|
243
|
+
if (result.totalTokens.provenance === 'measured') { /* exact */ }
|
|
244
|
+
// after
|
|
245
|
+
if (result.totalTokens.provenance === 'computed') { /* exact, and derived */ }
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
It affects `AgentHistoryBudgetResult.totalTokens` and
|
|
249
|
+
`ComposedAgentPrompt.instructionTokens`. A per-message or per-section count is
|
|
250
|
+
still `measured` — only the totals moved. When any part was estimated the total
|
|
251
|
+
is still `estimated`: an estimate survives arithmetic, and that is the weaker
|
|
252
|
+
claim, so it wins.
|
|
253
|
+
|
|
254
|
+
#### If you produce token counts
|
|
255
|
+
|
|
256
|
+
They are validated now, in the places they were not. A fractional count throws
|
|
257
|
+
where it used to flow into the context-window arithmetic:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
// refused from this release on
|
|
261
|
+
estimateTokens: (text) => ({ value: text.length / 4, provenance: 'estimated' })
|
|
262
|
+
// after
|
|
263
|
+
estimateTokens: (text) => ({ value: Math.ceil(text.length / 4), provenance: 'estimated' })
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The same applies to `ComposeAgentPromptOptions.estimateFallback` and
|
|
267
|
+
`.historyTokens`, to `AgentPromptBudget.toolSchemas` / `.attachments` /
|
|
268
|
+
`.providerOverhead`, and to `AgentPromptBudget.contextWindow` /
|
|
269
|
+
`.reservedOutput`, which must now be non-negative safe integers.
|
|
270
|
+
|
|
271
|
+
`AgentUsageValue.value` is `z.int()` too, which matters if you build usage
|
|
272
|
+
records by hand or in a store double. A figure arriving from a **provider** is
|
|
273
|
+
not thrown — `normalizeSdkUsage` and the OpenRouter adapter turn a non-integer
|
|
274
|
+
into `{ provenance: 'unavailable' }`, so a run that already answered is not
|
|
275
|
+
failed over its own bookkeeping.
|
|
276
|
+
|
|
277
|
+
#### The new export
|
|
278
|
+
|
|
279
|
+
`AgentProvenanceSchema` / `AgentProvenance` is the whole vocabulary:
|
|
280
|
+
`provider-reported`, `measured`, `computed`, `estimated`, `unavailable`. Each
|
|
281
|
+
surface declares its subset, so nothing widened — `AgentUsageValue` still refuses
|
|
282
|
+
`measured` and `AgentTokenCount` still refuses `provider-reported`. Use it when
|
|
283
|
+
you want one switch over the question instead of two.
|
|
284
|
+
|
|
285
|
+
## Released migration: 0.65.0
|
|
286
|
+
|
|
287
|
+
The largest migration of the pre-1.0 line, and most of it is the compiler
|
|
288
|
+
pointing at things. One item is a feature withdrawal and two change behaviour
|
|
289
|
+
with no compile error at all.
|
|
290
|
+
|
|
291
|
+
### A projection a provider accepts, and a policy withdrawn
|
|
292
|
+
|
|
293
|
+
### If you compact, or use `system-note`, you were broken and now are not
|
|
294
|
+
|
|
295
|
+
No code change to adopt the fix — but **check your own code if you call
|
|
296
|
+
`projectAgentHistory` yourself.** System and summary records no longer appear in
|
|
297
|
+
`messages`; they come back in `system` and belong in the provider's instructions
|
|
298
|
+
channel, which is the only place `ai` accepts them:
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
// before — the provider refuses this outright
|
|
302
|
+
const messages = await projectAgentHistory(snapshot.messages)
|
|
303
|
+
streamText({ model, messages })
|
|
304
|
+
|
|
305
|
+
// after
|
|
306
|
+
const { messages, system } = await projectAgentHistoryDetailed(snapshot.messages)
|
|
307
|
+
streamText({
|
|
308
|
+
model,
|
|
309
|
+
instructions: system.map((content) => ({ role: 'system', content })),
|
|
310
|
+
messages,
|
|
311
|
+
})
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
If you use `createAgentRuntime`, this is handled for you.
|
|
315
|
+
|
|
316
|
+
### `inputPolicy: 'inject'` is withdrawn
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
// before
|
|
320
|
+
runs: { inputPolicy: 'inject' }
|
|
321
|
+
// after
|
|
322
|
+
runs: { inputPolicy: 'queue' }
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
`'absorbed'`, `AgentRun.absorbedIntoRunId` and `AgentRuntimeStore.absorbQueuedRun`
|
|
326
|
+
go with it. A driver built on `AgentRuntimeStoreDriver` needs no change.
|
|
327
|
+
|
|
328
|
+
### Records must agree with themselves
|
|
329
|
+
|
|
330
|
+
If you construct `AgentRun` values — a store double, a fixture, a migration —
|
|
331
|
+
derive the state instead of setting it:
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
// after
|
|
335
|
+
import { runStateForTerminalReason } from 'stitchkit/agent-runtime'
|
|
336
|
+
AgentRunSchema.parse({ …run, terminalReason: reason, state: runStateForTerminalReason(reason) })
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
A terminal state with no reason, a queued run carrying one, and `policy_stop`
|
|
340
|
+
without a `terminalPolicyName` are now all refused at parse time.
|
|
341
|
+
|
|
342
|
+
### Enum and field changes the compiler will point at
|
|
343
|
+
|
|
344
|
+
- `AgentTerminalReason`: `'tool_failure'` removed (never produced),
|
|
345
|
+
`'context_overflow'` added — this runtime's own refusal when the prompt does
|
|
346
|
+
not fit, which used to report `provider_failure`.
|
|
347
|
+
- `AgentRunState`: `'absorbed'` removed.
|
|
348
|
+
- `AgentRunMetrics.usage` is required.
|
|
349
|
+
- `AgentHistoryBudgetDecision['reason']`: `'superseded'` → `'unspeakable'`.
|
|
350
|
+
|
|
351
|
+
### Two behaviour changes with no compile error
|
|
352
|
+
|
|
353
|
+
- **`loop.idleTimeoutMs` now defaults to 60 000.** A run whose provider stream
|
|
354
|
+
goes quiet for a minute ends as `timeout` instead of holding the lane forever.
|
|
355
|
+
Pass `null` for the old behaviour, and think about why you want it.
|
|
356
|
+
- **`advanceAgentRuntimeEventCursor` stops returning `gap` for durable events.**
|
|
357
|
+
If you reload a conversation on `gap`, you were reloading after essentially
|
|
358
|
+
every run. Transient events still report it, and there it is real.
|
|
359
|
+
|
|
360
|
+
## Released migration: 0.64.0
|
|
361
|
+
|
|
362
|
+
Two changes, and only one of them can break a build. Nothing was removed.
|
|
363
|
+
|
|
364
|
+
### An event that says which kind it is
|
|
365
|
+
|
|
366
|
+
### Narrow `AgentRunEvent` on `type`
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
// before
|
|
370
|
+
for (const event of events) record(event.usage?.cost?.value ?? 0)
|
|
371
|
+
|
|
372
|
+
// after — and the compiler will point at every site
|
|
373
|
+
for (const event of events) {
|
|
374
|
+
if (event.type !== 'run-terminal') continue
|
|
375
|
+
record(event.usage.cost.value ?? null) // `usage` is present; unknown says so
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
`step` is now required on `step-finished`, `terminalReason` on `run-terminal`,
|
|
380
|
+
and `usage` on both. `queueWaitMs` exists only on `run-started`. Nothing was
|
|
381
|
+
removed — the fields that were optional because a *different* kind of event
|
|
382
|
+
lacked them are now simply on the kinds that have them.
|
|
383
|
+
|
|
384
|
+
Import `AgentRunTerminalEventSchema` (or the sibling schemas) if you construct
|
|
385
|
+
events in tests.
|
|
386
|
+
|
|
387
|
+
### If you implement `AgentRuntimeStore` directly, move to the driver
|
|
388
|
+
|
|
389
|
+
Not urgent and nothing breaks today — but the aggregate is no longer the
|
|
390
|
+
supported target, so its future growth will not be announced as breaking
|
|
391
|
+
(→ ADR 0111). The supported shape is one line:
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
const driver: AgentRuntimeStoreDriver<TransactionClient> = { /* six primitives */ }
|
|
395
|
+
export const store = createAgentRuntimeStore(driver)
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Run `runAgentStoreConformance` against your adapter before and after any bump —
|
|
399
|
+
see *Before you bump, if you implement an agent store* above.
|
|
400
|
+
|
|
401
|
+
## Released migration: 0.63.0
|
|
402
|
+
|
|
403
|
+
Four changes to what a running system reports and how an input reaches a run
|
|
404
|
+
in flight. Nothing moves an export except one added store member, and only an
|
|
405
|
+
application implementing `AgentRuntimeStore` directly has to touch code.
|
|
406
|
+
|
|
407
|
+
### A spend figure that survives, and an input that joins
|
|
408
|
+
|
|
409
|
+
### `AgentRuntimeStore` has a ninth member
|
|
410
|
+
|
|
411
|
+
Only if you implement the aggregate interface directly — an adapter built on
|
|
412
|
+
`AgentRuntimeStoreDriver` needs no change, and the public conformance kit covers
|
|
413
|
+
the new operation.
|
|
414
|
+
|
|
415
|
+
```ts
|
|
416
|
+
// after
|
|
417
|
+
absorbQueuedRun(input: AbsorbQueuedRun): Promise<AgentStoreMutationResult>
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
It moves a queued successor's inputs into the run already answering, in one
|
|
421
|
+
mutation, and marks the successor `absorbed`. Two run records change in one
|
|
422
|
+
transaction — if your driver persists them one at a time, persist both.
|
|
423
|
+
|
|
424
|
+
### A provider failure says so
|
|
425
|
+
|
|
426
|
+
```ts
|
|
427
|
+
// before — an upstream error arrived as a policy stop with no policy
|
|
428
|
+
if (terminal.reason === 'policy_stop') retryLater()
|
|
429
|
+
|
|
430
|
+
// after
|
|
431
|
+
if (terminal.reason === 'provider_failure') retryLater()
|
|
432
|
+
if (terminal.reason === 'provider_stop') { /* a length cap or content filter */ }
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
`policy_stop` now always carries the `policyName` that caused it. If you switch
|
|
436
|
+
exhaustively on `AgentTerminalReason` or `AgentRunState`, add `'provider_stop'`
|
|
437
|
+
and `'absorbed'`.
|
|
438
|
+
|
|
439
|
+
### `partial` changed meaning
|
|
440
|
+
|
|
441
|
+
It used to tell you which event kind you were holding. It now tells you whether
|
|
442
|
+
the figure beside it is a confirmed total:
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
// after — true when the provider never reported the run finished
|
|
446
|
+
if (metrics.partial) treatAsFloor(metrics.usage)
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Terminal events for runs that were superseded, interrupted, timed out or failed
|
|
450
|
+
before the provider finished now report `partial: true` where they reported
|
|
451
|
+
`false`.
|
|
452
|
+
|
|
453
|
+
### Checkpoint metrics are a running total
|
|
454
|
+
|
|
455
|
+
```ts
|
|
456
|
+
// wrong, and now wrong by more than it used to be
|
|
457
|
+
const spent = checkpoints.reduce((total, c) => total + (c.metrics.usage?.cost?.value ?? 0), 0)
|
|
458
|
+
// right
|
|
459
|
+
const spent = checkpoints.at(-1)?.metrics.usage?.cost?.value
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### You can read a run's spend back from the store
|
|
463
|
+
|
|
464
|
+
`AgentRun.usage` is written at every checkpoint and with the terminal record, so
|
|
465
|
+
a dropped observability event no longer loses the number, and a process that dies
|
|
466
|
+
mid-stream leaves behind what it had already spent.
|
|
467
|
+
|
|
468
|
+
## Released migration: 0.62.0
|
|
469
|
+
|
|
470
|
+
Two groups of behaviour changes. Nothing moves an export — the surface is
|
|
471
|
+
strictly additive — and every item changes what a running system reports or
|
|
472
|
+
sends, which is what this heading is for. One of them changes a number you may
|
|
473
|
+
already be billing against.
|
|
474
|
+
|
|
475
|
+
### A run reports what it spent
|
|
476
|
+
|
|
477
|
+
Three changes to what the runtime says about cost and tokens. Nothing moves an
|
|
478
|
+
export; all three change numbers a running system reports, and one of them
|
|
479
|
+
changes a number you may already be billing against.
|
|
480
|
+
|
|
481
|
+
#### Multi-step cost was under-reported and is now summed
|
|
482
|
+
|
|
483
|
+
No code change is needed to get the fix — but check any predicate that reads
|
|
484
|
+
`provenance`:
|
|
485
|
+
|
|
486
|
+
```ts
|
|
487
|
+
// before — accepted a number that was one step's cost, not the run's
|
|
488
|
+
if (usage.cost?.provenance === 'provider-reported') bill(usage.cost.value)
|
|
489
|
+
|
|
490
|
+
// after — a sum stitchkit performed says so
|
|
491
|
+
if (usage.cost && usage.cost.provenance !== 'unavailable') bill(usage.cost.value)
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
`'computed'` means stitchkit added up provider-reported parts. It is not a guess
|
|
495
|
+
— `'estimated'` is the word for that — but it is deliberately not
|
|
496
|
+
`'provider-reported'`, because that label is what a caller filters on when it
|
|
497
|
+
wants a figure it can bill against unchanged, and a sum is not one.
|
|
498
|
+
|
|
499
|
+
Token totals moved with it. The AI SDK's `totalUsage` is a sum *it* performed
|
|
500
|
+
over per-step provider figures — not a run total any provider handed over — so
|
|
501
|
+
labelling it `provider-reported` was the same overstatement. **A run total on a
|
|
502
|
+
terminal event is always `computed`.** If you want a figure with the provider's
|
|
503
|
+
own word on it, read `step-finished`: each step carries what that call reported.
|
|
504
|
+
|
|
505
|
+
#### `usage` is always present on a terminal event
|
|
506
|
+
|
|
507
|
+
```ts
|
|
508
|
+
// before — absent when the run ended before the provider's `finish`
|
|
509
|
+
const spent = event.usage?.cost?.value ?? 0 // silently 0 for a real spend
|
|
510
|
+
|
|
511
|
+
// after — present, and it says what it does not know
|
|
512
|
+
event.usage?.cost?.provenance === 'unavailable' // we spent, and cannot say how much
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
Keep the optional chaining: one `AgentRunEvent` shape covers `run-started`,
|
|
516
|
+
`step-finished` and `run-terminal`, so `usage` stays optional on the type. The
|
|
517
|
+
guarantee is about terminal events, and a schema shared with `run-started`
|
|
518
|
+
cannot express it.
|
|
519
|
+
|
|
520
|
+
**Do not read `unavailable` as zero.** A run aborted mid-stream has spent real
|
|
521
|
+
money that nobody has counted; a run that never reached the provider has not.
|
|
522
|
+
Both used to look the same and now do not.
|
|
523
|
+
|
|
524
|
+
#### A losing executor reports its own spend
|
|
525
|
+
|
|
526
|
+
An execution that loses the terminal compare-and-swap now emits an operator
|
|
527
|
+
`run-terminal` event, because it ran and it spent. If a sink treated those events
|
|
528
|
+
as "runs this process committed", that is no longer true — `AgentRuntimeResult.metrics`
|
|
529
|
+
is still `undefined` for a losing executor and remains the way to tell.
|
|
530
|
+
|
|
531
|
+
The *delivery* `terminal` event is unchanged and still fires only for the winner,
|
|
532
|
+
so nothing delivers a turn twice.
|
|
533
|
+
|
|
534
|
+
### An interrupted answer stops passing as a finished one
|
|
535
|
+
|
|
536
|
+
Two behaviour changes, one shared cause: a run ended by a newer input used to
|
|
537
|
+
leave its half-written answer in the conversation with no sign that it was cut
|
|
538
|
+
off, and the next request to the provider carried it as an ordinary assistant
|
|
539
|
+
turn.
|
|
540
|
+
|
|
541
|
+
#### The projection marks an interrupted turn
|
|
542
|
+
|
|
543
|
+
Nothing to change to adopt the fix — the default is the fixed behaviour. What to
|
|
544
|
+
check is whether the marker is the *right* form for your surface, and the
|
|
545
|
+
question that decides it is not "was the run interrupted" but **"did anyone see
|
|
546
|
+
what it produced"**.
|
|
547
|
+
|
|
548
|
+
```ts
|
|
549
|
+
// after — pick the form; the default is 'assistant-marked'
|
|
550
|
+
createAgentRuntime({ history: { interruptedAssistant: 'system-note' } })
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
- **The user pressed stop and the text was on their screen** — keep
|
|
554
|
+
`'assistant-marked'`. The assistant turn is the truthful record of what the
|
|
555
|
+
human read, and the model should stay consistent with it.
|
|
556
|
+
- **The partial never reached anyone** — a surface that sends nothing until the
|
|
557
|
+
run is done — prefer `'system-note'`. An assistant turn in provider history is
|
|
558
|
+
a commitment the model stays consistent with; a system line is context.
|
|
559
|
+
|
|
560
|
+
If you pass `history.project` you own the projection outright and none of this
|
|
561
|
+
applies — but the same question does.
|
|
562
|
+
|
|
563
|
+
#### A run ended by a newer input can now say so
|
|
564
|
+
|
|
565
|
+
```ts
|
|
566
|
+
// before
|
|
567
|
+
runs: { inputPolicy: 'interrupt' } // ends the run, keeps its partial answer
|
|
568
|
+
|
|
569
|
+
// after — for a surface where a follow-up message invalidates the answer
|
|
570
|
+
// in flight rather than merely stopping it
|
|
571
|
+
runs: { inputPolicy: 'supersede' } // ends the run, discards its partial answer
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
`inputPolicy` also accepts `(input) => policy`, which is how one application
|
|
575
|
+
gives two conversation surfaces different rules without the runtime learning
|
|
576
|
+
which is which.
|
|
577
|
+
|
|
578
|
+
A superseded run terminates with `terminalReason: 'superseded'`, state
|
|
579
|
+
`'superseded'` and an assistant message of status `'superseded'`. **If you switch
|
|
580
|
+
exhaustively on any of those enums, add the arm** — that is the part of this
|
|
581
|
+
release that can break a build rather than a behaviour. The record itself is
|
|
582
|
+
kept: it is excluded from the projection, not deleted, so an operator can still
|
|
583
|
+
see what was thrown away.
|
|
584
|
+
|
|
12
585
|
## Released migration: 0.61.0
|
|
13
586
|
|
|
14
587
|
Three behaviour changes between versions. None moves an export — the surface is
|
|
@@ -599,506 +1172,3 @@ const mock: Pick<RealtimeClient<S, C>, 'emit'> = { emit: () => true }
|
|
|
599
1172
|
While migrating, consider replacing hand-rolled `if (client.connected)` guards
|
|
600
1173
|
with the new honest surface: check `client.emit(...) === false`, or observe
|
|
601
1174
|
drops centrally with `onDroppedEmit`.
|
|
602
|
-
|
|
603
|
-
## Released migration: 0.50.0
|
|
604
|
-
|
|
605
|
-
### The factory's scope union now covers per-endpoint overrides
|
|
606
|
-
|
|
607
|
-
`createContractFactory<Scope>()` already required a typed `scope` on the
|
|
608
|
-
contract. It now holds a per-endpoint `scope` override to the same union. Nothing
|
|
609
|
-
to migrate unless an override is outside the union — which was always a bug: the
|
|
610
|
-
scope reached no auth rule, and `createAuthHook` threw
|
|
611
|
-
`[stitchkit] auth: no rule for scope "…"` on the first request to it.
|
|
612
|
-
|
|
613
|
-
```ts
|
|
614
|
-
const { defineContract } = createContractFactory<'public' | 'user' | 'admin'>()
|
|
615
|
-
|
|
616
|
-
defineContract({ prefix: 'posts', scope: 'user' }, {
|
|
617
|
-
// before: compiled; failed at request time
|
|
618
|
-
// after: compile error naming the scope (TypeScript even suggests 'admin')
|
|
619
|
-
purge: { method: 'DELETE', path: '/all', desc: 'Purge', scope: 'admn', output },
|
|
620
|
-
})
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
Fix the typo, or widen the factory union if the scope is real. Contracts built
|
|
624
|
-
with plain `defineContract` are unaffected.
|
|
625
|
-
|
|
626
|
-
### A declared `defineErrors` message is now used
|
|
627
|
-
|
|
628
|
-
`ErrorDefinition` accepts `message`. Nothing to migrate unless a registry already
|
|
629
|
-
wrote that key: it type-checked before (excess-property checking does not fire
|
|
630
|
-
through a `const` generic) and was ignored, so the code itself went on the wire.
|
|
631
|
-
|
|
632
|
-
```ts
|
|
633
|
-
const { errors } = defineErrors({ GONE: { status: 410, message: 'Long gone' } })
|
|
634
|
-
// before: errors.GONE().message === 'GONE'
|
|
635
|
-
// after: errors.GONE().message === 'Long gone'
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
If a registry carried `message` as a note to the reader rather than as
|
|
639
|
-
user-facing text, either fix the text or drop the key. A code with no `details`
|
|
640
|
-
schema also shows that text to a model (its tool `details` is `{ message }`).
|
|
641
|
-
|
|
642
|
-
### Optional: adopt `createScopedImplement`
|
|
643
|
-
|
|
644
|
-
If the app declares one superset handler context because different scopes inject
|
|
645
|
-
different fields, replace it with a scope map. This is additive — `createImplement`
|
|
646
|
-
still works.
|
|
647
|
-
|
|
648
|
-
```ts
|
|
649
|
-
// before — one context for every scope; `ctx.userId` is typed even in a
|
|
650
|
-
// `public` handler, where the runtime never injects it
|
|
651
|
-
interface AppContext extends RuntimeContext { userId: string; isAdmin: boolean }
|
|
652
|
-
export const implement = createImplement<AppContext>()
|
|
653
|
-
|
|
654
|
-
// after — each handler typed by its endpoint's effective scope
|
|
655
|
-
export const implementFor = createScopedImplement<{
|
|
656
|
-
public: object
|
|
657
|
-
user: { userId: string }
|
|
658
|
-
admin: { userId: string; isAdmin: boolean }
|
|
659
|
-
}>()
|
|
660
|
-
```
|
|
661
|
-
|
|
662
|
-
`'public'` must be a key (a contract with no `scope` is `'public'`). Write
|
|
663
|
-
endpoints inline in the contract literal: an endpoint hoisted into a variable
|
|
664
|
-
widens its `scope` to `string` and is reported as undeclared.
|
|
665
|
-
|
|
666
|
-
## Released migration: 0.49.0
|
|
667
|
-
|
|
668
|
-
### The server handle became managed
|
|
669
|
-
|
|
670
|
-
`createServer()` and `serveNode()` return a handle that owns admission, HTTP
|
|
671
|
-
drain, realtime closure and one deadline-bounded runtime stop:
|
|
672
|
-
|
|
673
|
-
```ts
|
|
674
|
-
// before
|
|
675
|
-
server.stop()
|
|
676
|
-
await socket.io.close()
|
|
677
|
-
// after
|
|
678
|
-
await server.shutdown({ gracePeriodMs: 30_000 })
|
|
679
|
-
```
|
|
680
|
-
|
|
681
|
-
The runtime-specific instance stays reachable at `.runtime`, so an escape hatch
|
|
682
|
-
you already rely on does not disappear — but code that closed transports itself,
|
|
683
|
-
in its own order, is now racing the handle. Delete the manual closes rather than
|
|
684
|
-
keeping both; the handle's result tells you what it drained and what it forced.
|
|
685
|
-
|
|
686
|
-
### Socket.IO mounts through the whole handle
|
|
687
|
-
|
|
688
|
-
```ts
|
|
689
|
-
// before
|
|
690
|
-
createServer({ websocket: socket.websocket, rawRoutes: [socket.route] })
|
|
691
|
-
// after
|
|
692
|
-
createServer({ socket })
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
One owner for the route, the WebSocket attachment and the closure. For a raw Bun
|
|
696
|
-
lane, keep the composed `websocket` handler and pass `socket` beside it.
|
|
697
|
-
|
|
698
|
-
### Bun native `routes` are gone
|
|
699
|
-
|
|
700
|
-
Native routes run before the Fetch handler, so they bypassed managed admission —
|
|
701
|
-
which means they also bypassed shutdown, logging and observability, and that is
|
|
702
|
-
why they had to go rather than be wired up:
|
|
703
|
-
|
|
704
|
-
```ts
|
|
705
|
-
// before
|
|
706
|
-
createServer({ routes: { '/health': () => Response.json({ ok: true }) } })
|
|
707
|
-
// after
|
|
708
|
-
createServer({ rawRoutes: [{ method: 'GET', path: '/health', handler: () => Response.json({ ok: true }) }] })
|
|
709
|
-
```
|
|
710
|
-
|
|
711
|
-
### The handshake policy takes a Web `Request`
|
|
712
|
-
|
|
713
|
-
```ts
|
|
714
|
-
// before
|
|
715
|
-
createSocketIOServer({ serverOptions: { allowRequest: (req, done) => done(null, allowed(req)) } })
|
|
716
|
-
// after
|
|
717
|
-
createSocketIOServer({ allowRequest: (request) => allowed(request) })
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
The Node-shaped callback is gone, and the policy is now composed with shutdown
|
|
721
|
-
admission on both runtimes: a handshake arriving during drain is refused for
|
|
722
|
-
you.
|
|
723
|
-
|
|
724
|
-
## Released migration: 0.48.0
|
|
725
|
-
|
|
726
|
-
### Typed-client request options move to `.withOptions`
|
|
727
|
-
|
|
728
|
-
Generated endpoint methods reserve their ordinary call signature for contract
|
|
729
|
-
variables. This keeps them directly assignable to callback APIs whose runtime
|
|
730
|
-
supplies its own second context argument, including `react-query-kit` and
|
|
731
|
-
TanStack Query. Move imperative cancellation to the callable's explicit method:
|
|
732
|
-
|
|
733
|
-
```ts
|
|
734
|
-
// before — endpoint with arguments
|
|
735
|
-
await api.create({ name: 'Max' }, { signal })
|
|
736
|
-
|
|
737
|
-
// after
|
|
738
|
-
await api.create.withOptions({ name: 'Max' }, { signal })
|
|
739
|
-
|
|
740
|
-
// before — endpoint without arguments
|
|
741
|
-
await api.health({ signal })
|
|
742
|
-
|
|
743
|
-
// after
|
|
744
|
-
await api.health.withOptions({ signal })
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
Direct query and mutation composition remains unchanged:
|
|
748
|
-
|
|
749
|
-
```ts
|
|
750
|
-
createMutation({ mutationFn: api.create })
|
|
751
|
-
createQuery({ queryKey: ['search'], fetcher: api.search })
|
|
752
|
-
```
|
|
753
|
-
|
|
754
|
-
There is no positional-options alias. Ordinary generated methods ignore extra
|
|
755
|
-
runtime callback arguments; only `.withOptions` reads `ClientRequestOptions`.
|
|
756
|
-
|
|
757
|
-
## Released migration: 0.47.0
|
|
758
|
-
|
|
759
|
-
### HTTP auth moves to the pre-body `authorize` phase
|
|
760
|
-
|
|
761
|
-
Move the HTTP wiring of `createAuthHook` from `beforeHandle` to `authorize`.
|
|
762
|
-
This lets Stitchkit reject an unauthorized JSON or multipart request after path
|
|
763
|
-
parameter validation but before reading a body chunk. Keep application
|
|
764
|
-
preconditions that depend on validated input in `beforeHandle`.
|
|
765
|
-
|
|
766
|
-
```ts
|
|
767
|
-
const auth = createAuthHook({ authenticate, authorize })
|
|
768
|
-
|
|
769
|
-
// before
|
|
770
|
-
createServer({ services, hooks: { beforeHandle: auth } })
|
|
771
|
-
|
|
772
|
-
// after
|
|
773
|
-
createServer({ services, hooks: { authorize: auth } })
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
Tool transports already receive parsed input, so their wiring does not move:
|
|
777
|
-
|
|
778
|
-
```ts
|
|
779
|
-
createMcpHandler({ services, lifecycle: { beforeHandle: auth } })
|
|
780
|
-
```
|
|
781
|
-
|
|
782
|
-
If a custom HTTP authorization hook read `ctx.input`, `ctx.files` or raw body
|
|
783
|
-
state, split it: identity/scope checks belong in `authorize`; validated payload
|
|
784
|
-
preconditions belong in `beforeHandle` or the domain service.
|
|
785
|
-
|
|
786
|
-
### Multipart uses a typed descriptor and `ctx.files`
|
|
787
|
-
|
|
788
|
-
Replace every string multipart declaration, top-level `maxUploadBytes` and
|
|
789
|
-
`ctx.file`. The descriptor is now the only source of request, per-file,
|
|
790
|
-
cardinality and declared media-type policy.
|
|
791
|
-
|
|
792
|
-
```ts
|
|
793
|
-
// before
|
|
794
|
-
upload: {
|
|
795
|
-
method: 'POST',
|
|
796
|
-
path: '/',
|
|
797
|
-
multipart: 'file',
|
|
798
|
-
maxUploadBytes: 25 * 1024 * 1024,
|
|
799
|
-
}
|
|
800
|
-
upload: ({ file, input }) => store(file, input)
|
|
801
|
-
|
|
802
|
-
// after
|
|
803
|
-
upload: {
|
|
804
|
-
method: 'POST',
|
|
805
|
-
path: '/',
|
|
806
|
-
multipart: {
|
|
807
|
-
maxRequestBytes: 25 * 1024 * 1024,
|
|
808
|
-
files: {
|
|
809
|
-
file: {
|
|
810
|
-
maxBytes: 20 * 1024 * 1024,
|
|
811
|
-
contentTypes: ['image/*', 'application/pdf'],
|
|
812
|
-
},
|
|
813
|
-
},
|
|
814
|
-
},
|
|
815
|
-
}
|
|
816
|
-
upload: ({ files, input }) => store(files.file, input)
|
|
817
|
-
```
|
|
818
|
-
|
|
819
|
-
Multiple files are repeated under one multipart field name and arrive in the
|
|
820
|
-
same order:
|
|
821
|
-
|
|
822
|
-
```ts
|
|
823
|
-
files: {
|
|
824
|
-
attachments: { multiple: true, maxFiles: 8 },
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
await api.upload({ attachments: [firstFile, secondFile] })
|
|
828
|
-
// handler: files.attachments is File[]
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
For direct-to-storage delivery, set `delivery: 'stream'` and implement the
|
|
832
|
-
endpoint with `defineMultipartStream`. A receiver must consume its Web Stream
|
|
833
|
-
and return `{ value, cleanup }`; the final handler sees only receiver values.
|
|
834
|
-
There is no deprecated overload or buffered compatibility path under the old
|
|
835
|
-
contract shape.
|
|
836
|
-
|
|
837
|
-
## Released migration: 0.46.0
|
|
838
|
-
|
|
839
|
-
### `REALTIME_CONTRACT_VIOLATION` joined the error registry
|
|
840
|
-
|
|
841
|
-
Realtime contract failures use the framework error model instead of a bare
|
|
842
|
-
`ZodError`, so an exhaustive map stops compiling until the code is added:
|
|
843
|
-
|
|
844
|
-
```ts
|
|
845
|
-
// before
|
|
846
|
-
{ …, INTERNAL_SERVER_ERROR: 'internal' } satisfies Record<StitchErrorCode, string>
|
|
847
|
-
// after
|
|
848
|
-
{ …, INTERNAL_SERVER_ERROR: 'internal', REALTIME_CONTRACT_VIOLATION: 'internal' } satisfies Record<StitchErrorCode, string>
|
|
849
|
-
```
|
|
850
|
-
|
|
851
|
-
Only an exhaustive map breaks. Since 0.56.1 `codeMap` itself is partial, so a
|
|
852
|
-
map without the `satisfies` keeps compiling and lets the code travel as itself.
|
|
853
|
-
|
|
854
|
-
### `RealtimeRejectedEvent.error` is an `AppError`
|
|
855
|
-
|
|
856
|
-
```ts
|
|
857
|
-
// before
|
|
858
|
-
onRejected: ({ error }) => error.issues
|
|
859
|
-
// after
|
|
860
|
-
onRejected: ({ error }) => error.details?.issues // the ZodError moves to error.cause
|
|
861
|
-
```
|
|
862
|
-
|
|
863
|
-
The envelope gained `reason` and `fault`. The consequence worth checking: code
|
|
864
|
-
reading `.issues` directly does not fail to compile if the handler is loosely
|
|
865
|
-
typed — it silently reads `undefined`. Grep for `.issues` on rejection handlers.
|
|
866
|
-
|
|
867
|
-
### CLI construction refuses reserved names
|
|
868
|
-
|
|
869
|
-
A contract field or tool named `json`, `wait`, `quiet`, `dry-run`, `help`,
|
|
870
|
-
`version`, `wait-timeout` or `output-dir` now **throws while the CLI is built**,
|
|
871
|
-
instead of being silently shadowed:
|
|
872
|
-
|
|
873
|
-
```ts
|
|
874
|
-
// before: app schedule_job --wait 2h → {"path":"2h"}, exit 0
|
|
875
|
-
// after: building a CLI over a contract with a "wait" field throws
|
|
876
|
-
```
|
|
877
|
-
|
|
878
|
-
This one fires at startup, not at call time, so an application shipping such a
|
|
879
|
-
field crashes on boot after the upgrade. That is deliberate — the old behaviour
|
|
880
|
-
corrupted arguments silently — but it means the upgrade is not safe to deploy
|
|
881
|
-
without building the CLI once locally.
|
|
882
|
-
|
|
883
|
-
### `createToolLogger` writes to stderr
|
|
884
|
-
|
|
885
|
-
stdout is the JSON-RPC channel of a stdio MCP server, and the previous
|
|
886
|
-
`console.info` default corrupted it. Pass `log` to redirect if your process
|
|
887
|
-
collected tool logs from stdout.
|
|
888
|
-
|
|
889
|
-
## Released migration: 0.44.0
|
|
890
|
-
|
|
891
|
-
### MCP TypeScript SDK v2 and protocol `2026-07-28`
|
|
892
|
-
|
|
893
|
-
This is a hard cut: there is one Stitchkit API and no v1 aliases. Applications
|
|
894
|
-
that expose MCP install the split server package; applications that implement an
|
|
895
|
-
MCP host or run client E2E install the split client package.
|
|
896
|
-
|
|
897
|
-
```bash
|
|
898
|
-
bun remove @modelcontextprotocol/sdk
|
|
899
|
-
bun add @modelcontextprotocol/server@^2 ai@^7
|
|
900
|
-
# MCP hosts and client-side E2E only:
|
|
901
|
-
bun add -d @modelcontextprotocol/client@^2
|
|
902
|
-
```
|
|
903
|
-
|
|
904
|
-
Direct SDK imports move to the split packages too:
|
|
905
|
-
|
|
906
|
-
```ts
|
|
907
|
-
// before
|
|
908
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
909
|
-
|
|
910
|
-
// after
|
|
911
|
-
import { McpServer } from '@modelcontextprotocol/server'
|
|
912
|
-
```
|
|
913
|
-
|
|
914
|
-
MCP Apps additionally install `@modelcontextprotocol/ext-apps`. That adapter may
|
|
915
|
-
carry its own isolated v1-era transitive/peer relationship while the ecosystem
|
|
916
|
-
finishes its cutover; it does not permit application code to import the removed
|
|
917
|
-
monolithic SDK. Application-owned MCP server and client code uses the v2 split
|
|
918
|
-
packages exclusively.
|
|
919
|
-
|
|
920
|
-
```ts
|
|
921
|
-
// before
|
|
922
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
923
|
-
import { createMcpHandler } from 'stitchkit/tools'
|
|
924
|
-
|
|
925
|
-
const handleMcp = createMcpHandler({
|
|
926
|
-
serverInfo,
|
|
927
|
-
auth,
|
|
928
|
-
services,
|
|
929
|
-
sessionMode: 'stateless',
|
|
930
|
-
})
|
|
931
|
-
rawRoutes: [{ method: 'ALL', path: '/mcp', handler: handleMcp }]
|
|
932
|
-
|
|
933
|
-
// after
|
|
934
|
-
import { Client } from '@modelcontextprotocol/client'
|
|
935
|
-
import { createMcpHandler, createMcpHttpRoute } from 'stitchkit/tools'
|
|
936
|
-
|
|
937
|
-
const mcp = createMcpHandler({
|
|
938
|
-
serverInfo,
|
|
939
|
-
auth,
|
|
940
|
-
services,
|
|
941
|
-
legacy: 'serve',
|
|
942
|
-
})
|
|
943
|
-
rawRoutes: [createMcpHttpRoute({ path: '/mcp', handler: mcp })]
|
|
944
|
-
// graceful shutdown: await mcp.close()
|
|
945
|
-
```
|
|
946
|
-
|
|
947
|
-
Keep the owned handle and close it from the same shutdown path as the HTTP
|
|
948
|
-
server. A minimal runtime smoke should list tools before shutdown and prove the
|
|
949
|
-
closed handler no longer serves requests:
|
|
950
|
-
|
|
951
|
-
```ts
|
|
952
|
-
const mcp = createMcpHandler(config)
|
|
953
|
-
const route = createMcpHttpRoute({ path: '/mcp', handler: mcp })
|
|
954
|
-
|
|
955
|
-
const beforeClose = await route.handler(listToolsRequest)
|
|
956
|
-
if (!beforeClose.ok) throw new Error('MCP list-tools smoke failed')
|
|
957
|
-
|
|
958
|
-
await mcp.close()
|
|
959
|
-
```
|
|
960
|
-
|
|
961
|
-
Remove `@modelcontextprotocol/sdk`, `sessionMode`, `McpSessionMode`, session
|
|
962
|
-
stores and all `Mcp-Session-Id` handling. HTTP is always request-isolated and
|
|
963
|
-
stateless. `legacy: 'serve'` (default) lets the official SDK negotiate supported
|
|
964
|
-
pre-2026 stateless clients on the same endpoint; `legacy: 'reject'` makes it
|
|
965
|
-
modern-only. This is not a stateful compatibility transport.
|
|
966
|
-
|
|
967
|
-
#### Output shape depends on the negotiated protocol era
|
|
968
|
-
|
|
969
|
-
Stitchkit always validates the handler result against the declared output
|
|
970
|
-
schema. The negotiated MCP era determines only its wire representation:
|
|
971
|
-
|
|
972
|
-
| Negotiated era | Non-object `structuredContent` |
|
|
973
|
-
|---|---|
|
|
974
|
-
| MCP `2026-07-28` | the exact schema-valid JSON root: array, scalar or `null` |
|
|
975
|
-
| supported legacy era | the official SDK codec adapts it to `{ result: value }` |
|
|
976
|
-
|
|
977
|
-
Object roots keep their object shape in both eras. Do not change every consumer
|
|
978
|
-
expectation to the modern shape while `legacy: 'serve'` remains enabled. Pin
|
|
979
|
-
both protocol versions in the consumer's transport E2E and assert the boundary
|
|
980
|
-
explicitly:
|
|
981
|
-
|
|
982
|
-
```ts
|
|
983
|
-
await expectToolOutputForProtocol('2026-07-28', ['a', 'b'])
|
|
984
|
-
await expectToolOutputForProtocol('2025-11-25', { result: ['a', 'b'] })
|
|
985
|
-
|
|
986
|
-
async function expectToolOutputForProtocol(
|
|
987
|
-
protocolVersion: '2026-07-28' | '2025-11-25',
|
|
988
|
-
expected: unknown,
|
|
989
|
-
) {
|
|
990
|
-
const client = await connectConsumerMcpClient({ protocolVersion })
|
|
991
|
-
const result = await client.callTool({ name: 'list_notes', arguments: {} })
|
|
992
|
-
expect(result.structuredContent).toEqual(expected)
|
|
993
|
-
await client.close()
|
|
994
|
-
}
|
|
995
|
-
```
|
|
996
|
-
|
|
997
|
-
`connectConsumerMcpClient` represents the consumer's real HTTP or stdio setup;
|
|
998
|
-
configure its official client with `versionNegotiation.mode.pin` so the test
|
|
999
|
-
cannot silently negotiate a different era.
|
|
1000
|
-
|
|
1001
|
-
The stdio helper now returns an owned lifecycle handle:
|
|
1002
|
-
|
|
1003
|
-
```ts
|
|
1004
|
-
// before
|
|
1005
|
-
await createStdioMcpServer(config)
|
|
1006
|
-
|
|
1007
|
-
// after
|
|
1008
|
-
const stdio = await createStdioMcpServer({ ...config, legacy: 'serve' })
|
|
1009
|
-
await stdio.close()
|
|
1010
|
-
```
|
|
1011
|
-
|
|
1012
|
-
OAuth client registration is now one explicit policy object. CIMD is secure and
|
|
1013
|
-
enabled by default; DCR is disabled unless supplied:
|
|
1014
|
-
|
|
1015
|
-
```ts
|
|
1016
|
-
// before
|
|
1017
|
-
mountOAuthProvider({ ...oauth, clients, codes, refreshTokens })
|
|
1018
|
-
|
|
1019
|
-
// after
|
|
1020
|
-
mountOAuthProvider({
|
|
1021
|
-
...oauth,
|
|
1022
|
-
clientRegistration: {
|
|
1023
|
-
preRegistered: { get: clients.get },
|
|
1024
|
-
// optional: dcr: { register: clients.register, get: clients.get }
|
|
1025
|
-
},
|
|
1026
|
-
codes,
|
|
1027
|
-
refreshTokens,
|
|
1028
|
-
})
|
|
1029
|
-
```
|
|
1030
|
-
|
|
1031
|
-
A URL client id must be HTTPS and serve a document whose `client_id` exactly
|
|
1032
|
-
matches that URL, with explicit `redirect_uris` and
|
|
1033
|
-
`token_endpoint_auth_method: 'none'`. Do not keep a consumer-side metadata
|
|
1034
|
-
fetcher or DCR fallback; Stitchkit owns SSRF-safe resolution and caching.
|
|
1035
|
-
|
|
1036
|
-
Multi-round input is opt-in on the operation and does not change Agent, CLI or
|
|
1037
|
-
ordinary HTTP handlers:
|
|
1038
|
-
|
|
1039
|
-
```ts
|
|
1040
|
-
const ConfirmationSchema = z.object({ confirmed: z.boolean() })
|
|
1041
|
-
|
|
1042
|
-
mcp: {
|
|
1043
|
-
inputRequired: [{
|
|
1044
|
-
key: 'confirmation',
|
|
1045
|
-
message: 'Confirm this action',
|
|
1046
|
-
schema: ConfirmationSchema,
|
|
1047
|
-
}],
|
|
1048
|
-
}
|
|
1049
|
-
```
|
|
1050
|
-
|
|
1051
|
-
Configure `multiRound.state` on the MCP server with a key of at least 32 bytes
|
|
1052
|
-
and a stable authenticated `principal`. Read accepted typed content from
|
|
1053
|
-
`ctx.mcpInput.confirmation`. Multiple declarations run in array order, the
|
|
1054
|
-
aggregate remains exactly typed by key, keys must be unique, and declarations
|
|
1055
|
-
must fit `multiRound.serving.maxRounds` (default `10`). Do not execute a
|
|
1056
|
-
destructive side effect before the complete aggregate is accepted. A modern
|
|
1057
|
-
request missing the declared elicitation capability receives JSON-RPC error
|
|
1058
|
-
code `-32021`. The official per-request legacy HTTP bridge cannot issue
|
|
1059
|
-
server-to-client elicitation, so it returns a deterministic failed tool result;
|
|
1060
|
-
multi-round input is never silently treated as complete.
|
|
1061
|
-
|
|
1062
|
-
#### Compatibility matrix
|
|
1063
|
-
|
|
1064
|
-
| Host / transport | Tools and Apps | Multi-round input | Continuity |
|
|
1065
|
-
|---|---|---|---|
|
|
1066
|
-
| `2026-07-28` HTTP | yes | yes | request-isolated |
|
|
1067
|
-
| supported legacy stateless HTTP | yes | unsupported result | request-isolated |
|
|
1068
|
-
| `2026-07-28` stdio | yes | yes | one process connection |
|
|
1069
|
-
| supported legacy stdio | yes | official SDK bridge | one process connection |
|
|
1070
|
-
| Agent / CLI / ordinary HTTP | unchanged | not exposed | unchanged |
|
|
1071
|
-
|
|
1072
|
-
Subscriptions, cross-request progress and resumable stateful SSE are not
|
|
1073
|
-
implemented or advertised.
|
|
1074
|
-
|
|
1075
|
-
#### Consumer checklist
|
|
1076
|
-
|
|
1077
|
-
1. Replace the monolithic SDK with `@modelcontextprotocol/server@^2` and, only
|
|
1078
|
-
for hosts/tests, `@modelcontextprotocol/client@^2`.
|
|
1079
|
-
2. Replace raw MCP route wiring with `createMcpHttpRoute`; retain and close the
|
|
1080
|
-
returned handler/stdio handle during shutdown.
|
|
1081
|
-
3. Delete all session mode, event-store and session-id code.
|
|
1082
|
-
4. Move OAuth client policy under `clientRegistration`; publish CIMD or enable
|
|
1083
|
-
DCR explicitly.
|
|
1084
|
-
5. Make `authorizeUser` return the exact consented scope subset. The framework
|
|
1085
|
-
validates that it is a subset of the request before saving the authorization
|
|
1086
|
-
code:
|
|
1087
|
-
|
|
1088
|
-
```ts
|
|
1089
|
-
// before
|
|
1090
|
-
authorizeUser: async () => ({ userId })
|
|
1091
|
-
|
|
1092
|
-
// after
|
|
1093
|
-
authorizeUser: async (_req, request) => ({
|
|
1094
|
-
userId,
|
|
1095
|
-
approvedScopes: request.scope?.split(' ') ?? [],
|
|
1096
|
-
})
|
|
1097
|
-
```
|
|
1098
|
-
|
|
1099
|
-
6. Snapshot `listToolNames`, run one contract tool, one runtime tool, any raw
|
|
1100
|
-
multimodal tool and every MCP App resource you use.
|
|
1101
|
-
7. Exercise modern HTTP and stdio with protocol `2026-07-28`; exercise legacy
|
|
1102
|
-
only if `legacy: 'serve'` is part of your support policy.
|
|
1103
|
-
8. Run the consumer's typecheck and runtime gates. A browser/HTTP-only consumer
|
|
1104
|
-
must continue to work without either MCP package.
|