stitchkit 0.56.5 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/agent-runtime/compaction.d.ts +3 -0
  2. package/dist/agent-runtime/compaction.d.ts.map +1 -1
  3. package/dist/agent-runtime/events.d.ts +693 -0
  4. package/dist/agent-runtime/events.d.ts.map +1 -1
  5. package/dist/agent-runtime/history.d.ts +13 -0
  6. package/dist/agent-runtime/history.d.ts.map +1 -1
  7. package/dist/agent-runtime/managed-tools.d.ts +1 -0
  8. package/dist/agent-runtime/managed-tools.d.ts.map +1 -1
  9. package/dist/agent-runtime/models.d.ts +39 -3
  10. package/dist/agent-runtime/models.d.ts.map +1 -1
  11. package/dist/agent-runtime/observability.d.ts +3 -0
  12. package/dist/agent-runtime/observability.d.ts.map +1 -1
  13. package/dist/agent-runtime/prompt.d.ts +21 -0
  14. package/dist/agent-runtime/prompt.d.ts.map +1 -1
  15. package/dist/agent-runtime/runtime.d.ts +43 -4
  16. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  17. package/dist/agent-runtime/schemas.d.ts +75 -0
  18. package/dist/agent-runtime/schemas.d.ts.map +1 -1
  19. package/dist/agent-runtime/store-driver.d.ts +409 -0
  20. package/dist/agent-runtime/store-driver.d.ts.map +1 -0
  21. package/dist/agent-runtime/store.d.ts +169 -2
  22. package/dist/agent-runtime/store.d.ts.map +1 -1
  23. package/dist/agent-runtime/testing.d.ts +10 -1
  24. package/dist/agent-runtime/testing.d.ts.map +1 -1
  25. package/dist/agent-runtime.d.ts +7 -6
  26. package/dist/agent-runtime.d.ts.map +1 -1
  27. package/dist/agent-runtime.js +1157 -511
  28. package/dist/index-vtjgx3vv.js +161 -0
  29. package/dist/server/error-hook.d.ts +8 -1
  30. package/dist/server/error-hook.d.ts.map +1 -1
  31. package/dist/server/index.js +4 -2
  32. package/dist/testing/agent-store-conformance.d.ts +7 -0
  33. package/dist/testing/agent-store-conformance.d.ts.map +1 -0
  34. package/dist/testing.d.ts +2 -0
  35. package/dist/testing.d.ts.map +1 -1
  36. package/dist/testing.js +331 -0
  37. package/llms-full.txt +201 -28
  38. package/package.json +1 -1
