stitchkit 0.68.4 → 0.68.6
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/README.md +4 -1
- package/dist/agent-runtime/coordinator.d.ts +5 -2
- package/dist/agent-runtime/coordinator.d.ts.map +1 -1
- package/dist/agent-runtime/event-schema.d.ts +1349 -0
- package/dist/agent-runtime/event-schema.d.ts.map +1 -0
- package/dist/agent-runtime/events.d.ts +2 -1347
- package/dist/agent-runtime/events.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts +2 -0
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/runtime.d.ts +2 -0
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schemas.d.ts +12 -0
- package/dist/agent-runtime/schemas.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts +12 -0
- package/dist/agent-runtime/store-driver.d.ts.map +1 -1
- package/dist/agent-runtime/store.d.ts +37 -6
- package/dist/agent-runtime/store.d.ts.map +1 -1
- package/dist/agent-runtime/terminal-commit.d.ts +2 -0
- package/dist/agent-runtime/terminal-commit.d.ts.map +1 -1
- package/dist/agent-runtime-browser.d.ts +4 -0
- package/dist/agent-runtime-browser.d.ts.map +1 -0
- package/dist/agent-runtime-browser.js +424 -0
- package/dist/agent-runtime.js +169 -93
- package/dist/browser/cancellation.d.ts.map +1 -1
- package/dist/{index-thcy3w8c.js → index-n34x0q5e.js} +6 -6
- package/dist/{index-fhsmrzj7.js → index-ysphyxax.js} +4 -1
- package/dist/index.js +6 -6
- package/dist/remote.js +1 -1
- package/dist/testing/agent-store-conformance.d.ts.map +1 -1
- package/dist/testing.js +117 -6
- package/llms-full.txt +71 -10
- package/package.json +6 -2
package/dist/agent-runtime.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
AgentRecordIdSchema,
|
|
24
24
|
AgentRecordVersionSchema,
|
|
25
25
|
AgentRunMetricsSchema,
|
|
26
|
+
AgentRunQueuePrioritySchema,
|
|
26
27
|
AgentRunSchema,
|
|
27
28
|
AgentRunStateSchema,
|
|
28
29
|
AgentSnapshotSchema,
|
|
@@ -35,7 +36,7 @@ import {
|
|
|
35
36
|
AgentUsageSchema,
|
|
36
37
|
AgentUsageValueSchema,
|
|
37
38
|
runStateForTerminalReason
|
|
38
|
-
} from "./index-
|
|
39
|
+
} from "./index-ysphyxax.js";
|
|
39
40
|
import"./index-6djpbnda.js";
|
|
40
41
|
import"./index-cby4ar3v.js";
|
|
41
42
|
import {
|
|
@@ -227,6 +228,7 @@ function createAgentSessionCoordinator() {
|
|
|
227
228
|
}
|
|
228
229
|
const lane = laneFor(input.key);
|
|
229
230
|
const pending = {
|
|
231
|
+
priority: input.policy === "interrupt-next",
|
|
230
232
|
reject(reason) {
|
|
231
233
|
accepted.reject(reason);
|
|
232
234
|
result.reject(reason);
|
|
@@ -249,11 +251,20 @@ function createAgentSessionCoordinator() {
|
|
|
249
251
|
}
|
|
250
252
|
}
|
|
251
253
|
};
|
|
252
|
-
if (input.policy === "interrupt")
|
|
254
|
+
if (input.policy === "interrupt" || input.policy === "interrupt-next") {
|
|
253
255
|
lane.active?.controller.abort("user-interrupt");
|
|
256
|
+
}
|
|
254
257
|
if (input.policy === "supersede")
|
|
255
258
|
lane.active?.controller.abort("supersede");
|
|
256
|
-
|
|
259
|
+
if (pending.priority) {
|
|
260
|
+
const firstOrdinary = lane.queue.findIndex((queued) => !queued.priority);
|
|
261
|
+
if (firstOrdinary === -1)
|
|
262
|
+
lane.queue.push(pending);
|
|
263
|
+
else
|
|
264
|
+
lane.queue.splice(firstOrdinary, 0, pending);
|
|
265
|
+
} else {
|
|
266
|
+
lane.queue.push(pending);
|
|
267
|
+
}
|
|
257
268
|
startNext(input.key, lane);
|
|
258
269
|
return { accepted: accepted.promise, result: result.promise };
|
|
259
270
|
},
|
|
@@ -305,7 +316,7 @@ function createAgentSessionCoordinator() {
|
|
|
305
316
|
}
|
|
306
317
|
};
|
|
307
318
|
}
|
|
308
|
-
// src/agent-runtime/
|
|
319
|
+
// src/agent-runtime/event-schema.ts
|
|
309
320
|
import { z } from "zod";
|
|
310
321
|
var AgentAdmissionEventSchema = z.object({
|
|
311
322
|
type: z.literal("admission"),
|
|
@@ -422,6 +433,11 @@ function advanceAgentRuntimeEventCursor(rawCursor, event) {
|
|
|
422
433
|
cursor: { ...cursor, runtimeEpoch: event.runtimeEpoch, sequence: event.sequence }
|
|
423
434
|
};
|
|
424
435
|
}
|
|
436
|
+
function agentDurableEventId(type, runId, snapshotVersion) {
|
|
437
|
+
return `${runId}:${type}:${snapshotVersion}`;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/agent-runtime/events.ts
|
|
425
441
|
function createAgentRuntimeEventSink(config) {
|
|
426
442
|
const manager = createBoundedSinkManager({
|
|
427
443
|
write: config.write,
|
|
@@ -441,9 +457,6 @@ function createAgentRuntimeEventSink(config) {
|
|
|
441
457
|
close: () => manager.close()
|
|
442
458
|
};
|
|
443
459
|
}
|
|
444
|
-
function agentDurableEventId(type, runId, snapshotVersion) {
|
|
445
|
-
return `${runId}:${type}:${snapshotVersion}`;
|
|
446
|
-
}
|
|
447
460
|
// src/agent-runtime/history.ts
|
|
448
461
|
import { modelMessageSchema } from "ai";
|
|
449
462
|
function providerOptions(envelope) {
|
|
@@ -1493,6 +1506,7 @@ function createRunExecutor(dependencies) {
|
|
|
1493
1506
|
if (!absorbing?.assistant || !absorbing.run.terminalReason) {
|
|
1494
1507
|
throw new AgentRuntimeConflictError("absorbed run resolution");
|
|
1495
1508
|
}
|
|
1509
|
+
input.onAcquired?.();
|
|
1496
1510
|
return {
|
|
1497
1511
|
run: absorbing.run,
|
|
1498
1512
|
message: absorbing.assistant,
|
|
@@ -1511,6 +1525,7 @@ function createRunExecutor(dependencies) {
|
|
|
1511
1525
|
ownerId: runtimeEpoch
|
|
1512
1526
|
}), "run acquisition");
|
|
1513
1527
|
let run = findRun(acquired.runs, input.acceptedRun.id);
|
|
1528
|
+
input.onAcquired?.();
|
|
1514
1529
|
await publish({
|
|
1515
1530
|
type: "run-state",
|
|
1516
1531
|
eventId: agentDurableEventId("run-state", run.id, acquired.version),
|
|
@@ -2281,6 +2296,15 @@ function createAgentRuntime(config) {
|
|
|
2281
2296
|
const context = config.protocol.parseContext(rawInput.context);
|
|
2282
2297
|
const accepted = Promise.withResolvers();
|
|
2283
2298
|
const result = Promise.withResolvers();
|
|
2299
|
+
let acquisitionSettled = false;
|
|
2300
|
+
const resolveAcquisition = () => {
|
|
2301
|
+
acquisitionSettled = true;
|
|
2302
|
+
accepted.resolve();
|
|
2303
|
+
};
|
|
2304
|
+
const rejectAcquisition = (error) => {
|
|
2305
|
+
if (!acquisitionSettled)
|
|
2306
|
+
accepted.reject(error);
|
|
2307
|
+
};
|
|
2284
2308
|
const handedOff = beginAdmission();
|
|
2285
2309
|
(async () => {
|
|
2286
2310
|
try {
|
|
@@ -2294,7 +2318,6 @@ function createAgentRuntime(config) {
|
|
|
2294
2318
|
if (recoveredRun.state !== "queued") {
|
|
2295
2319
|
throw new Error("Only a queued recovered agent run can be resumed");
|
|
2296
2320
|
}
|
|
2297
|
-
accepted.resolve();
|
|
2298
2321
|
const ticket = coordinator.submit({
|
|
2299
2322
|
key: rawInput.conversationKey ?? rawInput.conversationId,
|
|
2300
2323
|
policy: "queue",
|
|
@@ -2304,16 +2327,20 @@ function createAgentRuntime(config) {
|
|
|
2304
2327
|
acceptedRun: recoveredRun,
|
|
2305
2328
|
context,
|
|
2306
2329
|
signal,
|
|
2307
|
-
key: rawInput.conversationKey ?? rawInput.conversationId
|
|
2330
|
+
key: rawInput.conversationKey ?? rawInput.conversationId,
|
|
2331
|
+
onAcquired: resolveAcquisition
|
|
2308
2332
|
})
|
|
2309
2333
|
})
|
|
2310
2334
|
});
|
|
2311
2335
|
ticket.accepted.catch(() => {
|
|
2312
2336
|
return;
|
|
2313
2337
|
});
|
|
2314
|
-
ticket.result.then(result.resolve,
|
|
2338
|
+
ticket.result.then(result.resolve, (error) => {
|
|
2339
|
+
rejectAcquisition(error);
|
|
2340
|
+
result.reject(error);
|
|
2341
|
+
});
|
|
2315
2342
|
} catch (error) {
|
|
2316
|
-
|
|
2343
|
+
rejectAcquisition(error);
|
|
2317
2344
|
result.reject(error);
|
|
2318
2345
|
} finally {
|
|
2319
2346
|
handedOff();
|
|
@@ -2369,6 +2396,7 @@ function createAgentRuntime(config) {
|
|
|
2369
2396
|
assistantMessageId,
|
|
2370
2397
|
state: "queued",
|
|
2371
2398
|
revision: 0,
|
|
2399
|
+
...policy === "interrupt-next" && { queuePriority: "interrupt-next" },
|
|
2372
2400
|
createdAt: nowIso,
|
|
2373
2401
|
updatedAt: nowIso
|
|
2374
2402
|
});
|
|
@@ -2378,7 +2406,7 @@ function createAgentRuntime(config) {
|
|
|
2378
2406
|
return;
|
|
2379
2407
|
});
|
|
2380
2408
|
const outerResult = Promise.withResolvers();
|
|
2381
|
-
const reservation = config.runs?.coalescePending ? reserveAdmission(key, runId) : undefined;
|
|
2409
|
+
const reservation = config.runs?.coalescePending && policy !== "interrupt-next" ? reserveAdmission(key, runId) : undefined;
|
|
2382
2410
|
const previousAcceptance = reservation?.lane.acceptanceTail ?? Promise.resolve();
|
|
2383
2411
|
const acceptanceDone = Promise.withResolvers();
|
|
2384
2412
|
if (reservation) {
|
|
@@ -2599,101 +2627,129 @@ function createAgentRuntime(config) {
|
|
|
2599
2627
|
if (!Number.isSafeInteger(maxRuns) || maxRuns < 1) {
|
|
2600
2628
|
throw new TypeError("Recovery maxRuns must be a positive safe integer");
|
|
2601
2629
|
}
|
|
2602
|
-
const
|
|
2630
|
+
const recoverable = [];
|
|
2603
2631
|
let cursor;
|
|
2604
|
-
while (
|
|
2632
|
+
while (recoverable.length < maxRuns && !options.signal?.aborted && !admissionClosed) {
|
|
2605
2633
|
const page = await config.store.scanRecoverable({
|
|
2606
2634
|
...cursor && { cursor },
|
|
2607
|
-
limit: Math.min(pageSize, maxRuns -
|
|
2635
|
+
limit: Math.min(pageSize, maxRuns - recoverable.length)
|
|
2608
2636
|
});
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2637
|
+
recoverable.push(...page.items);
|
|
2638
|
+
cursor = page.nextCursor;
|
|
2639
|
+
if (!cursor || page.items.length === 0)
|
|
2640
|
+
break;
|
|
2641
|
+
}
|
|
2642
|
+
const grouped = new Map;
|
|
2643
|
+
for (const item of recoverable) {
|
|
2644
|
+
const items = grouped.get(item.conversationId) ?? [];
|
|
2645
|
+
items.push(item);
|
|
2646
|
+
grouped.set(item.conversationId, items);
|
|
2647
|
+
}
|
|
2648
|
+
const ordered = [];
|
|
2649
|
+
for (const [conversationId, items] of grouped) {
|
|
2650
|
+
const active = await config.store.listActiveRuns(conversationId);
|
|
2651
|
+
const position = new Map(active.map((run, index) => [run.id, index]));
|
|
2652
|
+
ordered.push(...items.sort((left, right) => {
|
|
2653
|
+
const leftPosition = position.get(left.run.id);
|
|
2654
|
+
const rightPosition = position.get(right.run.id);
|
|
2655
|
+
if (leftPosition === undefined && rightPosition === undefined)
|
|
2656
|
+
return 0;
|
|
2657
|
+
if (leftPosition === undefined)
|
|
2658
|
+
return 1;
|
|
2659
|
+
if (rightPosition === undefined)
|
|
2660
|
+
return -1;
|
|
2661
|
+
return leftPosition - rightPosition;
|
|
2662
|
+
}));
|
|
2663
|
+
}
|
|
2664
|
+
const outcomes = [];
|
|
2665
|
+
const scheduledRuns = new Map;
|
|
2666
|
+
for (const item of ordered) {
|
|
2667
|
+
if (options.signal?.aborted)
|
|
2668
|
+
break;
|
|
2669
|
+
if (admissionClosed)
|
|
2670
|
+
break;
|
|
2671
|
+
const releaseAdmission = beginAdmission();
|
|
2672
|
+
try {
|
|
2673
|
+
const active = await config.store.listActiveRuns(item.conversationId);
|
|
2674
|
+
const position = active.findIndex((run) => run.id === item.run.id);
|
|
2675
|
+
const scheduled = scheduledRuns.get(item.conversationId) ?? new Set;
|
|
2676
|
+
const blockedByUnscheduledPredecessor = position > 0 && active.slice(0, position).some((run) => !scheduled.has(run.id));
|
|
2677
|
+
if (blockedByUnscheduledPredecessor) {
|
|
2678
|
+
outcomes.push({
|
|
2679
|
+
conversationId: item.conversationId,
|
|
2680
|
+
runId: item.run.id,
|
|
2681
|
+
outcome: "skipped"
|
|
2682
|
+
});
|
|
2683
|
+
continue;
|
|
2684
|
+
}
|
|
2685
|
+
const decision = await options.decide?.(item) ?? (item.run.state === "queued" ? { action: "resume" } : { action: "skip" });
|
|
2612
2686
|
if (admissionClosed)
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
if (item.run.state === "queued") {
|
|
2617
|
-
const active = await config.store.listActiveRuns(item.conversationId);
|
|
2618
|
-
const blockedByAcquiredPredecessor = active.some((run) => run.id !== item.run.id && (run.state === "running" || run.state === "interrupt_requested"));
|
|
2619
|
-
if (blockedByAcquiredPredecessor) {
|
|
2620
|
-
outcomes.push({
|
|
2621
|
-
conversationId: item.conversationId,
|
|
2622
|
-
runId: item.run.id,
|
|
2623
|
-
outcome: "skipped"
|
|
2624
|
-
});
|
|
2625
|
-
continue;
|
|
2626
|
-
}
|
|
2627
|
-
}
|
|
2628
|
-
const decision = await options.decide?.(item) ?? (item.run.state === "queued" ? { action: "resume" } : { action: "skip" });
|
|
2629
|
-
if (admissionClosed)
|
|
2630
|
-
throw closedError();
|
|
2631
|
-
if (decision.action === "skip") {
|
|
2632
|
-
outcomes.push({
|
|
2633
|
-
conversationId: item.conversationId,
|
|
2634
|
-
runId: item.run.id,
|
|
2635
|
-
outcome: "skipped"
|
|
2636
|
-
});
|
|
2637
|
-
continue;
|
|
2638
|
-
}
|
|
2639
|
-
if (decision.action === "abandon") {
|
|
2640
|
-
const abandoned = await config.store.recoverRun({
|
|
2641
|
-
conversationId: item.conversationId,
|
|
2642
|
-
runId: item.run.id,
|
|
2643
|
-
expectedRevision: item.run.revision,
|
|
2644
|
-
action: "abandon"
|
|
2645
|
-
});
|
|
2646
|
-
if (abandoned.outcome !== "applied") {
|
|
2647
|
-
throw new AgentRuntimeConflictError("recovery abandon");
|
|
2648
|
-
}
|
|
2649
|
-
outcomes.push({
|
|
2650
|
-
conversationId: item.conversationId,
|
|
2651
|
-
runId: item.run.id,
|
|
2652
|
-
outcome: "abandoned"
|
|
2653
|
-
});
|
|
2654
|
-
continue;
|
|
2655
|
-
}
|
|
2656
|
-
if (decision.action === "requeue") {
|
|
2657
|
-
const requeued = await config.store.recoverRun({
|
|
2658
|
-
conversationId: item.conversationId,
|
|
2659
|
-
runId: item.run.id,
|
|
2660
|
-
expectedRevision: item.run.revision,
|
|
2661
|
-
action: "requeue",
|
|
2662
|
-
replaySafe: true
|
|
2663
|
-
});
|
|
2664
|
-
if (requeued.outcome !== "applied") {
|
|
2665
|
-
throw new AgentRuntimeConflictError("recovery requeue");
|
|
2666
|
-
}
|
|
2667
|
-
}
|
|
2668
|
-
const context = await options.resolveContext(item);
|
|
2669
|
-
const resumed = resume({
|
|
2687
|
+
throw closedError();
|
|
2688
|
+
if (decision.action === "skip") {
|
|
2689
|
+
outcomes.push({
|
|
2670
2690
|
conversationId: item.conversationId,
|
|
2671
2691
|
runId: item.run.id,
|
|
2672
|
-
|
|
2692
|
+
outcome: "skipped"
|
|
2673
2693
|
});
|
|
2674
|
-
|
|
2675
|
-
|
|
2694
|
+
continue;
|
|
2695
|
+
}
|
|
2696
|
+
if (decision.action === "abandon") {
|
|
2697
|
+
const abandoned = await config.store.recoverRun({
|
|
2698
|
+
conversationId: item.conversationId,
|
|
2699
|
+
runId: item.run.id,
|
|
2700
|
+
expectedRevision: item.run.revision,
|
|
2701
|
+
action: "abandon"
|
|
2676
2702
|
});
|
|
2677
|
-
|
|
2703
|
+
if (abandoned.outcome !== "applied") {
|
|
2704
|
+
throw new AgentRuntimeConflictError("recovery abandon");
|
|
2705
|
+
}
|
|
2678
2706
|
outcomes.push({
|
|
2679
2707
|
conversationId: item.conversationId,
|
|
2680
2708
|
runId: item.run.id,
|
|
2681
|
-
outcome:
|
|
2709
|
+
outcome: "abandoned"
|
|
2682
2710
|
});
|
|
2683
|
-
|
|
2684
|
-
|
|
2711
|
+
continue;
|
|
2712
|
+
}
|
|
2713
|
+
if (decision.action === "requeue") {
|
|
2714
|
+
const requeued = await config.store.recoverRun({
|
|
2685
2715
|
conversationId: item.conversationId,
|
|
2686
2716
|
runId: item.run.id,
|
|
2687
|
-
|
|
2688
|
-
|
|
2717
|
+
expectedRevision: item.run.revision,
|
|
2718
|
+
action: "requeue",
|
|
2719
|
+
replaySafe: true
|
|
2689
2720
|
});
|
|
2690
|
-
|
|
2691
|
-
|
|
2721
|
+
if (requeued.outcome !== "applied") {
|
|
2722
|
+
throw new AgentRuntimeConflictError("recovery requeue");
|
|
2723
|
+
}
|
|
2692
2724
|
}
|
|
2725
|
+
const context = await options.resolveContext(item);
|
|
2726
|
+
const resumed = resume({
|
|
2727
|
+
conversationId: item.conversationId,
|
|
2728
|
+
runId: item.run.id,
|
|
2729
|
+
context
|
|
2730
|
+
});
|
|
2731
|
+
resumed.result.catch(() => {
|
|
2732
|
+
return;
|
|
2733
|
+
});
|
|
2734
|
+
await resumed.accepted;
|
|
2735
|
+
scheduled.add(item.run.id);
|
|
2736
|
+
scheduledRuns.set(item.conversationId, scheduled);
|
|
2737
|
+
outcomes.push({
|
|
2738
|
+
conversationId: item.conversationId,
|
|
2739
|
+
runId: item.run.id,
|
|
2740
|
+
outcome: decision.action === "requeue" ? "requeued" : "resumed",
|
|
2741
|
+
result: resumed.result
|
|
2742
|
+
});
|
|
2743
|
+
} catch (error) {
|
|
2744
|
+
outcomes.push({
|
|
2745
|
+
conversationId: item.conversationId,
|
|
2746
|
+
runId: item.run.id,
|
|
2747
|
+
outcome: "failed",
|
|
2748
|
+
error
|
|
2749
|
+
});
|
|
2750
|
+
} finally {
|
|
2751
|
+
releaseAdmission();
|
|
2693
2752
|
}
|
|
2694
|
-
cursor = page.nextCursor;
|
|
2695
|
-
if (!cursor || page.items.length === 0)
|
|
2696
|
-
break;
|
|
2697
2753
|
}
|
|
2698
2754
|
return outcomes;
|
|
2699
2755
|
},
|
|
@@ -2874,7 +2930,22 @@ function historyPositions(messages) {
|
|
|
2874
2930
|
}
|
|
2875
2931
|
function orderRuns(messages, runs) {
|
|
2876
2932
|
const positionOf = historyPositions(messages);
|
|
2877
|
-
|
|
2933
|
+
const fallback = (left, right) => left.createdAt.localeCompare(right.createdAt) || positionOf(left) - positionOf(right) || left.id.localeCompare(right.id);
|
|
2934
|
+
return [...runs].sort((left, right) => {
|
|
2935
|
+
if (left.executionSequence !== undefined && right.executionSequence !== undefined && left.executionSequence !== right.executionSequence) {
|
|
2936
|
+
return left.executionSequence - right.executionSequence;
|
|
2937
|
+
}
|
|
2938
|
+
const leftStarted = left.executionSequence !== undefined || left.state !== "queued";
|
|
2939
|
+
const rightStarted = right.executionSequence !== undefined || right.state !== "queued";
|
|
2940
|
+
if (leftStarted !== rightStarted)
|
|
2941
|
+
return leftStarted ? -1 : 1;
|
|
2942
|
+
if (!leftStarted && !rightStarted) {
|
|
2943
|
+
const priority = Number(right.queuePriority !== undefined) - Number(left.queuePriority !== undefined);
|
|
2944
|
+
if (priority !== 0)
|
|
2945
|
+
return priority;
|
|
2946
|
+
}
|
|
2947
|
+
return fallback(left, right);
|
|
2948
|
+
});
|
|
2878
2949
|
}
|
|
2879
2950
|
function orderRunMessages(messages, runs) {
|
|
2880
2951
|
const byId = new Map(messages.map((message) => [message.id, message]));
|
|
@@ -2986,7 +3057,7 @@ function reduceStore(current, operation) {
|
|
|
2986
3057
|
if (input.coalesceIntoRunId !== undefined && (!coalescedRun || coalescedRun.conversationId !== input.input.conversationId || coalescedRun.state !== "queued" || coalescedRun.ownerId !== undefined || coalescedRun.terminalReason !== undefined)) {
|
|
2987
3058
|
return coalescedRun ? conflict(coalescedRun.revision) : { outcome: "not_found" };
|
|
2988
3059
|
}
|
|
2989
|
-
if (input.run.conversationId !== input.input.conversationId || input.run.inputMessageIds.length !== 1 || input.run.inputMessageIds[0] !== input.input.id || input.run.state !== "queued" || input.run.revision !== 0 || input.run.ownerId !== undefined || input.run.terminalReason !== undefined || input.run.terminalPolicyName !== undefined || input.input.role !== "user" || input.input.status !== "committed" || input.input.runId !== undefined || current.messages.some((message) => message.id === input.input.id) || coalescedRun !== undefined && input.input.id === coalescedRun.assistantMessageId || !coalescedRun && (input.run.assistantMessageId === input.input.id || current.runs.some((candidate) => candidate.id === input.run.id) || current.runs.some((candidate) => candidate.assistantMessageId === input.run.assistantMessageId) || current.messages.some((message) => message.id === input.run.assistantMessageId))) {
|
|
3060
|
+
if (input.run.conversationId !== input.input.conversationId || input.run.inputMessageIds.length !== 1 || input.run.inputMessageIds[0] !== input.input.id || input.run.state !== "queued" || input.run.revision !== 0 || input.run.executionSequence !== undefined || input.run.ownerId !== undefined || input.run.terminalReason !== undefined || input.run.terminalPolicyName !== undefined || input.input.role !== "user" || input.input.status !== "committed" || input.input.runId !== undefined || current.messages.some((message) => message.id === input.input.id) || coalescedRun !== undefined && input.input.id === coalescedRun.assistantMessageId || !coalescedRun && (input.run.assistantMessageId === input.input.id || current.runs.some((candidate) => candidate.id === input.run.id) || current.runs.some((candidate) => candidate.assistantMessageId === input.run.assistantMessageId) || current.messages.some((message) => message.id === input.run.assistantMessageId))) {
|
|
2990
3061
|
throw new TypeError("Input and queued run do not form one valid assignment");
|
|
2991
3062
|
}
|
|
2992
3063
|
const assignedRun = coalescedRun ? AgentRunSchema.parse({
|
|
@@ -3025,6 +3096,7 @@ function reduceStore(current, operation) {
|
|
|
3025
3096
|
const next = AgentRunSchema.parse({
|
|
3026
3097
|
...run,
|
|
3027
3098
|
state: "running",
|
|
3099
|
+
executionSequence: run.executionSequence ?? current.version + 1,
|
|
3028
3100
|
ownerId: operation.input.ownerId,
|
|
3029
3101
|
fencingToken: (run.fencingToken ?? 0) + 1,
|
|
3030
3102
|
revision: run.revision + 1,
|
|
@@ -3276,7 +3348,10 @@ function createAgentRuntimeStore(driver) {
|
|
|
3276
3348
|
});
|
|
3277
3349
|
});
|
|
3278
3350
|
const listActiveRuns = (conversationId) => driver.transaction(async (transaction) => {
|
|
3279
|
-
const records = await
|
|
3351
|
+
const [records, messages] = await Promise.all([
|
|
3352
|
+
driver.runs.listActive(transaction, conversationId),
|
|
3353
|
+
driver.history.load(transaction, conversationId)
|
|
3354
|
+
]);
|
|
3280
3355
|
const runs = records.map((record) => AgentStoredRunSchema.parse(record).run);
|
|
3281
3356
|
for (const run of runs) {
|
|
3282
3357
|
if (run.conversationId !== conversationId) {
|
|
@@ -3286,7 +3361,7 @@ function createAgentRuntimeStore(driver) {
|
|
|
3286
3361
|
throw new TypeError("Active run listing returned a terminal run");
|
|
3287
3362
|
}
|
|
3288
3363
|
}
|
|
3289
|
-
return
|
|
3364
|
+
return orderRuns(messages, runs);
|
|
3290
3365
|
});
|
|
3291
3366
|
const mutate = (operation) => driver.transaction(async (transaction) => {
|
|
3292
3367
|
const conversationId = operationConversationId(operation);
|
|
@@ -3613,6 +3688,7 @@ export {
|
|
|
3613
3688
|
AgentRecoverablePageSchema,
|
|
3614
3689
|
AgentRunEventSchema,
|
|
3615
3690
|
AgentRunMetricsSchema,
|
|
3691
|
+
AgentRunQueuePrioritySchema,
|
|
3616
3692
|
AgentRunSchema,
|
|
3617
3693
|
AgentRunStartedEventSchema,
|
|
3618
3694
|
AgentRunStateEventSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cancellation.d.ts","sourceRoot":"","sources":["../../src/browser/cancellation.ts"],"names":[],"mappings":"AAAA,KAAK,iBAAiB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9C,4EAA4E;AAC5E,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,KAAK,EAAE,iBAAiB;IAApD,YAA4B,KAAK,EAAE,iBAAiB,EAGnD;CACF;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,mBAAmB,
|
|
1
|
+
{"version":3,"file":"cancellation.d.ts","sourceRoot":"","sources":["../../src/browser/cancellation.ts"],"names":[],"mappings":"AAAA,KAAK,iBAAiB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9C,4EAA4E;AAC5E,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,KAAK,EAAE,iBAAiB;IAApD,YAA4B,KAAK,EAAE,iBAAiB,EAGnD;CACF;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,mBAAmB,CAwCrB"}
|
|
@@ -28,34 +28,34 @@ function createRequestCancellation(caller, timeoutMs) {
|
|
|
28
28
|
if (!caller && timeoutMs === undefined) {
|
|
29
29
|
return { signal: undefined, run: (operation) => operation() };
|
|
30
30
|
}
|
|
31
|
-
const
|
|
31
|
+
const timeoutController = timeoutMs === undefined ? undefined : new AbortController;
|
|
32
|
+
const signal = caller && timeoutController ? AbortSignal.any([caller, timeoutController.signal]) : caller ?? timeoutController?.signal;
|
|
32
33
|
let cause;
|
|
33
34
|
let timer;
|
|
34
35
|
const abortFromCaller = () => {
|
|
35
36
|
if (cause)
|
|
36
37
|
return;
|
|
37
38
|
cause = "caller";
|
|
38
|
-
controller.abort(caller?.reason);
|
|
39
39
|
};
|
|
40
40
|
if (caller?.aborted)
|
|
41
41
|
abortFromCaller();
|
|
42
42
|
else
|
|
43
43
|
caller?.addEventListener("abort", abortFromCaller, { once: true });
|
|
44
|
-
if (timeoutMs !== undefined) {
|
|
44
|
+
if (timeoutMs !== undefined && timeoutController) {
|
|
45
45
|
timer = setTimeout(() => {
|
|
46
46
|
if (cause)
|
|
47
47
|
return;
|
|
48
48
|
cause = "timeout";
|
|
49
|
-
|
|
49
|
+
timeoutController.abort(new DOMException("Request timed out", "TimeoutError"));
|
|
50
50
|
}, timeoutMs);
|
|
51
51
|
}
|
|
52
52
|
return {
|
|
53
|
-
signal
|
|
53
|
+
signal,
|
|
54
54
|
async run(operation) {
|
|
55
55
|
try {
|
|
56
56
|
if (cause === "caller")
|
|
57
57
|
throw cancellationError(cause);
|
|
58
|
-
return await operation(
|
|
58
|
+
return await operation(signal);
|
|
59
59
|
} catch (error) {
|
|
60
60
|
if (cause)
|
|
61
61
|
throw cancellationError(cause);
|
|
@@ -103,6 +103,7 @@ var AgentRunStateSchema = z.enum([
|
|
|
103
103
|
"cancelled",
|
|
104
104
|
"abandoned"
|
|
105
105
|
]);
|
|
106
|
+
var AgentRunQueuePrioritySchema = z.enum(["interrupt-next"]);
|
|
106
107
|
var AgentTerminalReasonSchema = z.enum([
|
|
107
108
|
"success",
|
|
108
109
|
"policy_stop",
|
|
@@ -174,6 +175,8 @@ var AgentRunFieldsSchema = z.object({
|
|
|
174
175
|
assistantMessageId: AgentRecordIdSchema,
|
|
175
176
|
state: AgentRunStateSchema,
|
|
176
177
|
revision: AgentRecordVersionSchema,
|
|
178
|
+
queuePriority: AgentRunQueuePrioritySchema.optional(),
|
|
179
|
+
executionSequence: AgentRecordVersionSchema.optional(),
|
|
177
180
|
ownerId: z.string().min(1).optional(),
|
|
178
181
|
fencingToken: AgentRecordVersionSchema.optional(),
|
|
179
182
|
terminalReason: AgentTerminalReasonSchema.optional(),
|
|
@@ -253,4 +256,4 @@ var AgentRunMetricsSchema = z.object({
|
|
|
253
256
|
ttftMs: z.number().nonnegative().optional()
|
|
254
257
|
});
|
|
255
258
|
|
|
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 };
|
|
259
|
+
export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentRunQueuePrioritySchema, AgentTerminalReasonSchema, runStateForTerminalReason, AgentProvenanceSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunSchema, AgentSnapshotSchema, AgentRunMetricsSchema };
|
package/dist/index.js
CHANGED
|
@@ -42,34 +42,34 @@ function createRequestCancellation(caller, timeoutMs) {
|
|
|
42
42
|
if (!caller && timeoutMs === undefined) {
|
|
43
43
|
return { signal: undefined, run: (operation) => operation() };
|
|
44
44
|
}
|
|
45
|
-
const
|
|
45
|
+
const timeoutController = timeoutMs === undefined ? undefined : new AbortController;
|
|
46
|
+
const signal = caller && timeoutController ? AbortSignal.any([caller, timeoutController.signal]) : caller ?? timeoutController?.signal;
|
|
46
47
|
let cause;
|
|
47
48
|
let timer;
|
|
48
49
|
const abortFromCaller = () => {
|
|
49
50
|
if (cause)
|
|
50
51
|
return;
|
|
51
52
|
cause = "caller";
|
|
52
|
-
controller.abort(caller?.reason);
|
|
53
53
|
};
|
|
54
54
|
if (caller?.aborted)
|
|
55
55
|
abortFromCaller();
|
|
56
56
|
else
|
|
57
57
|
caller?.addEventListener("abort", abortFromCaller, { once: true });
|
|
58
|
-
if (timeoutMs !== undefined) {
|
|
58
|
+
if (timeoutMs !== undefined && timeoutController) {
|
|
59
59
|
timer = setTimeout(() => {
|
|
60
60
|
if (cause)
|
|
61
61
|
return;
|
|
62
62
|
cause = "timeout";
|
|
63
|
-
|
|
63
|
+
timeoutController.abort(new DOMException("Request timed out", "TimeoutError"));
|
|
64
64
|
}, timeoutMs);
|
|
65
65
|
}
|
|
66
66
|
return {
|
|
67
|
-
signal
|
|
67
|
+
signal,
|
|
68
68
|
async run(operation) {
|
|
69
69
|
try {
|
|
70
70
|
if (cause === "caller")
|
|
71
71
|
throw cancellationError(cause);
|
|
72
|
-
return await operation(
|
|
72
|
+
return await operation(signal);
|
|
73
73
|
} catch (error) {
|
|
74
74
|
if (cause)
|
|
75
75
|
throw cancellationError(cause);
|
package/dist/remote.js
CHANGED
|
@@ -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;;;;;;;;;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,
|
|
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,CAkCf"}
|