stitchkit 0.65.1 → 0.66.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/dist/agent-runtime/coordinator.d.ts +8 -5
- package/dist/agent-runtime/coordinator.d.ts.map +1 -1
- package/dist/agent-runtime/events.d.ts +36 -30
- package/dist/agent-runtime/events.d.ts.map +1 -1
- package/dist/agent-runtime/injection.d.ts +28 -0
- package/dist/agent-runtime/injection.d.ts.map +1 -0
- package/dist/agent-runtime/observability.d.ts +22 -20
- package/dist/agent-runtime/observability.d.ts.map +1 -1
- package/dist/agent-runtime/prompt.d.ts +11 -1
- package/dist/agent-runtime/prompt.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts +11 -0
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/runtime-internals.d.ts.map +1 -1
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schemas.d.ts +75 -21
- package/dist/agent-runtime/schemas.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts +21 -15
- package/dist/agent-runtime/store-driver.d.ts.map +1 -1
- package/dist/agent-runtime/store.d.ts +280 -46
- package/dist/agent-runtime/store.d.ts.map +1 -1
- package/dist/agent-runtime/terminal-commit.d.ts +33 -3
- package/dist/agent-runtime/terminal-commit.d.ts.map +1 -1
- package/dist/agent-runtime/terminal-status.d.ts.map +1 -1
- package/dist/agent-runtime-openrouter.js +1 -1
- package/dist/agent-runtime.d.ts +1 -1
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +384 -97
- package/dist/{index-sbkyvacf.js → index-fhsmrzj7.js} +45 -5
- package/dist/testing/agent-store-conformance.d.ts +34 -1
- package/dist/testing/agent-store-conformance.d.ts.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +175 -4
- package/llms-full.txt +281 -22
- package/package.json +1 -1
|
@@ -114,6 +114,7 @@ var AgentTerminalReasonSchema = z.enum([
|
|
|
114
114
|
"shutdown",
|
|
115
115
|
"provider_failure",
|
|
116
116
|
"context_overflow",
|
|
117
|
+
"absorbed",
|
|
117
118
|
"abandoned"
|
|
118
119
|
]);
|
|
119
120
|
function runStateForTerminalReason(reason) {
|
|
@@ -122,7 +123,7 @@ function runStateForTerminalReason(reason) {
|
|
|
122
123
|
}
|
|
123
124
|
if (reason === "interrupted")
|
|
124
125
|
return "interrupted";
|
|
125
|
-
if (reason === "superseded")
|
|
126
|
+
if (reason === "superseded" || reason === "absorbed")
|
|
126
127
|
return "superseded";
|
|
127
128
|
if (reason === "cancelled" || reason === "shutdown" || reason === "timeout") {
|
|
128
129
|
return "cancelled";
|
|
@@ -131,14 +132,31 @@ function runStateForTerminalReason(reason) {
|
|
|
131
132
|
return "abandoned";
|
|
132
133
|
return "failed";
|
|
133
134
|
}
|
|
135
|
+
var AgentProvenanceSchema = z.enum([
|
|
136
|
+
"provider-reported",
|
|
137
|
+
"measured",
|
|
138
|
+
"computed",
|
|
139
|
+
"estimated",
|
|
140
|
+
"unavailable"
|
|
141
|
+
]);
|
|
134
142
|
var AgentUsageValueSchema = z.object({
|
|
135
|
-
value: z.
|
|
136
|
-
provenance:
|
|
143
|
+
value: z.int().nonnegative().optional(),
|
|
144
|
+
provenance: AgentProvenanceSchema.extract([
|
|
145
|
+
"provider-reported",
|
|
146
|
+
"computed",
|
|
147
|
+
"estimated",
|
|
148
|
+
"unavailable"
|
|
149
|
+
])
|
|
137
150
|
});
|
|
138
151
|
var AgentCostValueSchema = z.object({
|
|
139
152
|
value: z.number().nonnegative().optional(),
|
|
140
153
|
currency: z.string().length(3).optional(),
|
|
141
|
-
provenance:
|
|
154
|
+
provenance: AgentProvenanceSchema.extract([
|
|
155
|
+
"provider-reported",
|
|
156
|
+
"computed",
|
|
157
|
+
"estimated",
|
|
158
|
+
"unavailable"
|
|
159
|
+
])
|
|
142
160
|
});
|
|
143
161
|
var AgentUsageSchema = z.object({
|
|
144
162
|
inputTokens: AgentUsageValueSchema,
|
|
@@ -160,11 +178,19 @@ var AgentRunFieldsSchema = z.object({
|
|
|
160
178
|
fencingToken: AgentRecordVersionSchema.optional(),
|
|
161
179
|
terminalReason: AgentTerminalReasonSchema.optional(),
|
|
162
180
|
terminalPolicyName: z.string().min(1).optional(),
|
|
181
|
+
absorbedIntoRunId: AgentRecordIdSchema.optional(),
|
|
163
182
|
usage: AgentUsageSchema.optional(),
|
|
164
183
|
createdAt: AgentTimestampSchema,
|
|
165
184
|
updatedAt: AgentTimestampSchema
|
|
166
185
|
});
|
|
167
186
|
var AgentRunSchema = AgentRunFieldsSchema.superRefine((run, ctx) => {
|
|
187
|
+
if (run.terminalReason !== "absorbed" && run.absorbedIntoRunId !== undefined) {
|
|
188
|
+
ctx.addIssue({
|
|
189
|
+
code: "custom",
|
|
190
|
+
path: ["absorbedIntoRunId"],
|
|
191
|
+
message: "Only an absorbed run names the run that answered it"
|
|
192
|
+
});
|
|
193
|
+
}
|
|
168
194
|
if (run.terminalReason === undefined) {
|
|
169
195
|
if (TERMINAL_RUN_STATES.has(run.state)) {
|
|
170
196
|
ctx.addIssue({
|
|
@@ -190,6 +216,20 @@ var AgentRunSchema = AgentRunFieldsSchema.superRefine((run, ctx) => {
|
|
|
190
216
|
message: "A policy stop names the policy that stopped the run"
|
|
191
217
|
});
|
|
192
218
|
}
|
|
219
|
+
if (run.terminalReason === "absorbed" && run.absorbedIntoRunId === undefined) {
|
|
220
|
+
ctx.addIssue({
|
|
221
|
+
code: "custom",
|
|
222
|
+
path: ["absorbedIntoRunId"],
|
|
223
|
+
message: "An absorbed run names the run that answered its input"
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
if (run.absorbedIntoRunId === run.id) {
|
|
227
|
+
ctx.addIssue({
|
|
228
|
+
code: "custom",
|
|
229
|
+
path: ["absorbedIntoRunId"],
|
|
230
|
+
message: "A run cannot absorb itself"
|
|
231
|
+
});
|
|
232
|
+
}
|
|
193
233
|
});
|
|
194
234
|
var TERMINAL_RUN_STATES = new Set([
|
|
195
235
|
"completed",
|
|
@@ -213,4 +253,4 @@ var AgentRunMetricsSchema = z.object({
|
|
|
213
253
|
ttftMs: z.number().nonnegative().optional()
|
|
214
254
|
});
|
|
215
255
|
|
|
216
|
-
export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentTerminalReasonSchema, runStateForTerminalReason, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunSchema, AgentSnapshotSchema, AgentRunMetricsSchema };
|
|
256
|
+
export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentTerminalReasonSchema, runStateForTerminalReason, AgentProvenanceSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunSchema, AgentSnapshotSchema, AgentRunMetricsSchema };
|
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import type { AgentRuntimeStore } from '../agent-runtime/store';
|
|
2
|
+
/**
|
|
3
|
+
* What the scenario is about to touch, handed over before the first mutation.
|
|
4
|
+
*
|
|
5
|
+
* The kit used to pick its conversation identities *after* `createStore()`
|
|
6
|
+
* returned, which locked out exactly the adapters it exists to certify: a
|
|
7
|
+
* durable store whose runtime rows hang off an application-owned conversation
|
|
8
|
+
* row cannot serve the first admission, because nobody ever told it which
|
|
9
|
+
* parent to provision. Running the kit against the memory reference store
|
|
10
|
+
* instead proves the reducer — which is not the thing under test.
|
|
11
|
+
*/
|
|
12
|
+
export interface AgentStoreConformanceContext {
|
|
13
|
+
/**
|
|
14
|
+
* Every conversation the scenario mutates, in the order it first touches
|
|
15
|
+
* them. Provision one parent per id before returning the store, and remove
|
|
16
|
+
* them again in `cleanup`.
|
|
17
|
+
*/
|
|
18
|
+
readonly conversationIds: readonly string[];
|
|
19
|
+
}
|
|
2
20
|
export interface AgentStoreConformanceConfig {
|
|
3
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Build the store under test. The context arrives first so an adapter can
|
|
23
|
+
* provision fixture state; a factory that needs none may ignore it, and an
|
|
24
|
+
* existing zero-argument factory stays valid unchanged.
|
|
25
|
+
*/
|
|
26
|
+
createStore(context: AgentStoreConformanceContext): AgentRuntimeStore | Promise<AgentRuntimeStore>;
|
|
27
|
+
/**
|
|
28
|
+
* Remove whatever `createStore` provisioned.
|
|
29
|
+
*
|
|
30
|
+
* Runs exactly once, after the scenario, whether it passed or failed — a kit
|
|
31
|
+
* that only cleans up on success leaks a row for every red run, which is the
|
|
32
|
+
* shape that makes a failing suite un-rerunnable. A failure here never
|
|
33
|
+
* replaces the scenario's own: the answer to "does this adapter conform" is
|
|
34
|
+
* not overwritten by the answer to "did the teardown work".
|
|
35
|
+
*/
|
|
36
|
+
cleanup?(context: AgentStoreConformanceContext): void | Promise<void>;
|
|
4
37
|
}
|
|
5
38
|
/** Black-box contract shared by memory and third-party durable agent stores. */
|
|
6
39
|
export declare function runAgentStoreConformance(config: AgentStoreConformanceConfig): Promise<void>;
|
|
@@ -1 +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,
|
|
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;;;;;;;;;GASG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,WAAW,CACT,OAAO,EAAE,4BAA4B,GACpC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClD;;;;;;;;OAQG;IACH,OAAO,CAAC,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAwCD,gFAAgF;AAChF,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
package/dist/testing.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare function createHandlerTestClients<T extends Record<string, Contra
|
|
|
32
32
|
[P in keyof T]: ScopedHttpClient<T[P]['endpoints'], ScopedKeys<K>>;
|
|
33
33
|
};
|
|
34
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';
|
|
35
|
+
export { type AgentStoreConformanceConfig, type AgentStoreConformanceContext, runAgentStoreConformance, } from './testing/agent-store-conformance';
|
|
36
36
|
export { type ManagedResourceConformanceConfig, type ManagedResourceConformanceControls, ManagedResourceConformanceError, type ManagedResourceConformanceFactoryInput, type ManagedResourceConformanceFixture, type ManagedResourceConformancePhase, ManagedResourceConformancePhaseSchema, type ManagedResourceConformanceScenario, type ManagedResourceConformanceScenarioId, ManagedResourceConformanceScenarioIdSchema, ManagedResourceConformanceScenarioSchema, type ManagedResourceConformanceTraceEntry, ManagedResourceConformanceTraceEntrySchema, type ManagedResourceConformanceTraceOutcome, ManagedResourceConformanceTraceOutcomeSchema, runManagedResourceConformance, } from './testing/managed-resource-conformance';
|
|
37
37
|
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';
|
|
38
38
|
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';
|
package/dist/testing.d.ts.map
CHANGED
|
@@ -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,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentMessageSchema,
|
|
3
3
|
AgentRunSchema
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-fhsmrzj7.js";
|
|
5
5
|
import {
|
|
6
6
|
createApplication
|
|
7
7
|
} from "./index-eabpd4tb.js";
|
|
@@ -141,8 +141,33 @@ function requireOutcome(actual, expected) {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
async function runAgentStoreConformance(config) {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
144
|
+
const run = `conformance-${crypto.randomUUID()}`;
|
|
145
|
+
const context = {
|
|
146
|
+
conversationIds: [run, `${run}-recovery`, `${run}-absorb`]
|
|
147
|
+
};
|
|
148
|
+
const store = await config.createStore(context);
|
|
149
|
+
let failure;
|
|
150
|
+
try {
|
|
151
|
+
await conformanceScenario(store, context.conversationIds);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
failure = error;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
await config.cleanup?.(context);
|
|
157
|
+
} catch (cleanupError) {
|
|
158
|
+
if (failure === undefined)
|
|
159
|
+
throw cleanupError;
|
|
160
|
+
throw new AggregateError([failure, cleanupError], `${failure instanceof Error ? failure.message : String(failure)} (cleanup also failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)})`);
|
|
161
|
+
}
|
|
162
|
+
if (failure !== undefined)
|
|
163
|
+
throw failure;
|
|
164
|
+
}
|
|
165
|
+
async function conformanceScenario(store, conversationIds) {
|
|
166
|
+
const [conversationId, recoveryConversationId, absorbConversationId] = conversationIds;
|
|
167
|
+
if (!conversationId || !recoveryConversationId || !absorbConversationId) {
|
|
168
|
+
throw new Error("Agent store conformance requires three conversation identities");
|
|
169
|
+
}
|
|
170
|
+
const absentConversationId = `${conversationId}-absent`;
|
|
146
171
|
const firstInput = userMessage(conversationId, "input-1");
|
|
147
172
|
const firstRun = queuedRun(conversationId, firstInput.id, "run-1");
|
|
148
173
|
const accepted = await store.acceptInputAndAssignRun({
|
|
@@ -352,6 +377,50 @@ async function runAgentStoreConformance(config) {
|
|
|
352
377
|
if (foreignOwner.outcome !== "conflict") {
|
|
353
378
|
throw new Error("A checkpoint from another owner must conflict");
|
|
354
379
|
}
|
|
380
|
+
const liveView = await store.loadRun({ conversationId, runId: running.id });
|
|
381
|
+
if (!liveView)
|
|
382
|
+
throw new Error("loadRun must find a run of this conversation");
|
|
383
|
+
if (liveView.run.id !== running.id || liveView.run.conversationId !== conversationId) {
|
|
384
|
+
throw new Error("loadRun returned a run it was not asked for");
|
|
385
|
+
}
|
|
386
|
+
if (liveView.run.revision !== checkpointedRun.revision) {
|
|
387
|
+
throw new Error("loadRun must return the run as the last mutation left it");
|
|
388
|
+
}
|
|
389
|
+
if (liveView.run.usage?.cost?.value !== 0.25) {
|
|
390
|
+
throw new Error("loadRun must carry the figure the run has spent so far");
|
|
391
|
+
}
|
|
392
|
+
if (liveView.snapshotVersion !== checkpoint.snapshot.version) {
|
|
393
|
+
throw new Error("loadRun must report the conversation version it read at");
|
|
394
|
+
}
|
|
395
|
+
if (liveView.assistant !== undefined) {
|
|
396
|
+
throw new Error("loadRun must not report a terminal answer for a live run");
|
|
397
|
+
}
|
|
398
|
+
if (await store.loadRun({ conversationId, runId: "no-such-run" })) {
|
|
399
|
+
throw new Error("loadRun must return undefined for an unknown run");
|
|
400
|
+
}
|
|
401
|
+
if (await store.loadRun({ conversationId: absentConversationId, runId: running.id })) {
|
|
402
|
+
throw new Error("loadRun must not cross conversation boundaries");
|
|
403
|
+
}
|
|
404
|
+
const activeRuns = await store.listActiveRuns(conversationId);
|
|
405
|
+
if (!activeRuns.some((run) => run.id === running.id)) {
|
|
406
|
+
throw new Error("listActiveRuns must report a run that is in flight");
|
|
407
|
+
}
|
|
408
|
+
if (activeRuns.some((run) => run.terminalReason !== undefined)) {
|
|
409
|
+
throw new Error("listActiveRuns must not report a run that has ended");
|
|
410
|
+
}
|
|
411
|
+
for (let index = 1;index < activeRuns.length; index += 1) {
|
|
412
|
+
const previous = activeRuns[index - 1];
|
|
413
|
+
const current = activeRuns[index];
|
|
414
|
+
if (!previous || !current)
|
|
415
|
+
continue;
|
|
416
|
+
const ordered = previous.createdAt === current.createdAt ? previous.id.localeCompare(current.id) < 0 : previous.createdAt < current.createdAt;
|
|
417
|
+
if (!ordered) {
|
|
418
|
+
throw new Error("listActiveRuns must order by createdAt and then by id");
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if ((await store.listActiveRuns(absentConversationId)).length !== 0) {
|
|
422
|
+
throw new Error("listActiveRuns must be empty for an unknown conversation");
|
|
423
|
+
}
|
|
355
424
|
const recoverable = await store.scanRecoverable({ limit: 10 });
|
|
356
425
|
if (!recoverable.items.some((item) => item.run.id === running.id)) {
|
|
357
426
|
throw new Error("A running run must appear in a recoverable scan");
|
|
@@ -409,6 +478,16 @@ async function runAgentStoreConformance(config) {
|
|
|
409
478
|
if (settledRun?.usage?.cost?.value !== 1.5) {
|
|
410
479
|
throw new Error("Terminal commit did not persist the run usage it was given");
|
|
411
480
|
}
|
|
481
|
+
const terminalView = await store.loadRun({ conversationId, runId: running.id });
|
|
482
|
+
if (terminalView?.run.terminalReason !== "success") {
|
|
483
|
+
throw new Error("loadRun must report the terminal reason a settled run ended with");
|
|
484
|
+
}
|
|
485
|
+
if (JSON.stringify(terminalView.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
486
|
+
throw new Error("loadRun must retain the answer a settled run produced");
|
|
487
|
+
}
|
|
488
|
+
if ((await store.listActiveRuns(conversationId)).some((run) => run.id === running.id)) {
|
|
489
|
+
throw new Error("listActiveRuns must drop a run once it has ended");
|
|
490
|
+
}
|
|
412
491
|
const compactedTerminal = await store.replaceCompactedRange({
|
|
413
492
|
conversationId,
|
|
414
493
|
expectedVersion: terminalApplied.snapshot.version,
|
|
@@ -434,7 +513,6 @@ async function runAgentStoreConformance(config) {
|
|
|
434
513
|
if (duplicateTerminal.run.terminalReason !== "success" || JSON.stringify(duplicateTerminal.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
435
514
|
throw new Error("Compaction discarded the canonical duplicate terminal result");
|
|
436
515
|
}
|
|
437
|
-
const recoveryConversationId = `${conversationId}-recovery`;
|
|
438
516
|
const recoveryInput = userMessage(recoveryConversationId, "recovery-input");
|
|
439
517
|
const recoveryRun = queuedRun(recoveryConversationId, recoveryInput.id, "recovery-run");
|
|
440
518
|
const recoveryAccepted = await store.acceptInputAndAssignRun({
|
|
@@ -468,6 +546,99 @@ async function runAgentStoreConformance(config) {
|
|
|
468
546
|
if (terminalRun?.state !== "abandoned" || terminalMessage?.status !== "failed") {
|
|
469
547
|
throw new Error("Abandon recovery did not atomically terminalize its assistant record");
|
|
470
548
|
}
|
|
549
|
+
await assertAbsorptionIsAtomic(store, absorbConversationId);
|
|
550
|
+
}
|
|
551
|
+
async function assertAbsorptionIsAtomic(store, conversationId) {
|
|
552
|
+
const leadInput = userMessage(conversationId, "absorb-input-1");
|
|
553
|
+
const leadRun = queuedRun(conversationId, leadInput.id, "absorb-run-1");
|
|
554
|
+
const lead = await store.acceptInputAndAssignRun({
|
|
555
|
+
idempotencyKey: "absorb-request-1",
|
|
556
|
+
input: leadInput,
|
|
557
|
+
run: leadRun
|
|
558
|
+
});
|
|
559
|
+
requireOutcome(lead, "applied");
|
|
560
|
+
const successorInput = userMessage(conversationId, "absorb-input-2");
|
|
561
|
+
const successorRun = queuedRun(conversationId, successorInput.id, "absorb-run-2");
|
|
562
|
+
const successor = await store.acceptInputAndAssignRun({
|
|
563
|
+
idempotencyKey: "absorb-request-2",
|
|
564
|
+
input: successorInput,
|
|
565
|
+
run: successorRun
|
|
566
|
+
});
|
|
567
|
+
requireOutcome(successor, "applied");
|
|
568
|
+
const acquired = await store.acquireRun({
|
|
569
|
+
conversationId,
|
|
570
|
+
runId: leadRun.id,
|
|
571
|
+
expectedRevision: 0,
|
|
572
|
+
ownerId: "absorb-owner"
|
|
573
|
+
});
|
|
574
|
+
requireOutcome(acquired, "applied");
|
|
575
|
+
const running = acquired.snapshot.runs.find((run) => run.id === leadRun.id);
|
|
576
|
+
if (!running)
|
|
577
|
+
throw new Error("Absorbing run disappeared after acquisition");
|
|
578
|
+
const answer = AgentMessageSchema.parse({
|
|
579
|
+
schemaVersion: 1,
|
|
580
|
+
id: running.assistantMessageId,
|
|
581
|
+
conversationId,
|
|
582
|
+
runId: running.id,
|
|
583
|
+
role: "assistant",
|
|
584
|
+
status: "completed",
|
|
585
|
+
parts: [{ type: "text", text: "answered both" }],
|
|
586
|
+
createdAt: "2026-08-26T00:00:00.000Z",
|
|
587
|
+
updatedAt: "2026-08-26T00:00:02.000Z"
|
|
588
|
+
});
|
|
589
|
+
await store.commitRunTerminal({
|
|
590
|
+
conversationId,
|
|
591
|
+
runId: running.id,
|
|
592
|
+
expectedRevision: running.revision,
|
|
593
|
+
ownerId: "absorb-owner",
|
|
594
|
+
assistant: AgentMessageSchema.parse({ ...answer, status: "interrupted" }),
|
|
595
|
+
reason: "interrupted",
|
|
596
|
+
absorb: [{ runId: successorRun.id, inputMessageIds: [successorInput.id] }]
|
|
597
|
+
}).then(() => {
|
|
598
|
+
throw new Error("A non-completing run absorbed a queued successor");
|
|
599
|
+
}, (error) => {
|
|
600
|
+
if (!(error instanceof TypeError))
|
|
601
|
+
throw error;
|
|
602
|
+
});
|
|
603
|
+
const committed = await store.commitRunTerminal({
|
|
604
|
+
conversationId,
|
|
605
|
+
runId: running.id,
|
|
606
|
+
expectedRevision: running.revision,
|
|
607
|
+
ownerId: "absorb-owner",
|
|
608
|
+
assistant: answer,
|
|
609
|
+
reason: "success",
|
|
610
|
+
absorb: [{ runId: successorRun.id, inputMessageIds: [successorInput.id] }]
|
|
611
|
+
});
|
|
612
|
+
requireOutcome(committed, "applied");
|
|
613
|
+
const absorbingView = await store.loadRun({ conversationId, runId: leadRun.id });
|
|
614
|
+
if (absorbingView?.run.inputMessageIds.join(",") !== "absorb-input-1,absorb-input-2") {
|
|
615
|
+
throw new Error("An absorbing run must record the inputs it answered");
|
|
616
|
+
}
|
|
617
|
+
const absorbedView = await store.loadRun({ conversationId, runId: successorRun.id });
|
|
618
|
+
if (absorbedView?.run.terminalReason !== "absorbed") {
|
|
619
|
+
throw new Error("An absorbed successor must be terminal in the same transaction");
|
|
620
|
+
}
|
|
621
|
+
if (absorbedView.run.absorbedIntoRunId !== leadRun.id) {
|
|
622
|
+
throw new Error("An absorbed run must name the run that answered its input");
|
|
623
|
+
}
|
|
624
|
+
if (absorbedView.assistant !== undefined) {
|
|
625
|
+
throw new Error("An absorbed run produced no answer and must retain none");
|
|
626
|
+
}
|
|
627
|
+
if ((await store.listActiveRuns(conversationId)).length !== 0) {
|
|
628
|
+
throw new Error("An absorbed successor must leave the active listing");
|
|
629
|
+
}
|
|
630
|
+
const retried = await store.acceptInputAndAssignRun({
|
|
631
|
+
idempotencyKey: "absorb-request-2",
|
|
632
|
+
input: userMessage(conversationId, "absorb-discarded"),
|
|
633
|
+
run: queuedRun(conversationId, "absorb-discarded", "absorb-discarded-run")
|
|
634
|
+
});
|
|
635
|
+
requireOutcome(retried, "duplicate");
|
|
636
|
+
if (retried.runId !== leadRun.id || retried.assistant?.id !== answer.id) {
|
|
637
|
+
throw new Error("A retried absorbed key must resolve to the run that answered it");
|
|
638
|
+
}
|
|
639
|
+
if (retried.inputMessageId !== successorInput.id) {
|
|
640
|
+
throw new Error("A retried absorbed key must still name its own input");
|
|
641
|
+
}
|
|
471
642
|
}
|
|
472
643
|
// src/testing/managed-resource-conformance-contract.ts
|
|
473
644
|
import { z } from "zod";
|