@@ -0,0 +1,161 @@
1
+ // src/agent-runtime/schemas.ts
2
+ import { z } from "zod";
3
+ var AgentRecordIdSchema = z.string().min(1);
4
+ var AgentRecordVersionSchema = z.int().nonnegative();
5
+ var AgentTimestampSchema = z.iso.datetime({ offset: true });
6
+ var AgentJsonObjectSchema = z.record(z.string(), z.json());
7
+ var AgentProviderEnvelopeSchema = z.object({
8
+ schemaVersion: z.int().positive(),
9
+ provider: z.string().min(1),
10
+ data: AgentJsonObjectSchema
11
+ });
12
+ var AgentTextPartSchema = z.object({
13
+ type: z.literal("text"),
14
+ text: z.string()
15
+ });
16
+ var AgentReasoningPartSchema = z.object({
17
+ type: z.literal("reasoning"),
18
+ text: z.string(),
19
+ provider: AgentProviderEnvelopeSchema.optional()
20
+ });
21
+ var AgentFilePartSchema = z.object({
22
+ type: z.literal("file"),
23
+ mediaType: z.string().min(1),
24
+ reference: z.string().min(1),
25
+ filename: z.string().min(1).optional()
26
+ });
27
+ var AgentSourcePartSchema = z.object({
28
+ type: z.literal("source"),
29
+ sourceId: z.string().min(1),
30
+ url: z.url().optional(),
31
+ title: z.string().optional()
32
+ });
33
+ var AgentToolCallPartSchema = z.object({
34
+ type: z.literal("tool-call"),
35
+ callId: z.string().min(1),
36
+ toolName: z.string().min(1),
37
+ input: z.json(),
38
+ provider: AgentProviderEnvelopeSchema.optional()
39
+ });
40
+ var AgentToolResultPartSchema = z.object({
41
+ type: z.literal("tool-result"),
42
+ callId: z.string().min(1),
43
+ toolName: z.string().min(1),
44
+ outcome: z.enum(["success", "error", "interrupted"]),
45
+ output: z.json().optional()
46
+ });
47
+ var AgentOpaquePartSchema = z.object({
48
+ type: z.literal("provider"),
49
+ envelope: AgentProviderEnvelopeSchema
50
+ });
51
+ var AgentControlPartSchema = z.object({
52
+ type: z.literal("control"),
53
+ reason: z.enum(["run-interrupted", "stale-run"])
54
+ });
55
+ var AgentMessagePartSchema = z.discriminatedUnion("type", [
56
+ AgentTextPartSchema,
57
+ AgentReasoningPartSchema,
58
+ AgentFilePartSchema,
59
+ AgentSourcePartSchema,
60
+ AgentToolCallPartSchema,
61
+ AgentToolResultPartSchema,
62
+ AgentOpaquePartSchema,
63
+ AgentControlPartSchema
64
+ ]);
65
+ var AgentMessageRoleSchema = z.enum(["user", "assistant", "system", "summary"]);
66
+ var AgentMessageStatusSchema = z.enum([
67
+ "committed",
68
+ "streaming",
69
+ "completed",
70
+ "interrupted",
71
+ "failed"
72
+ ]);
73
+ var AgentMessageSchema = z.object({
74
+ schemaVersion: z.literal(1),
75
+ id: AgentRecordIdSchema,
76
+ conversationId: AgentRecordIdSchema,
77
+ runId: AgentRecordIdSchema.optional(),
78
+ role: AgentMessageRoleSchema,
79
+ status: AgentMessageStatusSchema,
80
+ parts: z.array(AgentMessagePartSchema),
81
+ metadata: AgentJsonObjectSchema.optional(),
82
+ createdAt: AgentTimestampSchema,
83
+ updatedAt: AgentTimestampSchema
84
+ });
85
+ var AgentAssistantPlaceholderSchema = z.object({
86
+ schemaVersion: z.literal(1),
87
+ id: AgentRecordIdSchema,
88
+ conversationId: AgentRecordIdSchema,
89
+ runId: AgentRecordIdSchema,
90
+ status: z.literal("pending"),
91
+ createdAt: AgentTimestampSchema,
92
+ updatedAt: AgentTimestampSchema
93
+ });
94
+ var AgentRunStateSchema = z.enum([
95
+ "queued",
96
+ "running",
97
+ "interrupt_requested",
98
+ "completed",
99
+ "interrupted",
100
+ "failed",
101
+ "cancelled",
102
+ "abandoned"
103
+ ]);
104
+ var AgentTerminalReasonSchema = z.enum([
105
+ "success",
106
+ "policy_stop",
107
+ "interrupted",
108
+ "cancelled",
109
+ "timeout",
110
+ "shutdown",
111
+ "provider_failure",
112
+ "tool_failure",
113
+ "abandoned"
114
+ ]);
115
+ var AgentRunSchema = z.object({
116
+ schemaVersion: z.literal(1),
117
+ id: AgentRecordIdSchema,
118
+ conversationId: AgentRecordIdSchema,
119
+ inputMessageIds: z.array(AgentRecordIdSchema).min(1),
120
+ assistantMessageId: AgentRecordIdSchema,
121
+ state: AgentRunStateSchema,
122
+ revision: AgentRecordVersionSchema,
123
+ ownerId: z.string().min(1).optional(),
124
+ fencingToken: AgentRecordVersionSchema.optional(),
125
+ terminalReason: AgentTerminalReasonSchema.optional(),
126
+ terminalPolicyName: z.string().min(1).optional(),
127
+ createdAt: AgentTimestampSchema,
128
+ updatedAt: AgentTimestampSchema
129
+ });
130
+ var AgentSnapshotSchema = z.object({
131
+ schemaVersion: z.literal(1),
132
+ conversationId: AgentRecordIdSchema,
133
+ version: AgentRecordVersionSchema,
134
+ messages: z.array(AgentMessageSchema),
135
+ runs: z.array(AgentRunSchema)
136
+ });
137
+ var AgentUsageValueSchema = z.object({
138
+ value: z.number().nonnegative().optional(),
139
+ provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
140
+ });
141
+ var AgentCostValueSchema = z.object({
142
+ value: z.number().nonnegative().optional(),
143
+ currency: z.string().length(3).optional(),
144
+ provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
145
+ });
146
+ var AgentUsageSchema = z.object({
147
+ inputTokens: AgentUsageValueSchema,
148
+ outputTokens: AgentUsageValueSchema,
149
+ reasoningTokens: AgentUsageValueSchema.optional(),
150
+ cacheReadTokens: AgentUsageValueSchema.optional(),
151
+ cacheWriteTokens: AgentUsageValueSchema.optional(),
152
+ cost: AgentCostValueSchema.optional()
153
+ });
154
+ var AgentRunMetricsSchema = z.object({
155
+ partial: z.boolean(),
156
+ usage: AgentUsageSchema.optional(),
157
+ durationMs: z.number().nonnegative().optional(),
158
+ ttftMs: z.number().nonnegative().optional()
159
+ });
160
+
161
+ export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentTerminalReasonSchema, AgentRunSchema, AgentSnapshotSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunMetricsSchema };
@@ -5,7 +5,8 @@
5
5
  * Every project writes the same `onError`: turn a thrown value into one wire
