@noetaris/harness 0.8.0 → 0.10.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 +35 -3
- package/dist/index.d.ts +65 -1
- package/dist/index.js +286 -188
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -510,6 +510,14 @@ function safeInvoke(hookName, call, sink) {
|
|
|
510
510
|
reportObserverError(error, { hookName }, sink);
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
|
+
function safeCall(hookName, call, sink) {
|
|
514
|
+
try {
|
|
515
|
+
return call();
|
|
516
|
+
} catch (error) {
|
|
517
|
+
reportObserverError(error, { hookName }, sink);
|
|
518
|
+
return void 0;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
513
521
|
async function runWrapped(wrap, fn, onObserverError) {
|
|
514
522
|
let p;
|
|
515
523
|
const inner = () => {
|
|
@@ -556,6 +564,16 @@ function composeObservers(observers, onObserverError) {
|
|
|
556
564
|
onStepSettled: (ctx, event) => {
|
|
557
565
|
for (const o of observers) safeInvoke("onStepSettled", () => o.onStepSettled?.(ctx, event), onObserverError);
|
|
558
566
|
},
|
|
567
|
+
// Each observer isolated on its own; later keys win.
|
|
568
|
+
carry: (ctx) => {
|
|
569
|
+
let merged;
|
|
570
|
+
for (const o of observers) {
|
|
571
|
+
const carried = safeCall("carry", () => o.carry?.(ctx), onObserverError);
|
|
572
|
+
if (typeof carried !== "object" || carried === null || Array.isArray(carried)) continue;
|
|
573
|
+
merged = Object.assign(merged ?? {}, carried);
|
|
574
|
+
}
|
|
575
|
+
return merged;
|
|
576
|
+
},
|
|
559
577
|
// First observer outermost; each layer isolated on its own by runWrapped.
|
|
560
578
|
wrap: (ctx, scope, fn) => {
|
|
561
579
|
const layer = (i) => i === wrappers.length ? fn() : runWrapped((inner) => wrappers[i].wrap(ctx, scope, inner), () => layer(i + 1), onObserverError);
|
|
@@ -706,6 +724,11 @@ function stepContextOf(runCtx, stepName) {
|
|
|
706
724
|
function asError(e) {
|
|
707
725
|
return e instanceof Error ? e : new Error(String(e));
|
|
708
726
|
}
|
|
727
|
+
function normalizeCarrier(carried) {
|
|
728
|
+
if (typeof carried !== "object" || carried === null || Array.isArray(carried)) return void 0;
|
|
729
|
+
const entries = Object.entries(carried).filter(([, v]) => typeof v === "string");
|
|
730
|
+
return entries.length > 0 ? Object.freeze(Object.fromEntries(entries)) : void 0;
|
|
731
|
+
}
|
|
709
732
|
async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callbacks) {
|
|
710
733
|
const { onBeforeStep, onAfterStep, onError, onComplete, onInterrupt } = callbacks ?? {};
|
|
711
734
|
const obs = callbacks?.observer;
|
|
@@ -715,15 +738,22 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
715
738
|
if (!("$interrupt" in state)) state.$interrupt = null;
|
|
716
739
|
if (!("$interruptResponses" in state)) state.$interruptResponses = {};
|
|
717
740
|
const runStart = Date.now();
|
|
741
|
+
const branchPath = callbacks?.branchPath;
|
|
742
|
+
const isBranch = branchPath !== void 0 && branchPath.length > 0;
|
|
718
743
|
const runCtx = {
|
|
719
744
|
agentId: ctx.agentId,
|
|
720
745
|
sessionId: ctx.sessionId,
|
|
721
746
|
runId: typeof callbacks?.runId === "string" ? callbacks.runId : "",
|
|
722
747
|
...typeof callbacks?.parentRunId === "string" ? { parentRunId: callbacks.parentRunId } : {},
|
|
723
748
|
...typeof ctx.instanceId === "string" ? { instanceId: ctx.instanceId } : {},
|
|
724
|
-
...
|
|
749
|
+
...isBranch ? { branchPath } : {},
|
|
750
|
+
// Branch runLoops receive the outer callbacks by spread, so the refs are dropped here.
|
|
751
|
+
...!isBranch && callbacks?.resumedFrom !== void 0 ? { resumedFrom: callbacks.resumedFrom } : {},
|
|
752
|
+
...!isBranch && callbacks?.branchedFrom !== void 0 ? { branchedFrom: callbacks.branchedFrom } : {}
|
|
725
753
|
};
|
|
726
754
|
safeInvoke("onRunStart", () => obs?.onRunStart?.(runCtx), onObserverError);
|
|
755
|
+
const carrier = isBranch ? void 0 : normalizeCarrier(safeCall("carry", () => obs?.carry?.(runCtx), onObserverError));
|
|
756
|
+
const withCarrier = (result) => carrier !== void 0 ? { ...result, carrier } : result;
|
|
727
757
|
let runEnded = false;
|
|
728
758
|
const endRun = (signal, failure) => {
|
|
729
759
|
runEnded = true;
|
|
@@ -741,7 +771,7 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
741
771
|
while (true) {
|
|
742
772
|
if (shouldStop?.()) {
|
|
743
773
|
endRun("$stopped");
|
|
744
|
-
return { state, signal: null, cursor, paused: true };
|
|
774
|
+
return withCarrier({ state, signal: null, cursor, paused: true });
|
|
745
775
|
}
|
|
746
776
|
if (isForkCursor(cursor)) {
|
|
747
777
|
const forkCursor = cursor;
|
|
@@ -765,7 +795,7 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
765
795
|
graph
|
|
766
796
|
);
|
|
767
797
|
if (outcome.done) {
|
|
768
|
-
return outcome.result;
|
|
798
|
+
return withCarrier(outcome.result);
|
|
769
799
|
}
|
|
770
800
|
cursor = outcome.nextCursor;
|
|
771
801
|
continue;
|
|
@@ -788,7 +818,7 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
788
818
|
graph
|
|
789
819
|
);
|
|
790
820
|
if (outcome.done) {
|
|
791
|
-
return outcome.result;
|
|
821
|
+
return withCarrier(outcome.result);
|
|
792
822
|
}
|
|
793
823
|
cursor = outcome.nextCursor;
|
|
794
824
|
continue;
|
|
@@ -834,7 +864,7 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
834
864
|
safeInvoke("onInterrupt", () => obs?.onInterrupt?.(stepCtx, { prompt: e.prompt, interruptId: e.interruptId }), onObserverError);
|
|
835
865
|
settle({ outcome: "interrupt", interrupt: { interruptId: e.interruptId, prompt: e.prompt }, next: { kind: "pause" } });
|
|
836
866
|
endRun("$interrupt");
|
|
837
|
-
return { state, signal: "$interrupt", cursor, paused: true };
|
|
867
|
+
return withCarrier({ state, signal: "$interrupt", cursor, paused: true });
|
|
838
868
|
}
|
|
839
869
|
state.$error = e instanceof Error ? e : new Error(String(e));
|
|
840
870
|
onError?.(state.$error, cursor);
|
|
@@ -856,7 +886,7 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
856
886
|
state.$error = e instanceof Error ? e : new Error(String(e));
|
|
857
887
|
settle({ outcome: "error", error: state.$error, next: { kind: "pause" } });
|
|
858
888
|
endRun("$error", { error: state.$error });
|
|
859
|
-
return { state, signal: "$error", cursor, paused: true };
|
|
889
|
+
return withCarrier({ state, signal: "$error", cursor, paused: true });
|
|
860
890
|
}
|
|
861
891
|
const routed = runSucceeded || step.run === void 0 ? { outcome: "ok", signal } : { outcome: "error", signal, error: state.$error };
|
|
862
892
|
const transition = step.transitions.find((t) => t.signal === signal);
|
|
@@ -869,7 +899,7 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
869
899
|
settle({ ...routed, next: { kind: "end" } });
|
|
870
900
|
onComplete?.(state, signal);
|
|
871
901
|
endRun(signal);
|
|
872
|
-
return { state, signal, cursor: null, paused: false };
|
|
902
|
+
return withCarrier({ state, signal, cursor: null, paused: false });
|
|
873
903
|
}
|
|
874
904
|
settle({ ...routed, next: { kind: "step", name: transition.target.name } });
|
|
875
905
|
cursor = transition.target.name;
|
|
@@ -880,7 +910,7 @@ async function runLoop(graph, state, ctx, schema, shouldStop, startCursor, callb
|
|
|
880
910
|
} else {
|
|
881
911
|
settle({ outcome: "error", error: state.$error, next: { kind: "pause" } });
|
|
882
912
|
endRun("$error", { error: state.$error });
|
|
883
|
-
return { state, signal: "$error", cursor, paused: true };
|
|
913
|
+
return withCarrier({ state, signal: "$error", cursor, paused: true });
|
|
884
914
|
}
|
|
885
915
|
} else {
|
|
886
916
|
const next = step.next ?? implicitNextMap.get(cursor) ?? null;
|
|
@@ -1054,6 +1084,13 @@ async function handleFork(forkNode, priorBranches, state, ctx, schema, shouldSto
|
|
|
1054
1084
|
}
|
|
1055
1085
|
|
|
1056
1086
|
// src/agent/session-store.ts
|
|
1087
|
+
function isValidTtlMs(value) {
|
|
1088
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
1089
|
+
}
|
|
1090
|
+
function defaultClaimTtlMs() {
|
|
1091
|
+
const ttlMs = Number(process.env["HARNESS_CLAIM_TTL_MS"]);
|
|
1092
|
+
return isValidTtlMs(ttlMs) ? ttlMs : 3e4;
|
|
1093
|
+
}
|
|
1057
1094
|
function collectPendingInterrupts(cursor, state) {
|
|
1058
1095
|
if (cursor !== void 0 && isForkCursor(cursor)) {
|
|
1059
1096
|
const result = [];
|
|
@@ -1249,9 +1286,16 @@ async function querySessionPhase(store, agentId, sessionId) {
|
|
|
1249
1286
|
const loaded = await store.load(agentId, sessionId);
|
|
1250
1287
|
return storedSessionToPhase(loaded);
|
|
1251
1288
|
}
|
|
1289
|
+
function runRefsOf(loaded) {
|
|
1290
|
+
if (loaded === null || loaded.phase !== "paused") return {};
|
|
1291
|
+
if (loaded.step !== void 0) {
|
|
1292
|
+
return { resumedFrom: { runId: loaded.runId, ...loaded.carrier !== void 0 ? { carrier: loaded.carrier } : {} } };
|
|
1293
|
+
}
|
|
1294
|
+
return loaded.branchedFrom !== void 0 ? { branchedFrom: loaded.branchedFrom } : {};
|
|
1295
|
+
}
|
|
1252
1296
|
async function runWithSession(store, agentId, sessionId, runId, graph, initialStateArg, schema, ctx, options) {
|
|
1253
1297
|
const leaseRef = options?.leaseRef ?? { current: null };
|
|
1254
|
-
const keepAlive = createKeepAliveFn(leaseRef, store, options?.claimTtlMs ??
|
|
1298
|
+
const keepAlive = createKeepAliveFn(leaseRef, store, options?.claimTtlMs ?? defaultClaimTtlMs());
|
|
1255
1299
|
ctx["keepAlive"] = keepAlive;
|
|
1256
1300
|
let leaseExpired = false;
|
|
1257
1301
|
const composedShouldStop = () => {
|
|
@@ -1300,7 +1344,8 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1300
1344
|
const result = await runLoop(graph, state, ctx, schema, composedShouldStop, loaded?.step, {
|
|
1301
1345
|
...options,
|
|
1302
1346
|
runId,
|
|
1303
|
-
...options?.parentRunId !== void 0 ? { parentRunId: options.parentRunId } : {}
|
|
1347
|
+
...options?.parentRunId !== void 0 ? { parentRunId: options.parentRunId } : {},
|
|
1348
|
+
...runRefsOf(loaded)
|
|
1304
1349
|
});
|
|
1305
1350
|
if (leaseExpired) {
|
|
1306
1351
|
const expiredError = new LeaseExpiredError(sessionId);
|
|
@@ -1324,7 +1369,8 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1324
1369
|
finalState: result.state,
|
|
1325
1370
|
step: result.cursor,
|
|
1326
1371
|
...result.signal !== null ? { signal: result.signal } : {},
|
|
1327
|
-
...metadata !== void 0 ? { metadata } : {}
|
|
1372
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
1373
|
+
...result.carrier !== void 0 ? { carrier: result.carrier } : {}
|
|
1328
1374
|
};
|
|
1329
1375
|
await store.save(agentId, sessionId, saved);
|
|
1330
1376
|
} else {
|
|
@@ -1339,7 +1385,8 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1339
1385
|
initialState: initialStateSnapshot,
|
|
1340
1386
|
finalState: result.state,
|
|
1341
1387
|
...result.signal !== null ? { signal: result.signal } : {},
|
|
1342
|
-
...metadata !== void 0 ? { metadata } : {}
|
|
1388
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
1389
|
+
...result.carrier !== void 0 ? { carrier: result.carrier } : {}
|
|
1343
1390
|
};
|
|
1344
1391
|
await store.save(agentId, sessionId, saved);
|
|
1345
1392
|
}
|
|
@@ -1349,6 +1396,50 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1349
1396
|
return result;
|
|
1350
1397
|
}
|
|
1351
1398
|
|
|
1399
|
+
// src/agent/claim-scope.ts
|
|
1400
|
+
function failOutcome(failState, error) {
|
|
1401
|
+
const state = failState();
|
|
1402
|
+
state["$error"] = error;
|
|
1403
|
+
return { state, signal: "$error" };
|
|
1404
|
+
}
|
|
1405
|
+
async function runClaimed(args) {
|
|
1406
|
+
const { store, agentId, sessionId, claimOptions, onStoreError, failState, body } = args;
|
|
1407
|
+
const fail = (error) => failOutcome(failState, error);
|
|
1408
|
+
let leaseRef = void 0;
|
|
1409
|
+
if (typeof store?.claim === "function") {
|
|
1410
|
+
let lease;
|
|
1411
|
+
try {
|
|
1412
|
+
lease = await store.claim(agentId, sessionId, claimOptions);
|
|
1413
|
+
} catch (claimError) {
|
|
1414
|
+
const loadError = new StoreLoadError(claimError);
|
|
1415
|
+
onStoreError?.(loadError, "claim");
|
|
1416
|
+
return fail(loadError);
|
|
1417
|
+
}
|
|
1418
|
+
if (lease === null) {
|
|
1419
|
+
const busyError = new SessionBusyError(sessionId);
|
|
1420
|
+
onStoreError?.(busyError, "claim");
|
|
1421
|
+
return fail(busyError);
|
|
1422
|
+
}
|
|
1423
|
+
leaseRef = { current: lease };
|
|
1424
|
+
}
|
|
1425
|
+
try {
|
|
1426
|
+
return await body(leaseRef !== void 0 ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {});
|
|
1427
|
+
} catch (error) {
|
|
1428
|
+
if (error instanceof LeaseExpiredError) return fail(error);
|
|
1429
|
+
throw error;
|
|
1430
|
+
} finally {
|
|
1431
|
+
if (leaseRef !== void 0 && typeof store?.release === "function") {
|
|
1432
|
+
try {
|
|
1433
|
+
await store.release(leaseRef.current);
|
|
1434
|
+
} catch {
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
function parseClaimOptions(raw, fallback) {
|
|
1440
|
+
return typeof raw === "object" && raw !== null && typeof raw["ttlMs"] === "number" ? raw : fallback;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1352
1443
|
// src/agent/interrupt-resume.ts
|
|
1353
1444
|
var NoInterruptError = class extends Error {
|
|
1354
1445
|
constructor() {
|
|
@@ -1416,10 +1507,25 @@ async function injectInterruptResponse(store, agentId, sessionId, interruptId, r
|
|
|
1416
1507
|
initialState: loaded.initialState,
|
|
1417
1508
|
finalState: result.state,
|
|
1418
1509
|
...result.cursor !== void 0 ? { step: result.cursor } : {},
|
|
1419
|
-
...loaded.signal !== void 0 ? { signal: loaded.signal } : {}
|
|
1510
|
+
...loaded.signal !== void 0 ? { signal: loaded.signal } : {},
|
|
1511
|
+
...loaded.metadata !== void 0 ? { metadata: loaded.metadata } : {},
|
|
1512
|
+
...loaded.carrier !== void 0 ? { carrier: loaded.carrier } : {},
|
|
1513
|
+
...loaded.branchedFrom !== void 0 ? { branchedFrom: loaded.branchedFrom } : {}
|
|
1420
1514
|
};
|
|
1421
1515
|
await store.save(agentId, sessionId, updated);
|
|
1422
1516
|
}
|
|
1517
|
+
async function injectThenRun(args) {
|
|
1518
|
+
const { store, agentId, sessionId, interruptId, response, onStoreError, failState, run } = args;
|
|
1519
|
+
try {
|
|
1520
|
+
await injectInterruptResponse(store, agentId, sessionId, interruptId, response);
|
|
1521
|
+
} catch (injectError) {
|
|
1522
|
+
if (injectError instanceof NoInterruptError) throw injectError;
|
|
1523
|
+
const storeError = new StoreLoadError(injectError);
|
|
1524
|
+
onStoreError?.(storeError, "claim");
|
|
1525
|
+
return failOutcome(failState, storeError);
|
|
1526
|
+
}
|
|
1527
|
+
return run();
|
|
1528
|
+
}
|
|
1423
1529
|
|
|
1424
1530
|
// src/agent/run-handle.ts
|
|
1425
1531
|
function createRunHandle(sessionId, runId, execution, stopFlag, stepRef, resumeFn) {
|
|
@@ -1579,6 +1685,18 @@ var UnexpectedStoreSlotError = class extends Error {
|
|
|
1579
1685
|
this.key = key;
|
|
1580
1686
|
}
|
|
1581
1687
|
};
|
|
1688
|
+
function describeValue(value) {
|
|
1689
|
+
return typeof value === "string" ? JSON.stringify(value) : String(value);
|
|
1690
|
+
}
|
|
1691
|
+
var InvalidClaimOptionsError = class extends Error {
|
|
1692
|
+
/** The rejected `ttlMs` value, as given. */
|
|
1693
|
+
ttlMs;
|
|
1694
|
+
constructor(ttlMs) {
|
|
1695
|
+
super(`claimOptions.ttlMs must be a finite number of milliseconds greater than 0 \u2014 got ${describeValue(ttlMs)} in createAgent options`);
|
|
1696
|
+
this.name = "InvalidClaimOptionsError";
|
|
1697
|
+
this.ttlMs = ttlMs;
|
|
1698
|
+
}
|
|
1699
|
+
};
|
|
1582
1700
|
var _agentInternals = /* @__PURE__ */ Symbol("_agentInternals");
|
|
1583
1701
|
function createAgent(id, h, slots, agentOptions) {
|
|
1584
1702
|
const internals = getInternals(h);
|
|
@@ -1609,6 +1727,13 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1609
1727
|
}
|
|
1610
1728
|
}
|
|
1611
1729
|
}
|
|
1730
|
+
let agentClaimOptions = void 0;
|
|
1731
|
+
if (agentOptions?.claimOptions !== void 0) {
|
|
1732
|
+
const ttlMs = agentOptions.claimOptions?.ttlMs;
|
|
1733
|
+
if (!isValidTtlMs(ttlMs)) throw new InvalidClaimOptionsError(ttlMs);
|
|
1734
|
+
agentClaimOptions = { ttlMs };
|
|
1735
|
+
}
|
|
1736
|
+
const fallbackClaimOptions = () => agentClaimOptions ?? { ttlMs: defaultClaimTtlMs() };
|
|
1612
1737
|
const resolvedProviders = /* @__PURE__ */ new Map();
|
|
1613
1738
|
const storeEntries = [];
|
|
1614
1739
|
const runtimeKeys = /* @__PURE__ */ new Set();
|
|
@@ -1661,7 +1786,9 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1661
1786
|
const reservedRunKeys = /* @__PURE__ */ new Set(["sessionId", "signal", "events", "listeners", "observer", "onObserverError", "claimOptions", "parentRunId"]);
|
|
1662
1787
|
const inFlightSessions = /* @__PURE__ */ new Set();
|
|
1663
1788
|
const interruptPendingSessions = /* @__PURE__ */ new Set();
|
|
1664
|
-
const
|
|
1789
|
+
const resumeFailState = () => initializeState(null, {}, agentInternals.stateSchema);
|
|
1790
|
+
const makeAgentResumeHandle = (resp, sId, iId, resumeResources) => {
|
|
1791
|
+
const { onStoreError, observer, onObserverError, telemetrySlots, parentRunId, claimOptions } = resumeResources;
|
|
1665
1792
|
let _stopped = false;
|
|
1666
1793
|
const abortController = new AbortController();
|
|
1667
1794
|
const flag = {
|
|
@@ -1677,86 +1804,63 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1677
1804
|
const rId = randomUUID();
|
|
1678
1805
|
const exec = (async () => {
|
|
1679
1806
|
await Promise.resolve();
|
|
1680
|
-
const claimOptions = { ttlMs: 3e4 };
|
|
1681
|
-
let leaseRef = void 0;
|
|
1682
1807
|
try {
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
}
|
|
1736
|
-
|
|
1737
|
-
...leaseRef !== void 0 ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {},
|
|
1738
|
-
...observer !== void 0 ? { observer } : {},
|
|
1739
|
-
...onObserverError !== void 0 ? { onObserverError } : {},
|
|
1740
|
-
...telemetrySlots !== void 0 && telemetrySlots.length > 0 ? { telemetrySlots } : {}
|
|
1741
|
-
}
|
|
1742
|
-
);
|
|
1743
|
-
if (r.signal === "$interrupt") interruptPendingSessions.add(sId);
|
|
1744
|
-
return { state: r.state, signal: r.signal };
|
|
1745
|
-
} catch (error) {
|
|
1746
|
-
if (error instanceof LeaseExpiredError) {
|
|
1747
|
-
const failState = initializeState(null, {}, agentInternals.stateSchema);
|
|
1748
|
-
failState["$error"] = error;
|
|
1749
|
-
return { state: failState, signal: "$error" };
|
|
1750
|
-
}
|
|
1751
|
-
throw error;
|
|
1752
|
-
} finally {
|
|
1753
|
-
if (leaseRef !== void 0 && typeof capturedStore?.release === "function") {
|
|
1754
|
-
try {
|
|
1755
|
-
await capturedStore.release(leaseRef.current);
|
|
1756
|
-
} catch {
|
|
1757
|
-
}
|
|
1808
|
+
return await runClaimed({
|
|
1809
|
+
store: capturedStore,
|
|
1810
|
+
agentId: id,
|
|
1811
|
+
sessionId: sId,
|
|
1812
|
+
claimOptions,
|
|
1813
|
+
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
1814
|
+
failState: resumeFailState,
|
|
1815
|
+
body: async (lease) => {
|
|
1816
|
+
if (capturedStore === void 0) throw new NoInterruptError();
|
|
1817
|
+
const store = capturedStore;
|
|
1818
|
+
return injectThenRun({
|
|
1819
|
+
store,
|
|
1820
|
+
agentId: id,
|
|
1821
|
+
sessionId: sId,
|
|
1822
|
+
interruptId: iId,
|
|
1823
|
+
response: resp,
|
|
1824
|
+
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
1825
|
+
failState: resumeFailState,
|
|
1826
|
+
run: async () => {
|
|
1827
|
+
const agentCtx = {
|
|
1828
|
+
...Object.fromEntries(agentInternals.resolvedProviders),
|
|
1829
|
+
agentId: id,
|
|
1830
|
+
sessionId: sId,
|
|
1831
|
+
runId: rId,
|
|
1832
|
+
signal: abortController.signal,
|
|
1833
|
+
...agentOptions?.instanceId !== void 0 ? { instanceId: agentOptions.instanceId } : {}
|
|
1834
|
+
};
|
|
1835
|
+
const r = await runWithSession(
|
|
1836
|
+
store,
|
|
1837
|
+
id,
|
|
1838
|
+
sId,
|
|
1839
|
+
rId,
|
|
1840
|
+
agentInternals.loopDef,
|
|
1841
|
+
{},
|
|
1842
|
+
agentInternals.stateSchema,
|
|
1843
|
+
agentCtx,
|
|
1844
|
+
{
|
|
1845
|
+
shouldStop: () => flag.stopped,
|
|
1846
|
+
onBeforeStep: (n) => {
|
|
1847
|
+
ref.current = n;
|
|
1848
|
+
},
|
|
1849
|
+
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
1850
|
+
...lease,
|
|
1851
|
+
...observer !== void 0 ? { observer } : {},
|
|
1852
|
+
...onObserverError !== void 0 ? { onObserverError } : {},
|
|
1853
|
+
...telemetrySlots !== void 0 && telemetrySlots.length > 0 ? { telemetrySlots } : {},
|
|
1854
|
+
...agentOptions?.instanceId !== void 0 ? { instanceId: agentOptions.instanceId } : {},
|
|
1855
|
+
...parentRunId !== void 0 ? { parentRunId } : {}
|
|
1856
|
+
}
|
|
1857
|
+
);
|
|
1858
|
+
if (r.signal === "$interrupt") interruptPendingSessions.add(sId);
|
|
1859
|
+
return { state: r.state, signal: r.signal };
|
|
1860
|
+
}
|
|
1861
|
+
});
|
|
1758
1862
|
}
|
|
1759
|
-
}
|
|
1863
|
+
});
|
|
1760
1864
|
} finally {
|
|
1761
1865
|
inFlightSessions.delete(sId);
|
|
1762
1866
|
}
|
|
@@ -1765,7 +1869,8 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1765
1869
|
if (inFlightSessions.has(sId)) throw new SessionInFlightError(sId);
|
|
1766
1870
|
interruptPendingSessions.delete(sId);
|
|
1767
1871
|
inFlightSessions.add(sId);
|
|
1768
|
-
|
|
1872
|
+
const { parentRunId: _staleParentRunId, ...inherited } = resumeResources;
|
|
1873
|
+
return makeAgentResumeHandle(r, sId, i, inherited);
|
|
1769
1874
|
};
|
|
1770
1875
|
return createRunHandle(sId, rId, exec, flag, ref, resumeFn);
|
|
1771
1876
|
};
|
|
@@ -1839,6 +1944,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1839
1944
|
...Object.entries(runtimeSlots)
|
|
1840
1945
|
]);
|
|
1841
1946
|
const parentRunId = typeof resources["parentRunId"] === "string" ? resources["parentRunId"] : void 0;
|
|
1947
|
+
const claimOptions = parseClaimOptions(resources["claimOptions"], fallbackClaimOptions());
|
|
1842
1948
|
const options = {
|
|
1843
1949
|
shouldStop: () => stopFlag.stopped,
|
|
1844
1950
|
onBeforeStep: (name, state) => {
|
|
@@ -1861,63 +1967,31 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1861
1967
|
let lastResult = null;
|
|
1862
1968
|
const execution = (async () => {
|
|
1863
1969
|
await Promise.resolve();
|
|
1864
|
-
const rawClaimOpts = resources["claimOptions"];
|
|
1865
|
-
const claimOptions = typeof rawClaimOpts === "object" && rawClaimOpts !== null && typeof rawClaimOpts["ttlMs"] === "number" ? rawClaimOpts : { ttlMs: 3e4 };
|
|
1866
|
-
let leaseRef = void 0;
|
|
1867
1970
|
try {
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
capturedStore,
|
|
1891
|
-
id,
|
|
1892
|
-
sessionId,
|
|
1893
|
-
runId,
|
|
1894
|
-
agentInternals.loopDef,
|
|
1895
|
-
initialState,
|
|
1896
|
-
agentInternals.stateSchema,
|
|
1897
|
-
ctx,
|
|
1898
|
-
{
|
|
1899
|
-
...options,
|
|
1900
|
-
...leaseRef !== void 0 ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {}
|
|
1901
|
-
}
|
|
1902
|
-
);
|
|
1903
|
-
if (r.signal === "$interrupt") interruptPendingSessions.add(sessionId);
|
|
1904
|
-
lastResult = { state: r.state, cursor: r.cursor };
|
|
1905
|
-
return { state: r.state, signal: r.signal };
|
|
1906
|
-
} catch (error) {
|
|
1907
|
-
if (error instanceof LeaseExpiredError) {
|
|
1908
|
-
const failState = initializeState(null, initialState, agentInternals.stateSchema);
|
|
1909
|
-
failState["$error"] = error;
|
|
1910
|
-
return { state: failState, signal: "$error" };
|
|
1911
|
-
}
|
|
1912
|
-
throw error;
|
|
1913
|
-
} finally {
|
|
1914
|
-
if (leaseRef !== void 0 && typeof capturedStore?.release === "function") {
|
|
1915
|
-
try {
|
|
1916
|
-
await capturedStore.release(leaseRef.current);
|
|
1917
|
-
} catch {
|
|
1918
|
-
}
|
|
1971
|
+
return await runClaimed({
|
|
1972
|
+
store: capturedStore,
|
|
1973
|
+
agentId: id,
|
|
1974
|
+
sessionId,
|
|
1975
|
+
claimOptions,
|
|
1976
|
+
...events.onStoreError !== void 0 ? { onStoreError: events.onStoreError } : {},
|
|
1977
|
+
failState: () => initializeState(null, initialState, agentInternals.stateSchema),
|
|
1978
|
+
body: async (lease) => {
|
|
1979
|
+
const r = await runWithSession(
|
|
1980
|
+
capturedStore,
|
|
1981
|
+
id,
|
|
1982
|
+
sessionId,
|
|
1983
|
+
runId,
|
|
1984
|
+
agentInternals.loopDef,
|
|
1985
|
+
initialState,
|
|
1986
|
+
agentInternals.stateSchema,
|
|
1987
|
+
ctx,
|
|
1988
|
+
{ ...options, ...lease }
|
|
1989
|
+
);
|
|
1990
|
+
if (r.signal === "$interrupt") interruptPendingSessions.add(sessionId);
|
|
1991
|
+
lastResult = { state: r.state, cursor: r.cursor, runId, ...r.carrier !== void 0 ? { carrier: r.carrier } : {} };
|
|
1992
|
+
return { state: r.state, signal: r.signal };
|
|
1919
1993
|
}
|
|
1920
|
-
}
|
|
1994
|
+
});
|
|
1921
1995
|
} finally {
|
|
1922
1996
|
inFlightSessions.delete(sessionId);
|
|
1923
1997
|
}
|
|
@@ -1949,37 +2023,59 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1949
2023
|
signal: resumeAbortController.signal
|
|
1950
2024
|
};
|
|
1951
2025
|
if (capturedStore !== void 0) {
|
|
1952
|
-
|
|
1953
|
-
const
|
|
1954
|
-
|
|
1955
|
-
|
|
2026
|
+
const store = capturedStore;
|
|
2027
|
+
const onStoreError = events.onStoreError;
|
|
2028
|
+
return await runClaimed({
|
|
2029
|
+
store,
|
|
2030
|
+
agentId: id,
|
|
1956
2031
|
sessionId,
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
2032
|
+
claimOptions,
|
|
2033
|
+
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
2034
|
+
failState: resumeFailState,
|
|
2035
|
+
body: (lease) => injectThenRun({
|
|
2036
|
+
store,
|
|
2037
|
+
agentId: id,
|
|
2038
|
+
sessionId,
|
|
2039
|
+
interruptId,
|
|
2040
|
+
response,
|
|
2041
|
+
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
2042
|
+
failState: resumeFailState,
|
|
2043
|
+
run: async () => {
|
|
2044
|
+
const r2 = await runWithSession(
|
|
2045
|
+
store,
|
|
2046
|
+
id,
|
|
2047
|
+
sessionId,
|
|
2048
|
+
resumeRunId,
|
|
2049
|
+
agentInternals.loopDef,
|
|
2050
|
+
{},
|
|
2051
|
+
agentInternals.stateSchema,
|
|
2052
|
+
resumeCtx,
|
|
2053
|
+
{
|
|
2054
|
+
shouldStop: () => resumeStopFlag.stopped,
|
|
2055
|
+
onBeforeStep: (n, s) => {
|
|
2056
|
+
resumeStepRef.current = n;
|
|
2057
|
+
events.onBeforeStep?.(n, s);
|
|
2058
|
+
},
|
|
2059
|
+
// spread optional event callbacks only when defined (exactOptionalPropertyTypes requires omission, not undefined)
|
|
2060
|
+
...events.onStoreError !== void 0 ? { onStoreError: events.onStoreError } : {},
|
|
2061
|
+
...events.onAfterStep !== void 0 ? { onAfterStep: events.onAfterStep } : {},
|
|
2062
|
+
...events.onError !== void 0 ? { onError: events.onError } : {},
|
|
2063
|
+
...events.onComplete !== void 0 ? { onComplete: events.onComplete } : {},
|
|
2064
|
+
...events.onInterrupt !== void 0 ? { onInterrupt: events.onInterrupt } : {},
|
|
2065
|
+
...Object.keys(listeners).length > 0 ? { listeners } : {},
|
|
2066
|
+
...observer !== void 0 ? { observer } : {},
|
|
2067
|
+
...onObserverError !== void 0 ? { onObserverError } : {},
|
|
2068
|
+
...telemetrySlots.length > 0 ? { telemetrySlots } : {},
|
|
2069
|
+
...agentOptions?.instanceId !== void 0 ? { instanceId: agentOptions.instanceId } : {},
|
|
2070
|
+
...lease
|
|
2071
|
+
}
|
|
2072
|
+
);
|
|
2073
|
+
if (r2.signal === "$interrupt") interruptPendingSessions.add(sessionId);
|
|
2074
|
+
lastResult = { state: r2.state, cursor: r2.cursor, runId: resumeRunId, ...r2.carrier !== void 0 ? { carrier: r2.carrier } : {} };
|
|
2075
|
+
return { state: r2.state, signal: r2.signal };
|
|
2076
|
+
}
|
|
2077
|
+
})
|
|
2078
|
+
});
|
|
1983
2079
|
}
|
|
1984
2080
|
const prev = lastResult;
|
|
1985
2081
|
if (prev === null) throw new NoInterruptError();
|
|
@@ -1996,6 +2092,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1996
2092
|
cursor,
|
|
1997
2093
|
{
|
|
1998
2094
|
runId: resumeRunId,
|
|
2095
|
+
resumedFrom: { runId: prev.runId, ...prev.carrier !== void 0 ? { carrier: prev.carrier } : {} },
|
|
1999
2096
|
onBeforeStep: (n, s) => {
|
|
2000
2097
|
resumeStepRef.current = n;
|
|
2001
2098
|
events.onBeforeStep?.(n, s);
|
|
@@ -2011,15 +2108,8 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2011
2108
|
}
|
|
2012
2109
|
);
|
|
2013
2110
|
if (r.signal === "$interrupt") interruptPendingSessions.add(sessionId);
|
|
2014
|
-
lastResult = { state: r.state, cursor: r.cursor };
|
|
2111
|
+
lastResult = { state: r.state, cursor: r.cursor, runId: resumeRunId, ...r.carrier !== void 0 ? { carrier: r.carrier } : {} };
|
|
2015
2112
|
return { state: r.state, signal: r.signal };
|
|
2016
|
-
} catch (error) {
|
|
2017
|
-
if (error instanceof LeaseExpiredError) {
|
|
2018
|
-
const failState = initializeState(null, initialState, agentInternals.stateSchema);
|
|
2019
|
-
failState["$error"] = error;
|
|
2020
|
-
return { state: failState, signal: "$error" };
|
|
2021
|
-
}
|
|
2022
|
-
throw error;
|
|
2023
2113
|
} finally {
|
|
2024
2114
|
inFlightSessions.delete(sessionId);
|
|
2025
2115
|
}
|
|
@@ -2034,11 +2124,19 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2034
2124
|
interruptPendingSessions.delete(sessionId);
|
|
2035
2125
|
inFlightSessions.add(sessionId);
|
|
2036
2126
|
const events = extractRunEvents(resources ?? {});
|
|
2037
|
-
const resumeOpts = events.onStoreError !== void 0 ? { onStoreError: events.onStoreError } : void 0;
|
|
2038
2127
|
const observer = extractRunObserver(resources ?? {});
|
|
2039
2128
|
const onObserverError = extractRunErrorSink(resources ?? {});
|
|
2040
2129
|
const telemetrySlots = buildTelemetrySlots(agentInternals.resolvedProviders.entries());
|
|
2041
|
-
|
|
2130
|
+
const parentRunId = resources?.["parentRunId"];
|
|
2131
|
+
const claimOptions = parseClaimOptions(resources?.["claimOptions"], fallbackClaimOptions());
|
|
2132
|
+
return makeAgentResumeHandle(response, sessionId, interruptId, {
|
|
2133
|
+
claimOptions,
|
|
2134
|
+
...events.onStoreError !== void 0 ? { onStoreError: events.onStoreError } : {},
|
|
2135
|
+
...observer !== void 0 ? { observer } : {},
|
|
2136
|
+
...onObserverError !== void 0 ? { onObserverError } : {},
|
|
2137
|
+
...telemetrySlots.length > 0 ? { telemetrySlots } : {},
|
|
2138
|
+
...typeof parentRunId === "string" ? { parentRunId } : {}
|
|
2139
|
+
});
|
|
2042
2140
|
},
|
|
2043
2141
|
status: (sessionId) => querySessionPhase(capturedStore, id, sessionId),
|
|
2044
2142
|
[_agentInternals]: agentInternals
|