@librechat/agents 3.4.0 → 3.4.2

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 (204) hide show
  1. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  2. package/dist/cjs/graphs/Graph.cjs +165 -57
  3. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  4. package/dist/cjs/graphs/MultiAgentGraph.cjs +81 -33
  5. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  6. package/dist/cjs/graphs/applyGraphRuntimeConfig.cjs +14 -0
  7. package/dist/cjs/graphs/applyGraphRuntimeConfig.cjs.map +1 -0
  8. package/dist/cjs/graphs/createGraph.cjs +15 -0
  9. package/dist/cjs/graphs/createGraph.cjs.map +1 -0
  10. package/dist/cjs/graphs/index.cjs +1 -0
  11. package/dist/cjs/hooks/HookRegistry.cjs +83 -0
  12. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  13. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +1 -1
  14. package/dist/cjs/hooks/executeHooks.cjs +60 -14
  15. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  16. package/dist/cjs/hooks/index.cjs.map +1 -1
  17. package/dist/cjs/hooks/types.cjs +2 -0
  18. package/dist/cjs/hooks/types.cjs.map +1 -1
  19. package/dist/cjs/llm/init.cjs +3 -3
  20. package/dist/cjs/llm/invoke.cjs +2 -2
  21. package/dist/cjs/main.cjs +34 -24
  22. package/dist/cjs/messages/format.cjs +40 -23
  23. package/dist/cjs/messages/format.cjs.map +1 -1
  24. package/dist/cjs/run.cjs +130 -53
  25. package/dist/cjs/run.cjs.map +1 -1
  26. package/dist/cjs/session/AgentSession.cjs +37 -2
  27. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  28. package/dist/cjs/session/JsonlSessionStore.cjs +2 -2
  29. package/dist/cjs/stream.cjs +1 -1
  30. package/dist/cjs/summarization/node.cjs +6 -3
  31. package/dist/cjs/summarization/node.cjs.map +1 -1
  32. package/dist/cjs/tools/BashExecutor.cjs +1 -1
  33. package/dist/cjs/tools/CodeExecutor.cjs +1 -1
  34. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +1 -1
  35. package/dist/cjs/tools/SubagentTool.cjs +4 -4
  36. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  37. package/dist/cjs/tools/ToolNode.cjs +321 -95
  38. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  39. package/dist/cjs/tools/ToolSearch.cjs +1 -1
  40. package/dist/cjs/tools/eagerEventExecution.cjs +1 -0
  41. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +3 -3
  42. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +2 -2
  43. package/dist/cjs/tools/search/rerankers.cjs +154 -1
  44. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  45. package/dist/cjs/tools/search/tool.cjs +4 -1
  46. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  47. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs +601 -0
  48. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -0
  49. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1114 -233
  50. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  51. package/dist/cjs/tools/subagent/SubagentReplay.cjs +177 -0
  52. package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -0
  53. package/dist/cjs/tools/subagent/childGraphConfig.cjs +278 -0
  54. package/dist/cjs/tools/subagent/childGraphConfig.cjs.map +1 -0
  55. package/dist/cjs/tools/subagent/index.cjs +1 -0
  56. package/dist/cjs/tools/subagent/runtimeLimits.cjs +5 -0
  57. package/dist/cjs/tools/subagent/runtimeLimits.cjs.map +1 -0
  58. package/dist/cjs/tools/toolOutputReferences.cjs +20 -0
  59. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  60. package/dist/cjs/utils/index.cjs +2 -2
  61. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  62. package/dist/esm/graphs/Graph.mjs +165 -57
  63. package/dist/esm/graphs/Graph.mjs.map +1 -1
  64. package/dist/esm/graphs/MultiAgentGraph.mjs +81 -33
  65. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  66. package/dist/esm/graphs/applyGraphRuntimeConfig.mjs +14 -0
  67. package/dist/esm/graphs/applyGraphRuntimeConfig.mjs.map +1 -0
  68. package/dist/esm/graphs/createGraph.mjs +15 -0
  69. package/dist/esm/graphs/createGraph.mjs.map +1 -0
  70. package/dist/esm/graphs/index.mjs +1 -0
  71. package/dist/esm/hooks/HookRegistry.mjs +83 -0
  72. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  73. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +1 -1
  74. package/dist/esm/hooks/executeHooks.mjs +60 -14
  75. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  76. package/dist/esm/hooks/index.mjs.map +1 -1
  77. package/dist/esm/hooks/types.mjs +2 -1
  78. package/dist/esm/hooks/types.mjs.map +1 -1
  79. package/dist/esm/llm/init.mjs +1 -1
  80. package/dist/esm/llm/invoke.mjs +2 -2
  81. package/dist/esm/main.mjs +21 -19
  82. package/dist/esm/messages/format.mjs +40 -23
  83. package/dist/esm/messages/format.mjs.map +1 -1
  84. package/dist/esm/run.mjs +131 -54
  85. package/dist/esm/run.mjs.map +1 -1
  86. package/dist/esm/session/AgentSession.mjs +37 -2
  87. package/dist/esm/session/AgentSession.mjs.map +1 -1
  88. package/dist/esm/session/JsonlSessionStore.mjs +2 -2
  89. package/dist/esm/stream.mjs +1 -1
  90. package/dist/esm/summarization/node.mjs +6 -3
  91. package/dist/esm/summarization/node.mjs.map +1 -1
  92. package/dist/esm/tools/BashExecutor.mjs +1 -1
  93. package/dist/esm/tools/CodeExecutor.mjs +1 -1
  94. package/dist/esm/tools/ProgrammaticToolCalling.mjs +1 -1
  95. package/dist/esm/tools/SubagentTool.mjs +4 -4
  96. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  97. package/dist/esm/tools/ToolNode.mjs +322 -96
  98. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  99. package/dist/esm/tools/ToolSearch.mjs +1 -1
  100. package/dist/esm/tools/eagerEventExecution.mjs +1 -1
  101. package/dist/esm/tools/local/LocalExecutionEngine.mjs +3 -3
  102. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +2 -2
  103. package/dist/esm/tools/search/rerankers.mjs +154 -1
  104. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  105. package/dist/esm/tools/search/tool.mjs +4 -1
  106. package/dist/esm/tools/search/tool.mjs.map +1 -1
  107. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs +597 -0
  108. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -0
  109. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1114 -233
  110. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  111. package/dist/esm/tools/subagent/SubagentReplay.mjs +170 -0
  112. package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -0
  113. package/dist/esm/tools/subagent/childGraphConfig.mjs +272 -0
  114. package/dist/esm/tools/subagent/childGraphConfig.mjs.map +1 -0
  115. package/dist/esm/tools/subagent/index.mjs +1 -0
  116. package/dist/esm/tools/subagent/runtimeLimits.mjs +5 -0
  117. package/dist/esm/tools/subagent/runtimeLimits.mjs.map +1 -0
  118. package/dist/esm/tools/toolOutputReferences.mjs +20 -0
  119. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  120. package/dist/esm/utils/index.mjs +2 -2
  121. package/dist/types/agents/AgentContext.d.ts +1 -1
  122. package/dist/types/graphs/Graph.d.ts +22 -2
  123. package/dist/types/graphs/MultiAgentGraph.d.ts +7 -1
  124. package/dist/types/graphs/applyGraphRuntimeConfig.d.ts +3 -0
  125. package/dist/types/graphs/createGraph.d.ts +13 -0
  126. package/dist/types/graphs/graphFactory.d.ts +13 -0
  127. package/dist/types/graphs/index.d.ts +2 -0
  128. package/dist/types/hooks/HookRegistry.d.ts +10 -1
  129. package/dist/types/hooks/executeHooks.d.ts +5 -1
  130. package/dist/types/hooks/index.d.ts +2 -2
  131. package/dist/types/hooks/types.d.ts +12 -0
  132. package/dist/types/run.d.ts +6 -3
  133. package/dist/types/session/AgentSession.d.ts +1 -0
  134. package/dist/types/tools/SubagentTool.d.ts +1 -1
  135. package/dist/types/tools/ToolNode.d.ts +23 -15
  136. package/dist/types/tools/search/rerankers.d.ts +28 -0
  137. package/dist/types/tools/search/types.d.ts +38 -1
  138. package/dist/types/tools/subagent/SubagentExecutionRegistry.d.ts +171 -0
  139. package/dist/types/tools/subagent/SubagentExecutor.d.ts +70 -36
  140. package/dist/types/tools/subagent/SubagentReplay.d.ts +85 -0
  141. package/dist/types/tools/subagent/childGraphConfig.d.ts +37 -0
  142. package/dist/types/tools/subagent/index.d.ts +1 -1
  143. package/dist/types/tools/subagent/runtimeLimits.d.ts +4 -0
  144. package/dist/types/tools/toolOutputReferences.d.ts +12 -0
  145. package/dist/types/types/graph.d.ts +189 -24
  146. package/dist/types/types/hitl.d.ts +15 -0
  147. package/package.json +8 -2
  148. package/src/agents/AgentContext.ts +1 -1
  149. package/src/graphs/Graph.ts +349 -104
  150. package/src/graphs/MultiAgentGraph.ts +149 -47
  151. package/src/graphs/__tests__/Graph.breakerLifecycle.test.ts +48 -9
  152. package/src/graphs/__tests__/Graph.contextOverflow.test.ts +1 -1
  153. package/src/graphs/__tests__/Graph.subagentResumeState.test.ts +80 -0
  154. package/src/graphs/__tests__/MultiAgentGraph.test.ts +86 -0
  155. package/src/graphs/__tests__/composition.smoke.test.ts +152 -0
  156. package/src/graphs/__tests__/createGraph.test.ts +206 -0
  157. package/src/graphs/applyGraphRuntimeConfig.ts +25 -0
  158. package/src/graphs/createGraph.ts +32 -0
  159. package/src/graphs/graphFactory.ts +12 -0
  160. package/src/graphs/index.ts +2 -0
  161. package/src/hooks/HookRegistry.ts +151 -1
  162. package/src/hooks/__tests__/HookRegistry.test.ts +96 -0
  163. package/src/hooks/__tests__/executeHooks.test.ts +160 -0
  164. package/src/hooks/executeHooks.ts +133 -15
  165. package/src/hooks/index.ts +3 -1
  166. package/src/hooks/types.ts +16 -0
  167. package/src/messages/format.ts +54 -26
  168. package/src/messages/formatAgentMessages.reducer.test.ts +162 -0
  169. package/src/messages/formatAgentMessages.steer.test.ts +16 -11
  170. package/src/messages/formatAgentMessages.test.ts +7 -2
  171. package/src/run.ts +214 -56
  172. package/src/session/AgentSession.ts +52 -2
  173. package/src/session/__tests__/JsonlSessionStore.test.ts +53 -0
  174. package/src/specs/graph-subagent.live.test.ts +242 -0
  175. package/src/specs/graph-subagent.test.ts +322 -0
  176. package/src/specs/langfuse-routing.integration.test.ts +120 -1
  177. package/src/specs/subagent.test.ts +130 -4
  178. package/src/summarization/__tests__/node.test.ts +32 -14
  179. package/src/summarization/node.ts +15 -11
  180. package/src/tools/SubagentTool.ts +4 -4
  181. package/src/tools/ToolNode.ts +643 -157
  182. package/src/tools/__tests__/SubagentExecutor.test.ts +740 -15
  183. package/src/tools/__tests__/SubagentReplay.test.ts +329 -0
  184. package/src/tools/__tests__/ToolNode.breakerSignal.test.ts +208 -2
  185. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +512 -2
  186. package/src/tools/__tests__/hitl.test.ts +234 -5
  187. package/src/tools/__tests__/subagentHooks.test.ts +1126 -61
  188. package/src/tools/__tests__/toolOutputReferences.test.ts +19 -2
  189. package/src/tools/search/rag-api-reranker.test.ts +891 -0
  190. package/src/tools/search/rerankers.ts +260 -0
  191. package/src/tools/search/tool.ts +6 -0
  192. package/src/tools/search/types.ts +45 -1
  193. package/src/tools/subagent/SubagentExecutionRegistry.ts +1159 -0
  194. package/src/tools/subagent/SubagentExecutor.ts +2232 -312
  195. package/src/tools/subagent/SubagentReplay.ts +584 -0
  196. package/src/tools/subagent/__tests__/SubagentExecutionRegistry.test.ts +637 -0
  197. package/src/tools/subagent/__tests__/SubagentExecutor.lazy.test.ts +3054 -0
  198. package/src/tools/subagent/__tests__/childGraphConfig.test.ts +521 -0
  199. package/src/tools/subagent/childGraphConfig.ts +694 -0
  200. package/src/tools/subagent/index.ts +6 -0
  201. package/src/tools/subagent/runtimeLimits.ts +7 -0
  202. package/src/tools/toolOutputReferences.ts +40 -1
  203. package/src/types/graph.ts +222 -24
  204. package/src/types/hitl.ts +16 -0
