@noetaris/harness 0.9.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 +5 -4
- package/dist/index.d.ts +10 -1
- package/dist/index.js +218 -176
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -157,11 +157,12 @@ const resumed = agent.resume(response, sessionId, interruptId)
|
|
|
157
157
|
```
|
|
158
158
|
|
|
159
159
|
`agent.resume()` takes an optional fourth argument with these reserved resources (a subset of
|
|
160
|
-
`run()`'s): `observer`, `onObserverError`, `events: { onStoreError }`,
|
|
161
|
-
for a sub agent resumed from a step)
|
|
160
|
+
`run()`'s): `observer`, `onObserverError`, `events: { onStoreError }`, `parentRunId` (the caller's run id,
|
|
161
|
+
for a sub agent resumed from a step), and `claimOptions`. `parentRunId` applies to that resumed run only: calling
|
|
162
162
|
`resume()` again on the handle it returns keeps the other resources but not `parentRunId`, which
|
|
163
163
|
is stale by then. With a store, both `agent.resume()` and `run.resume()` record the agent's
|
|
164
|
-
`instanceId` in the resumed run's `metadata
|
|
164
|
+
`instanceId` in the resumed run's `metadata` and, when the store supports claims, claim the
|
|
165
|
+
session for the resumed run; a `resume()` on the returned handle reuses the same claim TTL.
|
|
165
166
|
|
|
166
167
|
**Resume replays the interrupted step from the top.** On resume, the step that called
|
|
167
168
|
`ctx.interrupt()` runs again from its first line; each `ctx.interrupt()` call it reaches
|
|
@@ -410,7 +411,7 @@ The harness never trusts a wrapper. `fn` always runs exactly once, and the calle
|
|
|
410
411
|
| Export | Description |
|
|
411
412
|
|---|---|
|
|
412
413
|
| `createHarness<Ctx>()(schema)` | Creates a harness. Fixes `Ctx`, infers `State` from schema. |
|
|
413
|
-
| `createAgent(id, h, slots)` | Assigns the agent an ID and fills `required()` slots. Returns an `Agent`. |
|
|
414
|
+
| `createAgent(id, h, slots, options?)` | Assigns the agent an ID and fills `required()` slots. `options` (`AgentOptions`) takes `instanceId`, `stores` (for `required()` store slots) and `claimOptions` (this agent's default claim TTL; per-call `claimOptions` wins, then `HARNESS_CLAIM_TTL_MS`, then 30 000 ms). Returns an `Agent`. |
|
|
414
415
|
| `field<T>(opts)` | Declares a state field with a default and optional reduce function. |
|
|
415
416
|
| `required()` | Marks a provider slot as required at `createAgent()`. |
|
|
416
417
|
| `runtime()` | Marks a provider slot as required at `agent.run()`. |
|
package/dist/index.d.ts
CHANGED
|
@@ -1045,6 +1045,12 @@ interface AgentOptions {
|
|
|
1045
1045
|
* Keyed by the store key used in the harness (e.g. `{ session: myStore }`).
|
|
1046
1046
|
*/
|
|
1047
1047
|
readonly stores?: Record<string, unknown>;
|
|
1048
|
+
/**
|
|
1049
|
+
* Default claim options for every run and resume of this agent, used when the call passes none.
|
|
1050
|
+
* Resolution: per-call `claimOptions` → this → `HARNESS_CLAIM_TTL_MS` → 30 000 ms.
|
|
1051
|
+
* `ttlMs` must be a finite number greater than 0; otherwise `createAgent` throws `InvalidClaimOptionsError`.
|
|
1052
|
+
*/
|
|
1053
|
+
readonly claimOptions?: ClaimOptions;
|
|
1048
1054
|
}
|
|
1049
1055
|
interface Agent {
|
|
1050
1056
|
/** The agent's unique identifier, as provided to createAgent(). */
|
|
@@ -1062,6 +1068,9 @@ interface Agent {
|
|
|
1062
1068
|
* - `parentRunId?: string` — the caller's run id, as for `run()`; set on this resumed run's
|
|
1063
1069
|
* `RunContext` only (a later `handle.resume()` on the returned handle does not inherit it)
|
|
1064
1070
|
* - `events?.onStoreError?` — raw store-error callback (unchanged from prior shape)
|
|
1071
|
+
* - `claimOptions?: ClaimOptions` — claim TTL for this resume, parsed like `agent.run()`'s; falls back
|
|
1072
|
+
* to `AgentOptions.claimOptions`, then `HARNESS_CLAIM_TTL_MS`, then 30 000 ms. A later `handle.resume()`
|
|
1073
|
+
* on the returned handle reuses it
|
|
1065
1074
|
*/
|
|
1066
1075
|
resume(response: unknown, sessionId: string, interruptId: string, resources?: Record<string, unknown>): RunHandle;
|
|
1067
1076
|
/**
|
|
@@ -1165,4 +1174,4 @@ declare class LeaseExpiredError extends Error {
|
|
|
1165
1174
|
constructor(sessionId: string);
|
|
1166
1175
|
}
|
|
1167
1176
|
|
|
1168
|
-
export { type Agent, type BranchCursor, type BranchDef, type ClaimOptions, type Cursor, type DeepWithMarkers, type FieldDefinition, type ForkCursor, type ForkDef, type FrameworkState, type Harness, type Lease, LeaseExpiredError, type LoopDefinition, type LoopNode, LoopNotDefinedError, NoInterruptError, type Observer, type ObserverAware, type ObserverErrorContext, type ObserverErrorSink, REQUIRED_TAG, RUNTIME_TAG, type RequiredMarker, type RouteFn, type RunCarrier, type RunContext, type RunFn, type RunRef, type RuntimeMarker, SessionBusyError, SessionInFlightError, SessionPendingInterruptError, type SessionStore, type SignalTransition, type StateFromSchema, type StepContext, type StepDef, type StepSettledEvent, type StepSettledNext, type StepState, StoreLoadError, type StoredRun, type StoredRunMetadata, type TelemetryContext, type TransitionTarget, type WrapScope, composeObservers, createAgent, createHarness, field, isForkCursor, isForkDef, isRequiredMarker, isRuntimeMarker, required, runtime };
|
|
1177
|
+
export { type Agent, type AgentOptions, type BranchCursor, type BranchDef, type ClaimOptions, type Cursor, type DeepWithMarkers, type FieldDefinition, type ForkCursor, type ForkDef, type FrameworkState, type Harness, type Lease, LeaseExpiredError, type LoopDefinition, type LoopNode, LoopNotDefinedError, NoInterruptError, type Observer, type ObserverAware, type ObserverErrorContext, type ObserverErrorSink, REQUIRED_TAG, RUNTIME_TAG, type RequiredMarker, type RouteFn, type RunCarrier, type RunContext, type RunFn, type RunRef, type RuntimeMarker, SessionBusyError, SessionInFlightError, SessionPendingInterruptError, type SessionStore, type SignalTransition, type StateFromSchema, type StepContext, type StepDef, type StepSettledEvent, type StepSettledNext, type StepState, StoreLoadError, type StoredRun, type StoredRunMetadata, type TelemetryContext, type TransitionTarget, type WrapScope, composeObservers, createAgent, createHarness, field, isForkCursor, isForkDef, isRequiredMarker, isRuntimeMarker, required, runtime };
|
package/dist/index.js
CHANGED
|
@@ -1084,6 +1084,13 @@ async function handleFork(forkNode, priorBranches, state, ctx, schema, shouldSto
|
|
|
1084
1084
|
}
|
|
1085
1085
|
|
|
1086
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
|
+
}
|
|
1087
1094
|
function collectPendingInterrupts(cursor, state) {
|
|
1088
1095
|
if (cursor !== void 0 && isForkCursor(cursor)) {
|
|
1089
1096
|
const result = [];
|
|
@@ -1288,7 +1295,7 @@ function runRefsOf(loaded) {
|
|
|
1288
1295
|
}
|
|
1289
1296
|
async function runWithSession(store, agentId, sessionId, runId, graph, initialStateArg, schema, ctx, options) {
|
|
1290
1297
|
const leaseRef = options?.leaseRef ?? { current: null };
|
|
1291
|
-
const keepAlive = createKeepAliveFn(leaseRef, store, options?.claimTtlMs ??
|
|
1298
|
+
const keepAlive = createKeepAliveFn(leaseRef, store, options?.claimTtlMs ?? defaultClaimTtlMs());
|
|
1292
1299
|
ctx["keepAlive"] = keepAlive;
|
|
1293
1300
|
let leaseExpired = false;
|
|
1294
1301
|
const composedShouldStop = () => {
|
|
@@ -1389,6 +1396,50 @@ async function runWithSession(store, agentId, sessionId, runId, graph, initialSt
|
|
|
1389
1396
|
return result;
|
|
1390
1397
|
}
|
|
1391
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
|
+
|
|
1392
1443
|
// src/agent/interrupt-resume.ts
|
|
1393
1444
|
var NoInterruptError = class extends Error {
|
|
1394
1445
|
constructor() {
|
|
@@ -1463,6 +1514,18 @@ async function injectInterruptResponse(store, agentId, sessionId, interruptId, r
|
|
|
1463
1514
|
};
|
|
1464
1515
|
await store.save(agentId, sessionId, updated);
|
|
1465
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
|
+
}
|
|
1466
1529
|
|
|
1467
1530
|
// src/agent/run-handle.ts
|
|
1468
1531
|
function createRunHandle(sessionId, runId, execution, stopFlag, stepRef, resumeFn) {
|
|
@@ -1622,6 +1685,18 @@ var UnexpectedStoreSlotError = class extends Error {
|
|
|
1622
1685
|
this.key = key;
|
|
1623
1686
|
}
|
|
1624
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
|
+
};
|
|
1625
1700
|
var _agentInternals = /* @__PURE__ */ Symbol("_agentInternals");
|
|
1626
1701
|
function createAgent(id, h, slots, agentOptions) {
|
|
1627
1702
|
const internals = getInternals(h);
|
|
@@ -1652,6 +1727,13 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1652
1727
|
}
|
|
1653
1728
|
}
|
|
1654
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() };
|
|
1655
1737
|
const resolvedProviders = /* @__PURE__ */ new Map();
|
|
1656
1738
|
const storeEntries = [];
|
|
1657
1739
|
const runtimeKeys = /* @__PURE__ */ new Set();
|
|
@@ -1704,8 +1786,9 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1704
1786
|
const reservedRunKeys = /* @__PURE__ */ new Set(["sessionId", "signal", "events", "listeners", "observer", "onObserverError", "claimOptions", "parentRunId"]);
|
|
1705
1787
|
const inFlightSessions = /* @__PURE__ */ new Set();
|
|
1706
1788
|
const interruptPendingSessions = /* @__PURE__ */ new Set();
|
|
1707
|
-
const
|
|
1708
|
-
|
|
1789
|
+
const resumeFailState = () => initializeState(null, {}, agentInternals.stateSchema);
|
|
1790
|
+
const makeAgentResumeHandle = (resp, sId, iId, resumeResources) => {
|
|
1791
|
+
const { onStoreError, observer, onObserverError, telemetrySlots, parentRunId, claimOptions } = resumeResources;
|
|
1709
1792
|
let _stopped = false;
|
|
1710
1793
|
const abortController = new AbortController();
|
|
1711
1794
|
const flag = {
|
|
@@ -1721,89 +1804,63 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1721
1804
|
const rId = randomUUID();
|
|
1722
1805
|
const exec = (async () => {
|
|
1723
1806
|
await Promise.resolve();
|
|
1724
|
-
const claimOptions = { ttlMs: 3e4 };
|
|
1725
|
-
let leaseRef = void 0;
|
|
1726
1807
|
try {
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
return { state: failState, signal: "$error" };
|
|
1744
|
-
}
|
|
1745
|
-
leaseRef = { current: lease };
|
|
1746
|
-
}
|
|
1747
|
-
try {
|
|
1748
|
-
if (capturedStore === void 0) throw new NoInterruptError();
|
|
1749
|
-
try {
|
|
1750
|
-
await injectInterruptResponse(capturedStore, id, sId, iId, resp);
|
|
1751
|
-
} catch (injectError) {
|
|
1752
|
-
if (injectError instanceof NoInterruptError) throw injectError;
|
|
1753
|
-
const storeError = new StoreLoadError(injectError);
|
|
1754
|
-
onStoreError?.(storeError, "claim");
|
|
1755
|
-
const failState = initializeState(null, {}, agentInternals.stateSchema);
|
|
1756
|
-
failState["$error"] = storeError;
|
|
1757
|
-
return { state: failState, signal: "$error" };
|
|
1758
|
-
}
|
|
1759
|
-
const agentCtx = {
|
|
1760
|
-
...Object.fromEntries(agentInternals.resolvedProviders),
|
|
1761
|
-
agentId: id,
|
|
1762
|
-
sessionId: sId,
|
|
1763
|
-
runId: rId,
|
|
1764
|
-
signal: abortController.signal,
|
|
1765
|
-
...agentOptions?.instanceId !== void 0 ? { instanceId: agentOptions.instanceId } : {}
|
|
1766
|
-
};
|
|
1767
|
-
const r = await runWithSession(
|
|
1768
|
-
capturedStore,
|
|
1769
|
-
id,
|
|
1770
|
-
sId,
|
|
1771
|
-
rId,
|
|
1772
|
-
agentInternals.loopDef,
|
|
1773
|
-
{},
|
|
1774
|
-
agentInternals.stateSchema,
|
|
1775
|
-
agentCtx,
|
|
1776
|
-
{
|
|
1777
|
-
shouldStop: () => flag.stopped,
|
|
1778
|
-
onBeforeStep: (n) => {
|
|
1779
|
-
ref.current = n;
|
|
1780
|
-
},
|
|
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,
|
|
1781
1824
|
...onStoreError !== void 0 ? { onStoreError } : {},
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
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
|
+
});
|
|
1805
1862
|
}
|
|
1806
|
-
}
|
|
1863
|
+
});
|
|
1807
1864
|
} finally {
|
|
1808
1865
|
inFlightSessions.delete(sId);
|
|
1809
1866
|
}
|
|
@@ -1887,6 +1944,7 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1887
1944
|
...Object.entries(runtimeSlots)
|
|
1888
1945
|
]);
|
|
1889
1946
|
const parentRunId = typeof resources["parentRunId"] === "string" ? resources["parentRunId"] : void 0;
|
|
1947
|
+
const claimOptions = parseClaimOptions(resources["claimOptions"], fallbackClaimOptions());
|
|
1890
1948
|
const options = {
|
|
1891
1949
|
shouldStop: () => stopFlag.stopped,
|
|
1892
1950
|
onBeforeStep: (name, state) => {
|
|
@@ -1909,63 +1967,31 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1909
1967
|
let lastResult = null;
|
|
1910
1968
|
const execution = (async () => {
|
|
1911
1969
|
await Promise.resolve();
|
|
1912
|
-
const rawClaimOpts = resources["claimOptions"];
|
|
1913
|
-
const claimOptions = typeof rawClaimOpts === "object" && rawClaimOpts !== null && typeof rawClaimOpts["ttlMs"] === "number" ? rawClaimOpts : { ttlMs: 3e4 };
|
|
1914
|
-
let leaseRef = void 0;
|
|
1915
1970
|
try {
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
capturedStore,
|
|
1939
|
-
id,
|
|
1940
|
-
sessionId,
|
|
1941
|
-
runId,
|
|
1942
|
-
agentInternals.loopDef,
|
|
1943
|
-
initialState,
|
|
1944
|
-
agentInternals.stateSchema,
|
|
1945
|
-
ctx,
|
|
1946
|
-
{
|
|
1947
|
-
...options,
|
|
1948
|
-
...leaseRef !== void 0 ? { leaseRef, claimTtlMs: claimOptions.ttlMs } : {}
|
|
1949
|
-
}
|
|
1950
|
-
);
|
|
1951
|
-
if (r.signal === "$interrupt") interruptPendingSessions.add(sessionId);
|
|
1952
|
-
lastResult = { state: r.state, cursor: r.cursor, runId, ...r.carrier !== void 0 ? { carrier: r.carrier } : {} };
|
|
1953
|
-
return { state: r.state, signal: r.signal };
|
|
1954
|
-
} catch (error) {
|
|
1955
|
-
if (error instanceof LeaseExpiredError) {
|
|
1956
|
-
const failState = initializeState(null, initialState, agentInternals.stateSchema);
|
|
1957
|
-
failState["$error"] = error;
|
|
1958
|
-
return { state: failState, signal: "$error" };
|
|
1959
|
-
}
|
|
1960
|
-
throw error;
|
|
1961
|
-
} finally {
|
|
1962
|
-
if (leaseRef !== void 0 && typeof capturedStore?.release === "function") {
|
|
1963
|
-
try {
|
|
1964
|
-
await capturedStore.release(leaseRef.current);
|
|
1965
|
-
} catch {
|
|
1966
|
-
}
|
|
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 };
|
|
1967
1993
|
}
|
|
1968
|
-
}
|
|
1994
|
+
});
|
|
1969
1995
|
} finally {
|
|
1970
1996
|
inFlightSessions.delete(sessionId);
|
|
1971
1997
|
}
|
|
@@ -1997,38 +2023,59 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
1997
2023
|
signal: resumeAbortController.signal
|
|
1998
2024
|
};
|
|
1999
2025
|
if (capturedStore !== void 0) {
|
|
2000
|
-
|
|
2001
|
-
const
|
|
2002
|
-
|
|
2003
|
-
|
|
2026
|
+
const store = capturedStore;
|
|
2027
|
+
const onStoreError = events.onStoreError;
|
|
2028
|
+
return await runClaimed({
|
|
2029
|
+
store,
|
|
2030
|
+
agentId: id,
|
|
2004
2031
|
sessionId,
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
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
|
+
});
|
|
2032
2079
|
}
|
|
2033
2080
|
const prev = lastResult;
|
|
2034
2081
|
if (prev === null) throw new NoInterruptError();
|
|
@@ -2063,13 +2110,6 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2063
2110
|
if (r.signal === "$interrupt") interruptPendingSessions.add(sessionId);
|
|
2064
2111
|
lastResult = { state: r.state, cursor: r.cursor, runId: resumeRunId, ...r.carrier !== void 0 ? { carrier: r.carrier } : {} };
|
|
2065
2112
|
return { state: r.state, signal: r.signal };
|
|
2066
|
-
} catch (error) {
|
|
2067
|
-
if (error instanceof LeaseExpiredError) {
|
|
2068
|
-
const failState = initializeState(null, initialState, agentInternals.stateSchema);
|
|
2069
|
-
failState["$error"] = error;
|
|
2070
|
-
return { state: failState, signal: "$error" };
|
|
2071
|
-
}
|
|
2072
|
-
throw error;
|
|
2073
2113
|
} finally {
|
|
2074
2114
|
inFlightSessions.delete(sessionId);
|
|
2075
2115
|
}
|
|
@@ -2088,7 +2128,9 @@ function createAgent(id, h, slots, agentOptions) {
|
|
|
2088
2128
|
const onObserverError = extractRunErrorSink(resources ?? {});
|
|
2089
2129
|
const telemetrySlots = buildTelemetrySlots(agentInternals.resolvedProviders.entries());
|
|
2090
2130
|
const parentRunId = resources?.["parentRunId"];
|
|
2131
|
+
const claimOptions = parseClaimOptions(resources?.["claimOptions"], fallbackClaimOptions());
|
|
2091
2132
|
return makeAgentResumeHandle(response, sessionId, interruptId, {
|
|
2133
|
+
claimOptions,
|
|
2092
2134
|
...events.onStoreError !== void 0 ? { onStoreError: events.onStoreError } : {},
|
|
2093
2135
|
...observer !== void 0 ? { observer } : {},
|
|
2094
2136
|
...onObserverError !== void 0 ? { onObserverError } : {},
|