6
6
  * shape, mapping stitchkit's own error codes to the app's public codes. The map
7
7
  * is partial — list the codes you have an opinion about, and an unlisted one
8
- * travels as itself, exactly like a code the project threw on its own. A
8
+ * travels as itself unless `unmappedCode` supplies one declarative fallback.
9
+ * Codes the project throws on its own always pass through unchanged. A
9
10
  * project whose envelope is a published contract adds `satisfies
10
11
  * Record<StitchErrorCode, …>` to its own map and buys the stricter deal: a code
11
12
  * added by a later release then breaks the build instead of reaching the wire
@@ -58,6 +59,12 @@ export interface ErrorHookConfig<TWireCode extends string = string> {
58
59
  * error here. Codes you threw yourself (not stitchkit's) pass through as-is.
59
60
  */
60
61
  codeMap?: Partial<Record<StitchErrorCode, TWireCode>>;
62
+ /**
63
+ * Wire code for every unmapped stitchkit code, or a resolver for grouping
64
+ * them. Explicit `codeMap` entries win. Project-owned codes never use this
65
+ * fallback and continue to pass through unchanged.
66
+ */
67
+ unmappedCode?: TWireCode | ((code: StitchErrorCode) => TWireCode);
61
68
  /** Build the response body from the resolved error. */
62
69
  /**
63
70
  * Build the response body from the resolved error. `ctx` is the request's
@@ -1 +1 @@
1
- {"version":3,"file":"error-hook.d.ts","sourceRoot":"","sources":["../../src/server/error-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzD,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM;IAChE;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC;IACtD,uDAAuD;IACvD;;;;;OAKG;IACH,MAAM,EAAE,CACN,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,EAC/D,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,GACjC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAgCxC"}
1
+ {"version":3,"file":"error-hook.d.ts","sourceRoot":"","sources":["../../src/server/error-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzD,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM;IAChE;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC;IACtD;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,eAAe,KAAK,SAAS,CAAC,CAAC;IAClE,uDAAuD;IACvD;;;;;OAKG;IACH,MAAM,EAAE,CACN,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,EAC/D,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,GACjC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAkCxC"}
@@ -351,8 +351,10 @@ function cacheHeaders(maxAge, scope = "public") {
351
351
  function createErrorHook(config) {
352
352
  return async (ctx, error, endpoint) => {
353
353
  const appErr = normalizeError(error);
354
- const mapped = config.codeMap && isStitchErrorCode(appErr.code) ? config.codeMap[appErr.code] : undefined;
355
- const code = mapped ?? appErr.code;
354
+ const stitchCode = isStitchErrorCode(appErr.code) ? appErr.code : undefined;
355
+ const mapped = stitchCode === undefined ? undefined : config.codeMap?.[stitchCode];
356
+ const fallback = mapped === undefined && stitchCode !== undefined ? typeof config.unmappedCode === "function" ? config.unmappedCode(stitchCode) : config.unmappedCode : undefined;
357
+ const code = mapped ?? fallback ?? appErr.code;
356
358
  const info = {
357
359
  code,
358
360
  status: appErr.status,
@@ -0,0 +1,7 @@
1
+ import type { AgentRuntimeStore } from '../agent-runtime/store';
2
+ export interface AgentStoreConformanceConfig {
3
+ createStore(): AgentRuntimeStore | Promise<AgentRuntimeStore>;
4
+ }
5
+ /** Black-box contract shared by memory and third-party durable agent stores. */
6
+ export declare function runAgentStoreConformance(config: AgentStoreConformanceConfig): Promise<void>;
7
+ //# sourceMappingURL=agent-store-conformance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-store-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/agent-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,2BAA2B;IAC1C,WAAW,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/D;AAwCD,gFAAgF;AAChF,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC,CAmPf"}
package/dist/testing.d.ts CHANGED
@@ -31,6 +31,8 @@ export declare function createHandlerTestClient<T extends Record<string, Endpoin
31
31
  export declare function createHandlerTestClients<T extends Record<string, ContractDef<Record<string, EndpointDef>, string>>, TServer = unknown, const K extends string = never>(config: HandlerTestClientsConfig<T, TServer, K>): {
32
32
  [P in keyof T]: ScopedHttpClient<T[P]['endpoints'], ScopedKeys<K>>;
33
33
  };
34
+ export { type AgentRaceBarrier, type AgentRaceDriver, type AgentRaceTrace, type AgentRaceTraceEntry, createAgentRaceBarrier, createAgentRaceDriver, createAgentRaceTrace, } from './agent-runtime/testing';
35
+ export { type AgentStoreConformanceConfig, runAgentStoreConformance, } from './testing/agent-store-conformance';
34
36
  export { assertSurfaceDiscovery, type ConformanceTransport, type CreateRealtimeProbeDriverConfig, createRealtimeProbeDriver, type DefineRealtimeProbeConfig, defineRealtimeProbe, type RealtimeDisconnectObservation, RealtimeDisconnectObservationSchema, type RealtimeProbeAdapter, type RealtimeProbeFixture, type RealtimeProbeScenario, type RealtimeRejectionObservation, RealtimeRejectionObservationSchema, type RunSurfaceProbesConfig, runSurfaceProbes, type SurfaceDiscoveryObservation, type SurfaceProbe, type SurfaceProbeDriver, type SurfaceRealtimeDiscoveryObservation, type SurfaceToolDiscoveryObservation, type TransportObservation, TransportObservationSchema, } from './testing/surface-conformance';
35
37
  export { assertSurfaceManifestSnapshot, buildSurfaceManifest, type IncompatibleSchemaPolicy, type McpSchemaValidationConfig, type SurfaceAgentProjection, type SurfaceManifest, type SurfaceManifestConfig, type SurfaceManifestExtension, SurfaceManifestExtensionSchema, type SurfaceManifestOperation, SurfaceManifestOperationSchema, type SurfaceManifestRealtimeEvent, SurfaceManifestRealtimeEventSchema, SurfaceManifestSchema, type SurfaceManifestTool, SurfaceManifestToolSchema, type SurfaceManifestToolSurface, SurfaceManifestToolSurfaceSchema, type SurfaceMcpPreparation, SurfaceRealtimeSchemaPairSchema, type SurfaceRuntimeToolDefinition, SurfaceSchemaDigestsSchema, type SurfaceToolDefinition, type SurfaceToolExtension, serializeSurfaceValue, } from './testing/surface-manifest';
36
38
  //# sourceMappingURL=testing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
package/dist/testing.js CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ AgentMessageSchema,
3
+ AgentRunSchema
4
+ } from "./index-vtjgx3vv.js";
1
5
  import {
2
6
  RealtimeRequestDisconnectedError,
3
7
  RealtimeRequestInvalidAcknowledgementError,
@@ -23,6 +27,329 @@ import {
23
27
  } from "./index-smpbdg6k.js";
24
28
  import"./index-1bx83sw4.js";
25
29
 
30
+ // src/agent-runtime/testing.ts
31
+ function createAgentRaceBarrier(timeoutMs = 5000) {
32
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1) {
33
+ throw new TypeError("Agent race barrier timeoutMs must be a positive safe integer");
34
+ }
35
+ const reached = Promise.withResolvers();
36
+ const released = Promise.withResolvers();
37
+ let announced = false;
38
+ return {
39
+ reached: reached.promise,
40
+ async wait() {
41
+ if (!announced) {
42
+ announced = true;
43
+ reached.resolve();
44
+ }
45
+ let timer;
46
+ try {
47
+ await Promise.race([
48
+ released.promise,
49
+ new Promise((_resolve, reject) => {
50
+ timer = setTimeout(() => reject(new Error(`Agent race barrier exceeded ${timeoutMs}ms teardown bound`)), timeoutMs);
51
+ })
52
+ ]);
53
+ } finally {
54
+ if (timer !== undefined)
55
+ clearTimeout(timer);
56
+ }
57
+ },
58
+ release: released.resolve
59
+ };
60
+ }
61
+ function createAgentRaceTrace() {
62
+ const recorded = [];
63
+ return {
64
+ record(name) {
65
+ const entry = { name, sequence: recorded.length };
66
+ recorded.push(entry);
67
+ return entry;
68
+ },
69
+ entries: () => recorded.map((entry) => ({ ...entry })),
70
+ assertBefore(first, second) {
71
+ const firstEntry = recorded.find((entry) => entry.name === first);
72
+ const secondEntry = recorded.find((entry) => entry.name === second);
73
+ if (!firstEntry || !secondEntry || firstEntry.sequence >= secondEntry.sequence) {
74
+ throw new Error(`Expected ${first} before ${second}`);
75
+ }
76
+ },
77
+ assertSequence(names) {
78
+ const actual = recorded.map((entry) => entry.name);
79
+ if (actual.length !== names.length || actual.some((name, index) => name !== names[index])) {
80
+ throw new Error(`Expected trace ${names.join(" -> ")}, received ${actual.join(" -> ")}`);
81
+ }
82
+ },
83
+ count: (name) => recorded.filter((entry) => entry.name === name).length
84
+ };
85
+ }
86
+ function createAgentRaceDriver(timeoutMs = 5000) {
87
+ const trace = createAgentRaceTrace();
88
+ const barriers = new Map;
89
+ return {
90
+ trace,
91
+ barrier(name) {
92
+ const existing = barriers.get(name);
93
+ if (existing)
94
+ return existing;
95
+ const created = createAgentRaceBarrier(timeoutMs);
96
+ barriers.set(name, created);
97
+ return created;
98
+ },
99
+ releaseAll() {
100
+ for (const barrier of barriers.values())
101
+ barrier.release();
102
+ }
103
+ };
104
+ }
105
+ // src/testing/agent-store-conformance.ts
106
+ function userMessage(conversationId, id) {
107
+ return AgentMessageSchema.parse({
108
+ schemaVersion: 1,
109
+ id,
110
+ conversationId,
111
+ role: "user",
112
+ status: "committed",
113
+ parts: [{ type: "text", text: id }],
114
+ createdAt: "2026-08-22T00:00:00.000Z",
115
+ updatedAt: "2026-08-22T00:00:00.000Z"
116
+ });
117
+ }
118
+ function queuedRun(conversationId, inputMessageId, id) {
119
+ return AgentRunSchema.parse({
120
+ schemaVersion: 1,
121
+ id,
122
+ conversationId,
123
+ inputMessageIds: [inputMessageId],
124
+ assistantMessageId: `${id}-assistant`,
125
+ state: "queued",
126
+ revision: 0,
127
+ createdAt: "2026-08-22T00:00:00.000Z",
128
+ updatedAt: "2026-08-22T00:00:00.000Z"
129
+ });
130
+ }
131
+ function requireOutcome(actual, expected) {
132
+ if (actual.outcome !== expected) {
133
+ throw new Error(`Agent store conformance expected ${expected}, received ${actual.outcome}`);
134
+ }
135
+ }
136
+ async function runAgentStoreConformance(config) {
137
+ const store = await config.createStore();
138
+ const conversationId = `conformance-${crypto.randomUUID()}`;
139
+ const firstInput = userMessage(conversationId, "input-1");
140
+ const firstRun = queuedRun(conversationId, firstInput.id, "run-1");
141
+ const accepted = await store.acceptInputAndAssignRun({
142
+ idempotencyKey: "request-1",
143
+ input: firstInput,
144
+ run: firstRun
145
+ });
146
+ requireOutcome(accepted, "applied");
147
+ const duplicate = await store.acceptInputAndAssignRun({
148
+ idempotencyKey: "request-1",
149
+ input: userMessage(conversationId, "discarded-input"),
150
+ run: queuedRun(conversationId, "discarded-input", "discarded-run")
151
+ });
152
+ requireOutcome(duplicate, "duplicate");
153
+ if (duplicate.input.id !== firstInput.id || duplicate.inputMessageId !== firstInput.id || duplicate.runId !== firstRun.id || duplicate.assistantMessageId !== firstRun.assistantMessageId) {
154
+ throw new Error("Duplicate admission did not return its original durable identity");
155
+ }
156
+ const secondInput = userMessage(conversationId, "input-2");
157
+ const coalesced = await store.acceptInputAndAssignRun({
158
+ idempotencyKey: "request-2",
159
+ input: secondInput,
160
+ run: queuedRun(conversationId, secondInput.id, "discarded-coalesced-run"),
161
+ coalesceIntoRunId: firstRun.id
162
+ });
163
+ requireOutcome(coalesced, "applied");
164
+ const assigned = coalesced.snapshot.runs.find((run) => run.id === firstRun.id);
165
+ if (assigned?.inputMessageIds.join(",") !== "input-1,input-2") {
166
+ throw new Error("Coalesced admission did not preserve ordered input identities");
167
+ }
168
+ const collidingInput = userMessage(conversationId, assigned.assistantMessageId);
169
+ await store.acceptInputAndAssignRun({
170
+ idempotencyKey: "request-collision",
171
+ input: collidingInput,
172
+ run: queuedRun(conversationId, collidingInput.id, "discarded-collision-run"),
173
+ coalesceIntoRunId: assigned.id
174
+ }).then(() => {
175
+ throw new Error("Coalesced input reused the reserved assistant identity");
176
+ }, (error) => {
177
+ if (!(error instanceof TypeError))
178
+ throw error;
179
+ });
180
+ await store.replaceCompactedRange({
181
+ conversationId,
182
+ expectedVersion: coalesced.snapshot.version,
183
+ replacedMessageIds: [firstInput.id, secondInput.id],
184
+ summary: AgentMessageSchema.parse({
185
+ schemaVersion: 1,
186
+ id: assigned.assistantMessageId,
187
+ conversationId,
188
+ role: "summary",
189
+ status: "committed",
190
+ parts: [{ type: "text", text: "invalid reserved identity" }],
191
+ createdAt: "2026-08-22T00:00:02.000Z",
192
+ updatedAt: "2026-08-22T00:00:02.000Z"
193
+ })
194
+ }).then(() => {
195
+ throw new Error("Compaction reused a reserved assistant identity");
196
+ }, (error) => {
197
+ if (!(error instanceof TypeError))
198
+ throw error;
199
+ });
200
+ const compacted = await store.replaceCompactedRange({
201
+ conversationId,
202
+ expectedVersion: coalesced.snapshot.version,
203
+ replacedMessageIds: [firstInput.id, secondInput.id],
204
+ summary: AgentMessageSchema.parse({
205
+ schemaVersion: 1,
206
+ id: "summary-1",
207
+ conversationId,
208
+ role: "summary",
209
+ status: "committed",
210
+ parts: [{ type: "text", text: "two inputs" }],
211
+ createdAt: "2026-08-22T00:00:02.000Z",
212
+ updatedAt: "2026-08-22T00:00:02.000Z"
213
+ })
214
+ });
215
+ requireOutcome(compacted, "applied");
216
+ const duplicateAfterCompaction = await store.acceptInputAndAssignRun({
217
+ idempotencyKey: "request-1",
218
+ input: userMessage(conversationId, "discarded-after-compaction"),
219
+ run: queuedRun(conversationId, "discarded-after-compaction", "discarded-run-2")
220
+ });
221
+ requireOutcome(duplicateAfterCompaction, "duplicate");
222
+ if (duplicateAfterCompaction.input.id !== firstInput.id) {
223
+ throw new Error("Compaction discarded the canonical duplicate admission input");
224
+ }
225
+ const acquired = await store.acquireRun({
226
+ conversationId,
227
+ runId: assigned.id,
228
+ expectedRevision: assigned.revision,
229
+ ownerId: "conformance-owner"
230
+ });
231
+ requireOutcome(acquired, "applied");
232
+ const running = acquired.snapshot.runs.find((run) => run.id === assigned.id);
233
+ if (!running)
234
+ throw new Error("Acquired run disappeared");
235
+ const stale = await store.checkpointRunAssistant({
236
+ conversationId,
237
+ runId: running.id,
238
+ expectedRevision: running.revision - 1,
239
+ ownerId: "conformance-owner",
240
+ assistant: AgentMessageSchema.parse({
241
+ schemaVersion: 1,
242
+ id: running.assistantMessageId,
243
+ conversationId,
244
+ runId: running.id,
245
+ role: "assistant",
246
+ status: "streaming",
247
+ parts: [],
248
+ createdAt: "2026-08-22T00:00:00.000Z",
249
+ updatedAt: "2026-08-22T00:00:01.000Z"
250
+ })
251
+ });
252
+ requireOutcome(stale, "conflict");
253
+ await store.recoverRun({
254
+ conversationId,
255
+ runId: running.id,
256
+ expectedRevision: running.revision,
257
+ action: "requeue"
258
+ }).then(() => {
259
+ throw new Error("Acquired recovery replayed without explicit safety evidence");
260
+ }, (error) => {
261
+ if (!(error instanceof TypeError))
262
+ throw error;
263
+ });
264
+ const checkpoint = await store.checkpointRunAssistant({
265
+ conversationId,
266
+ runId: running.id,
267
+ expectedRevision: running.revision,
268
+ ownerId: "conformance-owner",
269
+ assistant: AgentMessageSchema.parse({
270
+ schemaVersion: 1,
271
+ id: running.assistantMessageId,
272
+ conversationId,
273
+ runId: running.id,
274
+ role: "assistant",
275
+ status: "streaming",
276
+ parts: [{ type: "text", text: "checkpoint" }],
277
+ createdAt: "2026-08-22T00:00:00.000Z",
278
+ updatedAt: "2026-08-22T00:00:01.000Z"
279
+ })
280
+ });
281
+ requireOutcome(checkpoint, "applied");
282
+ const checkpointedRun = checkpoint.snapshot.runs.find((run) => run.id === running.id);
283
+ if (!checkpointedRun)
284
+ throw new Error("Checkpointed run disappeared");
285
+ const terminalAssistant = AgentMessageSchema.parse({
286
+ schemaVersion: 1,
287
+ id: running.assistantMessageId,
288
+ conversationId,
289
+ runId: running.id,
290
+ role: "assistant",
291
+ status: "completed",
292
+ parts: [{ type: "text", text: "done" }],
293
+ createdAt: "2026-08-22T00:00:00.000Z",
294
+ updatedAt: "2026-08-22T00:00:02.000Z"
295
+ });
296
+ const terminalResults = await Promise.all([
297
+ store.commitRunTerminal({
298
+ conversationId,
299
+ runId: running.id,
300
+ expectedRevision: checkpointedRun.revision,
301
+ ownerId: "conformance-owner",
302
+ assistant: terminalAssistant,
303
+ reason: "success"
304
+ }),
305
+ store.commitRunTerminal({
306
+ conversationId,
307
+ runId: running.id,
308
+ expectedRevision: checkpointedRun.revision,
309
+ ownerId: "conformance-owner",
310
+ assistant: terminalAssistant,
311
+ reason: "success"
312
+ })
313
+ ]);
314
+ const terminalOutcomes = terminalResults.map((result) => result.outcome).sort();
315
+ if (terminalOutcomes.join(",") !== "applied,conflict") {
316
+ throw new Error(`Terminal race was not linearized: ${terminalOutcomes.join(",")}`);
317
+ }
318
+ const recoveryConversationId = `${conversationId}-recovery`;
319
+ const recoveryInput = userMessage(recoveryConversationId, "recovery-input");
320
+ const recoveryRun = queuedRun(recoveryConversationId, recoveryInput.id, "recovery-run");
321
+ const recoveryAccepted = await store.acceptInputAndAssignRun({
322
+ idempotencyKey: "recovery-request",
323
+ input: recoveryInput,
324
+ run: recoveryRun
325
+ });
326
+ requireOutcome(recoveryAccepted, "applied");
327
+ const recoveryAssigned = recoveryAccepted.snapshot.runs.find((run) => run.id === recoveryRun.id);
328
+ if (!recoveryAssigned)
329
+ throw new Error("Recovery run disappeared after admission");
330
+ const recoveryAcquired = await store.acquireRun({
331
+ conversationId: recoveryConversationId,
332
+ runId: recoveryAssigned.id,
333
+ expectedRevision: recoveryAssigned.revision,
334
+ ownerId: "abandoned-owner"
335
+ });
336
+ requireOutcome(recoveryAcquired, "applied");
337
+ const abandonedRun = recoveryAcquired.snapshot.runs.find((run) => run.id === recoveryRun.id);
338
+ if (!abandonedRun)
339
+ throw new Error("Recovery run disappeared after acquisition");
340
+ const abandoned = await store.recoverRun({
341
+ conversationId: recoveryConversationId,
342
+ runId: abandonedRun.id,
343
+ expectedRevision: abandonedRun.revision,
344
+ action: "abandon"
345
+ });
346
+ requireOutcome(abandoned, "applied");
347
+ const terminalRun = abandoned.snapshot.runs.find((run) => run.id === abandonedRun.id);
348
+ const terminalMessage = abandoned.snapshot.messages.find((message) => message.id === abandonedRun.assistantMessageId);
349
+ if (terminalRun?.state !== "abandoned" || terminalMessage?.status !== "failed") {
350
+ throw new Error("Abandon recovery did not atomically terminalize its assistant record");
351
+ }
352
+ }
26
353
  // src/testing/surface-conformance.ts
27
354
  import { z as z2 } from "zod";
28
355
 
@@ -740,10 +1067,14 @@ export {
740
1067
  assertSurfaceDiscovery,
741
1068
  assertSurfaceManifestSnapshot,
742
1069
  buildSurfaceManifest,
1070
+ createAgentRaceBarrier,
1071
+ createAgentRaceDriver,
1072
+ createAgentRaceTrace,
743
1073
  createHandlerTestClient,
744
1074
  createHandlerTestClients,
745
1075
  createRealtimeProbeDriver,
746
1076
  defineRealtimeProbe,
1077
+ runAgentStoreConformance,
747
1078
  runSurfaceProbes,
748
1079
  serializeSurfaceValue
749
1080
  };