@@ -41,7 +41,11 @@ function parseStringifiedArgsObject(
41
41
  }
42
42
  try {
43
43
  const parsed = JSON.parse(value) as unknown;
44
- if (parsed != null && typeof parsed === 'object' && !Array.isArray(parsed)) {
44
+ if (
45
+ parsed != null &&
46
+ typeof parsed === 'object' &&
47
+ !Array.isArray(parsed)
48
+ ) {
45
49
  return parsed as Record<string, unknown>;
46
50
  }
47
51
  } catch {
@@ -91,6 +95,12 @@ export type ToolOutputReferenceRegistryOptions = {
91
95
  maxActiveRuns?: number;
92
96
  };
93
97
 
98
+ export interface ToolOutputReferenceState {
99
+ entries: Array<{ key: string; value: string }>;
100
+ turnCounter: number;
101
+ warnedNonStringTools: string[];
102
+ }
103
+
94
104
  /**
95
105
  * Result of resolving placeholders in tool args.
96
106
  */
@@ -397,6 +407,35 @@ export class ToolOutputReferenceRegistry {
397
407
  };
398
408
  }
399
409
 
410
+ /** Captures the checkpoint-safe state needed to resume one run bucket. */
411
+ snapshotState(runId: string | undefined): ToolOutputReferenceState {
412
+ const bucket = this.runStates.get(this.keyFor(runId));
413
+ return {
414
+ entries: [...(bucket?.entries ?? EMPTY_ENTRIES)].map(([key, value]) => ({
415
+ key,
416
+ value,
417
+ })),
418
+ turnCounter: bucket?.turnCounter ?? 0,
419
+ warnedNonStringTools: [...(bucket?.warnedNonStringTools ?? [])],
420
+ };
421
+ }
422
+
423
+ /** Restores a checkpointed run bucket under the current resume scope. */
424
+ restoreState(
425
+ runId: string | undefined,
426
+ state: ToolOutputReferenceState
427
+ ): void {
428
+ this.releaseRun(runId);
429
+ const bucket = this.getOrCreate(runId);
430
+ for (const { key, value } of state.entries) {
431
+ this.set(runId, key, value);
432
+ }
433
+ bucket.turnCounter = state.turnCounter;
434
+ for (const toolName of state.warnedNonStringTools) {
435
+ bucket.warnedNonStringTools.add(toolName);
436
+ }
437
+ }
438
+
400
439
  private resolveAgainst<T>(
401
440
  entries: ReadonlyMap<string, string>,
402
441
  args: T,
@@ -80,8 +80,14 @@ export type AgentSubgraphState = BaseGraphState & {
80
80
  summarizationRequest?: SummarizationNodeInput;
81
81
  };
82
82
 
83
+ export type SubagentGraphResult = {
84
+ agentId: string;
85
+ message?: BaseMessage;
86
+ };
87
+
83
88
  export type MultiAgentGraphState = BaseGraphState & {
84
89
  agentMessages?: BaseMessage[];
90
+ subagentResult?: SubagentGraphResult;
85
91
  };
86
92
 
87
93
  export type IState = BaseGraphState;
@@ -331,9 +337,9 @@ export type StandardGraphInput = {
331
337
  indexTokenCountMap?: Record<string, number>;
332
338
  calibrationRatio?: number;
333
339
  /**
334
- * Receives a {@link SubagentUsageEvent} for every model call made inside
335
- * a subagent child run spawned from this graph (including nested
336
- * subagents and child-side summarization calls). Child graphs run via
340
+ * Receives a {@link SubagentUsageEvent} for every model call that reports
341
+ * usage metadata inside a subagent child run spawned from this graph
342
+ * (including nested subagents and child-side summarization calls). Child graphs run via
337
343
  * `invoke()` outside the host's `streamEvents` loop, so their
338
344
  * `on_chat_model_end` events never reach the run's handler registry —
339
345
  * this sink is the only way hosts can observe child token usage for
@@ -364,10 +370,12 @@ export type StandardGraphInput = {
364
370
  * every streamed chunk event. See {@link StreamLimits}.
365
371
  */
366
372
  streamLimits?: StreamLimits;
373
+ /** Structured lineage for a graph executing as a subagent child. */
374
+ subagentExecutionContext?: SubagentExecutionContext;
367
375
  };
368
376
 
369
377
  export type GraphEdge = {
370
- /** Agent ID, use a list for multiple sources */
378
+ /** Agent ID; direct edges use an array as an all-of waiting source group. */
371
379
  from: string | string[];
372
380
  /** Agent ID, use a list for multiple destinations */
373
381
  to: string | string[];
@@ -403,32 +411,184 @@ export type GraphEdge = {
403
411
  promptKey?: string;
404
412
  };
405
413
 
414
+ export type GraphSubagentEdge = Omit<
415
+ GraphEdge,
416
+ 'edgeType' | 'condition' | 'promptKey'
417
+ > & {
418
+ edgeType: 'direct';
419
+ condition?: never;
420
+ promptKey?: never;
421
+ };
422
+
406
423
  export type MultiAgentGraphInput = StandardGraphInput & {
407
424
  edges: GraphEdge[];
425
+ /** Captures the designated member's final AI turn in graph state. */
426
+ resultAgentId?: string;
427
+ /** Optional per-member Pregel budget when the outer graph has its own topology budget. */
428
+ memberRecursionLimit?: number;
408
429
  };
409
430
 
410
- /** Configuration for a subagent type that can be spawned by a parent agent. */
411
- export type SubagentConfig = {
412
- /** Identifier used in the tool's `subagent_type` enum (e.g. 'researcher', 'coder'). */
431
+ /** Lightweight identity advertised to the model for a spawnable subagent. */
432
+ export interface SubagentDescriptor {
433
+ /** Stable identifier used in the tool's `subagent_type` enum (e.g. 'researcher', 'coder'). */
413
434
  type: string;
414
435
  /** Human-readable display name. */
415
436
  name: string;
416
437
  /** What this subagent specializes in — shown to the LLM. */
417
438
  description: string;
418
- /** Full agent config for the child graph. Omit when `self` is true. */
419
- agentInputs?: AgentInputs;
420
- /** When true, reuse the parent's AgentInputs (context isolation without separate config). */
421
- self?: boolean;
439
+ /**
440
+ * Opaque, versioned identity of the child configuration. Required when
441
+ * `resolveAgentInputs` is used and changed whenever its resolved inputs
442
+ * change incompatibly.
443
+ */
444
+ configId?: string;
445
+ }
446
+
447
+ /** Lazy descriptor with the durable configuration identity required to resolve it. */
448
+ export interface LazySubagentDescriptor extends SubagentDescriptor {
449
+ configId: string;
450
+ }
451
+
452
+ /** Stable request identifiers exposed to a selected subagent resolver. */
453
+ export interface SubagentResolveRequestContext {
454
+ conversationId?: string;
455
+ messageId?: string;
456
+ parentMessageId?: string;
457
+ }
458
+
459
+ /** Stable user identifiers exposed to a selected subagent resolver. */
460
+ export interface SubagentResolveUserContext {
461
+ id?: string;
462
+ role?: string;
463
+ tenantId?: string;
464
+ }
465
+
466
+ /** Sanitized host runtime context safe for lazy subagent resolution. */
467
+ export interface SubagentResolveConfigurable {
468
+ requestBody?: Readonly<SubagentResolveRequestContext>;
469
+ user?: Readonly<SubagentResolveUserContext>;
470
+ user_id?: string;
471
+ }
472
+
473
+ /** Runtime context supplied when a host lazily resolves a selected subagent. */
474
+ export interface SubagentResolveContext {
475
+ /** Stable subagent identity selected by the model. */
476
+ descriptor: Readonly<LazySubagentDescriptor>;
477
+ /** Stable child execution identity, including across HITL reconstruction. */
478
+ executionId: string;
479
+ /** Parent run that dispatched this execution. */
480
+ parentRunId: string;
481
+ /** Parent agent that dispatched this execution. */
482
+ parentAgentId?: string;
483
+ /** Parent-side tool call that selected the subagent. */
484
+ parentToolCallId?: string;
485
+ /** Durable parent conversation thread, when supplied by the host. */
486
+ threadId?: string;
487
+ /** Parent/breaker cancellation composed for this child execution. */
488
+ signal: AbortSignal;
489
+ /** Stable, sanitized host context from the parent tool invocation. */
490
+ configurable?: Readonly<SubagentResolveConfigurable>;
491
+ }
492
+
493
+ /** Host contract for resolving a selected subagent's full graph inputs. */
494
+ export type SubagentAgentInputsResolver = (
495
+ context: SubagentResolveContext
496
+ ) => Promise<AgentInputs>;
497
+
498
+ interface SubagentConfigBase extends SubagentDescriptor {
422
499
  /** Max AGENT→TOOLS cycles before forced stop (default: 25). */
423
500
  maxTurns?: number;
424
501
  /** Allow this subagent to spawn its own subagents (default: false). */
425
502
  allowNested?: boolean;
426
- };
503
+ }
427
504
 
428
- /** SubagentConfig with agentInputs guaranteed present (self-spawn resolved). */
429
- export type ResolvedSubagentConfig = SubagentConfig & {
505
+ export interface SubagentConfig extends SubagentConfigBase {
506
+ /** Full agent config for the child graph. Omit when `self` is true. */
507
+ agentInputs?: AgentInputs;
508
+ /**
509
+ * Resolve the full child config only after this descriptor is selected.
510
+ * Eager `agentInputs` take precedence when also supplied. `self` and a
511
+ * resolver are mutually exclusive and normalization rejects that pairing.
512
+ *
513
+ * Resolvers should rebuild inputs from the stable execution context instead
514
+ * of retaining request-owned state. The SDK keeps resolved inputs in memory
515
+ * only for the lifetime of the selected execution and supplies cancellation
516
+ * through `context.signal`. A reconstructed execution may invoke the
517
+ * resolver again, so the same `context.executionId` must produce equivalent
518
+ * child inputs. Durable resolver work should be idempotent on
519
+ * `(context.executionId, context.descriptor.configId)`.
520
+ */
521
+ resolveAgentInputs?: SubagentAgentInputsResolver;
522
+ /** When true, reuse the parent's AgentInputs (context isolation without separate config). */
523
+ self?: boolean;
524
+ }
525
+
526
+ export interface SingleAgentSubagentConfig extends SubagentConfig {
527
+ kind?: 'agent';
528
+ agents?: never;
529
+ edges?: never;
530
+ entryAgentId?: never;
531
+ resultAgentId?: never;
532
+ }
533
+
534
+ export interface GraphSubagentConfig extends SubagentConfigBase {
535
+ kind: 'graph';
536
+ configId?: never;
537
+ resolveAgentInputs?: never;
538
+ allowNested?: false;
539
+ agents: AgentInputs[];
540
+ /**
541
+ * Explicit direct DAG edges. Array-valued sources are all-of waiting edges.
542
+ * Relative message order between parallel branches is implementation-dependent.
543
+ * Prompted edges are supported in chains or on the final converged result transition.
544
+ */
545
+ edges: GraphSubagentEdge[];
546
+ entryAgentId: string;
547
+ resultAgentId: string;
548
+ agentInputs?: never;
549
+ self?: never;
550
+ }
551
+
552
+ /** Any configuration that can be spawned through the subagent tool. */
553
+ export type SubagentConfigEntry = SubagentConfig | GraphSubagentConfig;
554
+
555
+ /** Legacy single-agent config with self-spawn resolution completed. */
556
+ export interface ResolvedSubagentConfig extends SubagentConfig {
430
557
  agentInputs: AgentInputs;
431
- };
558
+ }
559
+
560
+ /** Explicit alias for graph-aware code that needs to name the legacy variant. */
561
+ export interface ResolvedSingleAgentSubagentConfig
562
+ extends ResolvedSubagentConfig {
563
+ kind?: 'agent';
564
+ agents?: never;
565
+ edges?: never;
566
+ entryAgentId?: never;
567
+ resultAgentId?: never;
568
+ }
569
+
570
+ export type ResolvedSubagentConfigEntry =
571
+ | ResolvedSubagentConfig
572
+ | GraphSubagentConfig;
573
+
574
+ /** Lazy single-agent entry accepted after descriptor validation. */
575
+ export interface LazySingleAgentSubagentConfig
576
+ extends SingleAgentSubagentConfig {
577
+ configId: string;
578
+ resolveAgentInputs: SubagentAgentInputsResolver;
579
+ agentInputs?: never;
580
+ self?: never;
581
+ }
582
+
583
+ /** Single-agent config accepted after eager/self/lazy eligibility checks. */
584
+ export type ExecutableSubagentConfig =
585
+ | ResolvedSubagentConfig
586
+ | LazySingleAgentSubagentConfig;
587
+
588
+ /** Graph-aware config accepted by the executor. Graph configs stay eager. */
589
+ export type ExecutableSubagentConfigEntry =
590
+ | ExecutableSubagentConfig
591
+ | GraphSubagentConfig;
432
592
 
433
593
  /** Lifecycle phase carried on {@link SubagentUpdateEvent}. */
434
594
  export type SubagentUpdatePhase =
@@ -441,14 +601,34 @@ export type SubagentUpdatePhase =
441
601
  | 'stop'
442
602
  | 'error';
443
603
 
604
+ export interface SubagentAncestryEntry {
605
+ readonly subagentRunId: string;
606
+ readonly subagentType: string;
607
+ readonly subagentKind: 'agent' | 'graph';
608
+ /** Execution subject ID; synthetic for graph subagents. */
609
+ readonly subagentAgentId: string;
610
+ readonly parentRunId: string;
611
+ readonly parentAgentId?: string;
612
+ readonly parentToolCallId?: string;
613
+ }
614
+
615
+ export interface SubagentExecutionContext {
616
+ readonly rootRunId: string;
617
+ readonly hookSessionId: string;
618
+ readonly depth: number;
619
+ readonly ancestry: readonly SubagentAncestryEntry[];
620
+ }
621
+
444
622
  /**
445
623
  * Wrapper event emitted when a subagent's child graph dispatches activity.
446
624
  * Lets hosts show subagent progress in a UI surface separate from the parent
447
625
  * conversation without having to untangle events by agent ID.
448
626
  */
449
627
  export interface SubagentUpdateEvent {
450
- /** Parent run ID. */
628
+ /** Root run ID that owns this execution tree. */
451
629
  runId: string;
630
+ /** Immediate parent run that spawned this child. */
631
+ parentRunId?: string;
452
632
  /** Child run ID (unique per subagent execution). */
453
633
  subagentRunId: string;
454
634
  /**
@@ -460,8 +640,16 @@ export interface SubagentUpdateEvent {
460
640
  parentToolCallId?: string;
461
641
  /** Subagent `type` identifier from the SubagentConfig. */
462
642
  subagentType: string;
463
- /** Child agent ID assigned to this subagent execution. */
643
+ /** Execution shape. Omitted by older emitters. */
644
+ subagentKind?: 'agent' | 'graph';
645
+ /** Execution subject ID; synthetic for graph subagents. */
464
646
  subagentAgentId: string;
647
+ /** Graph member that produced this update, when attributable. */
648
+ memberAgentId?: string;
649
+ /** One-based nesting depth beneath the root graph. */
650
+ depth?: number;
651
+ /** Root-to-leaf execution lineage, without parsing composed run IDs. */
652
+ ancestry?: readonly SubagentAncestryEntry[];
465
653
  /** Parent agent ID that spawned this subagent. */
466
654
  parentAgentId?: string;
467
655
  /** Lifecycle phase carried by this update. */
@@ -504,10 +692,20 @@ export interface SubagentUsageEvent {
504
692
  provider?: string;
505
693
  /** Subagent `type` identifier from the SubagentConfig. */
506
694
  subagentType: string;
695
+ /** Execution shape. Omitted by older emitters. */
696
+ subagentKind?: 'agent' | 'graph';
507
697
  /** Child run ID (unique per subagent execution). */
508
698
  subagentRunId: string;
509
- /** Child agent ID assigned to this subagent execution. */
699
+ /** Execution subject ID; synthetic for graph subagents. */
510
700
  subagentAgentId: string;
701
+ /** Graph member whose model call produced this usage. */
702
+ memberAgentId?: string;
703
+ /** Immediate parent run that spawned this child. */
704
+ parentRunId?: string;
705
+ /** One-based nesting depth beneath the root graph. */
706
+ depth?: number;
707
+ /** Root-to-leaf execution lineage, without parsing composed run IDs. */
708
+ ancestry?: readonly SubagentAncestryEntry[];
511
709
  /**
512
710
  * ROOT run ID of the host run that owns billing. For nested subagents
513
711
  * each forwarding layer rewrites this upward, so events from any depth
@@ -647,7 +845,7 @@ export interface AgentInputs {
647
845
  /** Pre-computed tool schema token count (from cache). Skips recalculation when provided. */
648
846
  toolSchemaTokens?: number;
649
847
  /** Subagent configurations for hierarchical delegation. Each defines a child agent type. */
650
- subagentConfigs?: SubagentConfig[];
848
+ subagentConfigs?: SubagentConfigEntry[];
651
849
  /** Maximum subagent nesting depth. Default 1 means top-level agents can spawn subagents but subagents cannot nest further. */
652
850
  maxSubagentDepth?: number;
653
851
  /**
@@ -659,11 +857,11 @@ export interface AgentInputs {
659
857
  * raise a LangGraph `interrupt()` (e.g. a tool built on `askUserQuestion()`) —
660
858
  * the host-side event handler runs outside the graph task, where `interrupt()`
661
859
  * throws. Do NOT also list these tools in `toolDefinitions` (they would be bound
662
- * twice). NOT inherited by SELF-SPAWNED subagent children (their config is a
663
- * shallow spread of the parent's inputs, and child graphs compile without a
664
- * checkpointer, so an interrupt-capable tool could never pause there)
665
- * `buildChildInputs` scrubs the inherited copy; an EXPLICIT child config that
666
- * lists its own `graphTools` keeps them.
860
+ * twice). NOT inherited by SELF-SPAWNED subagent children: `buildChildInputs`
861
+ * scrubs the shallow-spread parent copy so parent-scoped direct tools are not
862
+ * exposed to a child implicitly. An EXPLICIT child config that lists its own
863
+ * `graphTools` keeps them; with HITL enabled, those tools share the parent's
864
+ * checkpointer and may pause and resume inside the child graph.
667
865
  *
668
866
  * Deliberately `GenericTool[]`, not `GraphTools`: the wider union admits
669
867
  * schema-only shapes (OpenAI `BindToolsInput`, Google tool objects) that
package/src/types/hitl.ts CHANGED
@@ -101,6 +101,18 @@ export type ToolApprovalDecisionMap = Record<string, ToolApprovalDecision>;
101
101
  */
102
102
  export type HumanInterruptType = 'tool_approval' | 'ask_user_question';
103
103
 
104
+ /** Identifies an interrupt that originated inside a checkpointed subagent. */
105
+ export interface SubagentInterruptScope {
106
+ /** Child execution run id used by subagent update and usage events. */
107
+ run_id: string;
108
+ /** Child agent id that owns the interrupted tool call. */
109
+ agent_id: string;
110
+ /** Configured subagent type selected by the parent tool call. */
111
+ subagent_type: string;
112
+ /** Parent `subagent` tool call that launched this child. */
113
+ parent_tool_call_id?: string;
114
+ }
115
+
104
116
  /**
105
117
  * Structured payload the SDK passes to `interrupt()` when one or more
106
118
  * pending tool calls require host approval. All `ask`-decision tool calls
@@ -114,6 +126,10 @@ export interface ToolApprovalInterruptPayload {
114
126
  type: 'tool_approval';
115
127
  action_requests: ToolApprovalRequest[];
116
128
  review_configs: ToolApprovalReviewConfig[];
129
+ /** Hook-registry session whose policy raised this interrupt. */
130
+ hook_session_id?: string;
131
+ /** Present when the approval request was bridged from a child graph. */
132
+ subagent?: SubagentInterruptScope;
117
133
  }
118
134
 
119
135
  /**