@noetaris/harness 0.12.0 → 0.13.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.
- package/README.md +119 -10
- package/dist/index.d.ts +91 -11
- package/dist/index.js +137 -53
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -564,6 +564,9 @@ function composeObservers(observers, onObserverError) {
|
|
|
564
564
|
onStepSettled: (ctx, event) => {
|
|
565
565
|
for (const o of observers) safeInvoke("onStepSettled", () => o.onStepSettled?.(ctx, event), onObserverError);
|
|
566
566
|
},
|
|
567
|
+
onCheckpoint: (ctx, event) => {
|
|
568
|
+
for (const o of observers) safeInvoke("onCheckpoint", () => o.onCheckpoint?.(ctx, event), onObserverError);
|
|
569
|
+
},
|
|
567
570
|
// Each observer isolated on its own; later keys win.
|
|
568
571
|
carry: (ctx) => {
|
|
569
572
|
let merged;
|
|
@@ -766,8 +769,9 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
766
769
|
ctx["within"] = createWithinFn(obs, () => stepCtxRef.current, onObserverError);
|
|
767
770
|
const telemetryObserver = obs !== void 0 ? composeObservers([obs], onObserverError) : NOOP_OBSERVER;
|
|
768
771
|
let cursor = startCursor ?? graph.entryStep;
|
|
772
|
+
let first = true;
|
|
769
773
|
try {
|
|
770
|
-
|
|
774
|
+
for (; ; first = false) {
|
|
771
775
|
if (shouldStop?.()) {
|
|
772
776
|
endRun("$stopped");
|
|
773
777
|
return withCarrier({ state, signal: null, cursor, paused: true });
|
|
@@ -790,6 +794,14 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
790
794
|
return withCarrier({ state, signal: null, cursor, paused: true });
|
|
791
795
|
}
|
|
792
796
|
}
|
|
797
|
+
if (!first && callbacks?.checkpoint !== void 0 && typeof cursor === "string") {
|
|
798
|
+
const started = Date.now();
|
|
799
|
+
const saved = await callbacks.checkpoint(cursor, state, carrier);
|
|
800
|
+
if (saved !== void 0) {
|
|
801
|
+
const event = { step: cursor, version: saved.version, durationMs: Date.now() - started };
|
|
802
|
+
safeInvoke("onCheckpoint", () => obs?.onCheckpoint?.(runCtx, event), onObserverError);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
793
805
|
if (isForkCursor(cursor)) {
|
|
794
806
|
const forkCursor = cursor;
|
|
795
807
|
const forkNode = graph.steps.find((s) => s.name === forkCursor.fork);
|
|
@@ -976,7 +988,7 @@ async function dispatchFork(forkNode, priorBranches, outerState, outerCtx, schem
|
|
|
976
988
|
const branchSignals = forkNode.branches.map(
|
|
977
989
|
(_, i) => outerSignal !== void 0 ? AbortSignal.any([outerSignal, localAborts[i].signal]) : localAborts[i].signal
|
|
978
990
|
);
|
|
979
|
-
const { onBeforeStep: _outerOnBeforeStep, onAfterStep: _outerOnAfterStep, onComplete: _outerOnComplete, ...branchCallbacksRest } = callbacks ?? {};
|
|
991
|
+
const { onBeforeStep: _outerOnBeforeStep, onAfterStep: _outerOnAfterStep, onComplete: _outerOnComplete, checkpoint: _outerCheckpoint, ...branchCallbacksRest } = callbacks ?? {};
|
|
980
992
|
const branchCallbacksBase = callbacks !== void 0 ? branchCallbacksRest : void 0;
|
|
981
993
|
const settled = await Promise.allSettled(
|
|
982
994
|
forkNode.branches.map(async (branch, i) => {
|
|
@@ -1109,6 +1121,13 @@ function defaultClaimTtlMs() {
|
|
|
1109
1121
|
const ttlMs = Number(process.env["HARNESS_CLAIM_TTL_MS"]);
|
|
1110
1122
|
return isValidTtlMs(ttlMs) ? ttlMs : 3e4;
|
|
1111
1123
|
}
|
|
1124
|
+
function isCheckpointMode(value) {
|
|
1125
|
+
return value === "off" || value === "step";
|
|
1126
|
+
}
|
|
1127
|
+
async function saveRun(store, agentId, sessionId, run, lease) {
|
|
1128
|
+
if (lease !== null && lease !== void 0) await store.save(agentId, sessionId, run, { lease });
|
|
1129
|
+
else await store.save(agentId, sessionId, run);
|
|
1130
|
+
}
|
|
1112
1131
|
function collectPendingInterrupts(cursor, state) {
|
|
1113
1132
|
if (cursor !== void 0 && isForkCursor(cursor)) {
|
|
1114
1133
|
const result = [];
|
|
@@ -1130,14 +1149,23 @@ function storedSessionToPhase(loaded) {
|
|
|
1130
1149
|
if (loaded === null) {
|
|
1131
1150
|
return { phase: "fresh" };
|
|
1132
1151
|
}
|
|
1152
|
+
const step = loaded.step === void 0 ? "" : isForkCursor(loaded.step) ? loaded.step.fork : loaded.step;
|
|
1133
1153
|
if (loaded.phase === "paused") {
|
|
1134
|
-
const step = loaded.step === void 0 ? "" : isForkCursor(loaded.step) ? loaded.step.fork : loaded.step;
|
|
1135
1154
|
const pendingInterrupts = collectPendingInterrupts(loaded.step, loaded.finalState);
|
|
1136
1155
|
if (loaded.signal !== void 0) {
|
|
1137
1156
|
return { phase: "paused", step, signal: loaded.signal, pendingInterrupts };
|
|
1138
1157
|
}
|
|
1139
1158
|
return { phase: "paused", step, pendingInterrupts };
|
|
1140
1159
|
}
|
|
1160
|
+
if (loaded.phase === "running") {
|
|
1161
|
+
const instanceId = loaded.metadata?.instanceId;
|
|
1162
|
+
return {
|
|
1163
|
+
phase: "running",
|
|
1164
|
+
step,
|
|
1165
|
+
...instanceId !== void 0 ? { instanceId } : {},
|
|
1166
|
+
checkpointedAt: loaded.settledAt
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1141
1169
|
if (loaded.signal !== void 0) {
|
|
1142
1170
|
return { phase: "completed", signal: loaded.signal };
|
|
1143
1171
|
}
|
|
@@ -1238,12 +1266,19 @@ var SessionBusyError = class extends Error {
|
|
|
1238
1266
|
var LeaseExpiredError = class extends Error {
|
|
1239
1267
|
/** The session whose lease expired. */
|
|
1240
1268
|
sessionId;
|
|
1241
|
-
constructor(sessionId) {
|
|
1269
|
+
constructor(sessionId, cause) {
|
|
1242
1270
|
super(`lease for session "${sessionId}" has expired \u2014 run stopped without saving`);
|
|
1243
1271
|
this.name = "LeaseExpiredError";
|
|
1244
1272
|
this.sessionId = sessionId;
|
|
1273
|
+
if (cause !== void 0) this.cause = cause;
|
|
1245
1274
|
}
|
|
1246
1275
|
};
|
|
1276
|
+
function isLeaseLost(error) {
|
|
1277
|
+
return error instanceof Error && error.name === "LeaseLostError";
|
|
1278
|
+
}
|
|
1279
|
+
function isConflict(error) {
|
|
1280
|
+
return error instanceof Error && error.name === "ConcurrentModificationError";
|
|
1281
|
+
}
|
|
1247
1282
|
|
|
1248
1283
|
// src/agent/ctx-keep-alive.ts
|
|
1249
1284
|
function createKeepAliveFn(leaseRef, store, originalTtlMs) {
|
|
@@ -1353,7 +1388,7 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1353
1388
|
}
|
|
1354
1389
|
return false;
|
|
1355
1390
|
};
|
|
1356
|
-
const { mode = "run", requestId: callerRequestId, ...loopOptions } = options ?? {};
|
|
1391
|
+
const { mode = "run", requestId: callerRequestId, checkpoint: checkpointMode = "off", ...loopOptions } = options ?? {};
|
|
1357
1392
|
if (store === void 0) {
|
|
1358
1393
|
const state2 = initializeState(null, initialStateArg, schema);
|
|
1359
1394
|
const result2 = await runLoop(graph, state2, ctx, schema, composedShouldStop, void 0, {
|
|
@@ -1394,7 +1429,7 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1394
1429
|
state: row.finalState,
|
|
1395
1430
|
signal: row.signal ?? null,
|
|
1396
1431
|
cursor: row.step ?? null,
|
|
1397
|
-
paused: row.phase
|
|
1432
|
+
paused: row.phase !== "completed"
|
|
1398
1433
|
};
|
|
1399
1434
|
}
|
|
1400
1435
|
const segmentRequestId = mode === "run" ? requestId : loaded?.requestId;
|
|
@@ -1403,8 +1438,47 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1403
1438
|
const state = initializeState(base, input, schema);
|
|
1404
1439
|
const initialStateSnapshot = { ...state };
|
|
1405
1440
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1441
|
+
const metadata = options?.instanceId !== void 0 ? { instanceId: options.instanceId } : void 0;
|
|
1442
|
+
let nextVersion = (loaded?.version ?? -1) + 1;
|
|
1443
|
+
const baseRow = (carrier) => ({
|
|
1444
|
+
agentId,
|
|
1445
|
+
runId,
|
|
1446
|
+
sessionId,
|
|
1447
|
+
version: nextVersion,
|
|
1448
|
+
startedAt,
|
|
1449
|
+
settledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1450
|
+
initialState: initialStateSnapshot,
|
|
1451
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
1452
|
+
...carrier !== void 0 ? { carrier } : {},
|
|
1453
|
+
...segmentRequestId !== void 0 ? { requestId: segmentRequestId } : {}
|
|
1454
|
+
});
|
|
1455
|
+
const checkpoint = async (next, live, carrier) => {
|
|
1456
|
+
let finalState;
|
|
1457
|
+
try {
|
|
1458
|
+
finalState = structuredClone(live);
|
|
1459
|
+
} catch (error) {
|
|
1460
|
+
options?.onStoreError?.(error, "checkpoint");
|
|
1461
|
+
return void 0;
|
|
1462
|
+
}
|
|
1463
|
+
const row = { ...baseRow(carrier), phase: "running", step: next, finalState };
|
|
1464
|
+
try {
|
|
1465
|
+
await saveRun(store, agentId, sessionId, row, leaseRef.current);
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
if (isLeaseLost(error) || isConflict(error)) {
|
|
1468
|
+
const expiredError = new LeaseExpiredError(sessionId, error);
|
|
1469
|
+
options?.onStoreError?.(expiredError, "claim");
|
|
1470
|
+
throw expiredError;
|
|
1471
|
+
}
|
|
1472
|
+
options?.onStoreError?.(error, "checkpoint");
|
|
1473
|
+
return void 0;
|
|
1474
|
+
}
|
|
1475
|
+
nextVersion++;
|
|
1476
|
+
await extendLease(store, leaseRef, options?.claimTtlMs ?? defaultClaimTtlMs());
|
|
1477
|
+
return { version: row.version };
|
|
1478
|
+
};
|
|
1406
1479
|
const result = await runLoop(graph, state, ctx, schema, composedShouldStop, loaded?.step, {
|
|
1407
1480
|
...loopOptions,
|
|
1481
|
+
...checkpointMode === "step" ? { checkpoint } : {},
|
|
1408
1482
|
runId,
|
|
1409
1483
|
...options?.parentRunId !== void 0 ? { parentRunId: options.parentRunId } : {},
|
|
1410
1484
|
...segmentRequestId !== void 0 ? { requestId: segmentRequestId } : {},
|
|
@@ -1415,53 +1489,39 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1415
1489
|
options?.onStoreError?.(expiredError, "claim");
|
|
1416
1490
|
throw expiredError;
|
|
1417
1491
|
}
|
|
1418
|
-
const
|
|
1419
|
-
|
|
1492
|
+
const saved = {
|
|
1493
|
+
...baseRow(result.carrier),
|
|
1494
|
+
phase: result.paused ? "paused" : "completed",
|
|
1495
|
+
finalState: result.state,
|
|
1496
|
+
...result.paused ? { step: result.cursor } : {},
|
|
1497
|
+
...result.signal !== null ? { signal: result.signal } : {}
|
|
1498
|
+
};
|
|
1420
1499
|
try {
|
|
1421
|
-
|
|
1422
|
-
if (result.paused) {
|
|
1423
|
-
const saved = {
|
|
1424
|
-
agentId,
|
|
1425
|
-
runId,
|
|
1426
|
-
sessionId,
|
|
1427
|
-
version,
|
|
1428
|
-
startedAt,
|
|
1429
|
-
settledAt,
|
|
1430
|
-
phase: "paused",
|
|
1431
|
-
initialState: initialStateSnapshot,
|
|
1432
|
-
finalState: result.state,
|
|
1433
|
-
step: result.cursor,
|
|
1434
|
-
...result.signal !== null ? { signal: result.signal } : {},
|
|
1435
|
-
...metadata !== void 0 ? { metadata } : {},
|
|
1436
|
-
...result.carrier !== void 0 ? { carrier: result.carrier } : {},
|
|
1437
|
-
...segmentRequestId !== void 0 ? { requestId: segmentRequestId } : {}
|
|
1438
|
-
};
|
|
1439
|
-
await store.save(agentId, sessionId, saved);
|
|
1440
|
-
} else {
|
|
1441
|
-
const saved = {
|
|
1442
|
-
agentId,
|
|
1443
|
-
runId,
|
|
1444
|
-
sessionId,
|
|
1445
|
-
version,
|
|
1446
|
-
startedAt,
|
|
1447
|
-
settledAt,
|
|
1448
|
-
phase: "completed",
|
|
1449
|
-
initialState: initialStateSnapshot,
|
|
1450
|
-
finalState: result.state,
|
|
1451
|
-
...result.signal !== null ? { signal: result.signal } : {},
|
|
1452
|
-
...metadata !== void 0 ? { metadata } : {},
|
|
1453
|
-
...result.carrier !== void 0 ? { carrier: result.carrier } : {},
|
|
1454
|
-
...segmentRequestId !== void 0 ? { requestId: segmentRequestId } : {}
|
|
1455
|
-
};
|
|
1456
|
-
await store.save(agentId, sessionId, saved);
|
|
1457
|
-
}
|
|
1500
|
+
await saveRun(store, agentId, sessionId, saved, leaseRef.current);
|
|
1458
1501
|
} catch (error) {
|
|
1502
|
+
if (isLeaseLost(error)) {
|
|
1503
|
+
const expiredError = new LeaseExpiredError(sessionId, error);
|
|
1504
|
+
options?.onStoreError?.(expiredError, "claim");
|
|
1505
|
+
throw expiredError;
|
|
1506
|
+
}
|
|
1459
1507
|
options?.onStoreError?.(error, "persist");
|
|
1460
1508
|
}
|
|
1461
1509
|
return result;
|
|
1462
1510
|
}
|
|
1511
|
+
async function extendLease(store, leaseRef, ttlMs) {
|
|
1512
|
+
const held = leaseRef.current;
|
|
1513
|
+
if (held === null || typeof store.extendClaim !== "function") return;
|
|
1514
|
+
try {
|
|
1515
|
+
leaseRef.current = await store.extendClaim(held, { ttlMs });
|
|
1516
|
+
} catch {
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1463
1519
|
|
|
1464
1520
|
// src/agent/claim-scope.ts
|
|
1521
|
+
function heldLease(options) {
|
|
1522
|
+
const lease = options.leaseRef?.current ?? null;
|
|
1523
|
+
return lease !== null ? { lease } : {};
|
|
1524
|
+
}
|
|
1465
1525
|
function failOutcome(failState, error) {
|
|
1466
1526
|
const state = failState();
|
|
1467
1527
|
state["$error"] = error;
|
|
@@ -1555,7 +1615,7 @@ function injectInterruptResponseIntoState(cursor, state, interruptId, response)
|
|
|
1555
1615
|
found: true
|
|
1556
1616
|
};
|
|
1557
1617
|
}
|
|
1558
|
-
async function injectInterruptResponse(store, agentId, sessionId, interruptId, response) {
|
|
1618
|
+
async function injectInterruptResponse(store, agentId, sessionId, interruptId, response, lease) {
|
|
1559
1619
|
const loaded = await store.load(agentId, sessionId);
|
|
1560
1620
|
if (loaded === null) throw new NoInterruptError();
|
|
1561
1621
|
if (loaded.phase !== "paused") throw new NoInterruptError();
|
|
@@ -1578,14 +1638,19 @@ async function injectInterruptResponse(store, agentId, sessionId, interruptId, r
|
|
|
1578
1638
|
...loaded.branchedFrom !== void 0 ? { branchedFrom: loaded.branchedFrom } : {},
|
|
1579
1639
|
...loaded.requestId !== void 0 ? { requestId: loaded.requestId } : {}
|
|
1580
1640
|
};
|
|
1581
|
-
await store
|
|
1641
|
+
await saveRun(store, agentId, sessionId, updated, lease);
|
|
1582
1642
|
}
|
|
1583
1643
|
async function injectThenRun(args) {
|
|
1584
|
-
const { store, agentId, sessionId, interruptId, response, onStoreError, failState, run } = args;
|
|
1644
|
+
const { store, agentId, sessionId, interruptId, response, lease, onStoreError, failState, run } = args;
|
|
1585
1645
|
try {
|
|
1586
|
-
await injectInterruptResponse(store, agentId, sessionId, interruptId, response);
|
|
1646
|
+
await injectInterruptResponse(store, agentId, sessionId, interruptId, response, lease);
|
|
1587
1647
|
} catch (injectError) {
|
|
1588
1648
|
if (injectError instanceof NoInterruptError) throw injectError;
|
|
1649
|
+
if (isLeaseLost(injectError)) {
|
|
1650
|
+
const expiredError = new LeaseExpiredError(sessionId, injectError);
|
|
1651
|
+
onStoreError?.(expiredError, "claim");
|
|
1652
|
+
return failOutcome(failState, expiredError);
|
|
1653
|
+
}
|
|
1589
1654
|
const storeError = new StoreLoadError(injectError);
|
|
1590
1655
|
onStoreError?.(storeError, "claim");
|
|
1591
1656
|
return failOutcome(failState, storeError);
|
|
@@ -2329,13 +2394,14 @@ var InvalidClaimOptionsError = class extends Error {
|
|
|
2329
2394
|
this.ttlMs = ttlMs;
|
|
2330
2395
|
}
|
|
2331
2396
|
};
|
|
2397
|
+
var AGENT_OPTION_EXPECTED = { observer: "an object", onObserverError: "a function", checkpoint: "'off' or 'step'" };
|
|
2332
2398
|
var InvalidAgentOptionError = class extends Error {
|
|
2333
2399
|
/** The option that was rejected. */
|
|
2334
2400
|
key;
|
|
2335
2401
|
/** The rejected value, as given. */
|
|
2336
2402
|
value;
|
|
2337
2403
|
constructor(key, value) {
|
|
2338
|
-
super(`${key} must be ${key
|
|
2404
|
+
super(`${key} must be ${AGENT_OPTION_EXPECTED[key]} \u2014 got ${describeValue(value)} in createAgent options`);
|
|
2339
2405
|
this.name = "InvalidAgentOptionError";
|
|
2340
2406
|
this.key = key;
|
|
2341
2407
|
this.value = value;
|
|
@@ -2347,7 +2413,7 @@ var InvalidRunResourceError = class extends Error {
|
|
|
2347
2413
|
/** The rejected value, as given. */
|
|
2348
2414
|
value;
|
|
2349
2415
|
constructor(key, value) {
|
|
2350
|
-
super(`${key} must be a non-empty string \u2014 got ${describeValue(value)} in agent.run() resources`);
|
|
2416
|
+
super(key === "checkpoint" ? `checkpoint must be 'off' or 'step' \u2014 got ${describeValue(value)} in the call's resources` : `${key} must be a non-empty string \u2014 got ${describeValue(value)} in agent.run() resources`);
|
|
2351
2417
|
this.name = "InvalidRunResourceError";
|
|
2352
2418
|
this.key = key;
|
|
2353
2419
|
this.value = value;
|
|
@@ -2359,6 +2425,12 @@ function readIdResource(resources, key) {
|
|
|
2359
2425
|
if (typeof value !== "string" || value.length === 0) throw new InvalidRunResourceError(key, value);
|
|
2360
2426
|
return value;
|
|
2361
2427
|
}
|
|
2428
|
+
function readCheckpointResource(resources) {
|
|
2429
|
+
const value = resources["checkpoint"];
|
|
2430
|
+
if (value === void 0) return void 0;
|
|
2431
|
+
if (!isCheckpointMode(value)) throw new InvalidRunResourceError("checkpoint", value);
|
|
2432
|
+
return value;
|
|
2433
|
+
}
|
|
2362
2434
|
var _agentInternals = /* @__PURE__ */ Symbol("_agentInternals");
|
|
2363
2435
|
function createAgent(id, h, slots, agentOptions) {
|
|
2364
2436
|
const internals = getInternals(h);
|
|
@@ -2413,6 +2485,10 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2413
2485
|
...onObserverError !== void 0 ? { onObserverError } : {}
|
|
2414
2486
|
};
|
|
2415
2487
|
};
|
|
2488
|
+
const agentCheckpoint = agentOptions?.checkpoint;
|
|
2489
|
+
if (agentCheckpoint !== void 0 && !isCheckpointMode(agentCheckpoint)) {
|
|
2490
|
+
throw new InvalidAgentOptionError("checkpoint", agentCheckpoint);
|
|
2491
|
+
}
|
|
2416
2492
|
const resolvedProviders = /* @__PURE__ */ new Map();
|
|
2417
2493
|
const storeEntries = [];
|
|
2418
2494
|
const runtimeKeys = /* @__PURE__ */ new Set();
|
|
@@ -2462,13 +2538,13 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2462
2538
|
runtimeKeys,
|
|
2463
2539
|
requiredKeys
|
|
2464
2540
|
};
|
|
2465
|
-
const reservedRunKeys = /* @__PURE__ */ new Set(["sessionId", "requestId", "signal", "events", "listeners", "observer", "onObserverError", "claimOptions", "parentRunId"]);
|
|
2541
|
+
const reservedRunKeys = /* @__PURE__ */ new Set(["sessionId", "requestId", "signal", "events", "listeners", "observer", "onObserverError", "claimOptions", "parentRunId", "checkpoint"]);
|
|
2466
2542
|
const inFlightSessions = /* @__PURE__ */ new Set();
|
|
2467
2543
|
const debugSessions = /* @__PURE__ */ new Set();
|
|
2468
2544
|
const interruptPendingSessions = /* @__PURE__ */ new Set();
|
|
2469
2545
|
const resumeFailState = () => initializeState(null, {}, agentInternals.stateSchema);
|
|
2470
2546
|
const makeAgentResumeHandle = (resp, sId, iId, resumeResources) => {
|
|
2471
|
-
const { onStoreError, observer, onObserverError, telemetrySlots, parentRunId, claimOptions } = resumeResources;
|
|
2547
|
+
const { onStoreError, observer, onObserverError, telemetrySlots, parentRunId, claimOptions, checkpoint } = resumeResources;
|
|
2472
2548
|
let _stopped = false;
|
|
2473
2549
|
const abortController = new AbortController();
|
|
2474
2550
|
const flag = {
|
|
@@ -2501,6 +2577,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2501
2577
|
sessionId: sId,
|
|
2502
2578
|
interruptId: iId,
|
|
2503
2579
|
response: resp,
|
|
2580
|
+
...heldLease(lease),
|
|
2504
2581
|
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
2505
2582
|
failState: resumeFailState,
|
|
2506
2583
|
run: async () => {
|
|
@@ -2523,6 +2600,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2523
2600
|
agentCtx,
|
|
2524
2601
|
{
|
|
2525
2602
|
mode: "resume",
|
|
2603
|
+
checkpoint,
|
|
2526
2604
|
shouldStop: () => flag.stopped,
|
|
2527
2605
|
onBeforeStep: (n) => {
|
|
2528
2606
|
ref.current = n;
|
|
@@ -2574,6 +2652,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2574
2652
|
}
|
|
2575
2653
|
const sessionId = readIdResource(resources, "sessionId") ?? randomUUID();
|
|
2576
2654
|
const requestId = readIdResource(resources, "requestId");
|
|
2655
|
+
const checkpoint = readCheckpointResource(resources) ?? agentCheckpoint ?? "off";
|
|
2577
2656
|
const runId = randomUUID();
|
|
2578
2657
|
if (debugSessions.has(sessionId)) throw new SessionInDebugError(sessionId);
|
|
2579
2658
|
if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId);
|
|
@@ -2628,6 +2707,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2628
2707
|
const claimOptions = parseClaimOptions(resources["claimOptions"], fallbackClaimOptions());
|
|
2629
2708
|
const options = {
|
|
2630
2709
|
mode: "run",
|
|
2710
|
+
checkpoint,
|
|
2631
2711
|
...requestId !== void 0 ? { requestId } : {},
|
|
2632
2712
|
shouldStop: () => stopFlag.stopped,
|
|
2633
2713
|
onBeforeStep: (name, state) => {
|
|
@@ -2723,6 +2803,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2723
2803
|
sessionId,
|
|
2724
2804
|
interruptId,
|
|
2725
2805
|
response,
|
|
2806
|
+
...heldLease(lease),
|
|
2726
2807
|
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
2727
2808
|
failState: resumeFailState,
|
|
2728
2809
|
run: async () => {
|
|
@@ -2738,6 +2819,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2738
2819
|
resumeCtx,
|
|
2739
2820
|
{
|
|
2740
2821
|
mode: "resume",
|
|
2822
|
+
checkpoint,
|
|
2741
2823
|
shouldStop: () => resumeStopFlag.stopped,
|
|
2742
2824
|
onBeforeStep: (n, s) => {
|
|
2743
2825
|
resumeStepRef.current = n;
|
|
@@ -2813,6 +2895,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2813
2895
|
resume: (response, sessionId, interruptId, resources) => {
|
|
2814
2896
|
if (debugSessions.has(sessionId)) throw new SessionInDebugError(sessionId);
|
|
2815
2897
|
if (inFlightSessions.has(sessionId)) throw new SessionInFlightError(sessionId);
|
|
2898
|
+
const checkpoint = readCheckpointResource(resources ?? {}) ?? agentCheckpoint ?? "off";
|
|
2816
2899
|
interruptPendingSessions.delete(sessionId);
|
|
2817
2900
|
inFlightSessions.add(sessionId);
|
|
2818
2901
|
const events = extractRunEvents(resources ?? {});
|
|
@@ -2822,6 +2905,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2822
2905
|
const claimOptions = parseClaimOptions(resources?.["claimOptions"], fallbackClaimOptions());
|
|
2823
2906
|
return makeAgentResumeHandle(response, sessionId, interruptId, {
|
|
2824
2907
|
claimOptions,
|
|
2908
|
+
checkpoint,
|
|
2825
2909
|
...events.onStoreError !== void 0 ? { onStoreError: events.onStoreError } : {},
|
|
2826
2910
|
...observer !== void 0 ? { observer } : {},
|
|
2827
2911
|
...onObserverError !== void 0 ? { onObserverError } : {},
|