stitchkit 0.93.0 → 0.94.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +198 -0
- package/README.md +5 -2
- package/dist/agent-runtime/children-control.d.ts +6 -0
- package/dist/agent-runtime/children-control.d.ts.map +1 -0
- package/dist/agent-runtime/children-spawn.d.ts +6 -0
- package/dist/agent-runtime/children-spawn.d.ts.map +1 -0
- package/dist/agent-runtime/children-state.d.ts +46 -0
- package/dist/agent-runtime/children-state.d.ts.map +1 -0
- package/dist/agent-runtime/children-usage.d.ts +8 -0
- package/dist/agent-runtime/children-usage.d.ts.map +1 -0
- package/dist/agent-runtime/children.d.ts +11 -14
- package/dist/agent-runtime/children.d.ts.map +1 -1
- package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-contract.d.ts +2 -1
- package/dist/agent-runtime/coding-tool-contract.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-listing.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
- package/dist/agent-runtime/contained-darwin.d.ts +38 -0
- package/dist/agent-runtime/contained-darwin.d.ts.map +1 -0
- package/dist/agent-runtime/contained-files.d.ts +11 -26
- package/dist/agent-runtime/contained-files.d.ts.map +1 -1
- package/dist/agent-runtime/contained-scan.d.ts +21 -0
- package/dist/agent-runtime/contained-scan.d.ts.map +1 -0
- package/dist/agent-runtime/contained-write.d.ts +9 -0
- package/dist/agent-runtime/contained-write.d.ts.map +1 -0
- package/dist/agent-runtime/deferred-tool-types.d.ts +4 -3
- package/dist/agent-runtime/deferred-tool-types.d.ts.map +1 -1
- package/dist/agent-runtime/events.d.ts +1 -1
- package/dist/agent-runtime/events.d.ts.map +1 -1
- package/dist/agent-runtime/harness-control.d.ts +0 -1
- package/dist/agent-runtime/harness-control.d.ts.map +1 -1
- package/dist/agent-runtime/harness.d.ts +0 -5
- package/dist/agent-runtime/harness.d.ts.map +1 -1
- package/dist/agent-runtime/managed-tools.d.ts +3 -2
- package/dist/agent-runtime/managed-tools.d.ts.map +1 -1
- package/dist/agent-runtime/observability.d.ts +1 -1
- package/dist/agent-runtime/observability.d.ts.map +1 -1
- package/dist/agent-runtime/openrouter.d.ts +29 -0
- package/dist/agent-runtime/openrouter.d.ts.map +1 -0
- package/dist/agent-runtime/projections.d.ts +1 -1
- package/dist/agent-runtime/projections.d.ts.map +1 -1
- package/dist/agent-runtime/run-acquisition.d.ts +17 -0
- package/dist/agent-runtime/run-acquisition.d.ts.map +1 -0
- package/dist/agent-runtime/run-execution-state.d.ts +133 -0
- package/dist/agent-runtime/run-execution-state.d.ts.map +1 -0
- package/dist/agent-runtime/run-execution.d.ts +17 -33
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/run-failure.d.ts +18 -0
- package/dist/agent-runtime/run-failure.d.ts.map +1 -0
- package/dist/agent-runtime/run-model-attempts.d.ts +6 -0
- package/dist/agent-runtime/run-model-attempts.d.ts.map +1 -0
- package/dist/agent-runtime/run-prompt-history.d.ts +58 -0
- package/dist/agent-runtime/run-prompt-history.d.ts.map +1 -0
- package/dist/agent-runtime/run-provider-ledger.d.ts +26 -0
- package/dist/agent-runtime/run-provider-ledger.d.ts.map +1 -0
- package/dist/agent-runtime/run-stream-parts.d.ts +17 -0
- package/dist/agent-runtime/run-stream-parts.d.ts.map +1 -0
- package/dist/agent-runtime/run-terminal.d.ts +11 -0
- package/dist/agent-runtime/run-terminal.d.ts.map +1 -0
- package/dist/agent-runtime/run-turn-preparation.d.ts +22 -0
- package/dist/agent-runtime/run-turn-preparation.d.ts.map +1 -0
- package/dist/agent-runtime/runtime-admission-gate.d.ts +29 -0
- package/dist/agent-runtime/runtime-admission-gate.d.ts.map +1 -0
- package/dist/agent-runtime/runtime-control.d.ts +9 -0
- package/dist/agent-runtime/runtime-control.d.ts.map +1 -0
- package/dist/agent-runtime/runtime-recovery.d.ts +10 -0
- package/dist/agent-runtime/runtime-recovery.d.ts.map +1 -0
- package/dist/agent-runtime/runtime-state.d.ts +36 -0
- package/dist/agent-runtime/runtime-state.d.ts.map +1 -0
- package/dist/agent-runtime/runtime-submit.d.ts +5 -0
- package/dist/agent-runtime/runtime-submit.d.ts.map +1 -0
- package/dist/agent-runtime/runtime.d.ts +10 -5
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schedule-records.d.ts +34 -0
- package/dist/agent-runtime/schedule-records.d.ts.map +1 -0
- package/dist/agent-runtime/schedules.d.ts +34 -0
- package/dist/agent-runtime/schedules.d.ts.map +1 -1
- package/dist/agent-runtime/sqlite-bun.d.ts +12 -0
- package/dist/agent-runtime/sqlite-bun.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-events.d.ts +5 -0
- package/dist/agent-runtime/sqlite-events.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-history.d.ts +7 -0
- package/dist/agent-runtime/sqlite-history.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-ledger.d.ts +7 -0
- package/dist/agent-runtime/sqlite-ledger.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-node.d.ts +12 -0
- package/dist/agent-runtime/sqlite-node.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-reads.d.ts +14 -0
- package/dist/agent-runtime/sqlite-reads.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-rows.d.ts +178 -0
- package/dist/agent-runtime/sqlite-rows.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-schema.d.ts +7 -0
- package/dist/agent-runtime/sqlite-schema.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite-transactions.d.ts +25 -0
- package/dist/agent-runtime/sqlite-transactions.d.ts.map +1 -0
- package/dist/agent-runtime/sqlite.d.ts +10 -6
- package/dist/agent-runtime/sqlite.d.ts.map +1 -1
- package/dist/agent-runtime/store-archive.d.ts +16 -0
- package/dist/agent-runtime/store-archive.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance-lifecycle.d.ts +434 -0
- package/dist/agent-runtime/store-conformance-lifecycle.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance-ordering.d.ts +18 -0
- package/dist/agent-runtime/store-conformance-ordering.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance-support.d.ts +130 -0
- package/dist/agent-runtime/store-conformance-support.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance-terminal.d.ts +12 -0
- package/dist/agent-runtime/store-conformance-terminal.d.ts.map +1 -0
- package/dist/agent-runtime/store-conformance.d.ts +40 -0
- package/dist/agent-runtime/store-conformance.d.ts.map +1 -0
- package/dist/agent-runtime/store-create.d.ts +11 -0
- package/dist/agent-runtime/store-create.d.ts.map +1 -0
- package/dist/agent-runtime/store-driver-contract.d.ts +814 -0
- package/dist/agent-runtime/store-driver-contract.d.ts.map +1 -0
- package/dist/agent-runtime/store-events.d.ts +7 -89
- package/dist/agent-runtime/store-events.d.ts.map +1 -1
- package/dist/agent-runtime/store-memory.d.ts +4 -0
- package/dist/agent-runtime/store-memory.d.ts.map +1 -0
- package/dist/agent-runtime/store-mutate.d.ts +13 -0
- package/dist/agent-runtime/store-mutate.d.ts.map +1 -0
- package/dist/agent-runtime/store-purge.d.ts +1 -1
- package/dist/agent-runtime/store-purge.d.ts.map +1 -1
- package/dist/agent-runtime/store-reads.d.ts +29 -0
- package/dist/agent-runtime/store-reads.d.ts.map +1 -0
- package/dist/agent-runtime/store-reduce-history.d.ts +10 -0
- package/dist/agent-runtime/store-reduce-history.d.ts.map +1 -0
- package/dist/agent-runtime/store-reduce-run.d.ts +14 -0
- package/dist/agent-runtime/store-reduce-run.d.ts.map +1 -0
- package/dist/agent-runtime/store-reduce-shared.d.ts +76 -0
- package/dist/agent-runtime/store-reduce-shared.d.ts.map +1 -0
- package/dist/agent-runtime/store-reduce-terminal.d.ts +6 -0
- package/dist/agent-runtime/store-reduce-terminal.d.ts.map +1 -0
- package/dist/agent-runtime/store-reducer.d.ts +24 -0
- package/dist/agent-runtime/store-reducer.d.ts.map +1 -0
- package/dist/agent-runtime/store-snapshot.d.ts +19 -0
- package/dist/agent-runtime/store-snapshot.d.ts.map +1 -0
- package/dist/agent-runtime/store.d.ts +1 -1
- package/dist/agent-runtime/store.d.ts.map +1 -1
- package/dist/application/admission-rate.d.ts +21 -0
- package/dist/application/admission-rate.d.ts.map +1 -0
- package/dist/application/admission-run.d.ts +8 -0
- package/dist/application/admission-run.d.ts.map +1 -0
- package/dist/application/admission.d.ts +1 -1
- package/dist/application/admission.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-lock.d.ts +9 -34
- package/dist/application/diagnostic-journal-lock.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-manager.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-storage.d.ts.map +1 -1
- package/dist/application/events.d.ts +1 -1
- package/dist/application/events.d.ts.map +1 -1
- package/dist/application/file-state-store.d.ts +23 -0
- package/dist/application/file-state-store.d.ts.map +1 -0
- package/dist/application/health.d.ts +1 -1
- package/dist/application/health.d.ts.map +1 -1
- package/dist/application/kernel-admission.d.ts +8 -0
- package/dist/application/kernel-admission.d.ts.map +1 -0
- package/dist/application/kernel-contract.d.ts +142 -0
- package/dist/application/kernel-contract.d.ts.map +1 -0
- package/dist/application/kernel-resource-context.d.ts +24 -0
- package/dist/application/kernel-resource-context.d.ts.map +1 -0
- package/dist/application/kernel-restart.d.ts +5 -0
- package/dist/application/kernel-restart.d.ts.map +1 -0
- package/dist/application/kernel-rollback.d.ts +4 -0
- package/dist/application/kernel-rollback.d.ts.map +1 -0
- package/dist/application/kernel-shutdown.d.ts +6 -0
- package/dist/application/kernel-shutdown.d.ts.map +1 -0
- package/dist/application/kernel-start.d.ts +20 -0
- package/dist/application/kernel-start.d.ts.map +1 -0
- package/dist/application/kernel-state.d.ts +116 -0
- package/dist/application/kernel-state.d.ts.map +1 -0
- package/dist/application/kernel.d.ts +9 -140
- package/dist/application/kernel.d.ts.map +1 -1
- package/dist/application/latest-sink.d.ts +1 -1
- package/dist/application/latest-sink.d.ts.map +1 -1
- package/dist/application/notification-outbox.d.ts.map +1 -1
- package/dist/application/opentelemetry.d.ts +1 -1
- package/dist/application/opentelemetry.d.ts.map +1 -1
- package/dist/application/schedule.d.ts +0 -1
- package/dist/application/schedule.d.ts.map +1 -1
- package/dist/application/watch-hub-core.d.ts +122 -0
- package/dist/application/watch-hub-core.d.ts.map +1 -0
- package/dist/application/watch-hub.d.ts +3 -3
- package/dist/application/watch-hub.d.ts.map +1 -1
- package/dist/browser/client-executors.d.ts +14 -0
- package/dist/browser/client-executors.d.ts.map +1 -0
- package/dist/browser/client-multipart.d.ts +1 -1
- package/dist/browser/client-multipart.d.ts.map +1 -1
- package/dist/browser/client-url.d.ts +1 -1
- package/dist/browser/client-url.d.ts.map +1 -1
- package/dist/browser/client.d.ts +3 -2
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/contract-stream.d.ts +1 -1
- package/dist/browser/contract-stream.d.ts.map +1 -1
- package/dist/browser/http-fetch.d.ts +22 -0
- package/dist/browser/http-fetch.d.ts.map +1 -0
- package/dist/browser/http.d.ts +2 -4
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/live-state-core.d.ts +63 -0
- package/dist/browser/live-state-core.d.ts.map +1 -0
- package/dist/browser/live-state.d.ts.map +1 -1
- package/dist/browser/realtime-client.d.ts +26 -0
- package/dist/browser/realtime-client.d.ts.map +1 -0
- package/dist/browser/resumable.d.ts +1 -28
- package/dist/browser/resumable.d.ts.map +1 -1
- package/dist/browser/retained.d.ts.map +1 -0
- package/dist/browser/socket-io-connection.d.ts +82 -0
- package/dist/browser/socket-io-connection.d.ts.map +1 -0
- package/dist/browser/socket-io-peer.d.ts +20 -0
- package/dist/browser/socket-io-peer.d.ts.map +1 -0
- package/dist/browser/socket-io-trace.d.ts +31 -0
- package/dist/browser/socket-io-trace.d.ts.map +1 -0
- package/dist/browser/socket-io.d.ts +24 -18
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/browser/stream.d.ts +14 -2
- package/dist/browser/stream.d.ts.map +1 -1
- package/dist/contract/client-types.d.ts +134 -0
- package/dist/contract/client-types.d.ts.map +1 -0
- package/dist/contract/define-validation.d.ts +30 -0
- package/dist/contract/define-validation.d.ts.map +1 -0
- package/dist/contract/define.d.ts +47 -394
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/normalize.d.ts +56 -0
- package/dist/contract/normalize.d.ts.map +1 -0
- package/dist/contract/runtime-context.d.ts +131 -0
- package/dist/contract/runtime-context.d.ts.map +1 -0
- package/dist/contract/tool-options.d.ts +105 -0
- package/dist/contract/tool-options.d.ts.map +1 -0
- package/dist/contract/tool-view.d.ts +148 -0
- package/dist/contract/tool-view.d.ts.map +1 -0
- package/dist/declaration/declaration.d.ts.map +1 -0
- package/dist/durability/contract.d.ts +259 -0
- package/dist/durability/contract.d.ts.map +1 -0
- package/dist/durability/effect.d.ts +24 -0
- package/dist/durability/effect.d.ts.map +1 -0
- package/dist/durability/engine.d.ts +14 -0
- package/dist/durability/engine.d.ts.map +1 -0
- package/dist/durability/events.d.ts +103 -0
- package/dist/durability/events.d.ts.map +1 -0
- package/dist/durability/json.d.ts +3 -0
- package/dist/durability/json.d.ts.map +1 -0
- package/dist/durability/ledger.d.ts +27 -0
- package/dist/durability/ledger.d.ts.map +1 -0
- package/dist/durability/parks.d.ts +22 -0
- package/dist/durability/parks.d.ts.map +1 -0
- package/dist/durability/scheduler.d.ts +30 -0
- package/dist/durability/scheduler.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/browser.d.ts +5 -0
- package/dist/entrypoints/agent-runtime/browser.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/browser.js +124 -0
- package/dist/entrypoints/agent-runtime/coding-tools.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/coding-tools.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/coding-tools.js +22 -0
- package/dist/entrypoints/agent-runtime/harness.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/harness.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/harness.js +739 -0
- package/dist/entrypoints/agent-runtime/openrouter.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/openrouter.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/openrouter.js +270 -0
- package/dist/entrypoints/agent-runtime/sandbox.d.ts +5 -0
- package/dist/entrypoints/agent-runtime/sandbox.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/sandbox.js +797 -0
- package/dist/entrypoints/agent-runtime/sqlite/bun.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/sqlite/bun.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +44 -0
- package/dist/entrypoints/agent-runtime/sqlite/node.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/sqlite/node.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/sqlite/node.js +46 -0
- package/dist/entrypoints/agent-runtime/testing.d.ts +4 -0
- package/dist/entrypoints/agent-runtime/testing.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/testing.js +1116 -0
- package/dist/entrypoints/agent-runtime.d.ts +42 -0
- package/dist/entrypoints/agent-runtime.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime.js +2670 -0
- package/dist/entrypoints/application/diagnostic-journal.d.ts +21 -0
- package/dist/entrypoints/application/diagnostic-journal.d.ts.map +1 -0
- package/dist/entrypoints/application/diagnostic-journal.js +492 -0
- package/dist/entrypoints/application/grammy.d.ts +2 -0
- package/dist/entrypoints/application/grammy.d.ts.map +1 -0
- package/dist/entrypoints/application/grammy.js +169 -0
- package/dist/entrypoints/application/opentelemetry.d.ts +2 -0
- package/dist/entrypoints/application/opentelemetry.d.ts.map +1 -0
- package/dist/entrypoints/application/opentelemetry.js +250 -0
- package/dist/entrypoints/application/schemas.d.ts +15 -0
- package/dist/entrypoints/application/schemas.d.ts.map +1 -0
- package/dist/entrypoints/application/schemas.js +27 -0
- package/dist/entrypoints/application.d.ts +23 -0
- package/dist/entrypoints/application.d.ts.map +1 -0
- package/dist/entrypoints/application.js +2016 -0
- package/dist/entrypoints/bin/upgrade-cli.d.ts.map +1 -0
- package/dist/entrypoints/bin/upgrade-cli.js +177 -0
- package/dist/entrypoints/cli.d.ts +44 -0
- package/dist/entrypoints/cli.d.ts.map +1 -0
- package/dist/entrypoints/cli.js +773 -0
- package/dist/entrypoints/contract.d.ts +12 -0
- package/dist/entrypoints/contract.d.ts.map +1 -0
- package/dist/entrypoints/contract.js +64 -0
- package/dist/entrypoints/declaration.d.ts +2 -0
- package/dist/entrypoints/declaration.d.ts.map +1 -0
- package/dist/entrypoints/declaration.js +183 -0
- package/dist/entrypoints/files.d.ts +5 -0
- package/dist/entrypoints/files.d.ts.map +1 -0
- package/dist/entrypoints/files.js +111 -0
- package/dist/entrypoints/geo.d.ts +3 -0
- package/dist/entrypoints/geo.d.ts.map +1 -0
- package/dist/entrypoints/geo.js +245 -0
- package/dist/entrypoints/google.d.ts +2 -0
- package/dist/entrypoints/google.d.ts.map +1 -0
- package/dist/entrypoints/google.js +175 -0
- package/dist/entrypoints/index.d.ts +17 -0
- package/dist/entrypoints/index.d.ts.map +1 -0
- package/dist/entrypoints/index.js +764 -0
- package/dist/entrypoints/live.d.ts +19 -0
- package/dist/entrypoints/live.d.ts.map +1 -0
- package/dist/entrypoints/live.js +302 -0
- package/dist/entrypoints/node.d.ts +19 -0
- package/dist/entrypoints/node.d.ts.map +1 -0
- package/dist/entrypoints/node.js +308 -0
- package/dist/entrypoints/oauth.d.ts +2 -0
- package/dist/entrypoints/oauth.d.ts.map +1 -0
- package/dist/entrypoints/oauth.js +170 -0
- package/dist/entrypoints/observability.d.ts +19 -0
- package/dist/entrypoints/observability.d.ts.map +1 -0
- package/dist/entrypoints/observability.js +567 -0
- package/dist/entrypoints/primitives.d.ts +3 -0
- package/dist/entrypoints/primitives.d.ts.map +1 -0
- package/dist/entrypoints/primitives.js +749 -0
- package/dist/entrypoints/react.d.ts +5 -0
- package/dist/entrypoints/react.d.ts.map +1 -0
- package/dist/entrypoints/react.js +403 -0
- package/dist/entrypoints/release.d.ts +15 -0
- package/dist/entrypoints/release.d.ts.map +1 -0
- package/dist/entrypoints/release.js +196 -0
- package/dist/entrypoints/remote.d.ts +9 -0
- package/dist/entrypoints/remote.d.ts.map +1 -0
- package/dist/entrypoints/remote.js +66 -0
- package/dist/entrypoints/server.d.ts +39 -0
- package/dist/entrypoints/server.d.ts.map +1 -0
- package/dist/entrypoints/server.js +2009 -0
- package/dist/entrypoints/telegram.d.ts +3 -0
- package/dist/entrypoints/telegram.d.ts.map +1 -0
- package/dist/entrypoints/telegram.js +224 -0
- package/dist/entrypoints/testing.d.ts +10 -0
- package/dist/entrypoints/testing.d.ts.map +1 -0
- package/dist/entrypoints/testing.js +1377 -0
- package/dist/entrypoints/tools/connections.d.ts +19 -0
- package/dist/entrypoints/tools/connections.d.ts.map +1 -0
- package/dist/entrypoints/tools/connections.js +1110 -0
- package/dist/entrypoints/tools/contract.d.ts +29 -0
- package/dist/entrypoints/tools/contract.d.ts.map +1 -0
- package/dist/entrypoints/tools/contract.js +24 -0
- package/dist/entrypoints/tools/invoker.d.ts +9 -0
- package/dist/entrypoints/tools/invoker.d.ts.map +1 -0
- package/dist/entrypoints/tools/invoker.js +20 -0
- package/dist/entrypoints/tools.d.ts +54 -0
- package/dist/entrypoints/tools.d.ts.map +1 -0
- package/dist/entrypoints/tools.js +3009 -0
- package/dist/entrypoints/tracking/server.d.ts +15 -0
- package/dist/entrypoints/tracking/server.d.ts.map +1 -0
- package/dist/entrypoints/tracking.d.ts +24 -0
- package/dist/entrypoints/tracking.d.ts.map +1 -0
- package/dist/entrypoints/tracking.js +1140 -0
- package/dist/files/boundary.d.ts.map +1 -1
- package/dist/files/file-io.d.ts +14 -0
- package/dist/files/file-io.d.ts.map +1 -0
- package/dist/google/google.d.ts.map +1 -0
- package/dist/index-0b1ess5e.js +38 -0
- package/dist/index-1j8pm5t0.js +412 -0
- package/dist/index-1zbbzgfh.js +89 -0
- package/dist/index-2bxbyab0.js +47 -0
- package/dist/index-2gxzjvyr.js +266 -0
- package/dist/index-35mh5bhj.js +177 -0
- package/dist/index-48ffdxgk.js +6 -0
- package/dist/index-4gcnakhx.js +82 -0
- package/dist/index-55hkhm67.js +343 -0
- package/dist/index-79z7m7dt.js +675 -0
- package/dist/index-7f68ghdn.js +3618 -0
- package/dist/index-7p1f0vp2.js +154 -0
- package/dist/index-83bdg97s.js +16 -0
- package/dist/index-863ea9jb.js +154 -0
- package/dist/index-8p52kd5p.js +242 -0
- package/dist/index-d9pk3td4.js +326 -0
- package/dist/index-dce5wxcq.js +63 -0
- package/dist/index-e01r054k.js +105 -0
- package/dist/index-ensd0r74.js +595 -0
- package/dist/index-eqqvgdb3.js +46 -0
- package/dist/index-gxrt5h6v.js +341 -0
- package/dist/index-h6eeys1v.js +211 -0
- package/dist/index-ham5sz8m.js +734 -0
- package/dist/index-het2he5g.js +1387 -0
- package/dist/index-hffjpmq9.js +30 -0
- package/dist/index-hmp4800j.js +51 -0
- package/dist/index-k30h66yd.js +317 -0
- package/dist/index-k5hsfc3j.js +31 -0
- package/dist/index-khtgb21r.js +92 -0
- package/dist/index-m9zn6cpq.js +51 -0
- package/dist/index-ndddxtyx.js +324 -0
- package/dist/index-ngfhvfpd.js +30 -0
- package/dist/index-np4m8hd3.js +1205 -0
- package/dist/index-p3vsv1fb.js +3493 -0
- package/dist/index-p5r7qpdd.js +85 -0
- package/dist/index-p9e0w8hs.js +1084 -0
- package/dist/index-p9sh0xx4.js +64 -0
- package/dist/index-paz6sgdp.js +371 -0
- package/dist/index-px2gm2jp.js +448 -0
- package/dist/index-qwhynv6x.js +103 -0
- package/dist/index-s812ycat.js +65 -0
- package/dist/index-sp1tzwnb.js +281 -0
- package/dist/index-t9rhjr9f.js +2306 -0
- package/dist/index-v260df89.js +342 -0
- package/dist/index-w906953s.js +946 -0
- package/dist/index-wdkt63w3.js +214 -0
- package/dist/index-wqgjfstn.js +18 -0
- package/dist/index-wsm5w4ee.js +1023 -0
- package/dist/index-xw3s75nj.js +100 -0
- package/dist/index-yw4fzmdz.js +268 -0
- package/dist/index-zfrhfn82.js +85 -0
- package/dist/index-znfs20ss.js +98 -0
- package/dist/internal/atomic-file.d.ts +23 -2
- package/dist/internal/atomic-file.d.ts.map +1 -1
- package/dist/internal/backoff.d.ts +29 -0
- package/dist/internal/backoff.d.ts.map +1 -0
- package/dist/internal/canonical-json.d.ts +21 -11
- package/dist/internal/canonical-json.d.ts.map +1 -1
- package/dist/internal/channel.d.ts.map +1 -0
- package/dist/internal/exclusive-lock.d.ts +51 -0
- package/dist/internal/exclusive-lock.d.ts.map +1 -0
- package/dist/internal/logger.d.ts.map +1 -0
- package/dist/internal/process-identity.d.ts +47 -0
- package/dist/internal/process-identity.d.ts.map +1 -0
- package/dist/internal/request.d.ts.map +1 -0
- package/dist/internal/stable-digest.d.ts +0 -43
- package/dist/internal/stable-digest.d.ts.map +1 -1
- package/dist/internal/typed.d.ts +0 -8
- package/dist/internal/typed.d.ts.map +1 -1
- package/dist/internal/with-exclusive-lock.d.ts +67 -0
- package/dist/internal/with-exclusive-lock.d.ts.map +1 -0
- package/dist/internal/zod-issues.d.ts +38 -0
- package/dist/internal/zod-issues.d.ts.map +1 -0
- package/dist/json-schema/dialect.d.ts +17 -0
- package/dist/json-schema/dialect.d.ts.map +1 -0
- package/dist/json-schema/json-schema.d.ts.map +1 -0
- package/dist/live/watch-client.d.ts.map +1 -1
- package/dist/live/watch-delta.d.ts.map +1 -1
- package/dist/oauth/authorization-code.d.ts +57 -0
- package/dist/oauth/authorization-code.d.ts.map +1 -0
- package/dist/observability/audit.d.ts +3 -3
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/bounded-logger.d.ts +1 -1
- package/dist/observability/bounded-logger.d.ts.map +1 -1
- package/dist/observability/bounded-sink.d.ts +81 -0
- package/dist/observability/bounded-sink.d.ts.map +1 -0
- package/dist/observability/context.d.ts +1 -1
- package/dist/observability/context.d.ts.map +1 -1
- package/dist/observability/event.d.ts +2 -1
- package/dist/observability/event.d.ts.map +1 -1
- package/dist/observability/work.d.ts +1 -1
- package/dist/observability/work.d.ts.map +1 -1
- package/dist/primitives/audit.d.ts +1 -1
- package/dist/primitives/audit.d.ts.map +1 -1
- package/dist/primitives/export-operation.d.ts +4 -2
- package/dist/primitives/export-operation.d.ts.map +1 -1
- package/dist/realtime/registry.d.ts +0 -5
- package/dist/realtime/registry.d.ts.map +1 -1
- package/dist/realtime/socket.d.ts +1 -1
- package/dist/realtime/socket.d.ts.map +1 -1
- package/dist/server/bun.d.ts +0 -1
- package/dist/server/bun.d.ts.map +1 -1
- package/dist/server/context-contribution.d.ts +1 -1
- package/dist/server/context-contribution.d.ts.map +1 -1
- package/dist/server/context.d.ts +2 -2
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/contract-method.d.ts +15 -0
- package/dist/server/contract-method.d.ts.map +1 -0
- package/dist/server/contract-stream.d.ts +1 -1
- package/dist/server/contract-stream.d.ts.map +1 -1
- package/dist/server/create.d.ts +8 -0
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/endpoint-dispatch.d.ts +10 -0
- package/dist/server/endpoint-dispatch.d.ts.map +1 -0
- package/dist/server/endpoint-response.d.ts +19 -0
- package/dist/server/endpoint-response.d.ts.map +1 -0
- package/dist/server/error-dispatch.d.ts +17 -1
- package/dist/server/error-dispatch.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +2 -2
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/handler-state.d.ts +44 -0
- package/dist/server/handler-state.d.ts.map +1 -0
- package/dist/server/implement-registry.d.ts +54 -0
- package/dist/server/implement-registry.d.ts.map +1 -0
- package/dist/server/implement.d.ts +9 -55
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/middleware/auth.d.ts +1 -31
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/middleware/cors.d.ts +17 -0
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/middleware/jwt.d.ts +31 -0
- package/dist/server/middleware/jwt.d.ts.map +1 -0
- package/dist/server/middleware/trust-fence.d.ts +1 -1
- package/dist/server/middleware/trust-fence.d.ts.map +1 -1
- package/dist/server/multipart-reader.d.ts +22 -0
- package/dist/server/multipart-reader.d.ts.map +1 -0
- package/dist/server/multipart.d.ts +1 -1
- package/dist/server/multipart.d.ts.map +1 -1
- package/dist/server/oauth/cimd.d.ts +88 -0
- package/dist/server/oauth/cimd.d.ts.map +1 -0
- package/dist/server/oauth/endpoints.d.ts +39 -0
- package/dist/server/oauth/endpoints.d.ts.map +1 -0
- package/dist/server/oauth/metadata.d.ts +28 -0
- package/dist/server/oauth/metadata.d.ts.map +1 -0
- package/dist/server/oauth/provider.d.ts +117 -0
- package/dist/server/oauth/provider.d.ts.map +1 -0
- package/dist/server/realtime.d.ts +1 -1
- package/dist/server/realtime.d.ts.map +1 -1
- package/dist/server/request-completion.d.ts +16 -0
- package/dist/server/request-completion.d.ts.map +1 -0
- package/dist/server/response-metadata.d.ts +1 -1
- package/dist/server/response-metadata.d.ts.map +1 -1
- package/dist/server/route-table.d.ts +9 -0
- package/dist/server/route-table.d.ts.map +1 -0
- package/dist/server/stream.d.ts +0 -13
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/server/streaming-pump.d.ts +66 -0
- package/dist/server/streaming-pump.d.ts.map +1 -0
- package/dist/server/streaming-route.d.ts +12 -5
- package/dist/server/streaming-route.d.ts.map +1 -1
- package/dist/server/types.d.ts +10 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/unix-client-bun.d.ts.map +1 -1
- package/dist/server/unix-client-http1.d.ts +76 -0
- package/dist/server/unix-client-http1.d.ts.map +1 -0
- package/dist/server/unix-client.d.ts.map +1 -1
- package/dist/testing/handler-clients.d.ts +32 -0
- package/dist/testing/handler-clients.d.ts.map +1 -0
- package/dist/testing/managed-resource-conformance-scenarios.d.ts.map +1 -1
- package/dist/testing/realtime-probe.d.ts +33 -0
- package/dist/testing/realtime-probe.d.ts.map +1 -0
- package/dist/testing/surface-conformance.d.ts +2 -32
- package/dist/testing/surface-conformance.d.ts.map +1 -1
- package/dist/testing/surface-manifest-digest.d.ts +44 -0
- package/dist/testing/surface-manifest-digest.d.ts.map +1 -0
- package/dist/testing/surface-manifest.d.ts +30 -4
- 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-fields.d.ts +31 -0
- package/dist/tools/cli/args-fields.d.ts.map +1 -0
- package/dist/tools/cli/args-route.d.ts +42 -0
- package/dist/tools/cli/args-route.d.ts.map +1 -0
- package/dist/tools/cli/args-view.d.ts +32 -0
- package/dist/tools/cli/args-view.d.ts.map +1 -0
- package/dist/tools/cli/args.d.ts +80 -0
- package/dist/tools/cli/args.d.ts.map +1 -0
- package/dist/tools/cli/argument-error.d.ts +5 -0
- package/dist/tools/cli/argument-error.d.ts.map +1 -0
- package/dist/tools/cli/checkpoint.d.ts +24 -0
- package/dist/tools/cli/checkpoint.d.ts.map +1 -0
- package/dist/tools/cli/command.d.ts +70 -0
- package/dist/tools/cli/command.d.ts.map +1 -0
- package/dist/tools/cli/config.d.ts +90 -0
- package/dist/tools/cli/config.d.ts.map +1 -0
- package/dist/tools/cli/create-cli.d.ts +36 -0
- package/dist/tools/cli/create-cli.d.ts.map +1 -0
- package/dist/tools/cli/download.d.ts +8 -0
- package/dist/tools/cli/download.d.ts.map +1 -0
- package/dist/tools/cli/format.d.ts +50 -0
- package/dist/tools/cli/format.d.ts.map +1 -0
- package/dist/tools/cli/help.d.ts +24 -0
- package/dist/tools/cli/help.d.ts.map +1 -0
- package/dist/tools/cli/installer.d.ts +34 -0
- package/dist/tools/cli/installer.d.ts.map +1 -0
- package/dist/tools/cli/invoke.d.ts +144 -0
- package/dist/tools/cli/invoke.d.ts.map +1 -0
- package/dist/tools/cli/io.d.ts +10 -0
- package/dist/tools/cli/io.d.ts.map +1 -0
- package/dist/tools/cli/managed-surface.d.ts +30 -0
- package/dist/tools/cli/managed-surface.d.ts.map +1 -0
- package/dist/tools/cli/manifest.d.ts +80 -0
- package/dist/tools/cli/manifest.d.ts.map +1 -0
- package/dist/tools/cli/policy.d.ts +27 -0
- package/dist/tools/cli/policy.d.ts.map +1 -0
- package/dist/tools/cli/prepare.d.ts +14 -0
- package/dist/tools/cli/prepare.d.ts.map +1 -0
- package/dist/tools/cli/profile.d.ts +40 -0
- package/dist/tools/cli/profile.d.ts.map +1 -0
- package/dist/tools/cli/run-managed.d.ts +5 -0
- package/dist/tools/cli/run-managed.d.ts.map +1 -0
- package/dist/tools/cli/run-native.d.ts +9 -0
- package/dist/tools/cli/run-native.d.ts.map +1 -0
- package/dist/tools/cli/session.d.ts +40 -0
- package/dist/tools/cli/session.d.ts.map +1 -0
- package/dist/tools/cli/signature.d.ts +81 -0
- package/dist/tools/cli/signature.d.ts.map +1 -0
- package/dist/tools/cli/stream.d.ts +93 -0
- package/dist/tools/cli/stream.d.ts.map +1 -0
- package/dist/tools/cli/update.d.ts +145 -0
- package/dist/tools/cli/update.d.ts.map +1 -0
- package/dist/tools/cli/view.d.ts +12 -0
- package/dist/tools/cli/view.d.ts.map +1 -0
- package/dist/tools/cli/wait.d.ts +54 -0
- package/dist/tools/cli/wait.d.ts.map +1 -0
- package/dist/tools/connections/runtime.d.ts +1 -1
- package/dist/tools/connections/runtime.d.ts.map +1 -1
- package/dist/tools/connections/types.d.ts +3 -3
- package/dist/tools/connections/types.d.ts.map +1 -1
- package/dist/tools/durability-context.d.ts +1 -1
- package/dist/tools/durability-context.d.ts.map +1 -1
- package/dist/tools/execute-args.d.ts +23 -0
- package/dist/tools/execute-args.d.ts.map +1 -0
- package/dist/tools/execute-hooks.d.ts +146 -0
- package/dist/tools/execute-hooks.d.ts.map +1 -0
- package/dist/tools/execute-result.d.ts +40 -0
- package/dist/tools/execute-result.d.ts.map +1 -0
- package/dist/tools/execute.d.ts +31 -193
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools/internal/surface-projector.d.ts +9 -6
- package/dist/tools/internal/surface-projector.d.ts.map +1 -1
- package/dist/tools/internal/tool-view.d.ts +41 -0
- package/dist/tools/internal/tool-view.d.ts.map +1 -0
- package/dist/tools/invoker.d.ts +13 -4
- package/dist/tools/invoker.d.ts.map +1 -1
- package/dist/tools/lifecycle.d.ts +1 -1
- package/dist/tools/lifecycle.d.ts.map +1 -1
- package/dist/tools/list-names.d.ts +3 -3
- package/dist/tools/list-names.d.ts.map +1 -1
- package/dist/tools/manifest.d.ts +2 -2
- package/dist/tools/manifest.d.ts.map +1 -1
- package/dist/tools/mcp/app.d.ts +62 -0
- package/dist/tools/mcp/app.d.ts.map +1 -0
- package/dist/tools/mcp/catalog.d.ts +68 -0
- package/dist/tools/mcp/catalog.d.ts.map +1 -0
- package/dist/tools/mcp/handler.d.ts +46 -0
- package/dist/tools/mcp/handler.d.ts.map +1 -0
- package/dist/tools/mcp/mount.d.ts +152 -0
- package/dist/tools/mcp/mount.d.ts.map +1 -0
- package/dist/tools/mcp/prepare.d.ts +76 -0
- package/dist/tools/mcp/prepare.d.ts.map +1 -0
- package/dist/tools/mcp/progress.d.ts +46 -0
- package/dist/tools/mcp/progress.d.ts.map +1 -0
- package/dist/tools/mcp/register.d.ts +36 -0
- package/dist/tools/mcp/register.d.ts.map +1 -0
- package/dist/tools/mcp/round-context.d.ts +38 -0
- package/dist/tools/mcp/round-context.d.ts.map +1 -0
- package/dist/tools/mcp/round-policy.d.ts +33 -0
- package/dist/tools/mcp/round-policy.d.ts.map +1 -0
- package/dist/tools/mcp/round.d.ts +53 -0
- package/dist/tools/mcp/round.d.ts.map +1 -0
- package/dist/tools/mcp/runtime-tools.d.ts +25 -0
- package/dist/tools/mcp/runtime-tools.d.ts.map +1 -0
- package/dist/tools/mcp/stdio-signals.d.ts +33 -0
- package/dist/tools/mcp/stdio-signals.d.ts.map +1 -0
- package/dist/tools/mcp/stdio.d.ts +20 -0
- package/dist/tools/mcp/stdio.d.ts.map +1 -0
- package/dist/tools/mcp/trace.d.ts +12 -0
- package/dist/tools/mcp/trace.d.ts.map +1 -0
- package/dist/tools/mount.d.ts +14 -7
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/native-definition.d.ts +4 -3
- package/dist/tools/native-definition.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-binding-types.d.ts +127 -0
- package/dist/tools/operations/async-operation-binding-types.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-binding.d.ts +28 -0
- package/dist/tools/operations/async-operation-binding.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-canonical-types.d.ts +110 -0
- package/dist/tools/operations/async-operation-canonical-types.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-canonical.d.ts +7 -0
- package/dist/tools/operations/async-operation-canonical.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-contract.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-id.d.ts +23 -0
- package/dist/tools/operations/async-operation-id.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-runtime-tools.d.ts +41 -0
- package/dist/tools/operations/async-operation-runtime-tools.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-runtime-types.d.ts +69 -0
- package/dist/tools/operations/async-operation-runtime-types.d.ts.map +1 -0
- package/dist/tools/operations/async-operation-runtime.d.ts +5 -0
- package/dist/tools/operations/async-operation-runtime.d.ts.map +1 -0
- package/dist/tools/operations/define-wait-tool.d.ts +22 -0
- package/dist/tools/operations/define-wait-tool.d.ts.map +1 -0
- package/dist/tools/operations/mount-wait.d.ts.map +1 -0
- package/dist/tools/operations/wait-core.d.ts.map +1 -0
- package/dist/tools/remote.d.ts +1 -1
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/runtime-tool.d.ts +13 -4
- package/dist/tools/runtime-tool.d.ts.map +1 -1
- package/dist/tools/schema/coerce.d.ts.map +1 -0
- package/dist/tools/schema/flatten-join.d.ts.map +1 -0
- package/dist/tools/schema/flatten.d.ts.map +1 -0
- package/dist/tools/schema/portable-formats.d.ts.map +1 -0
- package/dist/tools/schema/presentation.d.ts +24 -0
- package/dist/tools/schema/presentation.d.ts.map +1 -0
- package/dist/tools/schema/schema.d.ts.map +1 -0
- package/dist/tools/schema/untyped-properties.d.ts.map +1 -0
- package/dist/tools/surface.d.ts +2 -3
- package/dist/tools/surface.d.ts.map +1 -1
- package/dist/tools/tool-logger.d.ts +1 -1
- package/dist/tools/tool-logger.d.ts.map +1 -1
- package/dist/tools/toolkit.d.ts +4 -4
- package/dist/tools/toolkit.d.ts.map +1 -1
- package/dist/tools/transfer/define-download-tool.d.ts +18 -0
- package/dist/tools/transfer/define-download-tool.d.ts.map +1 -0
- package/dist/tools/transfer/define-upload-tool.d.ts +16 -0
- package/dist/tools/transfer/define-upload-tool.d.ts.map +1 -0
- package/dist/tools/transfer/define-view-file-tool.d.ts +10 -0
- package/dist/tools/transfer/define-view-file-tool.d.ts.map +1 -0
- package/dist/tools/transfer/download-core.d.ts +20 -0
- package/dist/tools/transfer/download-core.d.ts.map +1 -0
- package/dist/tools/transfer/managed-file-error.d.ts +6 -0
- package/dist/tools/transfer/managed-file-error.d.ts.map +1 -0
- package/dist/tools/transfer/mount-download.d.ts +41 -0
- package/dist/tools/transfer/mount-download.d.ts.map +1 -0
- package/dist/tools/transfer/mount-upload.d.ts +21 -0
- package/dist/tools/transfer/mount-upload.d.ts.map +1 -0
- package/dist/tools/transfer/native-result.d.ts.map +1 -0
- package/dist/tools/transfer/upload-core.d.ts +4 -0
- package/dist/tools/transfer/upload-core.d.ts.map +1 -0
- package/dist/tools/transfer/view-file-contract.d.ts.map +1 -0
- package/dist/tools/transfer/view-file.d.ts +62 -0
- package/dist/tools/transfer/view-file.d.ts.map +1 -0
- package/dist/tools/transports.d.ts +1 -1
- package/dist/tools/transports.d.ts.map +1 -1
- package/dist/tracking/client-listeners.d.ts +30 -0
- package/dist/tracking/client-listeners.d.ts.map +1 -0
- package/dist/tracking/client-visit.d.ts +61 -0
- package/dist/tracking/client-visit.d.ts.map +1 -0
- package/dist/tracking/client.d.ts +3 -2
- package/dist/tracking/client.d.ts.map +1 -1
- package/dist/tracking/contract.d.ts +1 -1
- package/dist/tracking/contract.d.ts.map +1 -1
- package/llms/agent-runtime-browser.txt +33 -0
- package/llms/agent-runtime-coding-tools.txt +58 -0
- package/llms/agent-runtime-harness.txt +45 -0
- package/llms/agent-runtime-openrouter.txt +22 -0
- package/llms/agent-runtime-sandbox.txt +159 -0
- package/llms/agent-runtime-sqlite-bun.txt +29 -0
- package/llms/agent-runtime-sqlite-node.txt +26 -0
- package/llms/agent-runtime-testing.txt +30 -0
- package/llms/agent-runtime.2.txt +550 -0
- package/llms/agent-runtime.3.txt +311 -0
- package/llms/agent-runtime.txt +893 -0
- package/llms/application-diagnostic-journal.txt +30 -0
- package/llms/application-grammy.txt +27 -0
- package/llms/application-opentelemetry.txt +27 -0
- package/llms/application-schemas.txt +42 -0
- package/llms/application.2.txt +487 -0
- package/llms/application.txt +886 -0
- package/llms/cli.2.txt +80 -0
- package/llms/cli.txt +948 -0
- package/llms/contract.txt +606 -0
- package/llms/declaration.txt +286 -0
- package/llms/files.txt +33 -0
- package/llms/geo.txt +114 -0
- package/llms/google.txt +27 -0
- package/llms/live.txt +471 -0
- package/llms/node.txt +43 -0
- package/llms/oauth.txt +136 -0
- package/llms/observability.txt +893 -0
- package/llms/primitives.txt +158 -0
- package/llms/react.txt +184 -0
- package/llms/release.txt +176 -0
- package/llms/remote.txt +25 -0
- package/llms/server.2.txt +361 -0
- package/llms/server.3.txt +1031 -0
- package/llms/server.4.txt +905 -0
- package/llms/server.5.txt +250 -0
- package/llms/server.txt +996 -0
- package/llms/stitchkit.2.txt +836 -0
- package/llms/stitchkit.3.txt +147 -0
- package/llms/stitchkit.txt +260 -0
- package/llms/telegram.txt +30 -0
- package/llms/testing.txt +676 -0
- package/llms/tools-connections.txt +45 -0
- package/llms/tools-contract.txt +9 -0
- package/llms/tools-invoker.txt +9 -0
- package/llms/tools.2.txt +647 -0
- package/llms/tools.3.txt +288 -0
- package/llms/tools.txt +966 -0
- package/llms/tracking-server.txt +32 -0
- package/llms/tracking.txt +263 -0
- package/llms/upgrading-0.37.0-0.50.0.txt +947 -0
- package/llms/upgrading-0.53.0-0.67.0.txt +1174 -0
- package/llms/upgrading-0.68.0-0.94.0.txt +1159 -0
- package/llms/upgrading.txt +215 -0
- package/llms-full.txt +312 -77
- package/llms.txt +54 -5
- package/package.json +84 -83
- package/dist/agent-runtime/durability-contract.d.ts +0 -176
- package/dist/agent-runtime/durability-contract.d.ts.map +0 -1
- package/dist/agent-runtime/durability-json.d.ts +0 -3
- package/dist/agent-runtime/durability-json.d.ts.map +0 -1
- package/dist/agent-runtime/durability-ledger.d.ts +0 -16
- package/dist/agent-runtime/durability-ledger.d.ts.map +0 -1
- package/dist/agent-runtime/durability-scheduler.d.ts +0 -29
- package/dist/agent-runtime/durability-scheduler.d.ts.map +0 -1
- package/dist/agent-runtime/durability.d.ts +0 -14
- package/dist/agent-runtime/durability.d.ts.map +0 -1
- package/dist/agent-runtime/store-driver.d.ts +0 -814
- package/dist/agent-runtime/store-driver.d.ts.map +0 -1
- package/dist/agent-runtime-browser.d.ts +0 -5
- package/dist/agent-runtime-browser.d.ts.map +0 -1
- package/dist/agent-runtime-browser.js +0 -124
- package/dist/agent-runtime-coding-tools.d.ts +0 -2
- package/dist/agent-runtime-coding-tools.d.ts.map +0 -1
- package/dist/agent-runtime-coding-tools.js +0 -23
- package/dist/agent-runtime-harness.d.ts +0 -2
- package/dist/agent-runtime-harness.d.ts.map +0 -1
- package/dist/agent-runtime-harness.js +0 -729
- package/dist/agent-runtime-openrouter.d.ts +0 -29
- package/dist/agent-runtime-openrouter.d.ts.map +0 -1
- package/dist/agent-runtime-openrouter.js +0 -270
- package/dist/agent-runtime-sandbox.d.ts +0 -5
- package/dist/agent-runtime-sandbox.d.ts.map +0 -1
- package/dist/agent-runtime-sandbox.js +0 -798
- package/dist/agent-runtime-sqlite-bun.d.ts +0 -11
- package/dist/agent-runtime-sqlite-bun.d.ts.map +0 -1
- package/dist/agent-runtime-sqlite-bun.js +0 -42
- package/dist/agent-runtime-sqlite-node.d.ts +0 -11
- package/dist/agent-runtime-sqlite-node.d.ts.map +0 -1
- package/dist/agent-runtime-sqlite-node.js +0 -44
- package/dist/agent-runtime-testing.d.ts +0 -3
- package/dist/agent-runtime-testing.d.ts.map +0 -1
- package/dist/agent-runtime-testing.js +0 -156
- package/dist/agent-runtime.d.ts +0 -38
- package/dist/agent-runtime.d.ts.map +0 -1
- package/dist/agent-runtime.js +0 -2607
- package/dist/application/channel.d.ts.map +0 -1
- package/dist/application-diagnostic-journal.d.ts +0 -21
- package/dist/application-diagnostic-journal.d.ts.map +0 -1
- package/dist/application-diagnostic-journal.js +0 -632
- package/dist/application-grammy.d.ts +0 -2
- package/dist/application-grammy.d.ts.map +0 -1
- package/dist/application-grammy.js +0 -169
- package/dist/application-opentelemetry.d.ts +0 -2
- package/dist/application-opentelemetry.d.ts.map +0 -1
- package/dist/application-opentelemetry.js +0 -250
- package/dist/application-schemas.d.ts +0 -15
- package/dist/application-schemas.d.ts.map +0 -1
- package/dist/application-schemas.js +0 -27
- package/dist/application.d.ts +0 -22
- package/dist/application.d.ts.map +0 -1
- package/dist/application.js +0 -1977
- package/dist/cli.d.ts +0 -41
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -753
- package/dist/contract/index.d.ts +0 -8
- package/dist/contract/index.d.ts.map +0 -1
- package/dist/contract/index.js +0 -55
- package/dist/declaration.d.ts.map +0 -1
- package/dist/declaration.js +0 -183
- package/dist/files.d.ts +0 -3
- package/dist/files.d.ts.map +0 -1
- package/dist/files.js +0 -15
- package/dist/geo.d.ts +0 -3
- package/dist/geo.d.ts.map +0 -1
- package/dist/geo.js +0 -245
- package/dist/google.d.ts.map +0 -1
- package/dist/google.js +0 -175
- package/dist/index-0a349c33.js +0 -470
- package/dist/index-0j3vcp5m.js +0 -28
- package/dist/index-2c2bjw3s.js +0 -51
- package/dist/index-2na0qrfn.js +0 -214
- package/dist/index-2qzskm8h.js +0 -63
- package/dist/index-3bmnp41g.js +0 -2169
- package/dist/index-3xwxfj4z.js +0 -334
- package/dist/index-4fpa9dy2.js +0 -51
- package/dist/index-6kyksz9y.js +0 -268
- package/dist/index-77fekveh.js +0 -44
- package/dist/index-7gnkny4z.js +0 -326
- package/dist/index-7zbps32p.js +0 -89
- package/dist/index-9f8ztey6.js +0 -588
- package/dist/index-a11g2kry.js +0 -866
- package/dist/index-a916km3r.js +0 -45
- package/dist/index-actkayzn.js +0 -367
- package/dist/index-bn2cjajt.js +0 -524
- package/dist/index-bx75zwt7.js +0 -63
- package/dist/index-cby4ar3v.js +0 -46
- package/dist/index-cnyk6te3.js +0 -77
- package/dist/index-cxqhvq21.js +0 -413
- package/dist/index-e0znv5gn.js +0 -176
- package/dist/index-e42wzzz5.js +0 -154
- package/dist/index-f477k430.js +0 -324
- package/dist/index-f9mb610r.js +0 -177
- package/dist/index-fadnxwna.js +0 -1046
- package/dist/index-fq77yfzc.js +0 -1303
- package/dist/index-h9etkkyk.js +0 -1126
- package/dist/index-hrbajay7.js +0 -1196
- package/dist/index-kw9t5ayn.js +0 -507
- package/dist/index-mzvgxp0n.js +0 -80
- package/dist/index-n0f51dfn.js +0 -3170
- package/dist/index-p13mwz16.js +0 -16
- package/dist/index-s8cnx02s.js +0 -90
- package/dist/index-sr93cwf9.js +0 -325
- package/dist/index-tmwcrptx.js +0 -85
- package/dist/index-v5573g1k.js +0 -142
- package/dist/index-vjpvjqpn.js +0 -86
- package/dist/index-vk3kq9sb.js +0 -3344
- package/dist/index-wc4x00bn.js +0 -103
- package/dist/index-wnfk50r0.js +0 -211
- package/dist/index-yewwh1w4.js +0 -647
- package/dist/index-yn8remb1.js +0 -290
- package/dist/index-ywd0y6m1.js +0 -394
- package/dist/index-zwkgfq1s.js +0 -345
- package/dist/index.d.ts +0 -14
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -632
- package/dist/internal/errors.d.ts +0 -92
- package/dist/internal/errors.d.ts.map +0 -1
- package/dist/internal/observability-sink.d.ts +0 -81
- package/dist/internal/observability-sink.d.ts.map +0 -1
- package/dist/live.d.ts +0 -19
- package/dist/live.d.ts.map +0 -1
- package/dist/live.js +0 -282
- package/dist/logger.d.ts.map +0 -1
- package/dist/node.d.ts +0 -18
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js +0 -303
- package/dist/oauth.d.ts +0 -57
- package/dist/oauth.d.ts.map +0 -1
- package/dist/oauth.js +0 -170
- package/dist/observability/index.d.ts +0 -19
- package/dist/observability/index.d.ts.map +0 -1
- package/dist/observability/index.js +0 -569
- package/dist/primitives.d.ts +0 -3
- package/dist/primitives.d.ts.map +0 -1
- package/dist/primitives.js +0 -754
- package/dist/react.d.ts +0 -5
- package/dist/react.d.ts.map +0 -1
- package/dist/react.js +0 -403
- package/dist/release.d.ts +0 -15
- package/dist/release.d.ts.map +0 -1
- package/dist/release.js +0 -196
- package/dist/remote.d.ts +0 -9
- package/dist/remote.d.ts.map +0 -1
- package/dist/remote.js +0 -88
- package/dist/retained.d.ts.map +0 -1
- package/dist/server/file-state-store.d.ts +0 -23
- package/dist/server/file-state-store.d.ts.map +0 -1
- package/dist/server/index.d.ts +0 -36
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js +0 -1745
- package/dist/server/request.d.ts.map +0 -1
- package/dist/telegram.d.ts +0 -3
- package/dist/telegram.d.ts.map +0 -1
- package/dist/telegram.js +0 -224
- package/dist/testing/agent-store-conformance.d.ts +0 -40
- package/dist/testing/agent-store-conformance.d.ts.map +0 -1
- package/dist/testing.d.ts +0 -39
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -2209
- package/dist/tool-invoker.d.ts +0 -9
- package/dist/tool-invoker.d.ts.map +0 -1
- package/dist/tool-invoker.js +0 -21
- package/dist/tools/async-operation-contract.d.ts.map +0 -1
- package/dist/tools/async-operation.d.ts +0 -332
- package/dist/tools/async-operation.d.ts.map +0 -1
- package/dist/tools/cli-args.d.ts +0 -143
- package/dist/tools/cli-args.d.ts.map +0 -1
- package/dist/tools/cli-checkpoint.d.ts +0 -24
- package/dist/tools/cli-checkpoint.d.ts.map +0 -1
- package/dist/tools/cli-command.d.ts +0 -70
- package/dist/tools/cli-command.d.ts.map +0 -1
- package/dist/tools/cli-format.d.ts +0 -49
- package/dist/tools/cli-format.d.ts.map +0 -1
- package/dist/tools/cli-installer.d.ts +0 -34
- package/dist/tools/cli-installer.d.ts.map +0 -1
- package/dist/tools/cli-invoke.d.ts +0 -143
- package/dist/tools/cli-invoke.d.ts.map +0 -1
- package/dist/tools/cli-manifest.d.ts +0 -80
- package/dist/tools/cli-manifest.d.ts.map +0 -1
- package/dist/tools/cli-policy.d.ts +0 -27
- package/dist/tools/cli-policy.d.ts.map +0 -1
- package/dist/tools/cli-profile.d.ts +0 -40
- package/dist/tools/cli-profile.d.ts.map +0 -1
- package/dist/tools/cli-signature.d.ts +0 -81
- package/dist/tools/cli-signature.d.ts.map +0 -1
- package/dist/tools/cli-stream.d.ts +0 -93
- package/dist/tools/cli-stream.d.ts.map +0 -1
- package/dist/tools/cli-update.d.ts +0 -126
- package/dist/tools/cli-update.d.ts.map +0 -1
- package/dist/tools/cli-view.d.ts +0 -12
- package/dist/tools/cli-view.d.ts.map +0 -1
- package/dist/tools/cli-wait.d.ts +0 -54
- package/dist/tools/cli-wait.d.ts.map +0 -1
- package/dist/tools/cli.d.ts +0 -94
- package/dist/tools/cli.d.ts.map +0 -1
- package/dist/tools/coerce.d.ts.map +0 -1
- package/dist/tools/connections/index.d.ts +0 -20
- package/dist/tools/connections/index.d.ts.map +0 -1
- package/dist/tools/connections/index.js +0 -1107
- package/dist/tools/define-download-tool.d.ts +0 -18
- package/dist/tools/define-download-tool.d.ts.map +0 -1
- package/dist/tools/define-upload-tool.d.ts +0 -16
- package/dist/tools/define-upload-tool.d.ts.map +0 -1
- package/dist/tools/define-view-file-tool.d.ts +0 -10
- package/dist/tools/define-view-file-tool.d.ts.map +0 -1
- package/dist/tools/define-wait-tool.d.ts +0 -22
- package/dist/tools/define-wait-tool.d.ts.map +0 -1
- package/dist/tools/download-core.d.ts +0 -20
- package/dist/tools/download-core.d.ts.map +0 -1
- package/dist/tools/flatten-join.d.ts.map +0 -1
- package/dist/tools/flatten.d.ts.map +0 -1
- package/dist/tools/json-schema-dialect.d.ts +0 -17
- package/dist/tools/json-schema-dialect.d.ts.map +0 -1
- package/dist/tools/json-schema.d.ts.map +0 -1
- package/dist/tools/managed-file-error.d.ts +0 -6
- package/dist/tools/managed-file-error.d.ts.map +0 -1
- package/dist/tools/mcp-app.d.ts +0 -62
- package/dist/tools/mcp-app.d.ts.map +0 -1
- package/dist/tools/mcp-catalog.d.ts +0 -68
- package/dist/tools/mcp-catalog.d.ts.map +0 -1
- package/dist/tools/mcp-handler.d.ts +0 -46
- package/dist/tools/mcp-handler.d.ts.map +0 -1
- package/dist/tools/mcp-prepare.d.ts +0 -75
- package/dist/tools/mcp-prepare.d.ts.map +0 -1
- package/dist/tools/mcp-progress.d.ts +0 -46
- package/dist/tools/mcp-progress.d.ts.map +0 -1
- package/dist/tools/mcp-round-policy.d.ts +0 -33
- package/dist/tools/mcp-round-policy.d.ts.map +0 -1
- package/dist/tools/mcp-round.d.ts +0 -61
- package/dist/tools/mcp-round.d.ts.map +0 -1
- package/dist/tools/mcp-stdio-signals.d.ts +0 -33
- package/dist/tools/mcp-stdio-signals.d.ts.map +0 -1
- package/dist/tools/mcp-stdio.d.ts +0 -20
- package/dist/tools/mcp-stdio.d.ts.map +0 -1
- package/dist/tools/mcp-trace.d.ts +0 -12
- package/dist/tools/mcp-trace.d.ts.map +0 -1
- package/dist/tools/mcp.d.ts +0 -152
- package/dist/tools/mcp.d.ts.map +0 -1
- package/dist/tools/mount-download.d.ts +0 -41
- package/dist/tools/mount-download.d.ts.map +0 -1
- package/dist/tools/mount-upload.d.ts +0 -21
- package/dist/tools/mount-upload.d.ts.map +0 -1
- package/dist/tools/mount-wait.d.ts.map +0 -1
- package/dist/tools/native-mcp.d.ts +0 -20
- package/dist/tools/native-mcp.d.ts.map +0 -1
- package/dist/tools/native-result.d.ts.map +0 -1
- package/dist/tools/oauth-metadata.d.ts +0 -28
- package/dist/tools/oauth-metadata.d.ts.map +0 -1
- package/dist/tools/oauth-provider.d.ts +0 -184
- package/dist/tools/oauth-provider.d.ts.map +0 -1
- package/dist/tools/portable-formats.d.ts.map +0 -1
- package/dist/tools/presentation.d.ts +0 -22
- package/dist/tools/presentation.d.ts.map +0 -1
- package/dist/tools/schema.d.ts.map +0 -1
- package/dist/tools/untyped-properties.d.ts.map +0 -1
- package/dist/tools/upload-core.d.ts +0 -4
- package/dist/tools/upload-core.d.ts.map +0 -1
- package/dist/tools/view-file-contract.d.ts.map +0 -1
- package/dist/tools/view-file.d.ts +0 -62
- package/dist/tools/view-file.d.ts.map +0 -1
- package/dist/tools/wait-core.d.ts.map +0 -1
- package/dist/tools-contract.d.ts +0 -29
- package/dist/tools-contract.d.ts.map +0 -1
- package/dist/tools-contract.js +0 -24
- package/dist/tools.d.ts +0 -50
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js +0 -2930
- package/dist/tracking-server.d.ts +0 -15
- package/dist/tracking-server.d.ts.map +0 -1
- package/dist/tracking.d.ts +0 -24
- package/dist/tracking.d.ts.map +0 -1
- package/dist/tracking.js +0 -1092
- package/dist/upgrade-cli.d.ts.map +0 -1
- package/dist/upgrade-cli.js +0 -177
- /package/dist/{retained.d.ts → browser/retained.d.ts} +0 -0
- /package/dist/{declaration.d.ts → declaration/declaration.d.ts} +0 -0
- /package/dist/{upgrade-cli.d.ts → entrypoints/bin/upgrade-cli.d.ts} +0 -0
- /package/dist/{tracking-server.js → entrypoints/tracking/server.js} +0 -0
- /package/dist/{google.d.ts → google/google.d.ts} +0 -0
- /package/dist/{index-pq95qkbf.js → index-5jm36zv1.js} +0 -0
- /package/dist/{application → internal}/channel.d.ts +0 -0
- /package/dist/{logger.d.ts → internal/logger.d.ts} +0 -0
- /package/dist/{server → internal}/request.d.ts +0 -0
- /package/dist/{tools → json-schema}/json-schema.d.ts +0 -0
- /package/dist/tools/{async-operation-contract.d.ts → operations/async-operation-contract.d.ts} +0 -0
- /package/dist/tools/{mount-wait.d.ts → operations/mount-wait.d.ts} +0 -0
- /package/dist/tools/{wait-core.d.ts → operations/wait-core.d.ts} +0 -0
- /package/dist/tools/{coerce.d.ts → schema/coerce.d.ts} +0 -0
- /package/dist/tools/{flatten-join.d.ts → schema/flatten-join.d.ts} +0 -0
- /package/dist/tools/{flatten.d.ts → schema/flatten.d.ts} +0 -0
- /package/dist/tools/{portable-formats.d.ts → schema/portable-formats.d.ts} +0 -0
- /package/dist/tools/{schema.d.ts → schema/schema.d.ts} +0 -0
- /package/dist/tools/{untyped-properties.d.ts → schema/untyped-properties.d.ts} +0 -0
- /package/dist/tools/{native-result.d.ts → transfer/native-result.d.ts} +0 -0
- /package/dist/tools/{view-file-contract.d.ts → transfer/view-file-contract.d.ts} +0 -0
package/dist/testing.js
DELETED
|
@@ -1,2209 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createApplication
|
|
3
|
-
} from "./index-a11g2kry.js";
|
|
4
|
-
import"./index-3gye9wzb.js";
|
|
5
|
-
import"./index-2k4yrqkc.js";
|
|
6
|
-
import"./index-3z73fh2c.js";
|
|
7
|
-
import {
|
|
8
|
-
createMemoryAgentRuntimeStore
|
|
9
|
-
} from "./index-hrbajay7.js";
|
|
10
|
-
import {
|
|
11
|
-
decodeAgentConversationArchive
|
|
12
|
-
} from "./index-zwkgfq1s.js";
|
|
13
|
-
import {
|
|
14
|
-
AgentMessageSchema,
|
|
15
|
-
AgentRunSchema
|
|
16
|
-
} from "./index-gtj3zc53.js";
|
|
17
|
-
import {
|
|
18
|
-
createAgentRaceBarrier,
|
|
19
|
-
createAgentRaceDriver,
|
|
20
|
-
createAgentRaceTrace
|
|
21
|
-
} from "./index-cnyk6te3.js";
|
|
22
|
-
import {
|
|
23
|
-
RealtimeRejectDirectionSchema,
|
|
24
|
-
RealtimeRejectFaultSchema,
|
|
25
|
-
RealtimeRejectPhaseSchema,
|
|
26
|
-
RealtimeRejectReasonSchema
|
|
27
|
-
} from "./index-p7hgdyhb.js";
|
|
28
|
-
import {
|
|
29
|
-
createClient,
|
|
30
|
-
createClients
|
|
31
|
-
} from "./index-yewwh1w4.js";
|
|
32
|
-
import {
|
|
33
|
-
RealtimeRequestDisconnectedError,
|
|
34
|
-
RealtimeRequestInvalidAcknowledgementError,
|
|
35
|
-
RealtimeRequestTimeoutError
|
|
36
|
-
} from "./index-2qzskm8h.js";
|
|
37
|
-
import"./index-v5573g1k.js";
|
|
38
|
-
import"./index-3xwxfj4z.js";
|
|
39
|
-
import {
|
|
40
|
-
compareCodepoints,
|
|
41
|
-
serializeCanonicalJson
|
|
42
|
-
} from "./index-0j3vcp5m.js";
|
|
43
|
-
import"./index-e0znv5gn.js";
|
|
44
|
-
import {
|
|
45
|
-
joinRoutePath
|
|
46
|
-
} from "./index-0a349c33.js";
|
|
47
|
-
import"./index-rxfy4cq7.js";
|
|
48
|
-
import"./index-6k1937bx.js";
|
|
49
|
-
import"./index-zcgf3gqf.js";
|
|
50
|
-
import {
|
|
51
|
-
mcpProjectionCandidate,
|
|
52
|
-
prepareProjectedMcpTools,
|
|
53
|
-
projectToolSurface,
|
|
54
|
-
staticInputRounds
|
|
55
|
-
} from "./index-h9etkkyk.js";
|
|
56
|
-
import {
|
|
57
|
-
toJsonSchema
|
|
58
|
-
} from "./index-cby4ar3v.js";
|
|
59
|
-
import"./index-2vtcmrj9.js";
|
|
60
|
-
import"./index-kzfs85xp.js";
|
|
61
|
-
import {
|
|
62
|
-
isRecord
|
|
63
|
-
} from "./index-77fekveh.js";
|
|
64
|
-
// src/testing/agent-store-conformance.ts
|
|
65
|
-
function userMessage(conversationId, id) {
|
|
66
|
-
return AgentMessageSchema.parse({
|
|
67
|
-
schemaVersion: 1,
|
|
68
|
-
id,
|
|
69
|
-
conversationId,
|
|
70
|
-
role: "user",
|
|
71
|
-
status: "committed",
|
|
72
|
-
parts: [{ type: "text", text: id }],
|
|
73
|
-
createdAt: "2026-08-22T00:00:00.000Z",
|
|
74
|
-
updatedAt: "2026-08-22T00:00:00.000Z"
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
function queuedRun(conversationId, inputMessageId, id) {
|
|
78
|
-
return AgentRunSchema.parse({
|
|
79
|
-
schemaVersion: 1,
|
|
80
|
-
id,
|
|
81
|
-
conversationId,
|
|
82
|
-
inputMessageIds: [inputMessageId],
|
|
83
|
-
assistantMessageId: `${id}-assistant`,
|
|
84
|
-
state: "queued",
|
|
85
|
-
revision: 0,
|
|
86
|
-
createdAt: "2026-08-22T00:00:00.000Z",
|
|
87
|
-
updatedAt: "2026-08-22T00:00:00.000Z"
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
function requireOutcome(actual, expected) {
|
|
91
|
-
if (actual.outcome !== expected) {
|
|
92
|
-
throw new Error(`Agent store conformance expected ${expected}, received ${actual.outcome}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
async function runAgentStoreConformance(config) {
|
|
96
|
-
const run = `conformance-${crypto.randomUUID()}`;
|
|
97
|
-
const context = {
|
|
98
|
-
conversationIds: [
|
|
99
|
-
run,
|
|
100
|
-
`${run}-recovery`,
|
|
101
|
-
`${run}-absorb`,
|
|
102
|
-
`${run}-causal-history`,
|
|
103
|
-
`${run}-causal-active`,
|
|
104
|
-
`${run}-interrupt-priority`,
|
|
105
|
-
`${run}-ledger`,
|
|
106
|
-
`${run}-archive`,
|
|
107
|
-
`${run}-seed`
|
|
108
|
-
]
|
|
109
|
-
};
|
|
110
|
-
const store = await config.createStore(context);
|
|
111
|
-
let failure;
|
|
112
|
-
try {
|
|
113
|
-
await conformanceScenario(store, context.conversationIds);
|
|
114
|
-
} catch (error) {
|
|
115
|
-
failure = error;
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
await config.cleanup?.(context);
|
|
119
|
-
} catch (cleanupError) {
|
|
120
|
-
if (failure === undefined)
|
|
121
|
-
throw cleanupError;
|
|
122
|
-
throw new AggregateError([failure, cleanupError], `${failure instanceof Error ? failure.message : String(failure)} (cleanup also failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)})`);
|
|
123
|
-
}
|
|
124
|
-
if (failure !== undefined)
|
|
125
|
-
throw failure;
|
|
126
|
-
}
|
|
127
|
-
async function seedScenario(store, conversationId) {
|
|
128
|
-
const input = {
|
|
129
|
-
conversationId,
|
|
130
|
-
seedKey: "brief",
|
|
131
|
-
inputs: [userMessage(conversationId, "seed-a"), userMessage(conversationId, "seed-b")]
|
|
132
|
-
};
|
|
133
|
-
const first = await store.seedConversationInput(input);
|
|
134
|
-
requireOutcome(first, "applied");
|
|
135
|
-
const before = await store.loadSnapshot(conversationId);
|
|
136
|
-
if (before.messages.map((message) => message.id).join(",") !== "seed-a,seed-b")
|
|
137
|
-
throw new Error("Seed conformance: complete ordered seed missing");
|
|
138
|
-
await Promise.all([store.seedConversationInput(input), store.seedConversationInput(input)]);
|
|
139
|
-
const repeated = await store.loadSnapshot(conversationId);
|
|
140
|
-
if (repeated.version !== before.version || repeated.messages.length !== 2)
|
|
141
|
-
throw new Error("Seed conformance: replay changed history");
|
|
142
|
-
const compacted = await store.replaceCompactedRange({
|
|
143
|
-
conversationId,
|
|
144
|
-
expectedVersion: repeated.version,
|
|
145
|
-
replacedMessageIds: ["seed-a", "seed-b"],
|
|
146
|
-
summary: AgentMessageSchema.parse({
|
|
147
|
-
...userMessage(conversationId, "seed-summary"),
|
|
148
|
-
role: "summary"
|
|
149
|
-
})
|
|
150
|
-
});
|
|
151
|
-
requireOutcome(compacted, "applied");
|
|
152
|
-
await store.seedConversationInput(input);
|
|
153
|
-
const after = await store.loadSnapshot(conversationId);
|
|
154
|
-
if (after.messages.some((message) => message.id === "seed-a" || message.id === "seed-b"))
|
|
155
|
-
throw new Error("Seed conformance: compacted instructions resurrected");
|
|
156
|
-
}
|
|
157
|
-
async function conformanceScenario(store, conversationIds) {
|
|
158
|
-
const [
|
|
159
|
-
conversationId,
|
|
160
|
-
recoveryConversationId,
|
|
161
|
-
absorbConversationId,
|
|
162
|
-
causalHistoryConversationId,
|
|
163
|
-
causalActiveConversationId,
|
|
164
|
-
interruptPriorityConversationId,
|
|
165
|
-
ledgerConversationId,
|
|
166
|
-
archiveConversationId,
|
|
167
|
-
seedConversationId
|
|
168
|
-
] = conversationIds;
|
|
169
|
-
if (seedConversationId)
|
|
170
|
-
await seedScenario(store, seedConversationId);
|
|
171
|
-
if (ledgerConversationId)
|
|
172
|
-
await ledgerScenario(store, ledgerConversationId);
|
|
173
|
-
if (archiveConversationId)
|
|
174
|
-
await archiveScenario(store, archiveConversationId);
|
|
175
|
-
if (!conversationId || !recoveryConversationId || !absorbConversationId || !causalHistoryConversationId || !causalActiveConversationId || !interruptPriorityConversationId) {
|
|
176
|
-
throw new Error("Agent store conformance requires six conversation identities");
|
|
177
|
-
}
|
|
178
|
-
const absentConversationId = `${conversationId}-absent`;
|
|
179
|
-
const firstInput = userMessage(conversationId, "input-1");
|
|
180
|
-
const firstRun = queuedRun(conversationId, firstInput.id, "run-1");
|
|
181
|
-
const accepted = await store.acceptInputAndAssignRun({
|
|
182
|
-
idempotencyKey: "request-1",
|
|
183
|
-
input: firstInput,
|
|
184
|
-
run: firstRun
|
|
185
|
-
});
|
|
186
|
-
requireOutcome(accepted, "applied");
|
|
187
|
-
const duplicate = await store.acceptInputAndAssignRun({
|
|
188
|
-
idempotencyKey: "request-1",
|
|
189
|
-
input: userMessage(conversationId, "discarded-input"),
|
|
190
|
-
run: queuedRun(conversationId, "discarded-input", "discarded-run")
|
|
191
|
-
});
|
|
192
|
-
requireOutcome(duplicate, "duplicate");
|
|
193
|
-
if (duplicate.input.id !== firstInput.id || duplicate.inputMessageId !== firstInput.id || duplicate.runId !== firstRun.id || duplicate.assistantMessageId !== firstRun.assistantMessageId) {
|
|
194
|
-
throw new Error("Duplicate admission did not return its original durable identity");
|
|
195
|
-
}
|
|
196
|
-
const secondInput = userMessage(conversationId, "input-2");
|
|
197
|
-
const coalesced = await store.acceptInputAndAssignRun({
|
|
198
|
-
idempotencyKey: "request-2",
|
|
199
|
-
input: secondInput,
|
|
200
|
-
run: queuedRun(conversationId, secondInput.id, "discarded-coalesced-run"),
|
|
201
|
-
coalesceIntoRunId: firstRun.id
|
|
202
|
-
});
|
|
203
|
-
requireOutcome(coalesced, "applied");
|
|
204
|
-
const assigned = coalesced.snapshot.runs.find((run) => run.id === firstRun.id);
|
|
205
|
-
if (assigned?.inputMessageIds.join(",") !== "input-1,input-2") {
|
|
206
|
-
throw new Error("Coalesced admission did not preserve ordered input identities");
|
|
207
|
-
}
|
|
208
|
-
const collidingInput = userMessage(conversationId, assigned.assistantMessageId);
|
|
209
|
-
await store.acceptInputAndAssignRun({
|
|
210
|
-
idempotencyKey: "request-collision",
|
|
211
|
-
input: collidingInput,
|
|
212
|
-
run: queuedRun(conversationId, collidingInput.id, "discarded-collision-run"),
|
|
213
|
-
coalesceIntoRunId: assigned.id
|
|
214
|
-
}).then(() => {
|
|
215
|
-
throw new Error("Coalesced input reused the reserved assistant identity");
|
|
216
|
-
}, (error) => {
|
|
217
|
-
if (!(error instanceof TypeError))
|
|
218
|
-
throw error;
|
|
219
|
-
});
|
|
220
|
-
await store.replaceCompactedRange({
|
|
221
|
-
conversationId,
|
|
222
|
-
expectedVersion: coalesced.snapshot.version,
|
|
223
|
-
replacedMessageIds: [firstInput.id, secondInput.id],
|
|
224
|
-
summary: AgentMessageSchema.parse({
|
|
225
|
-
schemaVersion: 1,
|
|
226
|
-
id: assigned.assistantMessageId,
|
|
227
|
-
conversationId,
|
|
228
|
-
role: "summary",
|
|
229
|
-
status: "committed",
|
|
230
|
-
parts: [{ type: "text", text: "invalid reserved identity" }],
|
|
231
|
-
createdAt: "2026-08-22T00:00:02.000Z",
|
|
232
|
-
updatedAt: "2026-08-22T00:00:02.000Z"
|
|
233
|
-
})
|
|
234
|
-
}).then(() => {
|
|
235
|
-
throw new Error("Compaction reused a reserved assistant identity");
|
|
236
|
-
}, (error) => {
|
|
237
|
-
if (!(error instanceof TypeError))
|
|
238
|
-
throw error;
|
|
239
|
-
});
|
|
240
|
-
const compacted = await store.replaceCompactedRange({
|
|
241
|
-
conversationId,
|
|
242
|
-
expectedVersion: coalesced.snapshot.version,
|
|
243
|
-
replacedMessageIds: [firstInput.id, secondInput.id],
|
|
244
|
-
summary: AgentMessageSchema.parse({
|
|
245
|
-
schemaVersion: 1,
|
|
246
|
-
id: "summary-1",
|
|
247
|
-
conversationId,
|
|
248
|
-
role: "summary",
|
|
249
|
-
status: "committed",
|
|
250
|
-
parts: [{ type: "text", text: "two inputs" }],
|
|
251
|
-
createdAt: "2026-08-22T00:00:02.000Z",
|
|
252
|
-
updatedAt: "2026-08-22T00:00:02.000Z"
|
|
253
|
-
})
|
|
254
|
-
});
|
|
255
|
-
requireOutcome(compacted, "applied");
|
|
256
|
-
const duplicateAfterCompaction = await store.acceptInputAndAssignRun({
|
|
257
|
-
idempotencyKey: "request-1",
|
|
258
|
-
input: userMessage(conversationId, "discarded-after-compaction"),
|
|
259
|
-
run: queuedRun(conversationId, "discarded-after-compaction", "discarded-run-2")
|
|
260
|
-
});
|
|
261
|
-
requireOutcome(duplicateAfterCompaction, "duplicate");
|
|
262
|
-
if (duplicateAfterCompaction.input.id !== firstInput.id) {
|
|
263
|
-
throw new Error("Compaction discarded the canonical duplicate admission input");
|
|
264
|
-
}
|
|
265
|
-
const acquired = await store.acquireRun({
|
|
266
|
-
conversationId,
|
|
267
|
-
runId: assigned.id,
|
|
268
|
-
expectedRevision: assigned.revision,
|
|
269
|
-
ownerId: "conformance-owner"
|
|
270
|
-
});
|
|
271
|
-
requireOutcome(acquired, "applied");
|
|
272
|
-
const running = acquired.snapshot.runs.find((run) => run.id === assigned.id);
|
|
273
|
-
if (!running)
|
|
274
|
-
throw new Error("Acquired run disappeared");
|
|
275
|
-
const stale = await store.checkpointRunAssistant({
|
|
276
|
-
conversationId,
|
|
277
|
-
runId: running.id,
|
|
278
|
-
expectedRevision: running.revision - 1,
|
|
279
|
-
ownerId: "conformance-owner",
|
|
280
|
-
assistant: AgentMessageSchema.parse({
|
|
281
|
-
schemaVersion: 1,
|
|
282
|
-
id: running.assistantMessageId,
|
|
283
|
-
conversationId,
|
|
284
|
-
runId: running.id,
|
|
285
|
-
role: "assistant",
|
|
286
|
-
status: "streaming",
|
|
287
|
-
parts: [],
|
|
288
|
-
createdAt: "2026-08-22T00:00:00.000Z",
|
|
289
|
-
updatedAt: "2026-08-22T00:00:01.000Z"
|
|
290
|
-
})
|
|
291
|
-
});
|
|
292
|
-
requireOutcome(stale, "conflict");
|
|
293
|
-
await store.recoverRun({
|
|
294
|
-
conversationId,
|
|
295
|
-
runId: running.id,
|
|
296
|
-
expectedRevision: running.revision,
|
|
297
|
-
action: "requeue"
|
|
298
|
-
}).then(() => {
|
|
299
|
-
throw new Error("Acquired recovery replayed without explicit safety evidence");
|
|
300
|
-
}, (error) => {
|
|
301
|
-
if (!(error instanceof TypeError))
|
|
302
|
-
throw error;
|
|
303
|
-
});
|
|
304
|
-
const checkpoint = await store.checkpointRunAssistant({
|
|
305
|
-
conversationId,
|
|
306
|
-
runId: running.id,
|
|
307
|
-
expectedRevision: running.revision,
|
|
308
|
-
ownerId: "conformance-owner",
|
|
309
|
-
assistant: AgentMessageSchema.parse({
|
|
310
|
-
schemaVersion: 1,
|
|
311
|
-
id: running.assistantMessageId,
|
|
312
|
-
conversationId,
|
|
313
|
-
runId: running.id,
|
|
314
|
-
role: "assistant",
|
|
315
|
-
status: "streaming",
|
|
316
|
-
parts: [{ type: "text", text: "checkpoint" }],
|
|
317
|
-
createdAt: "2026-08-22T00:00:00.000Z",
|
|
318
|
-
updatedAt: "2026-08-22T00:00:01.000Z"
|
|
319
|
-
}),
|
|
320
|
-
usage: {
|
|
321
|
-
inputTokens: { value: 1000, provenance: "provider-reported" },
|
|
322
|
-
outputTokens: { value: 100, provenance: "provider-reported" },
|
|
323
|
-
cost: { value: 0.25, currency: "USD", provenance: "provider-reported" }
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
requireOutcome(checkpoint, "applied");
|
|
327
|
-
const checkpointedRun = checkpoint.snapshot.runs.find((run) => run.id === running.id);
|
|
328
|
-
if (!checkpointedRun)
|
|
329
|
-
throw new Error("Checkpointed run disappeared");
|
|
330
|
-
if (checkpointedRun.usage?.cost?.value !== 0.25) {
|
|
331
|
-
throw new Error("Checkpoint did not persist the run usage it was given");
|
|
332
|
-
}
|
|
333
|
-
const terminalAssistant = AgentMessageSchema.parse({
|
|
334
|
-
schemaVersion: 1,
|
|
335
|
-
id: running.assistantMessageId,
|
|
336
|
-
conversationId,
|
|
337
|
-
runId: running.id,
|
|
338
|
-
role: "assistant",
|
|
339
|
-
status: "completed",
|
|
340
|
-
parts: [{ type: "text", text: "done" }],
|
|
341
|
-
createdAt: "2026-08-22T00:00:00.000Z",
|
|
342
|
-
updatedAt: "2026-08-22T00:00:02.000Z"
|
|
343
|
-
});
|
|
344
|
-
if (checkpointedRun.fencingToken === undefined) {
|
|
345
|
-
throw new Error("Acquisition must persist a fencing token the store can read back");
|
|
346
|
-
}
|
|
347
|
-
const staleFence = await store.checkpointRunAssistant({
|
|
348
|
-
conversationId,
|
|
349
|
-
runId: running.id,
|
|
350
|
-
expectedRevision: checkpointedRun.revision,
|
|
351
|
-
ownerId: "conformance-owner",
|
|
352
|
-
fencingToken: checkpointedRun.fencingToken + 1,
|
|
353
|
-
assistant: AgentMessageSchema.parse({
|
|
354
|
-
schemaVersion: 1,
|
|
355
|
-
id: running.assistantMessageId,
|
|
356
|
-
conversationId,
|
|
357
|
-
runId: running.id,
|
|
358
|
-
role: "assistant",
|
|
359
|
-
status: "streaming",
|
|
360
|
-
parts: [{ type: "text", text: "stale fence" }],
|
|
361
|
-
createdAt: "2026-08-22T00:00:00.000Z",
|
|
362
|
-
updatedAt: "2026-08-22T00:00:01.500Z"
|
|
363
|
-
})
|
|
364
|
-
});
|
|
365
|
-
if (staleFence.outcome !== "conflict") {
|
|
366
|
-
throw new Error("A checkpoint with a stale fencing token must conflict");
|
|
367
|
-
}
|
|
368
|
-
const foreignOwner = await store.checkpointRunAssistant({
|
|
369
|
-
conversationId,
|
|
370
|
-
runId: running.id,
|
|
371
|
-
expectedRevision: checkpointedRun.revision,
|
|
372
|
-
ownerId: "a-different-runtime",
|
|
373
|
-
assistant: AgentMessageSchema.parse({
|
|
374
|
-
schemaVersion: 1,
|
|
375
|
-
id: running.assistantMessageId,
|
|
376
|
-
conversationId,
|
|
377
|
-
runId: running.id,
|
|
378
|
-
role: "assistant",
|
|
379
|
-
status: "streaming",
|
|
380
|
-
parts: [{ type: "text", text: "foreign owner" }],
|
|
381
|
-
createdAt: "2026-08-22T00:00:00.000Z",
|
|
382
|
-
updatedAt: "2026-08-22T00:00:01.700Z"
|
|
383
|
-
})
|
|
384
|
-
});
|
|
385
|
-
if (foreignOwner.outcome !== "conflict") {
|
|
386
|
-
throw new Error("A checkpoint from another owner must conflict");
|
|
387
|
-
}
|
|
388
|
-
const liveView = await store.loadRun({ conversationId, runId: running.id });
|
|
389
|
-
if (!liveView)
|
|
390
|
-
throw new Error("loadRun must find a run of this conversation");
|
|
391
|
-
if (liveView.run.id !== running.id || liveView.run.conversationId !== conversationId) {
|
|
392
|
-
throw new Error("loadRun returned a run it was not asked for");
|
|
393
|
-
}
|
|
394
|
-
if (liveView.run.revision !== checkpointedRun.revision) {
|
|
395
|
-
throw new Error("loadRun must return the run as the last mutation left it");
|
|
396
|
-
}
|
|
397
|
-
if (liveView.run.usage?.cost?.value !== 0.25) {
|
|
398
|
-
throw new Error("loadRun must carry the figure the run has spent so far");
|
|
399
|
-
}
|
|
400
|
-
if (liveView.snapshotVersion !== checkpoint.snapshot.version) {
|
|
401
|
-
throw new Error("loadRun must report the conversation version it read at");
|
|
402
|
-
}
|
|
403
|
-
if (liveView.assistant !== undefined) {
|
|
404
|
-
throw new Error("loadRun must not report a terminal answer for a live run");
|
|
405
|
-
}
|
|
406
|
-
if (await store.loadRun({ conversationId, runId: "no-such-run" })) {
|
|
407
|
-
throw new Error("loadRun must return undefined for an unknown run");
|
|
408
|
-
}
|
|
409
|
-
if (await store.loadRun({ conversationId: absentConversationId, runId: running.id })) {
|
|
410
|
-
throw new Error("loadRun must not cross conversation boundaries");
|
|
411
|
-
}
|
|
412
|
-
const activeRuns = await store.listActiveRuns(conversationId);
|
|
413
|
-
if (!activeRuns.some((run) => run.id === running.id)) {
|
|
414
|
-
throw new Error("listActiveRuns must report a run that is in flight");
|
|
415
|
-
}
|
|
416
|
-
if (activeRuns.some((run) => run.terminalReason !== undefined)) {
|
|
417
|
-
throw new Error("listActiveRuns must not report a run that has ended");
|
|
418
|
-
}
|
|
419
|
-
for (let index = 1;index < activeRuns.length; index += 1) {
|
|
420
|
-
const previous = activeRuns[index - 1];
|
|
421
|
-
const current = activeRuns[index];
|
|
422
|
-
if (!previous || !current)
|
|
423
|
-
continue;
|
|
424
|
-
const ordered = previous.createdAt === current.createdAt ? previous.id.localeCompare(current.id) < 0 : previous.createdAt < current.createdAt;
|
|
425
|
-
if (!ordered) {
|
|
426
|
-
throw new Error("listActiveRuns must order by createdAt and then by id");
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
if ((await store.listActiveRuns(absentConversationId)).length !== 0) {
|
|
430
|
-
throw new Error("listActiveRuns must be empty for an unknown conversation");
|
|
431
|
-
}
|
|
432
|
-
const recoverable = await store.scanRecoverable({ limit: 10 });
|
|
433
|
-
if (!recoverable.items.some((item) => item.run.id === running.id)) {
|
|
434
|
-
throw new Error("A running run must appear in a recoverable scan");
|
|
435
|
-
}
|
|
436
|
-
const operation = await store.recordRunOperation({
|
|
437
|
-
conversationId,
|
|
438
|
-
runId: running.id,
|
|
439
|
-
expectedRevision: checkpointedRun.revision,
|
|
440
|
-
ownerId: "conformance-owner",
|
|
441
|
-
fencingToken: checkpointedRun.fencingToken,
|
|
442
|
-
operation: {
|
|
443
|
-
operationId: "model-call-1:0",
|
|
444
|
-
kind: "model-request",
|
|
445
|
-
phase: "first-output",
|
|
446
|
-
step: 0,
|
|
447
|
-
startedAt: "2026-08-22T00:00:01.800Z",
|
|
448
|
-
firstOutputAt: "2026-08-22T00:00:01.900Z"
|
|
449
|
-
}
|
|
450
|
-
});
|
|
451
|
-
requireOutcome(operation, "applied");
|
|
452
|
-
const operatedRun = operation.snapshot.runs.find((run) => run.id === running.id);
|
|
453
|
-
if (operatedRun?.lastOperation?.operationId !== "model-call-1:0") {
|
|
454
|
-
throw new Error("Run operation identity did not survive its durable mutation");
|
|
455
|
-
}
|
|
456
|
-
const operatedView = await store.loadRun({ conversationId, runId: running.id });
|
|
457
|
-
if (operatedView?.run.lastOperation?.startedAt !== "2026-08-22T00:00:01.800Z") {
|
|
458
|
-
throw new Error("loadRun did not retain the original operation timestamp");
|
|
459
|
-
}
|
|
460
|
-
const interrupted = await store.requestRunInterrupt({
|
|
461
|
-
conversationId,
|
|
462
|
-
runId: running.id,
|
|
463
|
-
expectedRevision: operatedRun.revision
|
|
464
|
-
});
|
|
465
|
-
requireOutcome(interrupted, "applied");
|
|
466
|
-
const interruptedRun = interrupted.snapshot.runs.find((run) => run.id === running.id);
|
|
467
|
-
if (interruptedRun?.state !== "interrupt_requested") {
|
|
468
|
-
throw new Error("A durable interrupt must move the run to interrupt_requested");
|
|
469
|
-
}
|
|
470
|
-
if (interruptedRun.usage?.cost?.value !== 0.25) {
|
|
471
|
-
throw new Error("An interrupt must not discard the figure the run had already spent");
|
|
472
|
-
}
|
|
473
|
-
const terminalUsage = {
|
|
474
|
-
inputTokens: { value: 3000, provenance: "computed" },
|
|
475
|
-
outputTokens: { value: 300, provenance: "computed" },
|
|
476
|
-
reasoningTokens: { value: 30, provenance: "computed" },
|
|
477
|
-
cacheReadTokens: { value: 200, provenance: "computed" },
|
|
478
|
-
cacheWriteTokens: { value: 100, provenance: "computed" },
|
|
479
|
-
cost: { value: 1.5, currency: "USD", provenance: "computed" }
|
|
480
|
-
};
|
|
481
|
-
const terminalResults = await Promise.all([
|
|
482
|
-
store.commitRunTerminal({
|
|
483
|
-
conversationId,
|
|
484
|
-
runId: running.id,
|
|
485
|
-
expectedRevision: interruptedRun.revision,
|
|
486
|
-
ownerId: "conformance-owner",
|
|
487
|
-
assistant: terminalAssistant,
|
|
488
|
-
reason: "success",
|
|
489
|
-
usage: terminalUsage
|
|
490
|
-
}),
|
|
491
|
-
store.commitRunTerminal({
|
|
492
|
-
conversationId,
|
|
493
|
-
runId: running.id,
|
|
494
|
-
expectedRevision: interruptedRun.revision,
|
|
495
|
-
ownerId: "conformance-owner",
|
|
496
|
-
assistant: terminalAssistant,
|
|
497
|
-
reason: "success",
|
|
498
|
-
usage: terminalUsage
|
|
499
|
-
})
|
|
500
|
-
]);
|
|
501
|
-
const terminalOutcomes = terminalResults.map((result) => result.outcome).sort();
|
|
502
|
-
if (terminalOutcomes.join(",") !== "applied,conflict") {
|
|
503
|
-
throw new Error(`Terminal race was not linearized: ${terminalOutcomes.join(",")}`);
|
|
504
|
-
}
|
|
505
|
-
const terminalApplied = terminalResults.find((result) => result.outcome === "applied");
|
|
506
|
-
if (terminalApplied?.outcome !== "applied") {
|
|
507
|
-
throw new Error("Terminal race produced no applied result");
|
|
508
|
-
}
|
|
509
|
-
const settledRun = terminalApplied.snapshot.runs.find((run) => run.id === running.id);
|
|
510
|
-
if (JSON.stringify(settledRun?.usage) !== JSON.stringify(terminalUsage)) {
|
|
511
|
-
throw new Error("Terminal commit did not persist the run usage it was given");
|
|
512
|
-
}
|
|
513
|
-
const terminalView = await store.loadRun({ conversationId, runId: running.id });
|
|
514
|
-
if (terminalView?.run.terminalReason !== "success") {
|
|
515
|
-
throw new Error("loadRun must report the terminal reason a settled run ended with");
|
|
516
|
-
}
|
|
517
|
-
if (JSON.stringify(terminalView.run.usage) !== JSON.stringify(terminalUsage)) {
|
|
518
|
-
throw new Error("loadRun must return every persisted terminal usage field");
|
|
519
|
-
}
|
|
520
|
-
if (JSON.stringify(terminalView.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
521
|
-
throw new Error("loadRun must retain the answer a settled run produced");
|
|
522
|
-
}
|
|
523
|
-
if ((await store.listActiveRuns(conversationId)).some((run) => run.id === running.id)) {
|
|
524
|
-
throw new Error("listActiveRuns must drop a run once it has ended");
|
|
525
|
-
}
|
|
526
|
-
const compactedTerminal = await store.replaceCompactedRange({
|
|
527
|
-
conversationId,
|
|
528
|
-
expectedVersion: terminalApplied.snapshot.version,
|
|
529
|
-
replacedMessageIds: ["summary-1", terminalAssistant.id],
|
|
530
|
-
summary: AgentMessageSchema.parse({
|
|
531
|
-
schemaVersion: 1,
|
|
532
|
-
id: "summary-2",
|
|
533
|
-
conversationId,
|
|
534
|
-
role: "summary",
|
|
535
|
-
status: "committed",
|
|
536
|
-
parts: [{ type: "text", text: "terminal history" }],
|
|
537
|
-
createdAt: "2026-08-22T00:00:03.000Z",
|
|
538
|
-
updatedAt: "2026-08-22T00:00:03.000Z"
|
|
539
|
-
})
|
|
540
|
-
});
|
|
541
|
-
requireOutcome(compactedTerminal, "applied");
|
|
542
|
-
const duplicateTerminal = await store.acceptInputAndAssignRun({
|
|
543
|
-
idempotencyKey: "request-1",
|
|
544
|
-
input: userMessage(conversationId, "discarded-terminal-input"),
|
|
545
|
-
run: queuedRun(conversationId, "discarded-terminal-input", "discarded-terminal-run")
|
|
546
|
-
});
|
|
547
|
-
requireOutcome(duplicateTerminal, "duplicate");
|
|
548
|
-
if (duplicateTerminal.run.terminalReason !== "success" || JSON.stringify(duplicateTerminal.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
549
|
-
throw new Error("Compaction discarded the canonical duplicate terminal result");
|
|
550
|
-
}
|
|
551
|
-
const recoveryInput = userMessage(recoveryConversationId, "recovery-input");
|
|
552
|
-
const recoveryRun = queuedRun(recoveryConversationId, recoveryInput.id, "recovery-run");
|
|
553
|
-
const recoveryAccepted = await store.acceptInputAndAssignRun({
|
|
554
|
-
idempotencyKey: "recovery-request",
|
|
555
|
-
input: recoveryInput,
|
|
556
|
-
run: recoveryRun
|
|
557
|
-
});
|
|
558
|
-
requireOutcome(recoveryAccepted, "applied");
|
|
559
|
-
const recoveryAssigned = recoveryAccepted.snapshot.runs.find((run) => run.id === recoveryRun.id);
|
|
560
|
-
if (!recoveryAssigned)
|
|
561
|
-
throw new Error("Recovery run disappeared after admission");
|
|
562
|
-
const recoveryAcquired = await store.acquireRun({
|
|
563
|
-
conversationId: recoveryConversationId,
|
|
564
|
-
runId: recoveryAssigned.id,
|
|
565
|
-
expectedRevision: recoveryAssigned.revision,
|
|
566
|
-
ownerId: "abandoned-owner"
|
|
567
|
-
});
|
|
568
|
-
requireOutcome(recoveryAcquired, "applied");
|
|
569
|
-
const abandonedRun = recoveryAcquired.snapshot.runs.find((run) => run.id === recoveryRun.id);
|
|
570
|
-
if (!abandonedRun)
|
|
571
|
-
throw new Error("Recovery run disappeared after acquisition");
|
|
572
|
-
const abandoned = await store.recoverRun({
|
|
573
|
-
conversationId: recoveryConversationId,
|
|
574
|
-
runId: abandonedRun.id,
|
|
575
|
-
expectedRevision: abandonedRun.revision,
|
|
576
|
-
action: "abandon"
|
|
577
|
-
});
|
|
578
|
-
requireOutcome(abandoned, "applied");
|
|
579
|
-
const terminalRun = abandoned.snapshot.runs.find((run) => run.id === abandonedRun.id);
|
|
580
|
-
const terminalMessage = abandoned.snapshot.messages.find((message) => message.id === abandonedRun.assistantMessageId);
|
|
581
|
-
if (terminalRun?.state !== "abandoned" || terminalMessage?.status !== "failed") {
|
|
582
|
-
throw new Error("Abandon recovery did not atomically terminalize its assistant record");
|
|
583
|
-
}
|
|
584
|
-
const abandonedView = await store.loadRun({
|
|
585
|
-
conversationId: recoveryConversationId,
|
|
586
|
-
runId: abandonedRun.id
|
|
587
|
-
});
|
|
588
|
-
if (abandonedView?.run.state !== "abandoned" || abandonedView.run.terminalReason !== "abandoned" || abandonedView.assistant?.status !== "failed") {
|
|
589
|
-
throw new Error("The canonical run record disagrees with its abandoned index projection");
|
|
590
|
-
}
|
|
591
|
-
const afterAbandon = await store.scanRecoverable({ limit: 100 });
|
|
592
|
-
if (afterAbandon.items.some((item) => item.run.id === abandonedRun.id)) {
|
|
593
|
-
throw new Error("The recoverable index still exposes a canonically abandoned run");
|
|
594
|
-
}
|
|
595
|
-
await assertCausalHistoryOrder(store, causalHistoryConversationId);
|
|
596
|
-
await assertActiveRunCausalOrder(store, causalActiveConversationId);
|
|
597
|
-
await assertInterruptPriorityOrder(store, interruptPriorityConversationId);
|
|
598
|
-
await assertAbsorptionIsAtomic(store, absorbConversationId);
|
|
599
|
-
}
|
|
600
|
-
async function assertInterruptPriorityOrder(store, conversationId) {
|
|
601
|
-
const inputs = ["priority-a", "priority-b", "priority-c"].map((id) => userMessage(conversationId, id));
|
|
602
|
-
const [inputA, inputB, inputC] = inputs;
|
|
603
|
-
if (!inputA || !inputB || !inputC)
|
|
604
|
-
throw new Error("Priority fixture is incomplete");
|
|
605
|
-
const runA = queuedRun(conversationId, inputA.id, "priority-run-a");
|
|
606
|
-
const runB = queuedRun(conversationId, inputB.id, "priority-run-b");
|
|
607
|
-
const runC = AgentRunSchema.parse({
|
|
608
|
-
...queuedRun(conversationId, inputC.id, "priority-run-c"),
|
|
609
|
-
queuePriority: "interrupt-next"
|
|
610
|
-
});
|
|
611
|
-
requireOutcome(await store.acceptInputAndAssignRun({ idempotencyKey: runA.id, input: inputA, run: runA }), "applied");
|
|
612
|
-
const acquiredA = await store.acquireRun({
|
|
613
|
-
conversationId,
|
|
614
|
-
runId: runA.id,
|
|
615
|
-
expectedRevision: runA.revision,
|
|
616
|
-
ownerId: "priority-owner-a"
|
|
617
|
-
});
|
|
618
|
-
requireOutcome(acquiredA, "applied");
|
|
619
|
-
const runningA = acquiredA.snapshot.runs.find((run) => run.id === runA.id);
|
|
620
|
-
if (!runningA)
|
|
621
|
-
throw new Error("Priority lead run disappeared after acquisition");
|
|
622
|
-
requireOutcome(await store.acceptInputAndAssignRun({ idempotencyKey: runB.id, input: inputB, run: runB }), "applied");
|
|
623
|
-
requireOutcome(await store.acceptInputAndAssignRun({ idempotencyKey: runC.id, input: inputC, run: runC }), "applied");
|
|
624
|
-
const active = await store.listActiveRuns(conversationId);
|
|
625
|
-
if (active.map((run) => run.id).join(",") !== `${runA.id},${runC.id},${runB.id}`) {
|
|
626
|
-
throw new Error("Active runs did not place urgent work before ordinary pending work");
|
|
627
|
-
}
|
|
628
|
-
requireOutcome(await store.acquireRun({
|
|
629
|
-
conversationId,
|
|
630
|
-
runId: runB.id,
|
|
631
|
-
expectedRevision: runB.revision,
|
|
632
|
-
ownerId: "priority-owner-b"
|
|
633
|
-
}), "conflict");
|
|
634
|
-
const abandonedA = await store.recoverRun({
|
|
635
|
-
conversationId,
|
|
636
|
-
runId: runA.id,
|
|
637
|
-
expectedRevision: runningA.revision,
|
|
638
|
-
action: "abandon"
|
|
639
|
-
});
|
|
640
|
-
requireOutcome(abandonedA, "applied");
|
|
641
|
-
const queuedC = abandonedA.snapshot.runs.find((run) => run.id === runC.id);
|
|
642
|
-
if (!queuedC)
|
|
643
|
-
throw new Error("Urgent run disappeared after predecessor settlement");
|
|
644
|
-
const acquiredC = await store.acquireRun({
|
|
645
|
-
conversationId,
|
|
646
|
-
runId: runC.id,
|
|
647
|
-
expectedRevision: queuedC.revision,
|
|
648
|
-
ownerId: "priority-owner-c"
|
|
649
|
-
});
|
|
650
|
-
requireOutcome(acquiredC, "applied");
|
|
651
|
-
const runningC = acquiredC.snapshot.runs.find((run) => run.id === runC.id);
|
|
652
|
-
if (!runningC)
|
|
653
|
-
throw new Error("Urgent run disappeared after acquisition");
|
|
654
|
-
requireOutcome(await store.acquireRun({
|
|
655
|
-
conversationId,
|
|
656
|
-
runId: runB.id,
|
|
657
|
-
expectedRevision: runB.revision,
|
|
658
|
-
ownerId: "priority-owner-b"
|
|
659
|
-
}), "conflict");
|
|
660
|
-
const abandonedC = await store.recoverRun({
|
|
661
|
-
conversationId,
|
|
662
|
-
runId: runC.id,
|
|
663
|
-
expectedRevision: runningC.revision,
|
|
664
|
-
action: "abandon"
|
|
665
|
-
});
|
|
666
|
-
requireOutcome(abandonedC, "applied");
|
|
667
|
-
const queuedB = abandonedC.snapshot.runs.find((run) => run.id === runB.id);
|
|
668
|
-
if (!queuedB)
|
|
669
|
-
throw new Error("Ordinary run disappeared after urgent settlement");
|
|
670
|
-
const acquiredB = await store.acquireRun({
|
|
671
|
-
conversationId,
|
|
672
|
-
runId: runB.id,
|
|
673
|
-
expectedRevision: queuedB.revision,
|
|
674
|
-
ownerId: "priority-owner-b"
|
|
675
|
-
});
|
|
676
|
-
requireOutcome(acquiredB, "applied");
|
|
677
|
-
const ordered = acquiredB.snapshot.runs.map((run) => run.id).join(",");
|
|
678
|
-
if (ordered !== `${runA.id},${runC.id},${runB.id}`) {
|
|
679
|
-
throw new Error(`Durable execution order was not preserved: ${ordered}`);
|
|
680
|
-
}
|
|
681
|
-
const [sequenceA, sequenceC, sequenceB] = acquiredB.snapshot.runs.map((run) => run.executionSequence);
|
|
682
|
-
if (sequenceA === undefined || sequenceC === undefined || sequenceB === undefined || !(sequenceA < sequenceC && sequenceC < sequenceB)) {
|
|
683
|
-
throw new Error("Acquisition did not persist increasing execution sequence values");
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
async function assertActiveRunCausalOrder(store, conversationId) {
|
|
687
|
-
for (const id of ["z-causal-run", "a-causal-run"]) {
|
|
688
|
-
const input = userMessage(conversationId, `${id}-input`);
|
|
689
|
-
requireOutcome(await store.acceptInputAndAssignRun({
|
|
690
|
-
idempotencyKey: id,
|
|
691
|
-
input,
|
|
692
|
-
run: queuedRun(conversationId, input.id, id)
|
|
693
|
-
}), "applied");
|
|
694
|
-
}
|
|
695
|
-
const active = await store.listActiveRuns(conversationId);
|
|
696
|
-
if (active.map((run) => run.id).join(",") !== "z-causal-run,a-causal-run") {
|
|
697
|
-
throw new Error("listActiveRuns must preserve causal history order for timestamp ties");
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
async function assertCausalHistoryOrder(store, conversationId) {
|
|
701
|
-
const leadInput = userMessage(conversationId, "causal-input-1");
|
|
702
|
-
const leadRun = queuedRun(conversationId, leadInput.id, "causal-run-1");
|
|
703
|
-
requireOutcome(await store.acceptInputAndAssignRun({
|
|
704
|
-
idempotencyKey: "causal-request-1",
|
|
705
|
-
input: leadInput,
|
|
706
|
-
run: leadRun
|
|
707
|
-
}), "applied");
|
|
708
|
-
const acquired = await store.acquireRun({
|
|
709
|
-
conversationId,
|
|
710
|
-
runId: leadRun.id,
|
|
711
|
-
expectedRevision: leadRun.revision,
|
|
712
|
-
ownerId: "causal-owner"
|
|
713
|
-
});
|
|
714
|
-
requireOutcome(acquired, "applied");
|
|
715
|
-
const running = acquired.snapshot.runs.find((run) => run.id === leadRun.id);
|
|
716
|
-
if (!running)
|
|
717
|
-
throw new Error("Causal-order run disappeared after acquisition");
|
|
718
|
-
const successorInput = userMessage(conversationId, "causal-input-2");
|
|
719
|
-
const successorRun = queuedRun(conversationId, successorInput.id, "causal-run-2");
|
|
720
|
-
requireOutcome(await store.acceptInputAndAssignRun({
|
|
721
|
-
idempotencyKey: "causal-request-2",
|
|
722
|
-
input: successorInput,
|
|
723
|
-
run: successorRun
|
|
724
|
-
}), "applied");
|
|
725
|
-
const assistant = AgentMessageSchema.parse({
|
|
726
|
-
schemaVersion: 1,
|
|
727
|
-
id: running.assistantMessageId,
|
|
728
|
-
conversationId,
|
|
729
|
-
runId: running.id,
|
|
730
|
-
role: "assistant",
|
|
731
|
-
status: "streaming",
|
|
732
|
-
parts: [{ type: "text", text: "causal answer" }],
|
|
733
|
-
createdAt: "2026-08-28T00:00:00.000Z",
|
|
734
|
-
updatedAt: "2026-08-28T00:00:01.000Z"
|
|
735
|
-
});
|
|
736
|
-
const checkpoint = await store.checkpointRunAssistant({
|
|
737
|
-
conversationId,
|
|
738
|
-
runId: running.id,
|
|
739
|
-
expectedRevision: running.revision,
|
|
740
|
-
ownerId: "causal-owner",
|
|
741
|
-
...running.fencingToken !== undefined && { fencingToken: running.fencingToken },
|
|
742
|
-
assistant
|
|
743
|
-
});
|
|
744
|
-
requireOutcome(checkpoint, "applied");
|
|
745
|
-
const order = checkpoint.snapshot.messages.map((message) => message.id).join(",");
|
|
746
|
-
if (order !== `${leadInput.id},${assistant.id},${successorInput.id}`) {
|
|
747
|
-
throw new Error(`Agent history is not in causal run order: ${order}`);
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
async function assertAbsorptionIsAtomic(store, conversationId) {
|
|
751
|
-
const leadInput = userMessage(conversationId, "absorb-input-1");
|
|
752
|
-
const leadRun = queuedRun(conversationId, leadInput.id, "absorb-run-1");
|
|
753
|
-
const lead = await store.acceptInputAndAssignRun({
|
|
754
|
-
idempotencyKey: "absorb-request-1",
|
|
755
|
-
input: leadInput,
|
|
756
|
-
run: leadRun
|
|
757
|
-
});
|
|
758
|
-
requireOutcome(lead, "applied");
|
|
759
|
-
const successorInput = userMessage(conversationId, "absorb-input-2");
|
|
760
|
-
const successorRun = queuedRun(conversationId, successorInput.id, "absorb-run-2");
|
|
761
|
-
const successor = await store.acceptInputAndAssignRun({
|
|
762
|
-
idempotencyKey: "absorb-request-2",
|
|
763
|
-
input: successorInput,
|
|
764
|
-
run: successorRun
|
|
765
|
-
});
|
|
766
|
-
requireOutcome(successor, "applied");
|
|
767
|
-
const acquired = await store.acquireRun({
|
|
768
|
-
conversationId,
|
|
769
|
-
runId: leadRun.id,
|
|
770
|
-
expectedRevision: 0,
|
|
771
|
-
ownerId: "absorb-owner"
|
|
772
|
-
});
|
|
773
|
-
requireOutcome(acquired, "applied");
|
|
774
|
-
const running = acquired.snapshot.runs.find((run) => run.id === leadRun.id);
|
|
775
|
-
if (!running)
|
|
776
|
-
throw new Error("Absorbing run disappeared after acquisition");
|
|
777
|
-
const answer = AgentMessageSchema.parse({
|
|
778
|
-
schemaVersion: 1,
|
|
779
|
-
id: running.assistantMessageId,
|
|
780
|
-
conversationId,
|
|
781
|
-
runId: running.id,
|
|
782
|
-
role: "assistant",
|
|
783
|
-
status: "completed",
|
|
784
|
-
parts: [{ type: "text", text: "answered both" }],
|
|
785
|
-
createdAt: "2026-08-26T00:00:00.000Z",
|
|
786
|
-
updatedAt: "2026-08-26T00:00:02.000Z"
|
|
787
|
-
});
|
|
788
|
-
await store.commitRunTerminal({
|
|
789
|
-
conversationId,
|
|
790
|
-
runId: running.id,
|
|
791
|
-
expectedRevision: running.revision,
|
|
792
|
-
ownerId: "absorb-owner",
|
|
793
|
-
assistant: AgentMessageSchema.parse({ ...answer, status: "interrupted" }),
|
|
794
|
-
reason: "interrupted",
|
|
795
|
-
absorb: [{ runId: successorRun.id, inputMessageIds: [successorInput.id] }]
|
|
796
|
-
}).then(() => {
|
|
797
|
-
throw new Error("A non-completing run absorbed a queued successor");
|
|
798
|
-
}, (error) => {
|
|
799
|
-
if (!(error instanceof TypeError))
|
|
800
|
-
throw error;
|
|
801
|
-
});
|
|
802
|
-
const committed = await store.commitRunTerminal({
|
|
803
|
-
conversationId,
|
|
804
|
-
runId: running.id,
|
|
805
|
-
expectedRevision: running.revision,
|
|
806
|
-
ownerId: "absorb-owner",
|
|
807
|
-
assistant: answer,
|
|
808
|
-
reason: "success",
|
|
809
|
-
absorb: [{ runId: successorRun.id, inputMessageIds: [successorInput.id] }]
|
|
810
|
-
});
|
|
811
|
-
requireOutcome(committed, "applied");
|
|
812
|
-
const absorbingView = await store.loadRun({ conversationId, runId: leadRun.id });
|
|
813
|
-
if (absorbingView?.run.inputMessageIds.join(",") !== "absorb-input-1,absorb-input-2") {
|
|
814
|
-
throw new Error("An absorbing run must record the inputs it answered");
|
|
815
|
-
}
|
|
816
|
-
const absorbedView = await store.loadRun({ conversationId, runId: successorRun.id });
|
|
817
|
-
if (absorbedView?.run.terminalReason !== "absorbed") {
|
|
818
|
-
throw new Error("An absorbed successor must be terminal in the same transaction");
|
|
819
|
-
}
|
|
820
|
-
if (absorbedView.run.absorbedIntoRunId !== leadRun.id) {
|
|
821
|
-
throw new Error("An absorbed run must name the run that answered its input");
|
|
822
|
-
}
|
|
823
|
-
if (absorbedView.assistant !== undefined) {
|
|
824
|
-
throw new Error("An absorbed run produced no answer and must retain none");
|
|
825
|
-
}
|
|
826
|
-
if ((await store.listActiveRuns(conversationId)).length !== 0) {
|
|
827
|
-
throw new Error("An absorbed successor must leave the active listing");
|
|
828
|
-
}
|
|
829
|
-
const retried = await store.acceptInputAndAssignRun({
|
|
830
|
-
idempotencyKey: "absorb-request-2",
|
|
831
|
-
input: userMessage(conversationId, "absorb-discarded"),
|
|
832
|
-
run: queuedRun(conversationId, "absorb-discarded", "absorb-discarded-run")
|
|
833
|
-
});
|
|
834
|
-
requireOutcome(retried, "duplicate");
|
|
835
|
-
if (retried.runId !== leadRun.id || retried.assistant?.id !== answer.id) {
|
|
836
|
-
throw new Error("A retried absorbed key must resolve to the run that answered it");
|
|
837
|
-
}
|
|
838
|
-
if (retried.inputMessageId !== successorInput.id) {
|
|
839
|
-
throw new Error("A retried absorbed key must still name its own input");
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
async function ledgerScenario(store, conversationId) {
|
|
843
|
-
const first = await store.appendEvent({
|
|
844
|
-
conversationId,
|
|
845
|
-
kind: "state/set",
|
|
846
|
-
payload: { n: 1 }
|
|
847
|
-
});
|
|
848
|
-
if (first.seq !== 1)
|
|
849
|
-
throw new Error(`Agent store conformance expected seq 1, received ${first.seq}`);
|
|
850
|
-
const appended = await Promise.all(Array.from({ length: 20 }, (_, index) => store.appendEvent({ conversationId, kind: "state/set", payload: { n: index + 2 } })));
|
|
851
|
-
const seqs = [first.seq, ...appended.map((event) => event.seq)].sort((a, b) => a - b);
|
|
852
|
-
for (let index = 0;index < seqs.length; index += 1) {
|
|
853
|
-
if (seqs[index] !== index + 1) {
|
|
854
|
-
throw new Error(`Agent store conformance expected contiguous seq, received ${seqs.join(",")}`);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
const page = await store.readEvents({ conversationId, fromSeq: 5, toSeq: 9, limit: 3 });
|
|
858
|
-
if (page.items.map((event) => event.seq).join(",") !== "5,6,7" || page.nextSeq !== 8) {
|
|
859
|
-
throw new Error(`Agent store conformance expected events 5,6,7 then 8, received ${page.items.map((event) => event.seq).join(",")} then ${page.nextSeq}`);
|
|
860
|
-
}
|
|
861
|
-
const ignorable = await store.appendEvent({
|
|
862
|
-
conversationId,
|
|
863
|
-
kind: "state/set",
|
|
864
|
-
payload: { n: "ignorable" },
|
|
865
|
-
ignorable: true
|
|
866
|
-
});
|
|
867
|
-
if (ignorable.ignorable !== true) {
|
|
868
|
-
throw new Error("Agent store conformance expected the ignorable flag to persist");
|
|
869
|
-
}
|
|
870
|
-
const archive = await store.exportConversation(conversationId);
|
|
871
|
-
const again = await store.exportConversation(conversationId);
|
|
872
|
-
if (Buffer.compare(Buffer.from(archive), Buffer.from(again)) !== 0) {
|
|
873
|
-
throw new Error("Agent store conformance expected two exports of a quiet store to be byte-equal");
|
|
874
|
-
}
|
|
875
|
-
const decoded = decodeAgentConversationArchive(archive);
|
|
876
|
-
if (decoded.events.length !== 22) {
|
|
877
|
-
throw new Error(`Agent store conformance expected 22 archived events, received ${decoded.events.length}`);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
async function archiveScenario(store, conversationId) {
|
|
881
|
-
const origin = createMemoryAgentRuntimeStore();
|
|
882
|
-
const inputMessage = userMessage(conversationId, "archived-input");
|
|
883
|
-
const run = queuedRun(conversationId, inputMessage.id, "archived-run");
|
|
884
|
-
requireOutcome(await origin.acceptInputAndAssignRun({
|
|
885
|
-
idempotencyKey: "archived-request",
|
|
886
|
-
input: inputMessage,
|
|
887
|
-
run
|
|
888
|
-
}), "applied");
|
|
889
|
-
await origin.appendEvent({
|
|
890
|
-
conversationId,
|
|
891
|
-
kind: "state/set",
|
|
892
|
-
payload: { name: "topic", value: "archive" }
|
|
893
|
-
});
|
|
894
|
-
const imported = await store.importConversation(await origin.exportConversation(conversationId));
|
|
895
|
-
if (imported.conversationId !== conversationId || imported.events !== 2) {
|
|
896
|
-
throw new Error(`Agent store conformance expected 2 imported events for ${conversationId}, received ${imported.events} for ${imported.conversationId}`);
|
|
897
|
-
}
|
|
898
|
-
const restored = await store.loadSnapshot(conversationId);
|
|
899
|
-
const expected = await origin.loadSnapshot(conversationId);
|
|
900
|
-
if (restored.version !== expected.version || restored.messages.map((message) => message.id).join(",") !== expected.messages.map((message) => message.id).join(",") || restored.runs.map((entry) => `${entry.id}:${entry.state}`).join(",") !== expected.runs.map((entry) => `${entry.id}:${entry.state}`).join(",")) {
|
|
901
|
-
throw new Error(`Agent store conformance expected the imported snapshot to match its archive, received version ${restored.version} with ${restored.messages.length} messages and ${restored.runs.length} runs`);
|
|
902
|
-
}
|
|
903
|
-
const events = await store.readEvents({ conversationId, limit: 10 });
|
|
904
|
-
if (events.items.map((event) => event.kind).join(",") !== "runtime/transition,state/set") {
|
|
905
|
-
throw new Error(`Agent store conformance expected the imported ledger to keep its kinds, received ${events.items.map((event) => event.kind).join(",")}`);
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
// src/testing/managed-resource-conformance-contract.ts
|
|
909
|
-
import { z } from "zod";
|
|
910
|
-
var ManagedResourceConformanceScenarioIdSchema = z.enum([
|
|
911
|
-
"clean-shutdown",
|
|
912
|
-
"partial-start-rollback",
|
|
913
|
-
"readiness-rejection",
|
|
914
|
-
"completion-before-ready",
|
|
915
|
-
"required-late-completion",
|
|
916
|
-
"optional-late-completion",
|
|
917
|
-
"activation-rejection",
|
|
918
|
-
"shutdown-during-startup",
|
|
919
|
-
"force-after-stalled-close"
|
|
920
|
-
]);
|
|
921
|
-
var ManagedResourceConformanceScenarioSchema = z.discriminatedUnion("id", [
|
|
922
|
-
z.object({ id: z.literal("clean-shutdown"), required: z.literal(true) }).readonly(),
|
|
923
|
-
z.object({ id: z.literal("partial-start-rollback"), required: z.literal(true) }).readonly(),
|
|
924
|
-
z.object({ id: z.literal("readiness-rejection"), required: z.literal(true) }).readonly(),
|
|
925
|
-
z.object({ id: z.literal("completion-before-ready"), required: z.literal(true) }).readonly(),
|
|
926
|
-
z.object({ id: z.literal("required-late-completion"), required: z.literal(true) }).readonly(),
|
|
927
|
-
z.object({ id: z.literal("optional-late-completion"), required: z.literal(false) }).readonly(),
|
|
928
|
-
z.object({ id: z.literal("activation-rejection"), required: z.literal(true) }).readonly(),
|
|
929
|
-
z.object({ id: z.literal("shutdown-during-startup"), required: z.literal(true) }).readonly(),
|
|
930
|
-
z.object({ id: z.literal("force-after-stalled-close"), required: z.literal(true) }).readonly()
|
|
931
|
-
]);
|
|
932
|
-
var ManagedResourceConformancePhaseSchema = z.enum([
|
|
933
|
-
"start",
|
|
934
|
-
"readiness",
|
|
935
|
-
"completion",
|
|
936
|
-
"activate",
|
|
937
|
-
"stop-admission",
|
|
938
|
-
"drain",
|
|
939
|
-
"close",
|
|
940
|
-
"force",
|
|
941
|
-
"dispose"
|
|
942
|
-
]);
|
|
943
|
-
var ManagedResourceConformanceTraceOutcomeSchema = z.enum([
|
|
944
|
-
"enter",
|
|
945
|
-
"resolve",
|
|
946
|
-
"reject"
|
|
947
|
-
]);
|
|
948
|
-
var ManagedResourceConformanceTraceEntrySchema = z.object({
|
|
949
|
-
sequence: z.number().int().nonnegative(),
|
|
950
|
-
phase: ManagedResourceConformancePhaseSchema,
|
|
951
|
-
outcome: ManagedResourceConformanceTraceOutcomeSchema
|
|
952
|
-
}).strict().readonly();
|
|
953
|
-
|
|
954
|
-
class ManagedResourceConformanceError extends Error {
|
|
955
|
-
scenarioId;
|
|
956
|
-
expected;
|
|
957
|
-
trace;
|
|
958
|
-
code = "MANAGED_RESOURCE_CONFORMANCE_FAILED";
|
|
959
|
-
constructor(scenarioId, expected, trace, detail) {
|
|
960
|
-
const observed = trace.length === 0 ? "(empty)" : trace.map((entry) => `${entry.phase}:${entry.outcome}`).join(" -> ");
|
|
961
|
-
super(`[stitchkit] managed resource conformance "${scenarioId}" failed: ${detail}; ` + `expected ${expected.join(" -> ")}; observed ${observed}`);
|
|
962
|
-
this.scenarioId = scenarioId;
|
|
963
|
-
this.expected = expected;
|
|
964
|
-
this.trace = trace;
|
|
965
|
-
this.name = "ManagedResourceConformanceError";
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
// src/testing/managed-resource-conformance-driver.ts
|
|
970
|
-
function controlledPromise() {
|
|
971
|
-
const deferred = Promise.withResolvers();
|
|
972
|
-
let settled = false;
|
|
973
|
-
deferred.promise.catch(() => {
|
|
974
|
-
return;
|
|
975
|
-
});
|
|
976
|
-
return {
|
|
977
|
-
promise: deferred.promise,
|
|
978
|
-
resolve() {
|
|
979
|
-
if (settled)
|
|
980
|
-
return false;
|
|
981
|
-
settled = true;
|
|
982
|
-
deferred.resolve();
|
|
983
|
-
return true;
|
|
984
|
-
},
|
|
985
|
-
reject(error) {
|
|
986
|
-
if (settled)
|
|
987
|
-
return false;
|
|
988
|
-
settled = true;
|
|
989
|
-
deferred.reject(error);
|
|
990
|
-
return true;
|
|
991
|
-
}
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
class ManagedResourceConformanceTrace {
|
|
996
|
-
entries = [];
|
|
997
|
-
waiters = new Set;
|
|
998
|
-
record(phase, outcome) {
|
|
999
|
-
const entry = ManagedResourceConformanceTraceEntrySchema.parse({
|
|
1000
|
-
sequence: this.entries.length,
|
|
1001
|
-
phase,
|
|
1002
|
-
outcome
|
|
1003
|
-
});
|
|
1004
|
-
this.entries.push(entry);
|
|
1005
|
-
for (const waiter of this.waiters) {
|
|
1006
|
-
if (waiter.phase !== phase || waiter.outcome !== outcome)
|
|
1007
|
-
continue;
|
|
1008
|
-
this.waiters.delete(waiter);
|
|
1009
|
-
waiter.resolve();
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
has(phase, outcome) {
|
|
1013
|
-
return this.entries.some((entry) => entry.phase === phase && entry.outcome === outcome);
|
|
1014
|
-
}
|
|
1015
|
-
count(phase, outcome) {
|
|
1016
|
-
return this.entries.filter((entry) => entry.phase === phase && entry.outcome === outcome).length;
|
|
1017
|
-
}
|
|
1018
|
-
waitFor(phase, outcome = "enter") {
|
|
1019
|
-
if (this.has(phase, outcome))
|
|
1020
|
-
return Promise.resolve();
|
|
1021
|
-
return new Promise((resolve) => this.waiters.add({ phase, outcome, resolve }));
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
function createManagedResourceConformanceGates(trace) {
|
|
1025
|
-
const startup = controlledPromise();
|
|
1026
|
-
const readiness = controlledPromise();
|
|
1027
|
-
const completion = controlledPromise();
|
|
1028
|
-
const activation = controlledPromise();
|
|
1029
|
-
const close = controlledPromise();
|
|
1030
|
-
const force = controlledPromise();
|
|
1031
|
-
const gateFor = (phase) => {
|
|
1032
|
-
if (phase === "start")
|
|
1033
|
-
return startup;
|
|
1034
|
-
if (phase === "readiness")
|
|
1035
|
-
return readiness;
|
|
1036
|
-
if (phase === "completion")
|
|
1037
|
-
return completion;
|
|
1038
|
-
if (phase === "activate")
|
|
1039
|
-
return activation;
|
|
1040
|
-
if (phase === "close")
|
|
1041
|
-
return close;
|
|
1042
|
-
return force;
|
|
1043
|
-
};
|
|
1044
|
-
const resolve = (phase) => {
|
|
1045
|
-
if (gateFor(phase).resolve())
|
|
1046
|
-
trace.record(phase, "resolve");
|
|
1047
|
-
};
|
|
1048
|
-
return {
|
|
1049
|
-
controls: {
|
|
1050
|
-
startup: startup.promise,
|
|
1051
|
-
readiness: readiness.promise,
|
|
1052
|
-
completion: completion.promise,
|
|
1053
|
-
activation: activation.promise,
|
|
1054
|
-
close: close.promise,
|
|
1055
|
-
force: force.promise
|
|
1056
|
-
},
|
|
1057
|
-
resolve,
|
|
1058
|
-
reject(phase, error) {
|
|
1059
|
-
if (gateFor(phase).reject(error))
|
|
1060
|
-
trace.record(phase, "reject");
|
|
1061
|
-
},
|
|
1062
|
-
releaseAll() {
|
|
1063
|
-
resolve("start");
|
|
1064
|
-
resolve("readiness");
|
|
1065
|
-
resolve("completion");
|
|
1066
|
-
resolve("activate");
|
|
1067
|
-
resolve("close");
|
|
1068
|
-
resolve("force");
|
|
1069
|
-
}
|
|
1070
|
-
};
|
|
1071
|
-
}
|
|
1072
|
-
async function observePhase(trace, phase, invoke) {
|
|
1073
|
-
trace.record(phase, "enter");
|
|
1074
|
-
try {
|
|
1075
|
-
const value = await invoke();
|
|
1076
|
-
trace.record(phase, "resolve");
|
|
1077
|
-
return value;
|
|
1078
|
-
} catch (error) {
|
|
1079
|
-
trace.record(phase, "reject");
|
|
1080
|
-
throw error;
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
function optionalPhase(resource, trace, phase, invoke) {
|
|
1084
|
-
if (!invoke)
|
|
1085
|
-
return {};
|
|
1086
|
-
return {
|
|
1087
|
-
[phase]: (context) => observePhase(trace, phase, () => invoke.call(resource, context))
|
|
1088
|
-
};
|
|
1089
|
-
}
|
|
1090
|
-
function observeManagedResource(resource, required, trace) {
|
|
1091
|
-
const start = async (context) => {
|
|
1092
|
-
trace.record("start", "enter");
|
|
1093
|
-
try {
|
|
1094
|
-
const value = await resource.start(context);
|
|
1095
|
-
trace.record("start", "resolve");
|
|
1096
|
-
if (value === undefined)
|
|
1097
|
-
return;
|
|
1098
|
-
return value;
|
|
1099
|
-
} catch (error) {
|
|
1100
|
-
trace.record("start", "reject");
|
|
1101
|
-
throw error;
|
|
1102
|
-
}
|
|
1103
|
-
};
|
|
1104
|
-
return {
|
|
1105
|
-
id: resource.id,
|
|
1106
|
-
required,
|
|
1107
|
-
start,
|
|
1108
|
-
...optionalPhase(resource, trace, "activate", resource.activate),
|
|
1109
|
-
...resource.stopAdmission ? {
|
|
1110
|
-
stopAdmission: (context) => observePhase(trace, "stop-admission", () => resource.stopAdmission?.call(resource, context))
|
|
1111
|
-
} : {},
|
|
1112
|
-
...optionalPhase(resource, trace, "drain", resource.drain),
|
|
1113
|
-
...optionalPhase(resource, trace, "close", resource.close),
|
|
1114
|
-
...optionalPhase(resource, trace, "force", resource.force)
|
|
1115
|
-
};
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
// src/testing/managed-resource-conformance-scenarios.ts
|
|
1119
|
-
var MANAGED_RESOURCE_CONFORMANCE_SCENARIOS = ManagedResourceConformanceScenarioSchema.array().parse([
|
|
1120
|
-
{ id: "clean-shutdown", required: true },
|
|
1121
|
-
{ id: "partial-start-rollback", required: true },
|
|
1122
|
-
{ id: "readiness-rejection", required: true },
|
|
1123
|
-
{ id: "completion-before-ready", required: true },
|
|
1124
|
-
{ id: "required-late-completion", required: true },
|
|
1125
|
-
{ id: "optional-late-completion", required: false },
|
|
1126
|
-
{ id: "activation-rejection", required: true },
|
|
1127
|
-
{ id: "shutdown-during-startup", required: true },
|
|
1128
|
-
{ id: "force-after-stalled-close", required: true }
|
|
1129
|
-
]);
|
|
1130
|
-
var EXPECTED_TRACE = {
|
|
1131
|
-
"clean-shutdown": [
|
|
1132
|
-
"start:enter",
|
|
1133
|
-
"start:resolve",
|
|
1134
|
-
"readiness:resolve",
|
|
1135
|
-
"activate:enter",
|
|
1136
|
-
"activate:resolve",
|
|
1137
|
-
"stop-admission:enter",
|
|
1138
|
-
"drain:enter",
|
|
1139
|
-
"close:enter",
|
|
1140
|
-
"close:resolve"
|
|
1141
|
-
],
|
|
1142
|
-
"partial-start-rollback": ["start:enter", "start:reject", "close:enter", "close:resolve"],
|
|
1143
|
-
"readiness-rejection": [
|
|
1144
|
-
"start:enter",
|
|
1145
|
-
"start:resolve",
|
|
1146
|
-
"readiness:reject",
|
|
1147
|
-
"close:enter",
|
|
1148
|
-
"close:resolve"
|
|
1149
|
-
],
|
|
1150
|
-
"completion-before-ready": [
|
|
1151
|
-
"start:enter",
|
|
1152
|
-
"start:resolve",
|
|
1153
|
-
"completion:reject",
|
|
1154
|
-
"close:enter",
|
|
1155
|
-
"close:resolve"
|
|
1156
|
-
],
|
|
1157
|
-
"required-late-completion": [
|
|
1158
|
-
"activate:resolve",
|
|
1159
|
-
"completion:reject",
|
|
1160
|
-
"stop-admission:enter",
|
|
1161
|
-
"drain:enter",
|
|
1162
|
-
"close:enter"
|
|
1163
|
-
],
|
|
1164
|
-
"optional-late-completion": [
|
|
1165
|
-
"activate:resolve",
|
|
1166
|
-
"completion:reject",
|
|
1167
|
-
"stop-admission:enter",
|
|
1168
|
-
"drain:enter",
|
|
1169
|
-
"close:enter"
|
|
1170
|
-
],
|
|
1171
|
-
"activation-rejection": [
|
|
1172
|
-
"readiness:resolve",
|
|
1173
|
-
"activate:enter",
|
|
1174
|
-
"activate:reject",
|
|
1175
|
-
"close:enter",
|
|
1176
|
-
"close:resolve"
|
|
1177
|
-
],
|
|
1178
|
-
"shutdown-during-startup": ["start:enter", "start:resolve", "close:enter", "close:resolve"],
|
|
1179
|
-
"force-after-stalled-close": [
|
|
1180
|
-
"stop-admission:enter",
|
|
1181
|
-
"drain:enter",
|
|
1182
|
-
"close:enter",
|
|
1183
|
-
"force:enter",
|
|
1184
|
-
"force:resolve"
|
|
1185
|
-
]
|
|
1186
|
-
};
|
|
1187
|
-
function outcomeOf(promise) {
|
|
1188
|
-
return promise.then(() => ({ status: "resolved" }), (error) => ({ status: "rejected", error }));
|
|
1189
|
-
}
|
|
1190
|
-
function requireCondition(condition, detail) {
|
|
1191
|
-
if (!condition)
|
|
1192
|
-
throw new Error(detail);
|
|
1193
|
-
}
|
|
1194
|
-
function observedTrace(trace) {
|
|
1195
|
-
return trace.entries.map((entry) => `${entry.phase}:${entry.outcome}`);
|
|
1196
|
-
}
|
|
1197
|
-
function requireTrace(runtime) {
|
|
1198
|
-
const expected = EXPECTED_TRACE[runtime.scenario.id];
|
|
1199
|
-
const observed = observedTrace(runtime.trace);
|
|
1200
|
-
let cursor = 0;
|
|
1201
|
-
for (const entry of observed) {
|
|
1202
|
-
if (entry === expected[cursor])
|
|
1203
|
-
cursor += 1;
|
|
1204
|
-
}
|
|
1205
|
-
requireCondition(cursor === expected.length, `phase trace omitted or reordered "${expected[cursor] ?? "unknown"}"`);
|
|
1206
|
-
}
|
|
1207
|
-
async function phaseOrSettlement(trace, phase, settlement) {
|
|
1208
|
-
return Promise.race([
|
|
1209
|
-
trace.waitFor(phase).then(() => "phase"),
|
|
1210
|
-
settlement.then(() => "settled", () => "settled")
|
|
1211
|
-
]);
|
|
1212
|
-
}
|
|
1213
|
-
async function startSuccessfully(runtime) {
|
|
1214
|
-
const starting = runtime.application.start();
|
|
1215
|
-
const startOutcome = outcomeOf(starting);
|
|
1216
|
-
await runtime.trace.waitFor("start");
|
|
1217
|
-
runtime.gates.resolve("start");
|
|
1218
|
-
runtime.gates.resolve("readiness");
|
|
1219
|
-
const activation = await Promise.race([
|
|
1220
|
-
runtime.trace.waitFor("activate").then(() => ({ status: "resolved" })),
|
|
1221
|
-
startOutcome
|
|
1222
|
-
]);
|
|
1223
|
-
if (activation.status === "rejected")
|
|
1224
|
-
throw activation.error;
|
|
1225
|
-
runtime.gates.resolve("activate");
|
|
1226
|
-
const outcome = await startOutcome;
|
|
1227
|
-
requireCondition(outcome.status === "resolved", "application did not complete successful startup");
|
|
1228
|
-
}
|
|
1229
|
-
async function closeNormally(runtime) {
|
|
1230
|
-
const shuttingDown = runtime.application.shutdown();
|
|
1231
|
-
const close = await phaseOrSettlement(runtime.trace, "close", shuttingDown);
|
|
1232
|
-
if (close === "phase")
|
|
1233
|
-
runtime.gates.resolve("close");
|
|
1234
|
-
const outcome = await outcomeOf(shuttingDown);
|
|
1235
|
-
requireCondition(outcome.status === "resolved", "application shutdown rejected");
|
|
1236
|
-
}
|
|
1237
|
-
async function expectStartupFailure(runtime, starting) {
|
|
1238
|
-
const close = await phaseOrSettlement(runtime.trace, "close", starting);
|
|
1239
|
-
if (close === "phase")
|
|
1240
|
-
runtime.gates.resolve("close");
|
|
1241
|
-
const outcome = await outcomeOf(starting);
|
|
1242
|
-
if (outcome.status === "resolved") {
|
|
1243
|
-
await closeNormally(runtime);
|
|
1244
|
-
throw new Error("application startup unexpectedly resolved");
|
|
1245
|
-
}
|
|
1246
|
-
requireCondition(runtime.trace.count("close", "enter") === 1, "attempted resource was not closed once");
|
|
1247
|
-
await runtime.application.shutdown();
|
|
1248
|
-
}
|
|
1249
|
-
function waitForSnapshot(application, predicate) {
|
|
1250
|
-
const deferred = Promise.withResolvers();
|
|
1251
|
-
let unsubscribe = () => {
|
|
1252
|
-
return;
|
|
1253
|
-
};
|
|
1254
|
-
unsubscribe = application.subscribe((snapshot) => {
|
|
1255
|
-
if (!predicate(snapshot))
|
|
1256
|
-
return;
|
|
1257
|
-
unsubscribe();
|
|
1258
|
-
deferred.resolve(snapshot);
|
|
1259
|
-
});
|
|
1260
|
-
return deferred.promise;
|
|
1261
|
-
}
|
|
1262
|
-
async function cleanShutdown(runtime) {
|
|
1263
|
-
await startSuccessfully(runtime);
|
|
1264
|
-
await closeNormally(runtime);
|
|
1265
|
-
requireCondition(runtime.application.getSnapshot().lifecycle === "stopped", "clean shutdown did not stop the application");
|
|
1266
|
-
}
|
|
1267
|
-
async function partialStartRollback(runtime) {
|
|
1268
|
-
const starting = runtime.application.start();
|
|
1269
|
-
await runtime.trace.waitFor("start");
|
|
1270
|
-
runtime.gates.reject("start", new Error("controlled partial startup rejection"));
|
|
1271
|
-
await expectStartupFailure(runtime, starting);
|
|
1272
|
-
}
|
|
1273
|
-
async function readinessRejection(runtime) {
|
|
1274
|
-
const starting = runtime.application.start();
|
|
1275
|
-
await runtime.trace.waitFor("start");
|
|
1276
|
-
runtime.gates.resolve("start");
|
|
1277
|
-
await runtime.trace.waitFor("start", "resolve");
|
|
1278
|
-
runtime.gates.reject("readiness", new Error("controlled readiness rejection"));
|
|
1279
|
-
runtime.gates.resolve("activate");
|
|
1280
|
-
await expectStartupFailure(runtime, starting);
|
|
1281
|
-
}
|
|
1282
|
-
async function completionBeforeReady(runtime) {
|
|
1283
|
-
const starting = runtime.application.start();
|
|
1284
|
-
await runtime.trace.waitFor("start");
|
|
1285
|
-
runtime.gates.resolve("start");
|
|
1286
|
-
await runtime.trace.waitFor("start", "resolve");
|
|
1287
|
-
runtime.gates.reject("completion", new Error("controlled early completion rejection"));
|
|
1288
|
-
runtime.gates.resolve("readiness");
|
|
1289
|
-
runtime.gates.resolve("activate");
|
|
1290
|
-
await expectStartupFailure(runtime, starting);
|
|
1291
|
-
}
|
|
1292
|
-
async function lateCompletion(runtime) {
|
|
1293
|
-
await startSuccessfully(runtime);
|
|
1294
|
-
const expectedHealth = runtime.scenario.required ? "unhealthy" : "degraded";
|
|
1295
|
-
const changed = waitForSnapshot(runtime.application, (snapshot2) => snapshot2.health === expectedHealth);
|
|
1296
|
-
runtime.gates.reject("completion", new Error("controlled late completion rejection"));
|
|
1297
|
-
const snapshot = await changed;
|
|
1298
|
-
requireCondition(snapshot.lifecycle === "ready", "late completion changed lifecycle ownership");
|
|
1299
|
-
requireCondition(snapshot.health === expectedHealth, "late completion projected the wrong health");
|
|
1300
|
-
requireCondition(snapshot.ready === !runtime.scenario.required, "late completion projected the wrong readiness");
|
|
1301
|
-
requireCondition(snapshot.admission.accepting === !runtime.scenario.required, "late completion projected the wrong admission state");
|
|
1302
|
-
await closeNormally(runtime);
|
|
1303
|
-
}
|
|
1304
|
-
async function activationRejection(runtime) {
|
|
1305
|
-
const starting = runtime.application.start();
|
|
1306
|
-
await runtime.trace.waitFor("start");
|
|
1307
|
-
runtime.gates.resolve("start");
|
|
1308
|
-
await runtime.trace.waitFor("start", "resolve");
|
|
1309
|
-
runtime.gates.resolve("readiness");
|
|
1310
|
-
await runtime.trace.waitFor("activate");
|
|
1311
|
-
runtime.gates.reject("activate", new Error("controlled activation rejection"));
|
|
1312
|
-
await expectStartupFailure(runtime, starting);
|
|
1313
|
-
}
|
|
1314
|
-
async function shutdownDuringStartup(runtime) {
|
|
1315
|
-
const starting = runtime.application.start();
|
|
1316
|
-
await runtime.trace.waitFor("start");
|
|
1317
|
-
const shuttingDown = runtime.application.shutdown();
|
|
1318
|
-
runtime.gates.resolve("start");
|
|
1319
|
-
const close = await phaseOrSettlement(runtime.trace, "close", shuttingDown);
|
|
1320
|
-
if (close === "phase")
|
|
1321
|
-
runtime.gates.resolve("close");
|
|
1322
|
-
const [startOutcome, shutdownOutcome] = await Promise.all([
|
|
1323
|
-
outcomeOf(starting),
|
|
1324
|
-
outcomeOf(shuttingDown)
|
|
1325
|
-
]);
|
|
1326
|
-
requireCondition(startOutcome.status === "rejected", "startup won the shutdown race");
|
|
1327
|
-
requireCondition(shutdownOutcome.status === "resolved", "shutdown race rejected");
|
|
1328
|
-
requireCondition(!runtime.trace.has("activate", "enter"), "resource activated after shutdown won");
|
|
1329
|
-
}
|
|
1330
|
-
async function forceAfterStalledClose(runtime) {
|
|
1331
|
-
await startSuccessfully(runtime);
|
|
1332
|
-
const controller = new AbortController;
|
|
1333
|
-
const shuttingDown = runtime.application.shutdown({
|
|
1334
|
-
gracePeriodMs: 60000,
|
|
1335
|
-
forceTimeoutMs: 60000,
|
|
1336
|
-
signal: controller.signal
|
|
1337
|
-
});
|
|
1338
|
-
await runtime.trace.waitFor("close");
|
|
1339
|
-
controller.abort();
|
|
1340
|
-
const force = await phaseOrSettlement(runtime.trace, "force", shuttingDown);
|
|
1341
|
-
if (force === "phase")
|
|
1342
|
-
runtime.gates.resolve("force");
|
|
1343
|
-
const result = await shuttingDown;
|
|
1344
|
-
requireCondition(runtime.trace.count("close", "enter") === 1, "close was not invoked exactly once");
|
|
1345
|
-
requireCondition(runtime.trace.count("force", "enter") === 1, "unfinished close did not invoke force");
|
|
1346
|
-
requireCondition(result.outcome === "forced", "forced shutdown reported a clean outcome");
|
|
1347
|
-
requireCondition(result.reason === "signal", "forced shutdown lost its signal reason");
|
|
1348
|
-
runtime.gates.resolve("close");
|
|
1349
|
-
}
|
|
1350
|
-
function expectedManagedResourceConformanceTrace(scenarioId) {
|
|
1351
|
-
return EXPECTED_TRACE[scenarioId];
|
|
1352
|
-
}
|
|
1353
|
-
async function executeManagedResourceConformanceScenario(scenario, resource, gates, trace) {
|
|
1354
|
-
const application = createApplication({
|
|
1355
|
-
id: `conformance-${scenario.id}`,
|
|
1356
|
-
resources: [observeManagedResource(resource, scenario.required, trace)]
|
|
1357
|
-
});
|
|
1358
|
-
const runtime = { scenario, application, gates, trace };
|
|
1359
|
-
if (scenario.id === "clean-shutdown")
|
|
1360
|
-
await cleanShutdown(runtime);
|
|
1361
|
-
else if (scenario.id === "partial-start-rollback")
|
|
1362
|
-
await partialStartRollback(runtime);
|
|
1363
|
-
else if (scenario.id === "readiness-rejection")
|
|
1364
|
-
await readinessRejection(runtime);
|
|
1365
|
-
else if (scenario.id === "completion-before-ready")
|
|
1366
|
-
await completionBeforeReady(runtime);
|
|
1367
|
-
else if (scenario.id === "required-late-completion" || scenario.id === "optional-late-completion") {
|
|
1368
|
-
await lateCompletion(runtime);
|
|
1369
|
-
} else if (scenario.id === "activation-rejection")
|
|
1370
|
-
await activationRejection(runtime);
|
|
1371
|
-
else if (scenario.id === "shutdown-during-startup")
|
|
1372
|
-
await shutdownDuringStartup(runtime);
|
|
1373
|
-
else
|
|
1374
|
-
await forceAfterStalledClose(runtime);
|
|
1375
|
-
requireTrace(runtime);
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
|
-
// src/testing/managed-resource-conformance.ts
|
|
1379
|
-
var DEFAULT_WATCHDOG_TIMEOUT_MS = 2000;
|
|
1380
|
-
|
|
1381
|
-
class ManagedResourceConformanceWatchdogError extends Error {
|
|
1382
|
-
phase;
|
|
1383
|
-
constructor(phase) {
|
|
1384
|
-
super(`emergency watchdog expired during ${phase}`);
|
|
1385
|
-
this.phase = phase;
|
|
1386
|
-
this.name = "ManagedResourceConformanceWatchdogError";
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
async function withWatchdog(promise, timeoutMs, phase) {
|
|
1390
|
-
let timer;
|
|
1391
|
-
const watchdog = new Promise((_resolve, reject) => {
|
|
1392
|
-
timer = setTimeout(() => reject(new ManagedResourceConformanceWatchdogError(phase)), timeoutMs);
|
|
1393
|
-
});
|
|
1394
|
-
try {
|
|
1395
|
-
return await Promise.race([promise, watchdog]);
|
|
1396
|
-
} finally {
|
|
1397
|
-
if (timer !== undefined)
|
|
1398
|
-
clearTimeout(timer);
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
function detailOf(error) {
|
|
1402
|
-
if (error instanceof ManagedResourceConformanceWatchdogError)
|
|
1403
|
-
return error.message;
|
|
1404
|
-
if (error instanceof Error)
|
|
1405
|
-
return error.message;
|
|
1406
|
-
return "unknown conformance failure";
|
|
1407
|
-
}
|
|
1408
|
-
async function runScenario(config, scenario, watchdogTimeoutMs) {
|
|
1409
|
-
const trace = new ManagedResourceConformanceTrace;
|
|
1410
|
-
const gates = createManagedResourceConformanceGates(trace);
|
|
1411
|
-
const fixture = await withWatchdog(Promise.resolve().then(() => config.createFixture({ scenario, controls: gates.controls })), watchdogTimeoutMs, "factory").catch((error) => {
|
|
1412
|
-
throw new ManagedResourceConformanceError(scenario.id, expectedManagedResourceConformanceTrace(scenario.id), trace.entries, detailOf(error));
|
|
1413
|
-
});
|
|
1414
|
-
let failure;
|
|
1415
|
-
const execution = executeManagedResourceConformanceScenario(scenario, fixture.resource, gates, trace);
|
|
1416
|
-
execution.catch(() => {
|
|
1417
|
-
return;
|
|
1418
|
-
});
|
|
1419
|
-
let settlementIncomplete = false;
|
|
1420
|
-
try {
|
|
1421
|
-
await withWatchdog(execution, watchdogTimeoutMs, "scenario");
|
|
1422
|
-
} catch (error) {
|
|
1423
|
-
failure = { value: error };
|
|
1424
|
-
} finally {
|
|
1425
|
-
gates.releaseAll();
|
|
1426
|
-
if (failure?.value instanceof ManagedResourceConformanceWatchdogError) {
|
|
1427
|
-
try {
|
|
1428
|
-
await withWatchdog(execution, watchdogTimeoutMs, "settlement");
|
|
1429
|
-
} catch (error) {
|
|
1430
|
-
if (error instanceof ManagedResourceConformanceWatchdogError) {
|
|
1431
|
-
settlementIncomplete = true;
|
|
1432
|
-
} else {
|
|
1433
|
-
failure = { value: error };
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
trace.record("dispose", "enter");
|
|
1438
|
-
try {
|
|
1439
|
-
await withWatchdog(Promise.resolve(fixture.dispose()), watchdogTimeoutMs, "dispose");
|
|
1440
|
-
trace.record("dispose", "resolve");
|
|
1441
|
-
} catch (error) {
|
|
1442
|
-
trace.record("dispose", "reject");
|
|
1443
|
-
if (failure === undefined)
|
|
1444
|
-
failure = { value: error };
|
|
1445
|
-
}
|
|
1446
|
-
if (settlementIncomplete) {
|
|
1447
|
-
try {
|
|
1448
|
-
await withWatchdog(execution, watchdogTimeoutMs, "settlement");
|
|
1449
|
-
settlementIncomplete = false;
|
|
1450
|
-
} catch (error) {
|
|
1451
|
-
if (error instanceof ManagedResourceConformanceWatchdogError) {
|
|
1452
|
-
const original = failure?.value;
|
|
1453
|
-
failure = {
|
|
1454
|
-
value: new Error(`${detailOf(original)}; execution remained live after fixture disposal`)
|
|
1455
|
-
};
|
|
1456
|
-
} else {
|
|
1457
|
-
settlementIncomplete = false;
|
|
1458
|
-
failure = { value: error };
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
if (failure !== undefined) {
|
|
1464
|
-
if (failure.value instanceof ManagedResourceConformanceError)
|
|
1465
|
-
throw failure.value;
|
|
1466
|
-
throw new ManagedResourceConformanceError(scenario.id, expectedManagedResourceConformanceTrace(scenario.id), trace.entries, detailOf(failure.value));
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
async function runManagedResourceConformance(config) {
|
|
1470
|
-
const watchdogTimeoutMs = config.watchdogTimeoutMs ?? DEFAULT_WATCHDOG_TIMEOUT_MS;
|
|
1471
|
-
if (!Number.isSafeInteger(watchdogTimeoutMs) || watchdogTimeoutMs <= 0) {
|
|
1472
|
-
throw new TypeError("[stitchkit] managed resource conformance watchdogTimeoutMs must be positive");
|
|
1473
|
-
}
|
|
1474
|
-
const selected = new Set((config.scenarios ?? MANAGED_RESOURCE_CONFORMANCE_SCENARIOS.map((scenario) => scenario.id)).map((scenario) => ManagedResourceConformanceScenarioIdSchema.parse(scenario)));
|
|
1475
|
-
if (selected.size === 0) {
|
|
1476
|
-
throw new TypeError("[stitchkit] managed resource conformance scenarios must not be empty");
|
|
1477
|
-
}
|
|
1478
|
-
for (const scenario of MANAGED_RESOURCE_CONFORMANCE_SCENARIOS) {
|
|
1479
|
-
if (!selected.has(scenario.id))
|
|
1480
|
-
continue;
|
|
1481
|
-
await runScenario(config, scenario, watchdogTimeoutMs);
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
// src/testing/surface-conformance.ts
|
|
1485
|
-
import { z as z3 } from "zod";
|
|
1486
|
-
|
|
1487
|
-
// src/testing/surface-manifest.ts
|
|
1488
|
-
import { createHash } from "node:crypto";
|
|
1489
|
-
import { z as z2 } from "zod";
|
|
1490
|
-
var SURFACE_MANIFEST_VERSION = 3;
|
|
1491
|
-
var HttpMethodSchema = z2.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]);
|
|
1492
|
-
var ToolTransportSchema = z2.enum(["MCP", "AGENT", "CLI"]);
|
|
1493
|
-
var SurfaceTransportSchema = z2.enum(["HTTP", "MCP", "AGENT", "CLI", "REALTIME"]);
|
|
1494
|
-
var SurfaceSchemaDigestsSchema = z2.object({
|
|
1495
|
-
params: z2.string().nullable(),
|
|
1496
|
-
input: z2.string().nullable(),
|
|
1497
|
-
output: z2.string().nullable(),
|
|
1498
|
-
multipart: z2.string().nullable()
|
|
1499
|
-
});
|
|
1500
|
-
var SurfaceManifestOperationMcpSchema = z2.object({
|
|
1501
|
-
inputRequired: z2.union([
|
|
1502
|
-
z2.array(z2.object({ key: z2.string(), message: z2.string(), schema: z2.string().nullable() })),
|
|
1503
|
-
z2.literal("resolved-per-call")
|
|
1504
|
-
])
|
|
1505
|
-
}).nullable();
|
|
1506
|
-
var SurfaceManifestOperationSchema = z2.object({
|
|
1507
|
-
kind: z2.enum(["contract", "runtime"]),
|
|
1508
|
-
service: z2.string(),
|
|
1509
|
-
action: z2.string(),
|
|
1510
|
-
method: HttpMethodSchema,
|
|
1511
|
-
scope: z2.string().nullable(),
|
|
1512
|
-
description: z2.string(),
|
|
1513
|
-
schemas: SurfaceSchemaDigestsSchema,
|
|
1514
|
-
mcp: SurfaceManifestOperationMcpSchema,
|
|
1515
|
-
http: z2.array(z2.object({ method: HttpMethodSchema, path: z2.string() }))
|
|
1516
|
-
});
|
|
1517
|
-
var SurfaceManifestToolSchema = z2.object({
|
|
1518
|
-
kind: z2.enum(["contract", "runtime"]),
|
|
1519
|
-
service: z2.string(),
|
|
1520
|
-
action: z2.string(),
|
|
1521
|
-
name: z2.string(),
|
|
1522
|
-
input: z2.string()
|
|
1523
|
-
});
|
|
1524
|
-
var SurfaceManifestToolSurfaceSchema = z2.object({
|
|
1525
|
-
transport: ToolTransportSchema,
|
|
1526
|
-
surface: z2.string().nullable(),
|
|
1527
|
-
tools: z2.array(SurfaceManifestToolSchema)
|
|
1528
|
-
});
|
|
1529
|
-
var SurfaceManifestCliCommandSchema = z2.object({
|
|
1530
|
-
name: z2.string(),
|
|
1531
|
-
description: z2.string(),
|
|
1532
|
-
input: z2.string(),
|
|
1533
|
-
output: z2.string().nullable()
|
|
1534
|
-
});
|
|
1535
|
-
var SurfaceManifestExtensionSchema = z2.object({
|
|
1536
|
-
name: z2.string(),
|
|
1537
|
-
transport: SurfaceTransportSchema
|
|
1538
|
-
});
|
|
1539
|
-
var SurfaceRealtimeSchemaPairSchema = z2.object({
|
|
1540
|
-
input: z2.string(),
|
|
1541
|
-
output: z2.string()
|
|
1542
|
-
});
|
|
1543
|
-
var SurfaceManifestRealtimeEventSchema = z2.object({
|
|
1544
|
-
contract: z2.string(),
|
|
1545
|
-
direction: z2.enum(["serverToClient", "clientToServer"]),
|
|
1546
|
-
event: z2.string(),
|
|
1547
|
-
args: SurfaceRealtimeSchemaPairSchema,
|
|
1548
|
-
acknowledgement: SurfaceRealtimeSchemaPairSchema.nullable()
|
|
1549
|
-
});
|
|
1550
|
-
var SurfaceManifestSchema = z2.object({
|
|
1551
|
-
manifestVersion: z2.literal(SURFACE_MANIFEST_VERSION),
|
|
1552
|
-
digestVersion: z2.literal(1),
|
|
1553
|
-
operations: z2.array(SurfaceManifestOperationSchema),
|
|
1554
|
-
toolSurfaces: z2.array(SurfaceManifestToolSurfaceSchema),
|
|
1555
|
-
realtimeContracts: z2.array(z2.string()),
|
|
1556
|
-
realtime: z2.array(SurfaceManifestRealtimeEventSchema),
|
|
1557
|
-
cliOnly: z2.array(SurfaceManifestCliCommandSchema),
|
|
1558
|
-
extensions: z2.array(SurfaceManifestExtensionSchema)
|
|
1559
|
-
});
|
|
1560
|
-
var serializeSurfaceValue = serializeCanonicalJson;
|
|
1561
|
-
function digestValue(value) {
|
|
1562
|
-
return createHash("sha256").update(serializeSurfaceValue(value)).digest("hex").slice(0, 16);
|
|
1563
|
-
}
|
|
1564
|
-
function canonicalSchemaValue(value, parentKey) {
|
|
1565
|
-
if (Array.isArray(value)) {
|
|
1566
|
-
const entries = value.map((entry) => canonicalSchemaValue(entry));
|
|
1567
|
-
return parentKey === "required" && entries.every((entry) => typeof entry === "string") ? entries.sort((left, right) => compareCodepoints(String(left), String(right))) : entries;
|
|
1568
|
-
}
|
|
1569
|
-
if (!isRecord(value))
|
|
1570
|
-
return value;
|
|
1571
|
-
const result = {};
|
|
1572
|
-
for (const key of Object.keys(value).sort(compareCodepoints)) {
|
|
1573
|
-
result[key] = canonicalSchemaValue(value[key], key);
|
|
1574
|
-
}
|
|
1575
|
-
return result;
|
|
1576
|
-
}
|
|
1577
|
-
function schemaDigest(schema, io) {
|
|
1578
|
-
if (!schema)
|
|
1579
|
-
return null;
|
|
1580
|
-
return digestValue(canonicalSchemaValue(toJsonSchema(schema, io, "any")));
|
|
1581
|
-
}
|
|
1582
|
-
function presentationDigest(schema) {
|
|
1583
|
-
return digestValue(canonicalSchemaValue(schema));
|
|
1584
|
-
}
|
|
1585
|
-
function multipartDigest(value) {
|
|
1586
|
-
return value === undefined ? null : digestValue(value);
|
|
1587
|
-
}
|
|
1588
|
-
function operationKey(kind, service, action) {
|
|
1589
|
-
return `${kind}\x00${service}\x00${action}`;
|
|
1590
|
-
}
|
|
1591
|
-
function operationFrom(kind, source) {
|
|
1592
|
-
return {
|
|
1593
|
-
kind,
|
|
1594
|
-
service: source.serviceName,
|
|
1595
|
-
action: source.key,
|
|
1596
|
-
method: source.method,
|
|
1597
|
-
scope: source.scope ?? null,
|
|
1598
|
-
description: source.desc,
|
|
1599
|
-
schemas: {
|
|
1600
|
-
params: schemaDigest(source.paramsSchema, "input"),
|
|
1601
|
-
input: schemaDigest(source.inputSchema, "input"),
|
|
1602
|
-
output: schemaDigest(source.outputSchema, "output"),
|
|
1603
|
-
multipart: multipartDigest(source.multipart)
|
|
1604
|
-
},
|
|
1605
|
-
mcp: mcpRoundsOf(source),
|
|
1606
|
-
http: []
|
|
1607
|
-
};
|
|
1608
|
-
}
|
|
1609
|
-
function mcpRoundsOf(source) {
|
|
1610
|
-
if (!source.mcp)
|
|
1611
|
-
return null;
|
|
1612
|
-
const declared = staticInputRounds(source.mcp);
|
|
1613
|
-
return {
|
|
1614
|
-
inputRequired: declared ? declared.map((request) => ({
|
|
1615
|
-
key: request.key,
|
|
1616
|
-
message: request.message,
|
|
1617
|
-
schema: schemaDigest(request.schema, "input")
|
|
1618
|
-
})) : "resolved-per-call"
|
|
1619
|
-
};
|
|
1620
|
-
}
|
|
1621
|
-
function operationFingerprint(source) {
|
|
1622
|
-
const mcp = mcpRoundsOf(source);
|
|
1623
|
-
return serializeSurfaceValue({
|
|
1624
|
-
method: source.method,
|
|
1625
|
-
serviceName: source.serviceName,
|
|
1626
|
-
key: source.key,
|
|
1627
|
-
desc: source.desc,
|
|
1628
|
-
scope: source.scope ?? null,
|
|
1629
|
-
path: source.path ?? null,
|
|
1630
|
-
expose: source.expose ? [...source.expose].sort(compareCodepoints) : null,
|
|
1631
|
-
toolName: source.toolName ?? null,
|
|
1632
|
-
annotations: source.annotations ?? null,
|
|
1633
|
-
ui: source.ui ?? null,
|
|
1634
|
-
mcp,
|
|
1635
|
-
rawBody: source.rawBody ?? false,
|
|
1636
|
-
safelistedBody: source.safelistedBody ?? false,
|
|
1637
|
-
rawResponse: source.rawResponse ?? false,
|
|
1638
|
-
responseMeta: source.responseMeta ?? null,
|
|
1639
|
-
maxJsonBodyBytes: source.maxJsonBodyBytes ?? null,
|
|
1640
|
-
idempotent: source.idempotent ?? false,
|
|
1641
|
-
contentType: source.contentType ?? null,
|
|
1642
|
-
meta: source.meta ?? null,
|
|
1643
|
-
schemas: {
|
|
1644
|
-
params: schemaDigest(source.paramsSchema, "input"),
|
|
1645
|
-
input: schemaDigest(source.inputSchema, "input"),
|
|
1646
|
-
output: schemaDigest(source.outputSchema, "output"),
|
|
1647
|
-
multipart: multipartDigest(source.multipart)
|
|
1648
|
-
}
|
|
1649
|
-
});
|
|
1650
|
-
}
|
|
1651
|
-
function sortTools(tools) {
|
|
1652
|
-
return tools.sort((left, right) => compareCodepoints(left.name, right.name) || compareCodepoints(left.service, right.service) || compareCodepoints(left.action, right.action) || compareCodepoints(left.kind, right.kind));
|
|
1653
|
-
}
|
|
1654
|
-
function buildSurfaceManifest(config) {
|
|
1655
|
-
const operations = new Map;
|
|
1656
|
-
const operationFingerprints = new Map;
|
|
1657
|
-
const operationDefinitions = new Map;
|
|
1658
|
-
const addOperation = (kind, source) => {
|
|
1659
|
-
const candidate = operationFrom(kind, source);
|
|
1660
|
-
const key = operationKey(kind, candidate.service, candidate.action);
|
|
1661
|
-
const definition = source.definitionToken ?? source;
|
|
1662
|
-
const existing = operations.get(key);
|
|
1663
|
-
if (!existing) {
|
|
1664
|
-
operations.set(key, candidate);
|
|
1665
|
-
operationFingerprints.set(key, operationFingerprint(source));
|
|
1666
|
-
operationDefinitions.set(key, definition);
|
|
1667
|
-
return candidate;
|
|
1668
|
-
}
|
|
1669
|
-
if (operationDefinitions.get(key) !== definition || operationFingerprints.get(key) !== operationFingerprint(source)) {
|
|
1670
|
-
throw new Error(`Conflicting ${kind} operation identity ${candidate.service}.${candidate.action}`);
|
|
1671
|
-
}
|
|
1672
|
-
return existing;
|
|
1673
|
-
};
|
|
1674
|
-
const addHttp = (service, prefix) => {
|
|
1675
|
-
for (const method of Object.values(service.methods)) {
|
|
1676
|
-
const operation = addOperation("contract", method);
|
|
1677
|
-
if (method.expose && !method.expose.includes("HTTP"))
|
|
1678
|
-
continue;
|
|
1679
|
-
const route = {
|
|
1680
|
-
method: method.method,
|
|
1681
|
-
path: joinRoutePath(prefix, service.prefix, method.path)
|
|
1682
|
-
};
|
|
1683
|
-
if (!operation.http.some((entry) => entry.method === route.method && entry.path === route.path)) {
|
|
1684
|
-
operation.http.push(route);
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
};
|
|
1688
|
-
for (const service of config.services ?? []) {
|
|
1689
|
-
addHttp(service, config.scopePrefixes?.[service.scope] ?? "");
|
|
1690
|
-
}
|
|
1691
|
-
for (const group of config.groups ?? []) {
|
|
1692
|
-
for (const service of group.services)
|
|
1693
|
-
addHttp(service, group.pathPrefix ?? "");
|
|
1694
|
-
}
|
|
1695
|
-
const toolSurfaces = [];
|
|
1696
|
-
const addToolProjection = (transport, surface, projection, presentation = {}) => {
|
|
1697
|
-
const projected = projectToolSurface(projection, transport, transport === "MCP" ? config.mcpPreparation ?? {} : presentation);
|
|
1698
|
-
const collected = transport === "MCP" ? prepareProjectedMcpTools(projected.map(mcpProjectionCandidate), config.mcpPreparation ?? {}).map((prepared) => ({
|
|
1699
|
-
...prepared.tool,
|
|
1700
|
-
presentationSchema: prepared.inputSchema
|
|
1701
|
-
})) : projected;
|
|
1702
|
-
const tools = [];
|
|
1703
|
-
for (const entry of collected) {
|
|
1704
|
-
const source = entry.kind === "contract" ? entry.source : {
|
|
1705
|
-
definitionToken: entry.source,
|
|
1706
|
-
method: entry.source.identity.method,
|
|
1707
|
-
serviceName: entry.source.identity.serviceName,
|
|
1708
|
-
key: entry.source.identity.action,
|
|
1709
|
-
desc: entry.source.description,
|
|
1710
|
-
...entry.source.identity.scope !== undefined && {
|
|
1711
|
-
scope: entry.source.identity.scope
|
|
1712
|
-
},
|
|
1713
|
-
inputSchema: entry.source.input,
|
|
1714
|
-
...entry.source.output !== undefined && {
|
|
1715
|
-
outputSchema: entry.source.output
|
|
1716
|
-
},
|
|
1717
|
-
toolName: entry.source.name,
|
|
1718
|
-
expose: entry.source.transports,
|
|
1719
|
-
...entry.source.annotations !== undefined && {
|
|
1720
|
-
annotations: entry.source.annotations
|
|
1721
|
-
},
|
|
1722
|
-
...entry.source.ui !== undefined && { ui: entry.source.ui },
|
|
1723
|
-
...entry.source.identity.meta !== undefined && {
|
|
1724
|
-
meta: entry.source.identity.meta
|
|
1725
|
-
},
|
|
1726
|
-
...entry.source.mcp !== undefined && { mcp: entry.source.mcp }
|
|
1727
|
-
};
|
|
1728
|
-
const operation = addOperation(entry.kind, source);
|
|
1729
|
-
tools.push({
|
|
1730
|
-
kind: entry.kind,
|
|
1731
|
-
service: operation.service,
|
|
1732
|
-
action: operation.action,
|
|
1733
|
-
name: entry.name,
|
|
1734
|
-
input: presentationDigest(entry.presentationSchema)
|
|
1735
|
-
});
|
|
1736
|
-
}
|
|
1737
|
-
toolSurfaces.push({ transport, surface, tools: sortTools(tools) });
|
|
1738
|
-
};
|
|
1739
|
-
const shared = {
|
|
1740
|
-
services: config.services,
|
|
1741
|
-
runtimeTools: config.runtimeTools
|
|
1742
|
-
};
|
|
1743
|
-
const explicitMcp = config.toolSurfaces?.MCP;
|
|
1744
|
-
const namedMcp = config.mcpSurfaces;
|
|
1745
|
-
if (explicitMcp && namedMcp) {
|
|
1746
|
-
throw new Error("Surface manifest MCP topology must use either one direct surface or named surfaces");
|
|
1747
|
-
}
|
|
1748
|
-
if (explicitMcp)
|
|
1749
|
-
addToolProjection("MCP", null, explicitMcp);
|
|
1750
|
-
if (namedMcp) {
|
|
1751
|
-
for (const name of Object.keys(namedMcp).sort(compareCodepoints)) {
|
|
1752
|
-
const projection = namedMcp[name];
|
|
1753
|
-
if (projection)
|
|
1754
|
-
addToolProjection("MCP", name, projection);
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
if (!explicitMcp && !namedMcp)
|
|
1758
|
-
addToolProjection("MCP", null, shared);
|
|
1759
|
-
const agent = config.toolSurfaces?.AGENT;
|
|
1760
|
-
addToolProjection("AGENT", null, agent ?? shared, agent ?? {});
|
|
1761
|
-
addToolProjection("CLI", null, config.toolSurfaces?.CLI ?? shared);
|
|
1762
|
-
const realtime = [];
|
|
1763
|
-
const realtimeContracts = Object.keys(config.realtime ?? {}).sort(compareCodepoints);
|
|
1764
|
-
for (const contractName of realtimeContracts) {
|
|
1765
|
-
const contract = config.realtime?.[contractName];
|
|
1766
|
-
if (!contract)
|
|
1767
|
-
continue;
|
|
1768
|
-
for (const direction of ["serverToClient", "clientToServer"]) {
|
|
1769
|
-
const registry = contract[direction];
|
|
1770
|
-
for (const event of Object.keys(registry).sort(compareCodepoints)) {
|
|
1771
|
-
const definition = registry[event];
|
|
1772
|
-
if (!definition)
|
|
1773
|
-
continue;
|
|
1774
|
-
const argsInput = schemaDigest(definition.args, "input");
|
|
1775
|
-
const argsOutput = schemaDigest(definition.args, "output");
|
|
1776
|
-
if (!argsInput || !argsOutput)
|
|
1777
|
-
throw new Error("Realtime args schema digest missing");
|
|
1778
|
-
let acknowledgement = null;
|
|
1779
|
-
if (definition.ack) {
|
|
1780
|
-
const input = schemaDigest(definition.ack, "input");
|
|
1781
|
-
const output = schemaDigest(definition.ack, "output");
|
|
1782
|
-
if (!input || !output)
|
|
1783
|
-
throw new Error("Realtime ack schema digest missing");
|
|
1784
|
-
acknowledgement = { input, output };
|
|
1785
|
-
}
|
|
1786
|
-
realtime.push({
|
|
1787
|
-
contract: contractName,
|
|
1788
|
-
direction,
|
|
1789
|
-
event,
|
|
1790
|
-
args: { input: argsInput, output: argsOutput },
|
|
1791
|
-
acknowledgement
|
|
1792
|
-
});
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
const cliOnly = (config.cliCommands ?? []).map((command) => ({
|
|
1797
|
-
name: command.name,
|
|
1798
|
-
description: command.description,
|
|
1799
|
-
input: schemaDigest(command.input, "input") ?? digestValue({}),
|
|
1800
|
-
output: schemaDigest(command.output, "output")
|
|
1801
|
-
})).sort((left, right) => compareCodepoints(left.name, right.name));
|
|
1802
|
-
for (const operation of operations.values()) {
|
|
1803
|
-
operation.http.sort((left, right) => compareCodepoints(left.path, right.path) || compareCodepoints(left.method, right.method));
|
|
1804
|
-
}
|
|
1805
|
-
return SurfaceManifestSchema.parse({
|
|
1806
|
-
manifestVersion: SURFACE_MANIFEST_VERSION,
|
|
1807
|
-
digestVersion: 1,
|
|
1808
|
-
operations: [...operations.values()].sort((left, right) => compareCodepoints(left.service, right.service) || compareCodepoints(left.action, right.action) || compareCodepoints(left.kind, right.kind)),
|
|
1809
|
-
toolSurfaces: toolSurfaces.sort((left, right) => compareCodepoints(left.transport, right.transport) || compareCodepoints(left.surface ?? "", right.surface ?? "")),
|
|
1810
|
-
realtimeContracts,
|
|
1811
|
-
realtime,
|
|
1812
|
-
cliOnly,
|
|
1813
|
-
extensions: [...config.extensions ?? []].sort((left, right) => compareCodepoints(left.transport, right.transport) || compareCodepoints(left.name, right.name))
|
|
1814
|
-
});
|
|
1815
|
-
}
|
|
1816
|
-
function assertSurfaceManifestSnapshot(manifest, snapshot) {
|
|
1817
|
-
const committed = snapshot.manifestVersion;
|
|
1818
|
-
if (committed !== SURFACE_MANIFEST_VERSION) {
|
|
1819
|
-
throw new Error(`Surface snapshot is manifestVersion ${String(committed)}; this build writes ` + `${SURFACE_MANIFEST_VERSION}. Regenerate it and review the diff — the format ` + "changed, so the first regeneration is expected to be large.");
|
|
1820
|
-
}
|
|
1821
|
-
const actual = serializeSurfaceValue(SurfaceManifestSchema.parse(manifest));
|
|
1822
|
-
const expected = serializeSurfaceValue(SurfaceManifestSchema.parse(snapshot));
|
|
1823
|
-
if (actual !== expected) {
|
|
1824
|
-
throw new Error(`Surface manifest diverged from its committed snapshot
|
|
1825
|
-
expected: ${expected}
|
|
1826
|
-
actual: ${actual}`);
|
|
1827
|
-
}
|
|
1828
|
-
}
|
|
1829
|
-
|
|
1830
|
-
// src/testing/surface-conformance.ts
|
|
1831
|
-
var RealtimeRejectionObservationSchema = z3.object({
|
|
1832
|
-
direction: RealtimeRejectDirectionSchema,
|
|
1833
|
-
phase: RealtimeRejectPhaseSchema,
|
|
1834
|
-
reason: RealtimeRejectReasonSchema,
|
|
1835
|
-
fault: RealtimeRejectFaultSchema
|
|
1836
|
-
});
|
|
1837
|
-
var ObservationFields = {
|
|
1838
|
-
code: z3.string().optional(),
|
|
1839
|
-
data: z3.unknown().optional(),
|
|
1840
|
-
diagnostic: z3.string().optional(),
|
|
1841
|
-
handlerCalls: z3.number().int().nonnegative().optional()
|
|
1842
|
-
};
|
|
1843
|
-
var RealtimeDisconnectObservationSchema = z3.object({
|
|
1844
|
-
phase: z3.enum(["before-invoke", "in-flight"])
|
|
1845
|
-
});
|
|
1846
|
-
var TransportObservationSchema = z3.discriminatedUnion("outcome", [
|
|
1847
|
-
z3.object({ outcome: z3.literal("success"), ...ObservationFields }),
|
|
1848
|
-
z3.object({ outcome: z3.literal("validation_error"), ...ObservationFields }),
|
|
1849
|
-
z3.object({ outcome: z3.literal("domain_error"), ...ObservationFields }),
|
|
1850
|
-
z3.object({ outcome: z3.literal("aborted"), ...ObservationFields }),
|
|
1851
|
-
z3.object({
|
|
1852
|
-
outcome: z3.literal("realtime_rejected"),
|
|
1853
|
-
...ObservationFields,
|
|
1854
|
-
rejection: RealtimeRejectionObservationSchema
|
|
1855
|
-
}),
|
|
1856
|
-
z3.object({
|
|
1857
|
-
outcome: z3.literal("disconnected"),
|
|
1858
|
-
...ObservationFields,
|
|
1859
|
-
disconnect: RealtimeDisconnectObservationSchema
|
|
1860
|
-
}),
|
|
1861
|
-
z3.object({ outcome: z3.literal("timeout"), ...ObservationFields })
|
|
1862
|
-
]);
|
|
1863
|
-
function scenarioOutcome(scenario) {
|
|
1864
|
-
if (scenario === "event" || scenario === "acknowledgement")
|
|
1865
|
-
return "success";
|
|
1866
|
-
if (scenario === "invalid_arguments" || scenario === "invalid_acknowledgement" || scenario === "peer_rejection") {
|
|
1867
|
-
return "realtime_rejected";
|
|
1868
|
-
}
|
|
1869
|
-
if (scenario === "disconnected" || scenario === "in_flight_disconnect") {
|
|
1870
|
-
return "disconnected";
|
|
1871
|
-
}
|
|
1872
|
-
return "timeout";
|
|
1873
|
-
}
|
|
1874
|
-
function assertScenarioExpectation(scenario, expected) {
|
|
1875
|
-
const outcome = scenarioOutcome(scenario);
|
|
1876
|
-
if (expected.outcome !== outcome) {
|
|
1877
|
-
throw new TypeError(`Realtime probe scenario "${scenario}" requires outcome "${outcome}"`);
|
|
1878
|
-
}
|
|
1879
|
-
if (expected.outcome === "realtime_rejected" && (scenario === "invalid_arguments" && expected.rejection.phase !== "arguments" || scenario === "invalid_acknowledgement" && expected.rejection.phase !== "acknowledgement")) {
|
|
1880
|
-
throw new TypeError(`Realtime probe scenario "${scenario}" has incompatible rejection phase`);
|
|
1881
|
-
}
|
|
1882
|
-
if (scenario === "invalid_arguments" && expected.handlerCalls !== 0) {
|
|
1883
|
-
throw new TypeError('Realtime probe scenario "invalid_arguments" requires handlerCalls: 0');
|
|
1884
|
-
}
|
|
1885
|
-
if (scenario === "peer_rejection" && (expected.outcome !== "realtime_rejected" || expected.rejection.reason !== "rejected-by-peer")) {
|
|
1886
|
-
throw new TypeError('Realtime probe scenario "peer_rejection" requires a rejected-by-peer outcome');
|
|
1887
|
-
}
|
|
1888
|
-
if (expected.outcome === "disconnected") {
|
|
1889
|
-
const phase = scenario === "disconnected" ? "before-invoke" : "in-flight";
|
|
1890
|
-
if (expected.disconnect.phase !== phase) {
|
|
1891
|
-
throw new TypeError(`Realtime probe scenario "${scenario}" requires disconnect phase "${phase}"`);
|
|
1892
|
-
}
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
function defineRealtimeProbe(config) {
|
|
1896
|
-
const expected = TransportObservationSchema.parse(config.expected);
|
|
1897
|
-
assertScenarioExpectation(config.scenario, expected);
|
|
1898
|
-
return {
|
|
1899
|
-
name: config.name,
|
|
1900
|
-
fixture: { scenario: config.scenario, value: config.fixture },
|
|
1901
|
-
transports: ["REALTIME"],
|
|
1902
|
-
expected: { REALTIME: expected },
|
|
1903
|
-
setup: config.setup,
|
|
1904
|
-
teardown: config.teardown
|
|
1905
|
-
};
|
|
1906
|
-
}
|
|
1907
|
-
function rejectionObservation(rejected) {
|
|
1908
|
-
return RealtimeRejectionObservationSchema.parse(rejected);
|
|
1909
|
-
}
|
|
1910
|
-
function createRealtimeProbeDriver({
|
|
1911
|
-
bind,
|
|
1912
|
-
handlerCalls
|
|
1913
|
-
}) {
|
|
1914
|
-
return {
|
|
1915
|
-
async invoke(fixture, signal) {
|
|
1916
|
-
let rejected;
|
|
1917
|
-
const currentRejection = () => rejected;
|
|
1918
|
-
const adapter = bind((event) => {
|
|
1919
|
-
rejected = event;
|
|
1920
|
-
}, fixture);
|
|
1921
|
-
const connectedBefore = adapter.connected();
|
|
1922
|
-
const callsBefore = handlerCalls?.();
|
|
1923
|
-
const withCalls = (observation) => {
|
|
1924
|
-
if (callsBefore === undefined || !handlerCalls)
|
|
1925
|
-
return observation;
|
|
1926
|
-
return { ...observation, handlerCalls: handlerCalls() - callsBefore };
|
|
1927
|
-
};
|
|
1928
|
-
try {
|
|
1929
|
-
signal.throwIfAborted();
|
|
1930
|
-
const data = await adapter.invoke(fixture, signal);
|
|
1931
|
-
const observedRejection = currentRejection();
|
|
1932
|
-
if (observedRejection) {
|
|
1933
|
-
return withCalls({
|
|
1934
|
-
outcome: "realtime_rejected",
|
|
1935
|
-
code: observedRejection.error.code,
|
|
1936
|
-
rejection: rejectionObservation(observedRejection)
|
|
1937
|
-
});
|
|
1938
|
-
}
|
|
1939
|
-
return withCalls({
|
|
1940
|
-
outcome: "success",
|
|
1941
|
-
...data !== undefined && { data }
|
|
1942
|
-
});
|
|
1943
|
-
} catch (error) {
|
|
1944
|
-
const observedRejection = currentRejection();
|
|
1945
|
-
if (observedRejection) {
|
|
1946
|
-
return withCalls({
|
|
1947
|
-
outcome: "realtime_rejected",
|
|
1948
|
-
code: error instanceof RealtimeRequestInvalidAcknowledgementError ? error.code : observedRejection.error.code,
|
|
1949
|
-
rejection: rejectionObservation(observedRejection)
|
|
1950
|
-
});
|
|
1951
|
-
}
|
|
1952
|
-
if (error instanceof RealtimeRequestInvalidAcknowledgementError) {
|
|
1953
|
-
return withCalls({
|
|
1954
|
-
outcome: "realtime_rejected",
|
|
1955
|
-
code: error.code,
|
|
1956
|
-
rejection: {
|
|
1957
|
-
direction: "client-inbound",
|
|
1958
|
-
phase: "acknowledgement",
|
|
1959
|
-
reason: "invalid-acknowledgement-value",
|
|
1960
|
-
fault: "peer"
|
|
1961
|
-
}
|
|
1962
|
-
});
|
|
1963
|
-
}
|
|
1964
|
-
if (error instanceof RealtimeRequestDisconnectedError) {
|
|
1965
|
-
return withCalls({
|
|
1966
|
-
outcome: "disconnected",
|
|
1967
|
-
code: error.code,
|
|
1968
|
-
disconnect: {
|
|
1969
|
-
phase: connectedBefore ? "in-flight" : "before-invoke"
|
|
1970
|
-
}
|
|
1971
|
-
});
|
|
1972
|
-
}
|
|
1973
|
-
if (error instanceof RealtimeRequestTimeoutError) {
|
|
1974
|
-
return withCalls({ outcome: "timeout", code: error.code });
|
|
1975
|
-
}
|
|
1976
|
-
if (signal.aborted && error === signal.reason) {
|
|
1977
|
-
return withCalls({ outcome: "aborted" });
|
|
1978
|
-
}
|
|
1979
|
-
const parsedRejection = RealtimeRejectionObservationSchema.safeParse(typeof error === "object" && error !== null && "details" in error ? error.details : undefined);
|
|
1980
|
-
if (parsedRejection.success) {
|
|
1981
|
-
const code2 = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "REALTIME_CONTRACT_VIOLATION";
|
|
1982
|
-
return withCalls({
|
|
1983
|
-
outcome: "realtime_rejected",
|
|
1984
|
-
code: code2,
|
|
1985
|
-
rejection: parsedRejection.data
|
|
1986
|
-
});
|
|
1987
|
-
}
|
|
1988
|
-
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : undefined;
|
|
1989
|
-
return withCalls({
|
|
1990
|
-
outcome: "domain_error",
|
|
1991
|
-
...code !== undefined && { code },
|
|
1992
|
-
diagnostic: error instanceof Error ? error.message : String(error)
|
|
1993
|
-
});
|
|
1994
|
-
} finally {
|
|
1995
|
-
await adapter.dispose?.();
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
};
|
|
1999
|
-
}
|
|
2000
|
-
function sorted(values) {
|
|
2001
|
-
return [...values].sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
|
|
2002
|
-
}
|
|
2003
|
-
function assertSameSet(label, expectedValues, actualValues) {
|
|
2004
|
-
const expected = sorted(expectedValues);
|
|
2005
|
-
const actual = sorted(actualValues);
|
|
2006
|
-
if (serializeSurfaceValue(expected) === serializeSurfaceValue(actual))
|
|
2007
|
-
return;
|
|
2008
|
-
throw new Error(`${label} mismatch
|
|
2009
|
-
expected: ${expected.join(", ") || "(empty)"}
|
|
2010
|
-
actual: ${actual.join(", ") || "(empty)"}`);
|
|
2011
|
-
}
|
|
2012
|
-
function openApiOperations(document) {
|
|
2013
|
-
return Object.entries(document.paths).flatMap(([path, item]) => Object.keys(item).filter((method) => ["get", "post", "put", "patch", "delete", "head"].includes(method)).map((method) => `${method.toUpperCase()}:${path}`));
|
|
2014
|
-
}
|
|
2015
|
-
function expectedToolNames(manifest, transport, surface) {
|
|
2016
|
-
const projection = manifest.toolSurfaces.find((candidate) => candidate.transport === transport && candidate.surface === surface);
|
|
2017
|
-
if (!projection) {
|
|
2018
|
-
throw new Error(`${transport} surface "${surface ?? "(default)"}" is not declared in the manifest`);
|
|
2019
|
-
}
|
|
2020
|
-
return projection.tools.map((tool) => tool.name);
|
|
2021
|
-
}
|
|
2022
|
-
function assertSurfaceDiscovery(manifest, observed) {
|
|
2023
|
-
if (observed.openApi) {
|
|
2024
|
-
assertSameSet("HTTP/OpenAPI", manifest.operations.flatMap((operation) => operation.http.map((entry) => `${entry.method}:${entry.path.replace(/:([^/]+)/g, "{$1}")}`)), openApiOperations(observed.openApi));
|
|
2025
|
-
}
|
|
2026
|
-
for (const transport of ["MCP", "AGENT", "CLI"]) {
|
|
2027
|
-
const names = observed[transport];
|
|
2028
|
-
if (names) {
|
|
2029
|
-
assertSameSet(`${transport} discovery`, expectedToolNames(manifest, transport, null), names);
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
for (const projection of observed.toolSurfaces ?? []) {
|
|
2033
|
-
assertSameSet(`${projection.transport} surface "${projection.surface ?? "(default)"}" discovery`, expectedToolNames(manifest, projection.transport, projection.surface ?? null), projection.names);
|
|
2034
|
-
}
|
|
2035
|
-
for (const [contract, topology] of Object.entries(observed.realtime ?? {})) {
|
|
2036
|
-
if (!manifest.realtimeContracts.includes(contract)) {
|
|
2037
|
-
throw new Error(`REALTIME contract "${contract}" is not declared in the manifest`);
|
|
2038
|
-
}
|
|
2039
|
-
for (const direction of ["serverToClient", "clientToServer"]) {
|
|
2040
|
-
assertSameSet(`REALTIME ${contract}.${direction} discovery`, manifest.realtime.filter((entry) => entry.contract === contract && entry.direction === direction).map((entry) => entry.event), topology[direction]);
|
|
2041
|
-
}
|
|
2042
|
-
}
|
|
2043
|
-
if (observed.cliOnly) {
|
|
2044
|
-
assertSameSet("CLI-only discovery", manifest.cliOnly.map((command) => command.name), observed.cliOnly);
|
|
2045
|
-
}
|
|
2046
|
-
for (const transport of [
|
|
2047
|
-
"HTTP",
|
|
2048
|
-
"MCP",
|
|
2049
|
-
"AGENT",
|
|
2050
|
-
"CLI",
|
|
2051
|
-
"REALTIME"
|
|
2052
|
-
]) {
|
|
2053
|
-
const names = observed.extensions?.[transport];
|
|
2054
|
-
if (!names)
|
|
2055
|
-
continue;
|
|
2056
|
-
assertSameSet(`${transport} extension discovery`, manifest.extensions.filter((extension) => extension.transport === transport).map((extension) => extension.name), names);
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
function boundedObservation(observation, maxDiagnosticBytes) {
|
|
2060
|
-
const parsed = TransportObservationSchema.parse(observation);
|
|
2061
|
-
if (!parsed.diagnostic)
|
|
2062
|
-
return parsed;
|
|
2063
|
-
const bytes = new TextEncoder().encode(parsed.diagnostic);
|
|
2064
|
-
if (bytes.byteLength <= maxDiagnosticBytes)
|
|
2065
|
-
return parsed;
|
|
2066
|
-
return {
|
|
2067
|
-
...parsed,
|
|
2068
|
-
diagnostic: new TextDecoder().decode(bytes.slice(0, maxDiagnosticBytes))
|
|
2069
|
-
};
|
|
2070
|
-
}
|
|
2071
|
-
async function runBounded(run, signal) {
|
|
2072
|
-
if (signal.aborted) {
|
|
2073
|
-
Promise.resolve().then(run).catch(() => {
|
|
2074
|
-
return;
|
|
2075
|
-
});
|
|
2076
|
-
throw signal.reason;
|
|
2077
|
-
}
|
|
2078
|
-
let removeAbortListener = () => {
|
|
2079
|
-
return;
|
|
2080
|
-
};
|
|
2081
|
-
const aborted = new Promise((_resolve, reject) => {
|
|
2082
|
-
const onAbort = () => reject(signal.reason);
|
|
2083
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
2084
|
-
removeAbortListener = () => signal.removeEventListener("abort", onAbort);
|
|
2085
|
-
});
|
|
2086
|
-
try {
|
|
2087
|
-
return await Promise.race([Promise.resolve().then(run), aborted]);
|
|
2088
|
-
} finally {
|
|
2089
|
-
removeAbortListener();
|
|
2090
|
-
}
|
|
2091
|
-
}
|
|
2092
|
-
async function runSurfaceProbes({
|
|
2093
|
-
probes,
|
|
2094
|
-
drivers,
|
|
2095
|
-
signal,
|
|
2096
|
-
timeoutMs = 1e4,
|
|
2097
|
-
maxDiagnosticBytes = 4096
|
|
2098
|
-
}) {
|
|
2099
|
-
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
|
|
2100
|
-
throw new TypeError("Surface probe timeoutMs must be a positive integer");
|
|
2101
|
-
}
|
|
2102
|
-
if (!Number.isInteger(maxDiagnosticBytes) || maxDiagnosticBytes <= 0) {
|
|
2103
|
-
throw new TypeError("Surface probe maxDiagnosticBytes must be a positive integer");
|
|
2104
|
-
}
|
|
2105
|
-
for (const probe of probes) {
|
|
2106
|
-
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
2107
|
-
const probeSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
|
|
2108
|
-
let failed = false;
|
|
2109
|
-
let failure;
|
|
2110
|
-
try {
|
|
2111
|
-
probeSignal.throwIfAborted();
|
|
2112
|
-
if (probe.setup)
|
|
2113
|
-
await runBounded(() => probe.setup?.(probeSignal), probeSignal);
|
|
2114
|
-
for (const transport of probe.transports) {
|
|
2115
|
-
probeSignal.throwIfAborted();
|
|
2116
|
-
const driver = drivers[transport];
|
|
2117
|
-
if (!driver) {
|
|
2118
|
-
throw new Error(`Surface probe "${probe.name}" has no ${transport} driver`);
|
|
2119
|
-
}
|
|
2120
|
-
const actual = boundedObservation(await runBounded(() => driver.invoke(probe.fixture, probeSignal), probeSignal), maxDiagnosticBytes);
|
|
2121
|
-
const expected = probe.expected[transport];
|
|
2122
|
-
if (!expected) {
|
|
2123
|
-
throw new Error(`Surface probe "${probe.name}" has no ${transport} expectation`);
|
|
2124
|
-
}
|
|
2125
|
-
if (serializeSurfaceValue(actual) !== serializeSurfaceValue(expected)) {
|
|
2126
|
-
throw new Error(`Surface probe "${probe.name}" ${transport} mismatch
|
|
2127
|
-
expected: ${serializeSurfaceValue(expected)}
|
|
2128
|
-
actual: ${serializeSurfaceValue(actual)}`);
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
} catch (error) {
|
|
2132
|
-
failed = true;
|
|
2133
|
-
failure = error;
|
|
2134
|
-
}
|
|
2135
|
-
if (probe.teardown) {
|
|
2136
|
-
try {
|
|
2137
|
-
await runBounded(() => probe.teardown?.(probeSignal), probeSignal);
|
|
2138
|
-
} catch (error) {
|
|
2139
|
-
if (!failed) {
|
|
2140
|
-
failed = true;
|
|
2141
|
-
failure = error;
|
|
2142
|
-
}
|
|
2143
|
-
}
|
|
2144
|
-
}
|
|
2145
|
-
if (failed)
|
|
2146
|
-
throw failure;
|
|
2147
|
-
}
|
|
2148
|
-
}
|
|
2149
|
-
|
|
2150
|
-
// src/testing.ts
|
|
2151
|
-
function resolveTestBaseUrl(origin, pathPrefix) {
|
|
2152
|
-
const base = new URL(origin ?? "http://stitchkit.test");
|
|
2153
|
-
if (base.pathname !== "/" || base.search || base.hash) {
|
|
2154
|
-
throw new TypeError("Handler test client origin must contain only an absolute origin");
|
|
2155
|
-
}
|
|
2156
|
-
const prefix = pathPrefix?.replace(/^\/+|\/+$/g, "");
|
|
2157
|
-
return prefix ? `${base.origin}/${prefix}` : base.origin;
|
|
2158
|
-
}
|
|
2159
|
-
function createHandlerFetch(handler, server) {
|
|
2160
|
-
return async (input, init) => handler(new Request(input, init), server);
|
|
2161
|
-
}
|
|
2162
|
-
function createTestClientConfig(config) {
|
|
2163
|
-
return {
|
|
2164
|
-
...config.client,
|
|
2165
|
-
baseUrl: resolveTestBaseUrl(config.origin, config.pathPrefix),
|
|
2166
|
-
fetch: createHandlerFetch(config.handler, config.server)
|
|
2167
|
-
};
|
|
2168
|
-
}
|
|
2169
|
-
function createHandlerTestClient(config) {
|
|
2170
|
-
return createClient(config.contract, createTestClientConfig(config), config.contractConfig);
|
|
2171
|
-
}
|
|
2172
|
-
function createHandlerTestClients(config) {
|
|
2173
|
-
return createClients(config.contracts, createTestClientConfig(config), config.contractConfig);
|
|
2174
|
-
}
|
|
2175
|
-
export {
|
|
2176
|
-
serializeSurfaceValue,
|
|
2177
|
-
runSurfaceProbes,
|
|
2178
|
-
runManagedResourceConformance,
|
|
2179
|
-
runAgentStoreConformance,
|
|
2180
|
-
defineRealtimeProbe,
|
|
2181
|
-
createRealtimeProbeDriver,
|
|
2182
|
-
createHandlerTestClients,
|
|
2183
|
-
createHandlerTestClient,
|
|
2184
|
-
createAgentRaceTrace,
|
|
2185
|
-
createAgentRaceDriver,
|
|
2186
|
-
createAgentRaceBarrier,
|
|
2187
|
-
buildSurfaceManifest,
|
|
2188
|
-
assertSurfaceManifestSnapshot,
|
|
2189
|
-
assertSurfaceDiscovery,
|
|
2190
|
-
TransportObservationSchema,
|
|
2191
|
-
SurfaceSchemaDigestsSchema,
|
|
2192
|
-
SurfaceRealtimeSchemaPairSchema,
|
|
2193
|
-
SurfaceManifestToolSurfaceSchema,
|
|
2194
|
-
SurfaceManifestToolSchema,
|
|
2195
|
-
SurfaceManifestSchema,
|
|
2196
|
-
SurfaceManifestRealtimeEventSchema,
|
|
2197
|
-
SurfaceManifestOperationSchema,
|
|
2198
|
-
SurfaceManifestOperationMcpSchema,
|
|
2199
|
-
SurfaceManifestExtensionSchema,
|
|
2200
|
-
SURFACE_MANIFEST_VERSION,
|
|
2201
|
-
RealtimeRejectionObservationSchema,
|
|
2202
|
-
RealtimeDisconnectObservationSchema,
|
|
2203
|
-
ManagedResourceConformanceTraceOutcomeSchema,
|
|
2204
|
-
ManagedResourceConformanceTraceEntrySchema,
|
|
2205
|
-
ManagedResourceConformanceScenarioSchema,
|
|
2206
|
-
ManagedResourceConformanceScenarioIdSchema,
|
|
2207
|
-
ManagedResourceConformancePhaseSchema,
|
|
2208
|
-
ManagedResourceConformanceError
|
|
2209
|
-
};
|