@tangle-network/agent-runtime 0.48.0 → 0.49.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.
Files changed (40) hide show
  1. package/README.md +79 -15
  2. package/dist/agent.js +1 -1
  3. package/dist/chunk-GHX7XOJ2.js +433 -0
  4. package/dist/chunk-GHX7XOJ2.js.map +1 -0
  5. package/dist/{chunk-TJS7S3HJ.js → chunk-IQS4HI3F.js} +14 -5
  6. package/dist/chunk-IQS4HI3F.js.map +1 -0
  7. package/dist/{chunk-IW2LMLK6.js → chunk-PXUTIMGJ.js} +767 -129
  8. package/dist/chunk-PXUTIMGJ.js.map +1 -0
  9. package/dist/{chunk-656G2XCL.js → chunk-U2VEWKKK.js} +3 -3
  10. package/dist/{chunk-JNPK46YH.js → chunk-VIEDXELL.js} +408 -6
  11. package/dist/chunk-VIEDXELL.js.map +1 -0
  12. package/dist/{chunk-VR4JIC5H.js → chunk-XTEZ3YJ4.js} +2 -2
  13. package/dist/index.d.ts +29 -4
  14. package/dist/index.js +109 -21
  15. package/dist/index.js.map +1 -1
  16. package/dist/kb-gate-CsXpNRk7.d.ts +1145 -0
  17. package/dist/{loop-runner-bin-DEm4roYF.d.ts → loop-runner-bin-Cgn0A-NW.d.ts} +1 -1
  18. package/dist/loop-runner-bin.d.ts +2 -2
  19. package/dist/loop-runner-bin.js +3 -3
  20. package/dist/loops.d.ts +2 -2
  21. package/dist/loops.js +11 -1
  22. package/dist/mcp/bin.js +187 -24
  23. package/dist/mcp/bin.js.map +1 -1
  24. package/dist/mcp/index.d.ts +27 -124
  25. package/dist/mcp/index.js +28 -6
  26. package/dist/mcp/index.js.map +1 -1
  27. package/dist/platform.js +2 -2
  28. package/dist/platform.js.map +1 -1
  29. package/dist/runtime.d.ts +285 -8
  30. package/dist/runtime.js +11 -1
  31. package/dist/workflow.js +1 -1
  32. package/package.json +6 -5
  33. package/dist/chunk-IW2LMLK6.js.map +0 -1
  34. package/dist/chunk-JNPK46YH.js.map +0 -1
  35. package/dist/chunk-LX66I3SC.js +0 -218
  36. package/dist/chunk-LX66I3SC.js.map +0 -1
  37. package/dist/chunk-TJS7S3HJ.js.map +0 -1
  38. package/dist/kb-gate-51BlLlVM.d.ts +0 -529
  39. /package/dist/{chunk-656G2XCL.js.map → chunk-U2VEWKKK.js.map} +0 -0
  40. /package/dist/{chunk-VR4JIC5H.js.map → chunk-XTEZ3YJ4.js.map} +0 -0
@@ -3,14 +3,14 @@ import {
3
3
  } from "./chunk-FNMGYYSS.js";
4
4
  import {
5
5
  createDefaultCoderDelegate
6
- } from "./chunk-LX66I3SC.js";
6
+ } from "./chunk-GHX7XOJ2.js";
7
7
  import {
8
8
  runAnalystLoop
9
9
  } from "./chunk-HNUXAZIJ.js";
10
10
  import {
11
11
  createDriver,
12
12
  runLoop
13
- } from "./chunk-IW2LMLK6.js";
13
+ } from "./chunk-PXUTIMGJ.js";
14
14
  import {
15
15
  ConfigError
16
16
  } from "./chunk-GSUO5QS6.js";
@@ -200,4 +200,4 @@ export {
200
200
  runLoopRunnerCli,
201
201
  parseLoopRunnerArgv
202
202
  };
203
- //# sourceMappingURL=chunk-656G2XCL.js.map
203
+ //# sourceMappingURL=chunk-U2VEWKKK.js.map
@@ -1,23 +1,231 @@
1
1
  import {
2
- NotFoundError
2
+ formatDetachedSessionRef
3
+ } from "./chunk-GHX7XOJ2.js";
4
+ import {
5
+ AgentEvalError,
6
+ NotFoundError,
7
+ ValidationError
3
8
  } from "./chunk-GSUO5QS6.js";
4
9
 
