stitchkit 0.94.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 +64 -0
- package/dist/agent-runtime/coding-shell-process.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 +3 -2
- package/dist/agent-runtime/deferred-tool-types.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/runtime.d.ts +1 -1
- 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/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.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.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/kernel-resource-context.d.ts.map +1 -1
- package/dist/application/notification-outbox.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 +2 -2
- 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.d.ts +3 -2
- package/dist/browser/client.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 +1 -3
- 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/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 +2 -18
- package/dist/browser/socket-io.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 +3 -357
- package/dist/contract/define.d.ts.map +1 -1
- 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 +15 -2
- package/dist/contract/tool-view.d.ts.map +1 -1
- package/dist/durability/contract.d.ts +83 -0
- package/dist/durability/contract.d.ts.map +1 -1
- package/dist/durability/effect.d.ts +24 -0
- package/dist/durability/effect.d.ts.map +1 -0
- package/dist/durability/engine.d.ts +2 -2
- package/dist/durability/engine.d.ts.map +1 -1
- package/dist/durability/events.d.ts +2 -0
- package/dist/durability/events.d.ts.map +1 -1
- package/dist/durability/ledger.d.ts +11 -0
- package/dist/durability/ledger.d.ts.map +1 -1
- package/dist/durability/parks.d.ts +22 -0
- package/dist/durability/parks.d.ts.map +1 -0
- package/dist/durability/scheduler.d.ts +1 -0
- package/dist/durability/scheduler.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/coding-tools.js +4 -4
- package/dist/entrypoints/agent-runtime/harness.js +127 -116
- package/dist/entrypoints/agent-runtime/sandbox.js +4 -4
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +3 -3
- package/dist/entrypoints/agent-runtime/sqlite/node.js +3 -3
- package/dist/entrypoints/agent-runtime/testing.js +246 -214
- package/dist/entrypoints/agent-runtime.js +224 -203
- package/dist/entrypoints/application/diagnostic-journal.js +63 -203
- package/dist/entrypoints/application/opentelemetry.js +1 -1
- package/dist/entrypoints/application.js +361 -324
- package/dist/entrypoints/cli.d.ts +4 -1
- package/dist/entrypoints/cli.d.ts.map +1 -1
- package/dist/entrypoints/cli.js +57 -35
- package/dist/entrypoints/contract.d.ts +5 -2
- package/dist/entrypoints/contract.d.ts.map +1 -1
- package/dist/entrypoints/contract.js +3 -2
- package/dist/entrypoints/files.d.ts +2 -0
- package/dist/entrypoints/files.d.ts.map +1 -1
- package/dist/entrypoints/files.js +98 -2
- package/dist/entrypoints/index.d.ts +4 -2
- package/dist/entrypoints/index.d.ts.map +1 -1
- package/dist/entrypoints/index.js +348 -282
- package/dist/entrypoints/live.js +89 -71
- package/dist/entrypoints/node.d.ts +2 -1
- package/dist/entrypoints/node.d.ts.map +1 -1
- package/dist/entrypoints/node.js +13 -12
- package/dist/entrypoints/react.js +1 -1
- package/dist/entrypoints/remote.js +4 -4
- package/dist/entrypoints/server.d.ts +4 -2
- package/dist/entrypoints/server.d.ts.map +1 -1
- package/dist/entrypoints/server.js +293 -79
- package/dist/entrypoints/testing.d.ts +2 -1
- package/dist/entrypoints/testing.d.ts.map +1 -1
- package/dist/entrypoints/testing.js +288 -281
- package/dist/entrypoints/tools/connections.js +2 -2
- package/dist/entrypoints/tools/invoker.js +4 -4
- package/dist/entrypoints/tools.d.ts +6 -3
- package/dist/entrypoints/tools.d.ts.map +1 -1
- package/dist/entrypoints/tools.js +245 -202
- package/dist/entrypoints/tracking.js +325 -274
- 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/index-1j8pm5t0.js +412 -0
- package/dist/{index-kvj7f4hq.js → index-2bxbyab0.js} +10 -2
- package/dist/{index-xnj9bgxe.js → index-2gxzjvyr.js} +2 -162
- package/dist/index-4gcnakhx.js +82 -0
- package/dist/{index-j05z5gn4.js → index-55hkhm67.js} +136 -119
- package/dist/{index-cq4qfycf.js → index-79z7m7dt.js} +227 -59
- package/dist/{index-97ac4gph.js → index-7f68ghdn.js} +3 -3
- package/dist/{index-r7nmqpsg.js → index-7p1f0vp2.js} +1 -1
- package/dist/{index-dcpdvjsc.js → index-863ea9jb.js} +4 -4
- package/dist/index-8p52kd5p.js +242 -0
- package/dist/{index-2qzskm8h.js → index-dce5wxcq.js} +1 -1
- package/dist/index-e01r054k.js +105 -0
- package/dist/{index-sees8yf8.js → index-ensd0r74.js} +118 -111
- package/dist/{index-1nd48tm9.js → index-gxrt5h6v.js} +2 -1
- package/dist/{index-e87kakm4.js → index-ham5sz8m.js} +112 -110
- package/dist/{index-kj2wbeta.js → index-het2he5g.js} +280 -196
- package/dist/{index-vcvkq30w.js → index-hmp4800j.js} +3 -3
- package/dist/{index-gyr48nzg.js → index-k30h66yd.js} +71 -151
- package/dist/{index-2cr1cqhn.js → index-khtgb21r.js} +2 -2
- package/dist/{index-x4799c19.js → index-ndddxtyx.js} +11 -11
- package/dist/{index-dydjcp8z.js → index-np4m8hd3.js} +38 -36
- package/dist/{index-p81267c2.js → index-p3vsv1fb.js} +621 -357
- package/dist/{index-mp5sn43f.js → index-p9e0w8hs.js} +2 -2
- package/dist/{index-rewkc2hj.js → index-p9sh0xx4.js} +3 -3
- package/dist/{index-70yj2ebz.js → index-paz6sgdp.js} +107 -103
- package/dist/{index-bn2cjajt.js → index-px2gm2jp.js} +26 -102
- package/dist/index-s812ycat.js +65 -0
- package/dist/{index-xsqjkha9.js → index-sp1tzwnb.js} +2 -2
- package/dist/{index-n6hxg8as.js → index-t9rhjr9f.js} +615 -566
- package/dist/{index-zeemqhqx.js → index-v260df89.js} +88 -80
- package/dist/{index-fdp6hdxn.js → index-w906953s.js} +5 -1
- package/dist/{index-mdzh02yc.js → index-wdkt63w3.js} +1 -1
- package/dist/{index-58k4fp34.js → index-wsm5w4ee.js} +1 -1
- package/dist/{index-v38qyerb.js → index-xw3s75nj.js} +1 -1
- package/dist/internal/atomic-file.d.ts +23 -2
- package/dist/internal/atomic-file.d.ts.map +1 -1
- package/dist/internal/exclusive-lock.d.ts +51 -0
- package/dist/internal/exclusive-lock.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/with-exclusive-lock.d.ts +67 -0
- package/dist/internal/with-exclusive-lock.d.ts.map +1 -0
- package/dist/live/watch-client.d.ts.map +1 -1
- package/dist/observability/audit.d.ts +2 -2
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/event.d.ts +2 -1
- package/dist/observability/event.d.ts.map +1 -1
- package/dist/primitives/export-operation.d.ts +1 -1
- 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/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 +1 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/endpoint-response.d.ts +2 -1
- package/dist/server/endpoint-response.d.ts.map +1 -1
- package/dist/server/error-dispatch.d.ts +1 -1
- package/dist/server/error-dispatch.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +1 -1
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/handler-state.d.ts +1 -1
- package/dist/server/handler-state.d.ts.map +1 -1
- 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/jwt.d.ts +31 -0
- package/dist/server/middleware/jwt.d.ts.map +1 -0
- 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/provider.d.ts +1 -68
- package/dist/server/oauth/provider.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 +4 -1
- 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 +2 -1
- package/dist/testing/handler-clients.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 +0 -31
- 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.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 +2 -65
- package/dist/tools/cli/args.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/tools/cli/command.d.ts +1 -1
- package/dist/tools/cli/command.d.ts.map +1 -1
- package/dist/tools/cli/config.d.ts +1 -1
- package/dist/tools/cli/config.d.ts.map +1 -1
- package/dist/tools/cli/format.d.ts +2 -1
- package/dist/tools/cli/format.d.ts.map +1 -1
- package/dist/tools/cli/invoke.d.ts +2 -1
- package/dist/tools/cli/invoke.d.ts.map +1 -1
- package/dist/tools/cli/managed-surface.d.ts +1 -1
- package/dist/tools/cli/managed-surface.d.ts.map +1 -1
- package/dist/tools/cli/policy.d.ts +1 -1
- package/dist/tools/cli/policy.d.ts.map +1 -1
- package/dist/tools/cli/prepare.d.ts.map +1 -1
- package/dist/tools/cli/run-managed.d.ts.map +1 -1
- package/dist/tools/cli/session.d.ts +1 -1
- package/dist/tools/cli/session.d.ts.map +1 -1
- package/dist/tools/cli/update.d.ts +19 -0
- package/dist/tools/cli/update.d.ts.map +1 -1
- package/dist/tools/cli/view.d.ts +1 -1
- package/dist/tools/cli/view.d.ts.map +1 -1
- package/dist/tools/cli/wait.d.ts +1 -1
- package/dist/tools/cli/wait.d.ts.map +1 -1
- package/dist/tools/connections/runtime.d.ts +1 -1
- package/dist/tools/connections/runtime.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 +4 -193
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools/internal/surface-projector.d.ts +2 -1
- package/dist/tools/internal/surface-projector.d.ts.map +1 -1
- package/dist/tools/invoker.d.ts +2 -1
- 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/mcp/mount.d.ts +1 -1
- package/dist/tools/mcp/mount.d.ts.map +1 -1
- package/dist/tools/mcp/prepare.d.ts +2 -1
- package/dist/tools/mcp/prepare.d.ts.map +1 -1
- package/dist/tools/mcp/progress.d.ts +1 -1
- package/dist/tools/mcp/progress.d.ts.map +1 -1
- package/dist/tools/mcp/register.d.ts +3 -2
- package/dist/tools/mcp/register.d.ts.map +1 -1
- 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 +1 -1
- package/dist/tools/mcp/round-policy.d.ts.map +1 -1
- package/dist/tools/mcp/round.d.ts +3 -11
- package/dist/tools/mcp/round.d.ts.map +1 -1
- package/dist/tools/mcp/runtime-tools.d.ts +2 -1
- package/dist/tools/mcp/runtime-tools.d.ts.map +1 -1
- package/dist/tools/mount.d.ts +3 -1
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/native-definition.d.ts +2 -1
- package/dist/tools/native-definition.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-runtime-tools.d.ts +2 -1
- package/dist/tools/operations/async-operation-runtime-tools.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-runtime-types.d.ts +2 -1
- package/dist/tools/operations/async-operation-runtime-types.d.ts.map +1 -1
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/runtime-tool.d.ts +3 -1
- package/dist/tools/runtime-tool.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/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/llms/application.2.txt +266 -2
- package/llms/application.txt +8 -266
- package/llms/cli.2.txt +80 -0
- package/llms/cli.txt +45 -74
- package/llms/contract.txt +3 -3
- package/llms/files.txt +3 -0
- package/llms/tools.2.txt +88 -279
- package/llms/tools.3.txt +288 -0
- package/llms/tools.txt +27 -65
- package/llms-full.txt +108 -12
- package/llms.txt +5 -5
- package/package.json +1 -1
- package/dist/index-e2z3ahw9.js +0 -325
- package/dist/index-mkm15s49.js +0 -394
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMemoryAgentRuntimeStore
|
|
3
|
-
} from "../../index-
|
|
4
|
-
import"../../index-
|
|
3
|
+
} from "../../index-sp1tzwnb.js";
|
|
4
|
+
import"../../index-wsm5w4ee.js";
|
|
5
5
|
import {
|
|
6
6
|
decodeAgentConversationArchive
|
|
7
|
-
} from "../../index-
|
|
7
|
+
} from "../../index-gxrt5h6v.js";
|
|
8
8
|
import {
|
|
9
9
|
AgentMessageSchema,
|
|
10
10
|
AgentRunSchema
|
|
@@ -153,7 +153,7 @@ function createReplayAgentProvider(input) {
|
|
|
153
153
|
calls: (modelId) => calls.get(modelId) ?? 0
|
|
154
154
|
};
|
|
155
155
|
}
|
|
156
|
-
// src/agent-runtime/store-conformance.ts
|
|
156
|
+
// src/agent-runtime/store-conformance-support.ts
|
|
157
157
|
function userMessage(conversationId, id) {
|
|
158
158
|
return AgentMessageSchema.parse({
|
|
159
159
|
schemaVersion: 1,
|
|
@@ -184,90 +184,9 @@ function requireOutcome(actual, expected) {
|
|
|
184
184
|
throw new Error(`Agent store conformance expected ${expected}, received ${actual.outcome}`);
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
conversationIds: [
|
|
191
|
-
run,
|
|
192
|
-
`${run}-recovery`,
|
|
193
|
-
`${run}-absorb`,
|
|
194
|
-
`${run}-causal-history`,
|
|
195
|
-
`${run}-causal-active`,
|
|
196
|
-
`${run}-interrupt-priority`,
|
|
197
|
-
`${run}-ledger`,
|
|
198
|
-
`${run}-archive`,
|
|
199
|
-
`${run}-seed`
|
|
200
|
-
]
|
|
201
|
-
};
|
|
202
|
-
const store = await config.createStore(context);
|
|
203
|
-
let failure;
|
|
204
|
-
try {
|
|
205
|
-
await conformanceScenario(store, context.conversationIds);
|
|
206
|
-
} catch (error) {
|
|
207
|
-
failure = error;
|
|
208
|
-
}
|
|
209
|
-
try {
|
|
210
|
-
await config.cleanup?.(context);
|
|
211
|
-
} catch (cleanupError) {
|
|
212
|
-
if (failure === undefined)
|
|
213
|
-
throw cleanupError;
|
|
214
|
-
throw new AggregateError([failure, cleanupError], `${failure instanceof Error ? failure.message : String(failure)} (cleanup also failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)})`);
|
|
215
|
-
}
|
|
216
|
-
if (failure !== undefined)
|
|
217
|
-
throw failure;
|
|
218
|
-
}
|
|
219
|
-
async function seedScenario(store, conversationId) {
|
|
220
|
-
const input = {
|
|
221
|
-
conversationId,
|
|
222
|
-
seedKey: "brief",
|
|
223
|
-
inputs: [userMessage(conversationId, "seed-a"), userMessage(conversationId, "seed-b")]
|
|
224
|
-
};
|
|
225
|
-
const first = await store.seedConversationInput(input);
|
|
226
|
-
requireOutcome(first, "applied");
|
|
227
|
-
const before = await store.loadSnapshot(conversationId);
|
|
228
|
-
if (before.messages.map((message) => message.id).join(",") !== "seed-a,seed-b")
|
|
229
|
-
throw new Error("Seed conformance: complete ordered seed missing");
|
|
230
|
-
await Promise.all([store.seedConversationInput(input), store.seedConversationInput(input)]);
|
|
231
|
-
const repeated = await store.loadSnapshot(conversationId);
|
|
232
|
-
if (repeated.version !== before.version || repeated.messages.length !== 2)
|
|
233
|
-
throw new Error("Seed conformance: replay changed history");
|
|
234
|
-
const compacted = await store.replaceCompactedRange({
|
|
235
|
-
conversationId,
|
|
236
|
-
expectedVersion: repeated.version,
|
|
237
|
-
replacedMessageIds: ["seed-a", "seed-b"],
|
|
238
|
-
summary: AgentMessageSchema.parse({
|
|
239
|
-
...userMessage(conversationId, "seed-summary"),
|
|
240
|
-
role: "summary"
|
|
241
|
-
})
|
|
242
|
-
});
|
|
243
|
-
requireOutcome(compacted, "applied");
|
|
244
|
-
await store.seedConversationInput(input);
|
|
245
|
-
const after = await store.loadSnapshot(conversationId);
|
|
246
|
-
if (after.messages.some((message) => message.id === "seed-a" || message.id === "seed-b"))
|
|
247
|
-
throw new Error("Seed conformance: compacted instructions resurrected");
|
|
248
|
-
}
|
|
249
|
-
async function conformanceScenario(store, conversationIds) {
|
|
250
|
-
const [
|
|
251
|
-
conversationId,
|
|
252
|
-
recoveryConversationId,
|
|
253
|
-
absorbConversationId,
|
|
254
|
-
causalHistoryConversationId,
|
|
255
|
-
causalActiveConversationId,
|
|
256
|
-
interruptPriorityConversationId,
|
|
257
|
-
ledgerConversationId,
|
|
258
|
-
archiveConversationId,
|
|
259
|
-
seedConversationId
|
|
260
|
-
] = conversationIds;
|
|
261
|
-
if (seedConversationId)
|
|
262
|
-
await seedScenario(store, seedConversationId);
|
|
263
|
-
if (ledgerConversationId)
|
|
264
|
-
await ledgerScenario(store, ledgerConversationId);
|
|
265
|
-
if (archiveConversationId)
|
|
266
|
-
await archiveScenario(store, archiveConversationId);
|
|
267
|
-
if (!conversationId || !recoveryConversationId || !absorbConversationId || !causalHistoryConversationId || !causalActiveConversationId || !interruptPriorityConversationId) {
|
|
268
|
-
throw new Error("Agent store conformance requires six conversation identities");
|
|
269
|
-
}
|
|
270
|
-
const absentConversationId = `${conversationId}-absent`;
|
|
187
|
+
|
|
188
|
+
// src/agent-runtime/store-conformance-lifecycle.ts
|
|
189
|
+
async function admissionPhase(store, conversationId) {
|
|
271
190
|
const firstInput = userMessage(conversationId, "input-1");
|
|
272
191
|
const firstRun = queuedRun(conversationId, firstInput.id, "run-1");
|
|
273
192
|
const accepted = await store.acceptInputAndAssignRun({
|
|
@@ -354,6 +273,9 @@ async function conformanceScenario(store, conversationIds) {
|
|
|
354
273
|
if (duplicateAfterCompaction.input.id !== firstInput.id) {
|
|
355
274
|
throw new Error("Compaction discarded the canonical duplicate admission input");
|
|
356
275
|
}
|
|
276
|
+
return assigned;
|
|
277
|
+
}
|
|
278
|
+
async function fencingPhase(store, conversationId, assigned) {
|
|
357
279
|
const acquired = await store.acquireRun({
|
|
358
280
|
conversationId,
|
|
359
281
|
runId: assigned.id,
|
|
@@ -477,6 +399,10 @@ async function conformanceScenario(store, conversationIds) {
|
|
|
477
399
|
if (foreignOwner.outcome !== "conflict") {
|
|
478
400
|
throw new Error("A checkpoint from another owner must conflict");
|
|
479
401
|
}
|
|
402
|
+
return { running, checkpoint, checkpointedRun, terminalAssistant };
|
|
403
|
+
}
|
|
404
|
+
async function boundedReadsPhase(store, conversationId, absentConversationId, checkpointed) {
|
|
405
|
+
const { running, checkpoint, checkpointedRun } = checkpointed;
|
|
480
406
|
const liveView = await store.loadRun({ conversationId, runId: running.id });
|
|
481
407
|
if (!liveView)
|
|
482
408
|
throw new Error("loadRun must find a run of this conversation");
|
|
@@ -521,6 +447,9 @@ async function conformanceScenario(store, conversationIds) {
|
|
|
521
447
|
if ((await store.listActiveRuns(absentConversationId)).length !== 0) {
|
|
522
448
|
throw new Error("listActiveRuns must be empty for an unknown conversation");
|
|
523
449
|
}
|
|
450
|
+
}
|
|
451
|
+
async function interruptPhase(store, conversationId, checkpointed) {
|
|
452
|
+
const { running, checkpointedRun } = checkpointed;
|
|
524
453
|
const recoverable = await store.scanRecoverable({ limit: 10 });
|
|
525
454
|
if (!recoverable.items.some((item) => item.run.id === running.id)) {
|
|
526
455
|
throw new Error("A running run must appear in a recoverable scan");
|
|
@@ -562,133 +491,10 @@ async function conformanceScenario(store, conversationIds) {
|
|
|
562
491
|
if (interruptedRun.usage?.cost?.value !== 0.25) {
|
|
563
492
|
throw new Error("An interrupt must not discard the figure the run had already spent");
|
|
564
493
|
}
|
|
565
|
-
|
|
566
|
-
inputTokens: { value: 3000, provenance: "computed" },
|
|
567
|
-
outputTokens: { value: 300, provenance: "computed" },
|
|
568
|
-
reasoningTokens: { value: 30, provenance: "computed" },
|
|
569
|
-
cacheReadTokens: { value: 200, provenance: "computed" },
|
|
570
|
-
cacheWriteTokens: { value: 100, provenance: "computed" },
|
|
571
|
-
cost: { value: 1.5, currency: "USD", provenance: "computed" }
|
|
572
|
-
};
|
|
573
|
-
const terminalResults = await Promise.all([
|
|
574
|
-
store.commitRunTerminal({
|
|
575
|
-
conversationId,
|
|
576
|
-
runId: running.id,
|
|
577
|
-
expectedRevision: interruptedRun.revision,
|
|
578
|
-
ownerId: "conformance-owner",
|
|
579
|
-
assistant: terminalAssistant,
|
|
580
|
-
reason: "success",
|
|
581
|
-
usage: terminalUsage
|
|
582
|
-
}),
|
|
583
|
-
store.commitRunTerminal({
|
|
584
|
-
conversationId,
|
|
585
|
-
runId: running.id,
|
|
586
|
-
expectedRevision: interruptedRun.revision,
|
|
587
|
-
ownerId: "conformance-owner",
|
|
588
|
-
assistant: terminalAssistant,
|
|
589
|
-
reason: "success",
|
|
590
|
-
usage: terminalUsage
|
|
591
|
-
})
|
|
592
|
-
]);
|
|
593
|
-
const terminalOutcomes = terminalResults.map((result) => result.outcome).sort();
|
|
594
|
-
if (terminalOutcomes.join(",") !== "applied,conflict") {
|
|
595
|
-
throw new Error(`Terminal race was not linearized: ${terminalOutcomes.join(",")}`);
|
|
596
|
-
}
|
|
597
|
-
const terminalApplied = terminalResults.find((result) => result.outcome === "applied");
|
|
598
|
-
if (terminalApplied?.outcome !== "applied") {
|
|
599
|
-
throw new Error("Terminal race produced no applied result");
|
|
600
|
-
}
|
|
601
|
-
const settledRun = terminalApplied.snapshot.runs.find((run) => run.id === running.id);
|
|
602
|
-
if (JSON.stringify(settledRun?.usage) !== JSON.stringify(terminalUsage)) {
|
|
603
|
-
throw new Error("Terminal commit did not persist the run usage it was given");
|
|
604
|
-
}
|
|
605
|
-
const terminalView = await store.loadRun({ conversationId, runId: running.id });
|
|
606
|
-
if (terminalView?.run.terminalReason !== "success") {
|
|
607
|
-
throw new Error("loadRun must report the terminal reason a settled run ended with");
|
|
608
|
-
}
|
|
609
|
-
if (JSON.stringify(terminalView.run.usage) !== JSON.stringify(terminalUsage)) {
|
|
610
|
-
throw new Error("loadRun must return every persisted terminal usage field");
|
|
611
|
-
}
|
|
612
|
-
if (JSON.stringify(terminalView.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
613
|
-
throw new Error("loadRun must retain the answer a settled run produced");
|
|
614
|
-
}
|
|
615
|
-
if ((await store.listActiveRuns(conversationId)).some((run) => run.id === running.id)) {
|
|
616
|
-
throw new Error("listActiveRuns must drop a run once it has ended");
|
|
617
|
-
}
|
|
618
|
-
const compactedTerminal = await store.replaceCompactedRange({
|
|
619
|
-
conversationId,
|
|
620
|
-
expectedVersion: terminalApplied.snapshot.version,
|
|
621
|
-
replacedMessageIds: ["summary-1", terminalAssistant.id],
|
|
622
|
-
summary: AgentMessageSchema.parse({
|
|
623
|
-
schemaVersion: 1,
|
|
624
|
-
id: "summary-2",
|
|
625
|
-
conversationId,
|
|
626
|
-
role: "summary",
|
|
627
|
-
status: "committed",
|
|
628
|
-
parts: [{ type: "text", text: "terminal history" }],
|
|
629
|
-
createdAt: "2026-08-22T00:00:03.000Z",
|
|
630
|
-
updatedAt: "2026-08-22T00:00:03.000Z"
|
|
631
|
-
})
|
|
632
|
-
});
|
|
633
|
-
requireOutcome(compactedTerminal, "applied");
|
|
634
|
-
const duplicateTerminal = await store.acceptInputAndAssignRun({
|
|
635
|
-
idempotencyKey: "request-1",
|
|
636
|
-
input: userMessage(conversationId, "discarded-terminal-input"),
|
|
637
|
-
run: queuedRun(conversationId, "discarded-terminal-input", "discarded-terminal-run")
|
|
638
|
-
});
|
|
639
|
-
requireOutcome(duplicateTerminal, "duplicate");
|
|
640
|
-
if (duplicateTerminal.run.terminalReason !== "success" || JSON.stringify(duplicateTerminal.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
641
|
-
throw new Error("Compaction discarded the canonical duplicate terminal result");
|
|
642
|
-
}
|
|
643
|
-
const recoveryInput = userMessage(recoveryConversationId, "recovery-input");
|
|
644
|
-
const recoveryRun = queuedRun(recoveryConversationId, recoveryInput.id, "recovery-run");
|
|
645
|
-
const recoveryAccepted = await store.acceptInputAndAssignRun({
|
|
646
|
-
idempotencyKey: "recovery-request",
|
|
647
|
-
input: recoveryInput,
|
|
648
|
-
run: recoveryRun
|
|
649
|
-
});
|
|
650
|
-
requireOutcome(recoveryAccepted, "applied");
|
|
651
|
-
const recoveryAssigned = recoveryAccepted.snapshot.runs.find((run) => run.id === recoveryRun.id);
|
|
652
|
-
if (!recoveryAssigned)
|
|
653
|
-
throw new Error("Recovery run disappeared after admission");
|
|
654
|
-
const recoveryAcquired = await store.acquireRun({
|
|
655
|
-
conversationId: recoveryConversationId,
|
|
656
|
-
runId: recoveryAssigned.id,
|
|
657
|
-
expectedRevision: recoveryAssigned.revision,
|
|
658
|
-
ownerId: "abandoned-owner"
|
|
659
|
-
});
|
|
660
|
-
requireOutcome(recoveryAcquired, "applied");
|
|
661
|
-
const abandonedRun = recoveryAcquired.snapshot.runs.find((run) => run.id === recoveryRun.id);
|
|
662
|
-
if (!abandonedRun)
|
|
663
|
-
throw new Error("Recovery run disappeared after acquisition");
|
|
664
|
-
const abandoned = await store.recoverRun({
|
|
665
|
-
conversationId: recoveryConversationId,
|
|
666
|
-
runId: abandonedRun.id,
|
|
667
|
-
expectedRevision: abandonedRun.revision,
|
|
668
|
-
action: "abandon"
|
|
669
|
-
});
|
|
670
|
-
requireOutcome(abandoned, "applied");
|
|
671
|
-
const terminalRun = abandoned.snapshot.runs.find((run) => run.id === abandonedRun.id);
|
|
672
|
-
const terminalMessage = abandoned.snapshot.messages.find((message) => message.id === abandonedRun.assistantMessageId);
|
|
673
|
-
if (terminalRun?.state !== "abandoned" || terminalMessage?.status !== "failed") {
|
|
674
|
-
throw new Error("Abandon recovery did not atomically terminalize its assistant record");
|
|
675
|
-
}
|
|
676
|
-
const abandonedView = await store.loadRun({
|
|
677
|
-
conversationId: recoveryConversationId,
|
|
678
|
-
runId: abandonedRun.id
|
|
679
|
-
});
|
|
680
|
-
if (abandonedView?.run.state !== "abandoned" || abandonedView.run.terminalReason !== "abandoned" || abandonedView.assistant?.status !== "failed") {
|
|
681
|
-
throw new Error("The canonical run record disagrees with its abandoned index projection");
|
|
682
|
-
}
|
|
683
|
-
const afterAbandon = await store.scanRecoverable({ limit: 100 });
|
|
684
|
-
if (afterAbandon.items.some((item) => item.run.id === abandonedRun.id)) {
|
|
685
|
-
throw new Error("The recoverable index still exposes a canonically abandoned run");
|
|
686
|
-
}
|
|
687
|
-
await assertCausalHistoryOrder(store, causalHistoryConversationId);
|
|
688
|
-
await assertActiveRunCausalOrder(store, causalActiveConversationId);
|
|
689
|
-
await assertInterruptPriorityOrder(store, interruptPriorityConversationId);
|
|
690
|
-
await assertAbsorptionIsAtomic(store, absorbConversationId);
|
|
494
|
+
return interruptedRun;
|
|
691
495
|
}
|
|
496
|
+
|
|
497
|
+
// src/agent-runtime/store-conformance-ordering.ts
|
|
692
498
|
async function assertInterruptPriorityOrder(store, conversationId) {
|
|
693
499
|
const inputs = ["priority-a", "priority-b", "priority-c"].map((id) => userMessage(conversationId, id));
|
|
694
500
|
const [inputA, inputB, inputC] = inputs;
|
|
@@ -931,6 +737,232 @@ async function assertAbsorptionIsAtomic(store, conversationId) {
|
|
|
931
737
|
throw new Error("A retried absorbed key must still name its own input");
|
|
932
738
|
}
|
|
933
739
|
}
|
|
740
|
+
|
|
741
|
+
// src/agent-runtime/store-conformance-terminal.ts
|
|
742
|
+
async function terminalPhase(store, conversationId, checkpointed, interruptedRun) {
|
|
743
|
+
const { running, terminalAssistant } = checkpointed;
|
|
744
|
+
const terminalUsage = {
|
|
745
|
+
inputTokens: { value: 3000, provenance: "computed" },
|
|
746
|
+
outputTokens: { value: 300, provenance: "computed" },
|
|
747
|
+
reasoningTokens: { value: 30, provenance: "computed" },
|
|
748
|
+
cacheReadTokens: { value: 200, provenance: "computed" },
|
|
749
|
+
cacheWriteTokens: { value: 100, provenance: "computed" },
|
|
750
|
+
cost: { value: 1.5, currency: "USD", provenance: "computed" }
|
|
751
|
+
};
|
|
752
|
+
const terminalResults = await Promise.all([
|
|
753
|
+
store.commitRunTerminal({
|
|
754
|
+
conversationId,
|
|
755
|
+
runId: running.id,
|
|
756
|
+
expectedRevision: interruptedRun.revision,
|
|
757
|
+
ownerId: "conformance-owner",
|
|
758
|
+
assistant: terminalAssistant,
|
|
759
|
+
reason: "success",
|
|
760
|
+
usage: terminalUsage
|
|
761
|
+
}),
|
|
762
|
+
store.commitRunTerminal({
|
|
763
|
+
conversationId,
|
|
764
|
+
runId: running.id,
|
|
765
|
+
expectedRevision: interruptedRun.revision,
|
|
766
|
+
ownerId: "conformance-owner",
|
|
767
|
+
assistant: terminalAssistant,
|
|
768
|
+
reason: "success",
|
|
769
|
+
usage: terminalUsage
|
|
770
|
+
})
|
|
771
|
+
]);
|
|
772
|
+
const terminalOutcomes = terminalResults.map((result) => result.outcome).sort();
|
|
773
|
+
if (terminalOutcomes.join(",") !== "applied,conflict") {
|
|
774
|
+
throw new Error(`Terminal race was not linearized: ${terminalOutcomes.join(",")}`);
|
|
775
|
+
}
|
|
776
|
+
const terminalApplied = terminalResults.find((result) => result.outcome === "applied");
|
|
777
|
+
if (terminalApplied?.outcome !== "applied") {
|
|
778
|
+
throw new Error("Terminal race produced no applied result");
|
|
779
|
+
}
|
|
780
|
+
const settledRun = terminalApplied.snapshot.runs.find((run) => run.id === running.id);
|
|
781
|
+
if (JSON.stringify(settledRun?.usage) !== JSON.stringify(terminalUsage)) {
|
|
782
|
+
throw new Error("Terminal commit did not persist the run usage it was given");
|
|
783
|
+
}
|
|
784
|
+
const terminalView = await store.loadRun({ conversationId, runId: running.id });
|
|
785
|
+
if (terminalView?.run.terminalReason !== "success") {
|
|
786
|
+
throw new Error("loadRun must report the terminal reason a settled run ended with");
|
|
787
|
+
}
|
|
788
|
+
if (JSON.stringify(terminalView.run.usage) !== JSON.stringify(terminalUsage)) {
|
|
789
|
+
throw new Error("loadRun must return every persisted terminal usage field");
|
|
790
|
+
}
|
|
791
|
+
if (JSON.stringify(terminalView.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
792
|
+
throw new Error("loadRun must retain the answer a settled run produced");
|
|
793
|
+
}
|
|
794
|
+
if ((await store.listActiveRuns(conversationId)).some((run) => run.id === running.id)) {
|
|
795
|
+
throw new Error("listActiveRuns must drop a run once it has ended");
|
|
796
|
+
}
|
|
797
|
+
const compactedTerminal = await store.replaceCompactedRange({
|
|
798
|
+
conversationId,
|
|
799
|
+
expectedVersion: terminalApplied.snapshot.version,
|
|
800
|
+
replacedMessageIds: ["summary-1", terminalAssistant.id],
|
|
801
|
+
summary: AgentMessageSchema.parse({
|
|
802
|
+
schemaVersion: 1,
|
|
803
|
+
id: "summary-2",
|
|
804
|
+
conversationId,
|
|
805
|
+
role: "summary",
|
|
806
|
+
status: "committed",
|
|
807
|
+
parts: [{ type: "text", text: "terminal history" }],
|
|
808
|
+
createdAt: "2026-08-22T00:00:03.000Z",
|
|
809
|
+
updatedAt: "2026-08-22T00:00:03.000Z"
|
|
810
|
+
})
|
|
811
|
+
});
|
|
812
|
+
requireOutcome(compactedTerminal, "applied");
|
|
813
|
+
const duplicateTerminal = await store.acceptInputAndAssignRun({
|
|
814
|
+
idempotencyKey: "request-1",
|
|
815
|
+
input: userMessage(conversationId, "discarded-terminal-input"),
|
|
816
|
+
run: queuedRun(conversationId, "discarded-terminal-input", "discarded-terminal-run")
|
|
817
|
+
});
|
|
818
|
+
requireOutcome(duplicateTerminal, "duplicate");
|
|
819
|
+
if (duplicateTerminal.run.terminalReason !== "success" || JSON.stringify(duplicateTerminal.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
820
|
+
throw new Error("Compaction discarded the canonical duplicate terminal result");
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
async function abandonPhase(store, recoveryConversationId) {
|
|
824
|
+
const recoveryInput = userMessage(recoveryConversationId, "recovery-input");
|
|
825
|
+
const recoveryRun = queuedRun(recoveryConversationId, recoveryInput.id, "recovery-run");
|
|
826
|
+
const recoveryAccepted = await store.acceptInputAndAssignRun({
|
|
827
|
+
idempotencyKey: "recovery-request",
|
|
828
|
+
input: recoveryInput,
|
|
829
|
+
run: recoveryRun
|
|
830
|
+
});
|
|
831
|
+
requireOutcome(recoveryAccepted, "applied");
|
|
832
|
+
const recoveryAssigned = recoveryAccepted.snapshot.runs.find((run) => run.id === recoveryRun.id);
|
|
833
|
+
if (!recoveryAssigned)
|
|
834
|
+
throw new Error("Recovery run disappeared after admission");
|
|
835
|
+
const recoveryAcquired = await store.acquireRun({
|
|
836
|
+
conversationId: recoveryConversationId,
|
|
837
|
+
runId: recoveryAssigned.id,
|
|
838
|
+
expectedRevision: recoveryAssigned.revision,
|
|
839
|
+
ownerId: "abandoned-owner"
|
|
840
|
+
});
|
|
841
|
+
requireOutcome(recoveryAcquired, "applied");
|
|
842
|
+
const abandonedRun = recoveryAcquired.snapshot.runs.find((run) => run.id === recoveryRun.id);
|
|
843
|
+
if (!abandonedRun)
|
|
844
|
+
throw new Error("Recovery run disappeared after acquisition");
|
|
845
|
+
const abandoned = await store.recoverRun({
|
|
846
|
+
conversationId: recoveryConversationId,
|
|
847
|
+
runId: abandonedRun.id,
|
|
848
|
+
expectedRevision: abandonedRun.revision,
|
|
849
|
+
action: "abandon"
|
|
850
|
+
});
|
|
851
|
+
requireOutcome(abandoned, "applied");
|
|
852
|
+
const terminalRun = abandoned.snapshot.runs.find((run) => run.id === abandonedRun.id);
|
|
853
|
+
const terminalMessage = abandoned.snapshot.messages.find((message) => message.id === abandonedRun.assistantMessageId);
|
|
854
|
+
if (terminalRun?.state !== "abandoned" || terminalMessage?.status !== "failed") {
|
|
855
|
+
throw new Error("Abandon recovery did not atomically terminalize its assistant record");
|
|
856
|
+
}
|
|
857
|
+
const abandonedView = await store.loadRun({
|
|
858
|
+
conversationId: recoveryConversationId,
|
|
859
|
+
runId: abandonedRun.id
|
|
860
|
+
});
|
|
861
|
+
if (abandonedView?.run.state !== "abandoned" || abandonedView.run.terminalReason !== "abandoned" || abandonedView.assistant?.status !== "failed") {
|
|
862
|
+
throw new Error("The canonical run record disagrees with its abandoned index projection");
|
|
863
|
+
}
|
|
864
|
+
const afterAbandon = await store.scanRecoverable({ limit: 100 });
|
|
865
|
+
if (afterAbandon.items.some((item) => item.run.id === abandonedRun.id)) {
|
|
866
|
+
throw new Error("The recoverable index still exposes a canonically abandoned run");
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// src/agent-runtime/store-conformance.ts
|
|
871
|
+
async function runAgentStoreConformance(config) {
|
|
872
|
+
const run = `conformance-${crypto.randomUUID()}`;
|
|
873
|
+
const context = {
|
|
874
|
+
conversationIds: [
|
|
875
|
+
run,
|
|
876
|
+
`${run}-recovery`,
|
|
877
|
+
`${run}-absorb`,
|
|
878
|
+
`${run}-causal-history`,
|
|
879
|
+
`${run}-causal-active`,
|
|
880
|
+
`${run}-interrupt-priority`,
|
|
881
|
+
`${run}-ledger`,
|
|
882
|
+
`${run}-archive`,
|
|
883
|
+
`${run}-seed`
|
|
884
|
+
]
|
|
885
|
+
};
|
|
886
|
+
const store = await config.createStore(context);
|
|
887
|
+
let failure;
|
|
888
|
+
try {
|
|
889
|
+
await conformanceScenario(store, context.conversationIds);
|
|
890
|
+
} catch (error) {
|
|
891
|
+
failure = error;
|
|
892
|
+
}
|
|
893
|
+
try {
|
|
894
|
+
await config.cleanup?.(context);
|
|
895
|
+
} catch (cleanupError) {
|
|
896
|
+
if (failure === undefined)
|
|
897
|
+
throw cleanupError;
|
|
898
|
+
throw new AggregateError([failure, cleanupError], `${failure instanceof Error ? failure.message : String(failure)} (cleanup also failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)})`);
|
|
899
|
+
}
|
|
900
|
+
if (failure !== undefined)
|
|
901
|
+
throw failure;
|
|
902
|
+
}
|
|
903
|
+
async function seedScenario(store, conversationId) {
|
|
904
|
+
const input = {
|
|
905
|
+
conversationId,
|
|
906
|
+
seedKey: "brief",
|
|
907
|
+
inputs: [userMessage(conversationId, "seed-a"), userMessage(conversationId, "seed-b")]
|
|
908
|
+
};
|
|
909
|
+
const first = await store.seedConversationInput(input);
|
|
910
|
+
requireOutcome(first, "applied");
|
|
911
|
+
const before = await store.loadSnapshot(conversationId);
|
|
912
|
+
if (before.messages.map((message) => message.id).join(",") !== "seed-a,seed-b")
|
|
913
|
+
throw new Error("Seed conformance: complete ordered seed missing");
|
|
914
|
+
await Promise.all([store.seedConversationInput(input), store.seedConversationInput(input)]);
|
|
915
|
+
const repeated = await store.loadSnapshot(conversationId);
|
|
916
|
+
if (repeated.version !== before.version || repeated.messages.length !== 2)
|
|
917
|
+
throw new Error("Seed conformance: replay changed history");
|
|
918
|
+
const compacted = await store.replaceCompactedRange({
|
|
919
|
+
conversationId,
|
|
920
|
+
expectedVersion: repeated.version,
|
|
921
|
+
replacedMessageIds: ["seed-a", "seed-b"],
|
|
922
|
+
summary: AgentMessageSchema.parse({
|
|
923
|
+
...userMessage(conversationId, "seed-summary"),
|
|
924
|
+
role: "summary"
|
|
925
|
+
})
|
|
926
|
+
});
|
|
927
|
+
requireOutcome(compacted, "applied");
|
|
928
|
+
await store.seedConversationInput(input);
|
|
929
|
+
const after = await store.loadSnapshot(conversationId);
|
|
930
|
+
if (after.messages.some((message) => message.id === "seed-a" || message.id === "seed-b"))
|
|
931
|
+
throw new Error("Seed conformance: compacted instructions resurrected");
|
|
932
|
+
}
|
|
933
|
+
async function conformanceScenario(store, conversationIds) {
|
|
934
|
+
const [
|
|
935
|
+
conversationId,
|
|
936
|
+
recoveryConversationId,
|
|
937
|
+
absorbConversationId,
|
|
938
|
+
causalHistoryConversationId,
|
|
939
|
+
causalActiveConversationId,
|
|
940
|
+
interruptPriorityConversationId,
|
|
941
|
+
ledgerConversationId,
|
|
942
|
+
archiveConversationId,
|
|
943
|
+
seedConversationId
|
|
944
|
+
] = conversationIds;
|
|
945
|
+
if (seedConversationId)
|
|
946
|
+
await seedScenario(store, seedConversationId);
|
|
947
|
+
if (ledgerConversationId)
|
|
948
|
+
await ledgerScenario(store, ledgerConversationId);
|
|
949
|
+
if (archiveConversationId)
|
|
950
|
+
await archiveScenario(store, archiveConversationId);
|
|
951
|
+
if (!conversationId || !recoveryConversationId || !absorbConversationId || !causalHistoryConversationId || !causalActiveConversationId || !interruptPriorityConversationId) {
|
|
952
|
+
throw new Error("Agent store conformance requires six conversation identities");
|
|
953
|
+
}
|
|
954
|
+
const absentConversationId = `${conversationId}-absent`;
|
|
955
|
+
const assigned = await admissionPhase(store, conversationId);
|
|
956
|
+
const checkpointed = await fencingPhase(store, conversationId, assigned);
|
|
957
|
+
await boundedReadsPhase(store, conversationId, absentConversationId, checkpointed);
|
|
958
|
+
const interruptedRun = await interruptPhase(store, conversationId, checkpointed);
|
|
959
|
+
await terminalPhase(store, conversationId, checkpointed, interruptedRun);
|
|
960
|
+
await abandonPhase(store, recoveryConversationId);
|
|
961
|
+
await assertCausalHistoryOrder(store, causalHistoryConversationId);
|
|
962
|
+
await assertActiveRunCausalOrder(store, causalActiveConversationId);
|
|
963
|
+
await assertInterruptPriorityOrder(store, interruptPriorityConversationId);
|
|
964
|
+
await assertAbsorptionIsAtomic(store, absorbConversationId);
|
|
965
|
+
}
|
|
934
966
|
async function ledgerScenario(store, conversationId) {
|
|
935
967
|
const first = await store.appendEvent({
|
|
936
968
|
conversationId,
|