stitchkit 0.84.1 → 0.85.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 +52 -0
- package/dist/agent-runtime/control-schema.d.ts +61 -0
- package/dist/agent-runtime/control-schema.d.ts.map +1 -1
- package/dist/agent-runtime/event-schema.d.ts +88 -1
- package/dist/agent-runtime/event-schema.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/run-operation-lifecycle.d.ts +25 -0
- package/dist/agent-runtime/run-operation-lifecycle.d.ts.map +1 -0
- package/dist/agent-runtime/schemas.d.ts +67 -0
- package/dist/agent-runtime/schemas.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts +18 -0
- package/dist/agent-runtime/store-driver.d.ts.map +1 -1
- package/dist/agent-runtime/store.d.ts +208 -0
- package/dist/agent-runtime/store.d.ts.map +1 -1
- package/dist/agent-runtime/terminal-commit.d.ts +9 -0
- package/dist/agent-runtime/terminal-commit.d.ts.map +1 -1
- package/dist/agent-runtime-browser.js +11 -3
- package/dist/agent-runtime-harness.js +4 -4
- package/dist/agent-runtime-sqlite-bun.js +3 -3
- package/dist/agent-runtime-sqlite-node.js +3 -3
- package/dist/agent-runtime.d.ts +2 -2
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +14 -4
- package/dist/{index-85vfqd7m.js → index-4hk633vz.js} +11 -3
- package/dist/{index-devfkwfm.js → index-66nxrgy0.js} +2 -2
- package/dist/{index-5s3zajp8.js → index-ff0kcqvp.js} +9 -3
- package/dist/{index-11vzj2sk.js → index-fq492hg0.js} +28 -2
- package/dist/{index-st8v8739.js → index-jpp7jd1p.js} +206 -26
- package/dist/{index-x1th9s8c.js → index-x15ss2dx.js} +50 -1
- package/dist/testing.js +26 -2
- package/llms-full.txt +61 -5
- package/package.json +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentRuntimeEventSchema
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-4hk633vz.js";
|
|
4
4
|
import {
|
|
5
5
|
AgentMessagePartSchema,
|
|
6
6
|
AgentSnapshotSchema
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-x15ss2dx.js";
|
|
8
8
|
|
|
9
9
|
// src/agent-runtime/control-schema.ts
|
|
10
10
|
import { z } from "zod";
|
|
@@ -82,7 +82,13 @@ var AgentMultiSessionCursorSchema = z.object({
|
|
|
82
82
|
}).strict())
|
|
83
83
|
}).strict();
|
|
84
84
|
function durable(event) {
|
|
85
|
-
return [
|
|
85
|
+
return [
|
|
86
|
+
"admission",
|
|
87
|
+
"assistant-checkpoint",
|
|
88
|
+
"run-state",
|
|
89
|
+
"run-operation",
|
|
90
|
+
"terminal"
|
|
91
|
+
].includes(event.type);
|
|
86
92
|
}
|
|
87
93
|
function advanceAgentMultiSessionCursor(raw, event) {
|
|
88
94
|
const cursor = AgentMultiSessionCursorSchema.parse(raw);
|
|
@@ -5,12 +5,13 @@ import {
|
|
|
5
5
|
AgentMessageSchema,
|
|
6
6
|
AgentRecordIdSchema,
|
|
7
7
|
AgentRecordVersionSchema,
|
|
8
|
+
AgentRunOperationSchema,
|
|
8
9
|
AgentRunSchema,
|
|
9
10
|
AgentSnapshotSchema,
|
|
10
11
|
AgentTerminalReasonSchema,
|
|
11
12
|
AgentUsageSchema,
|
|
12
13
|
runStateForTerminalReason
|
|
13
|
-
} from "./index-
|
|
14
|
+
} from "./index-x15ss2dx.js";
|
|
14
15
|
|
|
15
16
|
// src/agent-runtime/conversations.ts
|
|
16
17
|
import { z } from "zod";
|
|
@@ -114,6 +115,14 @@ var CheckpointRunAssistantSchema = z3.object({
|
|
|
114
115
|
assistant: AgentMessageSchema,
|
|
115
116
|
usage: AgentUsageSchema.optional()
|
|
116
117
|
});
|
|
118
|
+
var RecordRunOperationSchema = z3.object({
|
|
119
|
+
conversationId: AgentRecordIdSchema,
|
|
120
|
+
runId: AgentRecordIdSchema,
|
|
121
|
+
expectedRevision: AgentRecordVersionSchema,
|
|
122
|
+
ownerId: z3.string().min(1),
|
|
123
|
+
fencingToken: AgentRecordVersionSchema.optional(),
|
|
124
|
+
operation: AgentRunOperationSchema
|
|
125
|
+
});
|
|
117
126
|
var CommitRunTerminalSchema = z3.object({
|
|
118
127
|
conversationId: AgentRecordIdSchema,
|
|
119
128
|
runId: AgentRecordIdSchema,
|
|
@@ -437,6 +446,19 @@ function reduceStore(current, operation) {
|
|
|
437
446
|
historyMutations: [{ type: "upsert-assistant", message: input.assistant }]
|
|
438
447
|
});
|
|
439
448
|
}
|
|
449
|
+
if (operation.type === "operation" && run) {
|
|
450
|
+
const input = operation.input;
|
|
451
|
+
if (run.revision !== input.expectedRevision || run.state !== "running" && run.state !== "interrupt_requested" || run.ownerId !== input.ownerId || input.fencingToken !== undefined && run.fencingToken !== input.fencingToken) {
|
|
452
|
+
return conflict(run.revision);
|
|
453
|
+
}
|
|
454
|
+
const next = AgentRunSchema.parse({
|
|
455
|
+
...run,
|
|
456
|
+
lastOperation: input.operation,
|
|
457
|
+
revision: run.revision + 1,
|
|
458
|
+
updatedAt: new Date().toISOString()
|
|
459
|
+
});
|
|
460
|
+
return applied(current, { runs: replaceRun(current.runs, next) }, { runRecords: [AgentStoredRunSchema.parse({ schemaVersion: 1, run: next })] });
|
|
461
|
+
}
|
|
440
462
|
if (operation.type === "interrupt" && run) {
|
|
441
463
|
if (run.revision !== operation.input.expectedRevision || run.state !== "running") {
|
|
442
464
|
return conflict(run.revision);
|
|
@@ -794,6 +816,10 @@ function createAgentRuntimeStore(driver) {
|
|
|
794
816
|
type: "checkpoint",
|
|
795
817
|
input: CheckpointRunAssistantSchema.parse(input)
|
|
796
818
|
}),
|
|
819
|
+
recordRunOperation: (input) => mutate({
|
|
820
|
+
type: "operation",
|
|
821
|
+
input: RecordRunOperationSchema.parse(input)
|
|
822
|
+
}),
|
|
797
823
|
requestRunInterrupt: (input) => mutate({
|
|
798
824
|
type: "interrupt",
|
|
799
825
|
input: RequestRunInterruptSchema.parse(input)
|
|
@@ -988,4 +1014,4 @@ function createMemoryAgentRuntimeStore() {
|
|
|
988
1014
|
return createAgentRuntimeStore(driver);
|
|
989
1015
|
}
|
|
990
1016
|
|
|
991
|
-
export { AgentConversationSummarySchema, AgentConversationPageSchema, AgentConversationMessagePageSchema, AgentConversationPurgeInputSchema, AgentConversationPurgeResultSchema, AgentConversationPurgedError, purgeAgentConversation, AgentStoreConflictSchema, AgentStoreNotFoundSchema, AgentStoreAppliedSchema, AgentStoreDuplicateSchema, AgentStoreMutationResultSchema, AgentRunViewSchema, AcceptInputAndAssignRunSchema, AcquireAgentRunSchema, CheckpointRunAssistantSchema, CommitRunTerminalSchema, RequestRunInterruptSchema, RecoverAgentRunSchema, ReplaceCompactedRangeSchema, AgentRecoverableDescriptorSchema, AgentRecoverablePageSchema, AgentRuntimeHeadSchema, AgentStoredRunSchema, AgentAdmissionReceiptSchema, AgentHistoryMutationSchema, ACTIVE_AGENT_RUN_STATES, createAgentRuntimeStore, createMemoryAgentRuntimeStore };
|
|
1017
|
+
export { AgentConversationSummarySchema, AgentConversationPageSchema, AgentConversationMessagePageSchema, AgentConversationPurgeInputSchema, AgentConversationPurgeResultSchema, AgentConversationPurgedError, purgeAgentConversation, AgentStoreConflictSchema, AgentStoreNotFoundSchema, AgentStoreAppliedSchema, AgentStoreDuplicateSchema, AgentStoreMutationResultSchema, AgentRunViewSchema, AcceptInputAndAssignRunSchema, AcquireAgentRunSchema, CheckpointRunAssistantSchema, RecordRunOperationSchema, CommitRunTerminalSchema, RequestRunInterruptSchema, RecoverAgentRunSchema, ReplaceCompactedRangeSchema, AgentRecoverableDescriptorSchema, AgentRecoverablePageSchema, AgentRuntimeHeadSchema, AgentStoredRunSchema, AgentAdmissionReceiptSchema, AgentHistoryMutationSchema, ACTIVE_AGENT_RUN_STATES, createAgentRuntimeStore, createMemoryAgentRuntimeStore };
|
|
@@ -12,17 +12,18 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
AgentRuntimeEventSchema,
|
|
14
14
|
agentDurableEventId
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-4hk633vz.js";
|
|
16
16
|
import {
|
|
17
17
|
AgentAssistantPlaceholderSchema,
|
|
18
18
|
AgentJsonObjectSchema,
|
|
19
19
|
AgentMessagePartSchema,
|
|
20
20
|
AgentMessageSchema,
|
|
21
21
|
AgentProvenanceSchema,
|
|
22
|
+
AgentRunOperationSchema,
|
|
22
23
|
AgentRunSchema,
|
|
23
24
|
AgentSnapshotSchema,
|
|
24
25
|
runStateForTerminalReason
|
|
25
|
-
} from "./index-
|
|
26
|
+
} from "./index-x15ss2dx.js";
|
|
26
27
|
import {
|
|
27
28
|
isAgentToolError
|
|
28
29
|
} from "./index-3xnq72rz.js";
|
|
@@ -933,6 +934,9 @@ function repairedSearchCall(toolCall, searchName) {
|
|
|
933
934
|
};
|
|
934
935
|
}
|
|
935
936
|
|
|
937
|
+
// src/agent-runtime/run-operation-lifecycle.ts
|
|
938
|
+
import { wrapLanguageModel } from "ai";
|
|
939
|
+
|
|
936
940
|
// src/agent-runtime/runtime-internals.ts
|
|
937
941
|
import { z as z2 } from "zod";
|
|
938
942
|
function findRun(runs, runId) {
|
|
@@ -1074,6 +1078,117 @@ function createIdleDeadline(parent, timeoutMs) {
|
|
|
1074
1078
|
};
|
|
1075
1079
|
}
|
|
1076
1080
|
|
|
1081
|
+
// src/agent-runtime/run-operation-lifecycle.ts
|
|
1082
|
+
function createAgentRunOperationLifecycle(config) {
|
|
1083
|
+
let active;
|
|
1084
|
+
let providerCallId;
|
|
1085
|
+
let checkpointedStep = -1;
|
|
1086
|
+
const checkpointWaiters = new Map;
|
|
1087
|
+
const record = async (operation) => {
|
|
1088
|
+
const current = config.currentRun();
|
|
1089
|
+
const snapshot = appliedSnapshot(await config.store.recordRunOperation({
|
|
1090
|
+
conversationId: current.conversationId,
|
|
1091
|
+
runId: current.id,
|
|
1092
|
+
expectedRevision: current.revision,
|
|
1093
|
+
ownerId: config.runtimeEpoch,
|
|
1094
|
+
...current.fencingToken !== undefined && { fencingToken: current.fencingToken },
|
|
1095
|
+
operation
|
|
1096
|
+
}), "run operation");
|
|
1097
|
+
config.acceptSnapshot(snapshot);
|
|
1098
|
+
const run = findRun(snapshot.runs, current.id);
|
|
1099
|
+
active = operation;
|
|
1100
|
+
await config.publish({
|
|
1101
|
+
type: "run-operation",
|
|
1102
|
+
eventId: agentDurableEventId("run-operation", run.id, snapshot.version),
|
|
1103
|
+
conversationId: run.conversationId,
|
|
1104
|
+
runId: run.id,
|
|
1105
|
+
snapshotVersion: snapshot.version,
|
|
1106
|
+
operation,
|
|
1107
|
+
emittedAt: config.now().toISOString()
|
|
1108
|
+
});
|
|
1109
|
+
};
|
|
1110
|
+
const startModelRequest = (callId, step) => record(AgentRunOperationSchema.parse({
|
|
1111
|
+
operationId: `${callId}:${step}`,
|
|
1112
|
+
kind: "model-request",
|
|
1113
|
+
phase: "started",
|
|
1114
|
+
step,
|
|
1115
|
+
startedAt: config.now().toISOString()
|
|
1116
|
+
}));
|
|
1117
|
+
return {
|
|
1118
|
+
noteProviderCall(callId) {
|
|
1119
|
+
providerCallId = callId;
|
|
1120
|
+
},
|
|
1121
|
+
async prepareModel(model, step, fallbackCallId) {
|
|
1122
|
+
if (step > checkpointedStep + 1) {
|
|
1123
|
+
const waiter = checkpointWaiters.get(step - 1) ?? Promise.withResolvers();
|
|
1124
|
+
checkpointWaiters.set(step - 1, waiter);
|
|
1125
|
+
await waiter.promise;
|
|
1126
|
+
}
|
|
1127
|
+
if (typeof model === "string") {
|
|
1128
|
+
await startModelRequest(fallbackCallId, step);
|
|
1129
|
+
return model;
|
|
1130
|
+
}
|
|
1131
|
+
return wrapLanguageModel({
|
|
1132
|
+
model,
|
|
1133
|
+
middleware: {
|
|
1134
|
+
specificationVersion: "v4",
|
|
1135
|
+
wrapStream: async ({ doStream }) => {
|
|
1136
|
+
const callId = providerCallId;
|
|
1137
|
+
providerCallId = undefined;
|
|
1138
|
+
if (!callId) {
|
|
1139
|
+
throw new Error("AgentRuntime model call reached the provider without lifecycle identity");
|
|
1140
|
+
}
|
|
1141
|
+
await startModelRequest(callId, step);
|
|
1142
|
+
return doStream();
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
});
|
|
1146
|
+
},
|
|
1147
|
+
checkpointStep(step) {
|
|
1148
|
+
checkpointedStep = Math.max(checkpointedStep, step);
|
|
1149
|
+
for (const [waitingFor, waiter] of checkpointWaiters) {
|
|
1150
|
+
if (waitingFor > checkpointedStep)
|
|
1151
|
+
continue;
|
|
1152
|
+
checkpointWaiters.delete(waitingFor);
|
|
1153
|
+
waiter.resolve();
|
|
1154
|
+
}
|
|
1155
|
+
},
|
|
1156
|
+
failStepCheckpoints(error) {
|
|
1157
|
+
for (const waiter of checkpointWaiters.values())
|
|
1158
|
+
waiter.reject(error);
|
|
1159
|
+
checkpointWaiters.clear();
|
|
1160
|
+
},
|
|
1161
|
+
startCompaction(operationId) {
|
|
1162
|
+
return record(AgentRunOperationSchema.parse({
|
|
1163
|
+
operationId,
|
|
1164
|
+
kind: "compaction",
|
|
1165
|
+
phase: "started",
|
|
1166
|
+
startedAt: config.now().toISOString()
|
|
1167
|
+
}));
|
|
1168
|
+
},
|
|
1169
|
+
firstOutput() {
|
|
1170
|
+
if (active?.kind !== "model-request" || active.phase !== "started") {
|
|
1171
|
+
return Promise.resolve();
|
|
1172
|
+
}
|
|
1173
|
+
return record(AgentRunOperationSchema.parse({
|
|
1174
|
+
...active,
|
|
1175
|
+
phase: "first-output",
|
|
1176
|
+
firstOutputAt: config.now().toISOString()
|
|
1177
|
+
}));
|
|
1178
|
+
},
|
|
1179
|
+
finish(phase) {
|
|
1180
|
+
if (!active || ["completed", "failed", "cancelled"].includes(active.phase)) {
|
|
1181
|
+
return Promise.resolve();
|
|
1182
|
+
}
|
|
1183
|
+
return record(AgentRunOperationSchema.parse({
|
|
1184
|
+
...active,
|
|
1185
|
+
phase,
|
|
1186
|
+
finishedAt: config.now().toISOString()
|
|
1187
|
+
}));
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1077
1192
|
// src/agent-runtime/run-execution.ts
|
|
1078
1193
|
function snapshotForRunPrompt(snapshot, runId) {
|
|
1079
1194
|
const runIndex = snapshot.runs.findIndex((candidate) => candidate.id === runId);
|
|
@@ -1184,7 +1299,7 @@ function createRunExecutor(dependencies) {
|
|
|
1184
1299
|
let observedVersion = snapshot.version;
|
|
1185
1300
|
const parts = [];
|
|
1186
1301
|
const absorbed = new Map;
|
|
1187
|
-
let
|
|
1302
|
+
let eventsSinceCheckpoint = 0;
|
|
1188
1303
|
let sequence = 0;
|
|
1189
1304
|
let terminalReason = "success";
|
|
1190
1305
|
let nonModelUsage = input.acceptedRun.usage;
|
|
@@ -1199,6 +1314,18 @@ function createRunExecutor(dependencies) {
|
|
|
1199
1314
|
let terminalPolicyName;
|
|
1200
1315
|
const idleDeadline = createIdleDeadline(input.signal, idleTimeoutMs);
|
|
1201
1316
|
const executionSignal = idleDeadline.signal;
|
|
1317
|
+
const operationLifecycle = createAgentRunOperationLifecycle({
|
|
1318
|
+
store: config.store,
|
|
1319
|
+
runtimeEpoch,
|
|
1320
|
+
currentRun: () => run,
|
|
1321
|
+
acceptSnapshot: (next) => {
|
|
1322
|
+
snapshot = next;
|
|
1323
|
+
observedVersion = next.version;
|
|
1324
|
+
run = findRun(next.runs, run.id);
|
|
1325
|
+
},
|
|
1326
|
+
publish,
|
|
1327
|
+
now
|
|
1328
|
+
});
|
|
1202
1329
|
const updateReasoning = (text, metadata) => {
|
|
1203
1330
|
const provider = providerEnvelope(metadata);
|
|
1204
1331
|
if (reasoningPartIndex === undefined) {
|
|
@@ -1256,14 +1383,30 @@ function createRunExecutor(dependencies) {
|
|
|
1256
1383
|
};
|
|
1257
1384
|
try {
|
|
1258
1385
|
if (config.history?.compact) {
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1386
|
+
await operationLifecycle.startCompaction(generateId());
|
|
1387
|
+
let compacted;
|
|
1388
|
+
try {
|
|
1389
|
+
compacted = await config.history.compact({
|
|
1390
|
+
conversationId: run.conversationId,
|
|
1391
|
+
store: config.store,
|
|
1392
|
+
signal: executionSignal
|
|
1393
|
+
});
|
|
1394
|
+
snapshot = compacted.snapshot;
|
|
1395
|
+
observedVersion = snapshot.version;
|
|
1396
|
+
run = findRun(snapshot.runs, run.id);
|
|
1397
|
+
await operationLifecycle.finish("completed");
|
|
1398
|
+
} catch (error) {
|
|
1399
|
+
const latest = await config.store.loadRun({
|
|
1400
|
+
conversationId: run.conversationId,
|
|
1401
|
+
runId: run.id
|
|
1402
|
+
});
|
|
1403
|
+
if (latest?.run.ownerId === runtimeEpoch) {
|
|
1404
|
+
observedVersion = latest.snapshotVersion;
|
|
1405
|
+
run = latest.run;
|
|
1406
|
+
}
|
|
1407
|
+
await operationLifecycle.finish(executionSignal.aborted ? "cancelled" : "failed");
|
|
1408
|
+
throw error;
|
|
1409
|
+
}
|
|
1267
1410
|
if (compacted.usage) {
|
|
1268
1411
|
nonModelUsage = addUsage(nonModelUsage, compacted.usage);
|
|
1269
1412
|
usage = modelUsage ? addUsage(nonModelUsage, modelUsage) : nonModelUsage;
|
|
@@ -1410,14 +1553,18 @@ function createRunExecutor(dependencies) {
|
|
|
1410
1553
|
}
|
|
1411
1554
|
return messages;
|
|
1412
1555
|
};
|
|
1556
|
+
const fallbackModel = selectedModel.model;
|
|
1413
1557
|
const result = streamAgentTextBoundary({
|
|
1414
|
-
model:
|
|
1558
|
+
model: fallbackModel,
|
|
1415
1559
|
tools,
|
|
1416
1560
|
instructions: withCarriedSystem(prompt.instructions),
|
|
1417
1561
|
messages: history,
|
|
1418
1562
|
abortSignal: executionSignal,
|
|
1419
1563
|
maxRetries: 0,
|
|
1420
1564
|
stopWhen: stopConditions,
|
|
1565
|
+
onLanguageModelCallStart: (event) => {
|
|
1566
|
+
operationLifecycle.noteProviderCall(event.callId);
|
|
1567
|
+
},
|
|
1421
1568
|
repairToolCall: deferredToolRepair(config.loop?.prepareStep),
|
|
1422
1569
|
...config.loop?.toolApproval && {
|
|
1423
1570
|
toolApproval: config.loop.toolApproval,
|
|
@@ -1426,27 +1573,39 @@ function createRunExecutor(dependencies) {
|
|
|
1426
1573
|
...config.loop?.toolApprovalSecret && {
|
|
1427
1574
|
experimental_toolApprovalSecret: config.loop.toolApprovalSecret
|
|
1428
1575
|
},
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
if (injected.length === 0)
|
|
1437
|
-
return prepared;
|
|
1438
|
-
const base = prepared?.messages ?? options.messages;
|
|
1439
|
-
return { ...prepared, messages: [...base, ...injected] };
|
|
1576
|
+
prepareStep: async (options) => {
|
|
1577
|
+
const previousStep = options.steps.at(-1);
|
|
1578
|
+
if (previousStep) {
|
|
1579
|
+
lastPromptTokens = selectedModel?.normalizeUsage?.({
|
|
1580
|
+
usage: previousStep.usage,
|
|
1581
|
+
providerMetadata: previousStep.providerMetadata
|
|
1582
|
+
})?.inputTokens ?? normalizeSdkUsage(previousStep.usage).inputTokens;
|
|
1440
1583
|
}
|
|
1584
|
+
const prepared = await config.loop?.prepareStep?.({
|
|
1585
|
+
...options,
|
|
1586
|
+
...runtimeContext
|
|
1587
|
+
});
|
|
1588
|
+
const injected = await takeInjectedMessages();
|
|
1589
|
+
const preparedStep = injected.length === 0 ? prepared : {
|
|
1590
|
+
...prepared,
|
|
1591
|
+
messages: [...prepared?.messages ?? options.messages, ...injected]
|
|
1592
|
+
};
|
|
1593
|
+
return {
|
|
1594
|
+
...preparedStep,
|
|
1595
|
+
model: await operationLifecycle.prepareModel(preparedStep?.model ?? fallbackModel, options.stepNumber, generateId())
|
|
1596
|
+
};
|
|
1441
1597
|
}
|
|
1442
1598
|
});
|
|
1443
1599
|
for await (const part of result.stream) {
|
|
1444
1600
|
idleDeadline.touch();
|
|
1445
|
-
|
|
1601
|
+
eventsSinceCheckpoint += 1;
|
|
1446
1602
|
sequence += 1;
|
|
1447
|
-
if (firstOutputAt === undefined &&
|
|
1603
|
+
if (firstOutputAt === undefined && (part.type === "text-delta" && part.text.length > 0 || part.type === "reasoning-delta" && part.text.length > 0 || part.type === "tool-input-delta" && part.delta.length > 0 || part.type === "tool-call")) {
|
|
1448
1604
|
firstOutputAt = performance.now();
|
|
1449
1605
|
}
|
|
1606
|
+
if (part.type === "text-delta" && part.text.length > 0 || part.type === "reasoning-delta" && part.text.length > 0 || part.type === "tool-input-delta" && part.delta.length > 0 || part.type === "tool-call") {
|
|
1607
|
+
await operationLifecycle.firstOutput();
|
|
1608
|
+
}
|
|
1450
1609
|
if (part.type === "text-delta") {
|
|
1451
1610
|
appendText(parts, part.text);
|
|
1452
1611
|
await publish({
|
|
@@ -1552,6 +1711,7 @@ function createRunExecutor(dependencies) {
|
|
|
1552
1711
|
status: "interrupted",
|
|
1553
1712
|
emittedAt: now().toISOString()
|
|
1554
1713
|
});
|
|
1714
|
+
await checkpoint();
|
|
1555
1715
|
throw part.error;
|
|
1556
1716
|
}
|
|
1557
1717
|
const output = isAgentToolError(part.error) ? jsonValue(part.error.output) : { message: "Tool execution failed" };
|
|
@@ -1661,6 +1821,7 @@ function createRunExecutor(dependencies) {
|
|
|
1661
1821
|
terminalReason = part.error instanceof AgentContextOverflowError ? "context_overflow" : "provider_failure";
|
|
1662
1822
|
internalCause = part.error;
|
|
1663
1823
|
} else if (part.type === "finish-step") {
|
|
1824
|
+
await operationLifecycle.finish(part.finishReason === "error" ? "failed" : "completed");
|
|
1664
1825
|
const stepTrace = trace ? config.observe?.rootTrace(trace) : undefined;
|
|
1665
1826
|
const stepUsage = selectedModel.normalizeUsage?.({
|
|
1666
1827
|
usage: part.usage,
|
|
@@ -1696,9 +1857,23 @@ function createRunExecutor(dependencies) {
|
|
|
1696
1857
|
modelUsage = mergeModelTotals(normalizeSdkUsage(part.totalUsage), modelUsage);
|
|
1697
1858
|
usage = nonModelUsage ? addUsage(nonModelUsage, modelUsage) : modelUsage;
|
|
1698
1859
|
}
|
|
1699
|
-
|
|
1860
|
+
const structuralBoundary = [
|
|
1861
|
+
"tool-call",
|
|
1862
|
+
"tool-result",
|
|
1863
|
+
"tool-error",
|
|
1864
|
+
"tool-output-denied",
|
|
1865
|
+
"tool-approval-request",
|
|
1866
|
+
"tool-approval-response",
|
|
1867
|
+
"finish-step"
|
|
1868
|
+
].includes(part.type);
|
|
1869
|
+
if (structuralBoundary || eventsSinceCheckpoint >= checkpointEveryEvents) {
|
|
1700
1870
|
await checkpoint();
|
|
1871
|
+
eventsSinceCheckpoint = 0;
|
|
1872
|
+
if (part.type === "finish-step")
|
|
1873
|
+
operationLifecycle.checkpointStep(step - 1);
|
|
1874
|
+
}
|
|
1701
1875
|
}
|
|
1876
|
+
await operationLifecycle.finish(executionSignal.aborted ? "cancelled" : terminalReason === "provider_failure" ? "failed" : "completed");
|
|
1702
1877
|
if (terminalPolicyName !== undefined)
|
|
1703
1878
|
terminalReason = "policy_stop";
|
|
1704
1879
|
if (executionSignal.aborted)
|
|
@@ -1721,6 +1896,7 @@ function createRunExecutor(dependencies) {
|
|
|
1721
1896
|
}
|
|
1722
1897
|
}
|
|
1723
1898
|
} catch (error) {
|
|
1899
|
+
operationLifecycle.failStepCheckpoints(error);
|
|
1724
1900
|
internalCause = error;
|
|
1725
1901
|
const latest = await config.store.loadRun({
|
|
1726
1902
|
conversationId: run.conversationId,
|
|
@@ -1732,6 +1908,10 @@ function createRunExecutor(dependencies) {
|
|
|
1732
1908
|
observedVersion = latest.snapshotVersion;
|
|
1733
1909
|
run = latestRun;
|
|
1734
1910
|
}
|
|
1911
|
+
const staleOwner = isToolExecutionControlError(error) && error.reason === "stale_run";
|
|
1912
|
+
if (!staleOwner) {
|
|
1913
|
+
await operationLifecycle.finish(executionSignal.aborted || durableInterrupt ? "cancelled" : "failed");
|
|
1914
|
+
}
|
|
1735
1915
|
if (isToolExecutionControlError(error) || executionSignal.aborted || durableInterrupt) {
|
|
1736
1916
|
terminalReason = executionSignal.aborted ? abortTerminalReason(executionSignal) : "interrupted";
|
|
1737
1917
|
parts.push(AgentMessagePartSchema.parse({
|
|
@@ -125,6 +125,54 @@ var AgentRunStateSchema = z.enum([
|
|
|
125
125
|
"abandoned"
|
|
126
126
|
]);
|
|
127
127
|
var AgentRunQueuePrioritySchema = z.enum(["interrupt-next"]);
|
|
128
|
+
var AgentRunOperationKindSchema = z.enum(["model-request", "compaction"]);
|
|
129
|
+
var AgentRunOperationPhaseSchema = z.enum([
|
|
130
|
+
"started",
|
|
131
|
+
"first-output",
|
|
132
|
+
"completed",
|
|
133
|
+
"failed",
|
|
134
|
+
"cancelled"
|
|
135
|
+
]);
|
|
136
|
+
var AgentRunOperationFieldsSchema = z.object({
|
|
137
|
+
operationId: AgentRecordIdSchema,
|
|
138
|
+
kind: AgentRunOperationKindSchema,
|
|
139
|
+
phase: AgentRunOperationPhaseSchema,
|
|
140
|
+
step: z.int().nonnegative().optional(),
|
|
141
|
+
startedAt: AgentTimestampSchema,
|
|
142
|
+
firstOutputAt: AgentTimestampSchema.optional(),
|
|
143
|
+
finishedAt: AgentTimestampSchema.optional()
|
|
144
|
+
});
|
|
145
|
+
var AgentRunOperationSchema = AgentRunOperationFieldsSchema.superRefine((operation, ctx) => {
|
|
146
|
+
if (operation.kind === "model-request" !== (operation.step !== undefined)) {
|
|
147
|
+
ctx.addIssue({
|
|
148
|
+
code: "custom",
|
|
149
|
+
path: ["step"],
|
|
150
|
+
message: "Only a model request has a step identity"
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (operation.kind === "compaction" && operation.phase === "first-output") {
|
|
154
|
+
ctx.addIssue({
|
|
155
|
+
code: "custom",
|
|
156
|
+
path: ["phase"],
|
|
157
|
+
message: "Compaction has no first-output phase"
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (operation.phase === "first-output" && operation.firstOutputAt === undefined || operation.phase === "started" && operation.firstOutputAt !== undefined || operation.kind === "compaction" && operation.firstOutputAt !== undefined) {
|
|
161
|
+
ctx.addIssue({
|
|
162
|
+
code: "custom",
|
|
163
|
+
path: ["firstOutputAt"],
|
|
164
|
+
message: "Only model output phases carry the observed first-output timestamp"
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const terminal = ["completed", "failed", "cancelled"].includes(operation.phase);
|
|
168
|
+
if (terminal !== (operation.finishedAt !== undefined)) {
|
|
169
|
+
ctx.addIssue({
|
|
170
|
+
code: "custom",
|
|
171
|
+
path: ["finishedAt"],
|
|
172
|
+
message: "A terminal operation phase carries its observed finish timestamp"
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
});
|
|
128
176
|
var AgentTerminalReasonSchema = z.enum([
|
|
129
177
|
"success",
|
|
130
178
|
"policy_stop",
|
|
@@ -204,6 +252,7 @@ var AgentRunFieldsSchema = z.object({
|
|
|
204
252
|
terminalPolicyName: z.string().min(1).optional(),
|
|
205
253
|
absorbedIntoRunId: AgentRecordIdSchema.optional(),
|
|
206
254
|
usage: AgentUsageSchema.optional(),
|
|
255
|
+
lastOperation: AgentRunOperationSchema.optional(),
|
|
207
256
|
createdAt: AgentTimestampSchema,
|
|
208
257
|
updatedAt: AgentTimestampSchema
|
|
209
258
|
});
|
|
@@ -277,4 +326,4 @@ var AgentRunMetricsSchema = z.object({
|
|
|
277
326
|
ttftMs: z.number().nonnegative().optional()
|
|
278
327
|
});
|
|
279
328
|
|
|
280
|
-
export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentToolApprovalRequestPartSchema, AgentToolApprovalResponsePartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentRunQueuePrioritySchema, AgentTerminalReasonSchema, runStateForTerminalReason, AgentProvenanceSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunSchema, AgentSnapshotSchema, AgentRunMetricsSchema };
|
|
329
|
+
export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentToolApprovalRequestPartSchema, AgentToolApprovalResponsePartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentRunQueuePrioritySchema, AgentRunOperationKindSchema, AgentRunOperationPhaseSchema, AgentRunOperationSchema, AgentTerminalReasonSchema, runStateForTerminalReason, AgentProvenanceSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunSchema, AgentSnapshotSchema, AgentRunMetricsSchema };
|
package/dist/testing.js
CHANGED
|
@@ -7,7 +7,7 @@ import"./index-3z73fh2c.js";
|
|
|
7
7
|
import {
|
|
8
8
|
AgentMessageSchema,
|
|
9
9
|
AgentRunSchema
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-x15ss2dx.js";
|
|
11
11
|
import {
|
|
12
12
|
RealtimeRejectDirectionSchema,
|
|
13
13
|
RealtimeRejectFaultSchema,
|
|
@@ -450,10 +450,34 @@ async function conformanceScenario(store, conversationIds) {
|
|
|
450
450
|
if (!recoverable.items.some((item) => item.run.id === running.id)) {
|
|
451
451
|
throw new Error("A running run must appear in a recoverable scan");
|
|
452
452
|
}
|
|
453
|
+
const operation = await store.recordRunOperation({
|
|
454
|
+
conversationId,
|
|
455
|
+
runId: running.id,
|
|
456
|
+
expectedRevision: checkpointedRun.revision,
|
|
457
|
+
ownerId: "conformance-owner",
|
|
458
|
+
fencingToken: checkpointedRun.fencingToken,
|
|
459
|
+
operation: {
|
|
460
|
+
operationId: "model-call-1:0",
|
|
461
|
+
kind: "model-request",
|
|
462
|
+
phase: "first-output",
|
|
463
|
+
step: 0,
|
|
464
|
+
startedAt: "2026-08-22T00:00:01.800Z",
|
|
465
|
+
firstOutputAt: "2026-08-22T00:00:01.900Z"
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
requireOutcome(operation, "applied");
|
|
469
|
+
const operatedRun = operation.snapshot.runs.find((run) => run.id === running.id);
|
|
470
|
+
if (operatedRun?.lastOperation?.operationId !== "model-call-1:0") {
|
|
471
|
+
throw new Error("Run operation identity did not survive its durable mutation");
|
|
472
|
+
}
|
|
473
|
+
const operatedView = await store.loadRun({ conversationId, runId: running.id });
|
|
474
|
+
if (operatedView?.run.lastOperation?.startedAt !== "2026-08-22T00:00:01.800Z") {
|
|
475
|
+
throw new Error("loadRun did not retain the original operation timestamp");
|
|
476
|
+
}
|
|
453
477
|
const interrupted = await store.requestRunInterrupt({
|
|
454
478
|
conversationId,
|
|
455
479
|
runId: running.id,
|
|
456
|
-
expectedRevision:
|
|
480
|
+
expectedRevision: operatedRun.revision
|
|
457
481
|
});
|
|
458
482
|
requireOutcome(interrupted, "applied");
|
|
459
483
|
const interruptedRun = interrupted.snapshot.runs.find((run) => run.id === running.id);
|