10
+ // src/mcp/delegation-store.ts
11
+ import { mkdir, readFile, rename, writeFile } from "fs/promises";
12
+ import { dirname } from "path";
13
+ var DelegationStateCorruptError = class extends AgentEvalError {
14
+ constructor(message, options) {
15
+ super("validation", message, options);
16
+ }
17
+ };
18
+ var DelegationPersistenceError = class extends AgentEvalError {
19
+ constructor(message, options) {
20
+ super("config", message, options);
21
+ }
22
+ };
23
+ var InMemoryDelegationStore = class {
24
+ records = /* @__PURE__ */ new Map();
25
+ async loadAll() {
26
+ return [...this.records.values()].map(cloneRecord);
27
+ }
28
+ async upsert(record) {
29
+ this.records.set(record.taskId, cloneRecord(record));
30
+ }
31
+ async lookupIdempotencyKey(key) {
32
+ for (const record of this.records.values()) {
33
+ if (record.idempotencyKey === key) return record.taskId;
34
+ }
35
+ return void 0;
36
+ }
37
+ async remove(taskIds) {
38
+ for (const taskId of taskIds) this.records.delete(taskId);
39
+ }
40
+ };
41
+ var STATE_FORMAT_VERSION = 1;
42
+ var FileDelegationStore = class {
43
+ filePath;
44
+ recoverCorrupt;
45
+ records = /* @__PURE__ */ new Map();
46
+ loaded = false;
47
+ writeTail = Promise.resolve();
48
+ tmpSeq = 0;
49
+ constructor(options) {
50
+ this.filePath = options.filePath;
51
+ this.recoverCorrupt = options.recoverCorrupt ?? false;
52
+ }
53
+ async loadAll() {
54
+ let raw;
55
+ try {
56
+ raw = await readFile(this.filePath, "utf8");
57
+ } catch (err) {
58
+ if (err.code === "ENOENT") {
59
+ this.loaded = true;
60
+ return [];
61
+ }
62
+ throw new DelegationPersistenceError(
63
+ `FileDelegationStore: failed to read ${this.filePath}: ${errorMessage(err)}`,
64
+ { cause: err }
65
+ );
66
+ }
67
+ let state;
68
+ try {
69
+ state = parsePersistedState(raw);
70
+ } catch (err) {
71
+ if (!this.recoverCorrupt) {
72
+ throw new DelegationStateCorruptError(
73
+ `FileDelegationStore: state file ${this.filePath} is corrupt (${errorMessage(err)}). Repair or archive the file, or opt into automatic recovery (recoverCorrupt / AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1) to archive it and start empty.`,
74
+ { cause: err }
75
+ );
76
+ }
77
+ const archivePath = `${this.filePath}.corrupt-${Date.now()}`;
78
+ await rename(this.filePath, archivePath);
79
+ this.loaded = true;
80
+ return [];
81
+ }
82
+ this.records.clear();
83
+ for (const record of state.records) this.records.set(record.taskId, record);
84
+ this.loaded = true;
85
+ return [...this.records.values()].map(cloneRecord);
86
+ }
87
+ async upsert(record) {
88
+ this.assertLoaded("upsert");
89
+ this.records.set(record.taskId, cloneRecord(record));
90
+ await this.enqueueWrite();
91
+ }
92
+ async lookupIdempotencyKey(key) {
93
+ this.assertLoaded("lookupIdempotencyKey");
94
+ for (const record of this.records.values()) {
95
+ if (record.idempotencyKey === key) return record.taskId;
96
+ }
97
+ return void 0;
98
+ }
99
+ async remove(taskIds) {
100
+ this.assertLoaded("remove");
101
+ let changed = false;
102
+ for (const taskId of taskIds) {
103
+ if (this.records.delete(taskId)) changed = true;
104
+ }
105
+ if (changed) await this.enqueueWrite();
106
+ }
107
+ assertLoaded(op) {
108
+ if (this.loaded) return;
109
+ throw new DelegationPersistenceError(
110
+ `FileDelegationStore: ${op} called before loadAll() \u2014 the on-disk state has not been read yet`
111
+ );
112
+ }
113
+ enqueueWrite() {
114
+ const write = this.writeTail.then(() => this.writeSnapshot());
115
+ this.writeTail = write.catch(() => {
116
+ });
117
+ return write;
118
+ }
119
+ async writeSnapshot() {
120
+ const state = {
121
+ version: STATE_FORMAT_VERSION,
122
+ records: [...this.records.values()]
123
+ };
124
+ const payload = `${JSON.stringify(state)}
125
+ `;
126
+ this.tmpSeq += 1;
127
+ const tmpPath = `${this.filePath}.tmp-${process.pid}-${this.tmpSeq}`;
128
+ try {
129
+ await mkdir(dirname(this.filePath), { recursive: true });
130
+ await writeFile(tmpPath, payload, "utf8");
131
+ await rename(tmpPath, this.filePath);
132
+ } catch (err) {
133
+ throw new DelegationPersistenceError(
134
+ `FileDelegationStore: failed to write ${this.filePath}: ${errorMessage(err)}`,
135
+ { cause: err }
136
+ );
137
+ }
138
+ }
139
+ };
140
+ function parsePersistedState(raw) {
141
+ const parsed = JSON.parse(raw);
142
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
143
+ throw new Error("top-level value is not an object");
144
+ }
145
+ const state = parsed;
146
+ if (state.version !== STATE_FORMAT_VERSION) {
147
+ throw new Error(`unsupported state version ${JSON.stringify(state.version)}`);
148
+ }
149
+ if (!Array.isArray(state.records)) {
150
+ throw new Error("`records` is not an array");
151
+ }
152
+ for (const record of state.records) {
153
+ if (record === null || typeof record !== "object") {
154
+ throw new Error("a record entry is not an object");
155
+ }
156
+ const candidate = record;
157
+ if (typeof candidate.taskId !== "string" || typeof candidate.status !== "string") {
158
+ throw new Error("a record entry is missing `taskId`/`status`");
159
+ }
160
+ }
161
+ return { version: STATE_FORMAT_VERSION, records: state.records };
162
+ }
163
+ function cloneRecord(record) {
164
+ return structuredClone(record);
165
+ }
166
+ function errorMessage(err) {
167
+ return err instanceof Error ? err.message : String(err);
168
+ }
169
+
5
170
  // src/mcp/task-queue.ts
6
- var DelegationTaskQueue = class {
171
+ var DelegationTaskQueue = class _DelegationTaskQueue {
7
172
  records = /* @__PURE__ */ new Map();
8
173
  controllers = /* @__PURE__ */ new Map();
9
174
  byIdempotencyKey = /* @__PURE__ */ new Map();
10
175
  generateId;
11
176
  now;
177
+ store;
178
+ resumeDelegate;
179
+ maxTerminalRecords;
180
+ onPersistError;
181
+ persistTail = Promise.resolve();
182
+ persistFailure;
12
183
  constructor(options = {}) {
13
184
  this.generateId = options.generateId ?? randomTaskId;
14
185
  this.now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
186
+ this.store = options.store ?? new InMemoryDelegationStore();
187
+ this.resumeDelegate = options.resumeDelegate;
188
+ if (options.maxTerminalRecords !== void 0) {
189
+ if (!Number.isInteger(options.maxTerminalRecords) || options.maxTerminalRecords < 1) {
190
+ throw new ValidationError(
191
+ `DelegationTaskQueue: maxTerminalRecords must be a positive integer, got ${String(options.maxTerminalRecords)}`
192
+ );
193
+ }
194
+ }
195
+ this.maxTerminalRecords = options.maxTerminalRecords ?? Number.POSITIVE_INFINITY;
196
+ this.onPersistError = options.onPersistError ?? ((error) => {
197
+ queueMicrotask(() => {
198
+ throw error;
199
+ });
200
+ });
201
+ }
202
+ /**
203
+ * Construct a queue from previously-persisted state. Loads every record
204
+ * from `options.store`, rebuilds the idempotency index (so a re-submitted
205
+ * identical task returns the prior taskId and its terminal state), then:
206
+ *
207
+ * - terminal records stay queryable via `status()` / `history()`
208
+ * - in-flight records with a `detachedSessionRef` re-attach through
209
+ * `options.resumeDelegate` and report `running`
210
+ * - other in-flight records settle as failed — their driver died with
211
+ * the previous process and the result is unrecoverable
212
+ *
213
+ * The retention cap applies to the loaded set as well.
214
+ */
215
+ static async restore(options = {}) {
216
+ const queue = new _DelegationTaskQueue(options);
217
+ const loaded = await queue.store.loadAll();
218
+ queue.rehydrate(loaded);
219
+ return queue;
15
220
  }
16
221
  /**
17
222
  * Kick off a delegation in the background. Returns immediately. The
18
- * `taskId` is queryable via `status` once this method returns.
223
+ * `taskId` is queryable via `status` once this method returns. Throws
224
+ * the recorded `DelegationPersistenceError` once the store has failed —
225
+ * the queue does not accept work it cannot journal.
19
226
  */
20
227
  submit(input) {
228
+ if (this.persistFailure) throw this.persistFailure;
21
229
  if (input.idempotencyKey) {
22
230
  const existing = this.byIdempotencyKey.get(input.idempotencyKey);
23
231
  if (existing && this.records.has(existing)) {
@@ -34,11 +242,13 @@ var DelegationTaskQueue = class {
34
242
  status: "pending",
35
243
  startedAt: this.now(),
36
244
  feedback: [],
37
- idempotencyKey: input.idempotencyKey
245
+ idempotencyKey: input.idempotencyKey,
246
+ detachedSessionRef: input.detachedSessionRef
38
247
  };
39
248
  this.records.set(taskId, record);
40
249
  this.controllers.set(taskId, controller);
41
250
  if (input.idempotencyKey) this.byIdempotencyKey.set(input.idempotencyKey, taskId);
251
+ this.persist(record);
42
252
  queueMicrotask(() => {
43
253
  this.execute(taskId, input, controller);
44
254
  });
@@ -69,6 +279,8 @@ var DelegationTaskQueue = class {
69
279
  record.status = "cancelled";
70
280
  record.completedAt = this.now();
71
281
  record.error = { message: "cancelled by caller", kind: "CancelledError" };
282
+ this.persist(record);
283
+ this.enforceRetention();
72
284
  return true;
73
285
  }
74
286
  /**
@@ -81,6 +293,7 @@ var DelegationTaskQueue = class {
81
293
  const record = this.records.get(taskId);
82
294
  if (!record) return false;
83
295
  record.feedback.push(snapshot);
296
+ this.persist(record);
84
297
  return true;
85
298
  }
86
299
  /**
@@ -100,6 +313,15 @@ var DelegationTaskQueue = class {
100
313
  out.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
101
314
  return out.slice(0, limit);
102
315
  }
316
+ /**
317
+ * Await every journal write issued so far. Rejects with the recorded
318
+ * `DelegationPersistenceError` when any of them failed. Call before
319
+ * handing the store's backing file to another process.
320
+ */
321
+ async flush() {
322
+ await this.persistTail;
323
+ if (this.persistFailure) throw this.persistFailure;
324
+ }
103
325
  /** Test-only — number of in-flight (non-terminal) records. */
104
326
  inflightCount() {
105
327
  let n = 0;
@@ -112,26 +334,173 @@ var DelegationTaskQueue = class {
112
334
  const record = this.records.get(taskId);
113
335
  if (!record) return;
114
336
  record.status = "running";
337
+ this.persist(record);
115
338
  try {
116
339
  const output = await input.run({
117
340
  signal: controller.signal,
118
341
  report: (progress) => {
119
- if (record.status === "running") record.progress = progress;
342
+ if (record.status === "running") {
343
+ record.progress = progress;
344
+ this.persist(record);
345
+ }
346
+ },
347
+ ...record.detachedSessionRef !== void 0 ? { detachedSessionRef: record.detachedSessionRef } : {},
348
+ updateDetachedSessionRef: (ref) => {
349
+ if (typeof ref !== "string" || ref.length === 0) {
350
+ throw new ValidationError(
351
+ "DelegationTaskQueue: updateDetachedSessionRef requires a non-empty ref"
352
+ );
353
+ }
354
+ if (isTerminal(currentStatus(record))) return;
355
+ record.detachedSessionRef = ref;
356
+ this.persist(record);
120
357
  }
121
358
  });
122
359
  if (currentStatus(record) === "cancelled") return;
123
360
  record.status = "completed";
124
361
  record.completedAt = this.now();
125
362
  record.result = { profile: input.profile, output };
363
+ this.persist(record);
364
+ this.enforceRetention();
126
365
  } catch (err) {
127
366
  if (currentStatus(record) === "cancelled") return;
128
367
  record.status = "failed";
129
368
  record.completedAt = this.now();
130
369
  record.error = errorToShape(err);
370
+ this.persist(record);
371
+ this.enforceRetention();
131
372
  } finally {
132
373
  this.controllers.delete(taskId);
133
374
  }
134
375
  }
376
+ rehydrate(loaded) {
377
+ const records = [...loaded].sort((a, b) => a.startedAt.localeCompare(b.startedAt));
378
+ for (const record of records) {
379
+ this.records.set(record.taskId, record);
380
+ if (record.idempotencyKey) this.byIdempotencyKey.set(record.idempotencyKey, record.taskId);
381
+ }
382
+ for (const record of this.records.values()) {
383
+ if (isTerminal(record.status)) continue;
384
+ if (record.detachedSessionRef && this.resumeDelegate) {
385
+ record.status = "running";
386
+ this.persist(record);
387
+ this.startResume(record, record.detachedSessionRef, this.resumeDelegate);
388
+ continue;
389
+ }
390
+ record.status = "failed";
391
+ record.completedAt = this.now();
392
+ record.error = {
393
+ message: record.detachedSessionRef ? `delegation driver restarted while the task was in flight; detached session "${record.detachedSessionRef}" needs a resumeDelegate to be resumed` : "delegation driver restarted while the task was in flight; the run was not detached and cannot be resumed",
394
+ kind: "DriverRestartError"
395
+ };
396
+ this.persist(record);
397
+ }
398
+ this.enforceRetention();
399
+ }
400
+ startResume(record, detachedSessionRef, driver) {
401
+ const controller = new AbortController();
402
+ this.controllers.set(record.taskId, controller);
403
+ void this.driveResume(record, detachedSessionRef, driver, controller);
404
+ }
405
+ async driveResume(record, detachedSessionRef, driver, controller) {
406
+ const intervalMs = driver.intervalMs ?? 5e3;
407
+ const ctx = {
408
+ signal: controller.signal,
409
+ report: (progress) => {
410
+ if (currentStatus(record) !== "running") return;
411
+ record.progress = progress;
412
+ this.persist(record);
413
+ }
414
+ };
415
+ try {
416
+ while (!controller.signal.aborted && currentStatus(record) === "running") {
417
+ const tick = await driver.tick({ record: structuredClone(record), detachedSessionRef }, ctx);
418
+ if (currentStatus(record) === "cancelled") return;
419
+ if (tick.state === "completed") {
420
+ record.status = "completed";
421
+ record.completedAt = this.now();
422
+ record.result = {
423
+ profile: record.profile,
424
+ output: tick.output
425
+ };
426
+ if (tick.costUsd !== void 0) record.costUsd = tick.costUsd;
427
+ this.persist(record);
428
+ this.enforceRetention();
429
+ return;
430
+ }
431
+ if (tick.state === "failed") {
432
+ record.status = "failed";
433
+ record.completedAt = this.now();
434
+ record.error = tick.error;
435
+ this.persist(record);
436
+ this.enforceRetention();
437
+ return;
438
+ }
439
+ await abortableDelay(intervalMs, controller.signal);
440
+ }
441
+ } catch (err) {
442
+ if (currentStatus(record) === "cancelled") return;
443
+ record.status = "failed";
444
+ record.completedAt = this.now();
445
+ record.error = errorToShape(err);
446
+ this.persist(record);
447
+ this.enforceRetention();
448
+ } finally {
449
+ this.controllers.delete(record.taskId);
450
+ }
451
+ }
452
+ persist(record) {
453
+ if (this.persistFailure) return;
454
+ const snapshot = structuredClone(record);
455
+ this.persistTail = this.persistTail.then(async () => {
456
+ if (this.persistFailure) return;
457
+ try {
458
+ await this.store.upsert(snapshot);
459
+ } catch (err) {
460
+ this.failPersistence(err);
461
+ }
462
+ });
463
+ }
464
+ persistRemoval(taskIds) {
465
+ if (this.persistFailure || taskIds.length === 0) return;
466
+ this.persistTail = this.persistTail.then(async () => {
467
+ if (this.persistFailure) return;
468
+ try {
469
+ await this.store.remove(taskIds);
470
+ } catch (err) {
471
+ this.failPersistence(err);
472
+ }
473
+ });
474
+ }
475
+ failPersistence(cause) {
476
+ if (this.persistFailure) return;
477
+ const error = cause instanceof DelegationPersistenceError ? cause : new DelegationPersistenceError(
478
+ `DelegationTaskQueue: store write failed: ${cause instanceof Error ? cause.message : String(cause)}`,
479
+ { cause }
480
+ );
481
+ this.persistFailure = error;
482
+ this.onPersistError(error);
483
+ }
484
+ enforceRetention() {
485
+ if (!Number.isFinite(this.maxTerminalRecords)) return;
486
+ const terminal = [];
487
+ for (const record of this.records.values()) {
488
+ if (isTerminal(record.status)) terminal.push(record);
489
+ }
490
+ const excess = terminal.length - this.maxTerminalRecords;
491
+ if (excess <= 0) return;
492
+ terminal.sort(
493
+ (a, b) => (a.completedAt ?? a.startedAt).localeCompare(b.completedAt ?? b.startedAt)
494
+ );
495
+ const evicted = terminal.slice(0, excess);
496
+ for (const record of evicted) {
497
+ this.records.delete(record.taskId);
498
+ if (record.idempotencyKey && this.byIdempotencyKey.get(record.idempotencyKey) === record.taskId) {
499
+ this.byIdempotencyKey.delete(record.idempotencyKey);
500
+ }
501
+ }
502
+ this.persistRemoval(evicted.map((record) => record.taskId));
503
+ }
135
504
  };
136
505
  function isTerminal(status) {
137
506
  return status === "completed" || status === "failed" || status === "cancelled";
@@ -145,6 +514,23 @@ function clampLimit(raw) {
145
514
  if (n <= 0) return 50;
146
515
  return Math.min(n, 500);
147
516
  }
517
+ function abortableDelay(ms, signal) {
518
+ return new Promise((resolve) => {
519
+ if (signal.aborted) {
520
+ resolve();
521
+ return;
522
+ }
523
+ const onAbort = () => {
524
+ clearTimeout(timer);
525
+ resolve();
526
+ };
527
+ const timer = setTimeout(() => {
528
+ signal.removeEventListener("abort", onAbort);
529
+ resolve();
530
+ }, ms);
531
+ signal.addEventListener("abort", onAbort, { once: true });
532
+ });
533
+ }
148
534
  function toStatusResult(record) {
149
535
  const out = {
150
536
  taskId: record.taskId,
@@ -351,11 +737,17 @@ function createDelegateCodeHandler(options) {
351
737
  config: args.config,
352
738
  namespace: args.namespace
353
739
  });
740
+ const detached = options.detachedDispatch === true && (args.variants ?? 1) <= 1;
354
741
  const submitted = options.queue.submit({
355
742
  profile: "coder",
356
743
  args,
357
744
  namespace: args.namespace,
358
745
  idempotencyKey,
746
+ ...detached ? {
747
+ detachedSessionRef: formatDetachedSessionRef({
748
+ sessionId: `dlg-turn-coder-${idempotencyKey}`
749
+ })
750
+ } : {},
359
751
  run: async (ctx) => options.delegate(args, ctx)
360
752
  });
361
753
  return {
@@ -702,11 +1094,17 @@ function createDelegateResearchHandler(options) {
702
1094
  variants: args.variants ?? 1,
703
1095
  config: args.config
704
1096
  });
1097
+ const detached = options.detachedDispatch === true && (args.variants ?? 1) <= 1;
705
1098
  const submitted = options.queue.submit({
706
1099
  profile: "researcher",
707
1100
  args,
708
1101
  namespace: args.namespace,
709
1102
  idempotencyKey,
1103
+ ...detached ? {
1104
+ detachedSessionRef: formatDetachedSessionRef({
1105
+ sessionId: `dlg-turn-research-${idempotencyKey}`
1106
+ })
1107
+ } : {},
710
1108
  run: async (ctx) => options.delegate(args, ctx)
711
1109
  });
712
1110
  return {
@@ -1170,6 +1568,10 @@ async function exportEvalRuns(events, config) {
1170
1568
  }
1171
1569
 
1172
1570
  export {
1571
+ DelegationStateCorruptError,
1572
+ DelegationPersistenceError,
1573
+ InMemoryDelegationStore,
1574
+ FileDelegationStore,
1173
1575
  DelegationTaskQueue,
1174
1576
  hashIdempotencyInput,
1175
1577
  DELEGATE_CODE_TOOL_NAME,
@@ -1205,4 +1607,4 @@ export {
1205
1607
  INTELLIGENCE_WIRE_VERSION,
1206
1608
  exportEvalRuns
1207
1609
  };
1208
- //# sourceMappingURL=chunk-JNPK46YH.js.map
1610
+ //# sourceMappingURL=chunk-VIEDXELL.js.map