@illuma-ai/agents 1.1.25 → 1.3.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 (272) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +20 -3
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/common/spawnPath.cjs +104 -0
  4. package/dist/cjs/common/spawnPath.cjs.map +1 -0
  5. package/dist/cjs/graphs/Graph.cjs +87 -31
  6. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  7. package/dist/cjs/graphs/HandoffRegistry.cjs +143 -0
  8. package/dist/cjs/graphs/HandoffRegistry.cjs.map +1 -0
  9. package/dist/cjs/graphs/MultiAgentGraph.cjs +587 -184
  10. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  11. package/dist/cjs/graphs/phases/flushLoop.cjs +214 -0
  12. package/dist/cjs/graphs/phases/flushLoop.cjs.map +1 -0
  13. package/dist/cjs/graphs/phases/memoryFlushPhase.cjs +102 -0
  14. package/dist/cjs/graphs/phases/memoryFlushPhase.cjs.map +1 -0
  15. package/dist/cjs/llm/bedrock/index.cjs +4 -3
  16. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  17. package/dist/cjs/main.cjs +115 -0
  18. package/dist/cjs/main.cjs.map +1 -1
  19. package/dist/cjs/memory/citations.cjs +69 -0
  20. package/dist/cjs/memory/citations.cjs.map +1 -0
  21. package/dist/cjs/memory/compositeBackend.cjs +60 -0
  22. package/dist/cjs/memory/compositeBackend.cjs.map +1 -0
  23. package/dist/cjs/memory/constants.cjs +232 -0
  24. package/dist/cjs/memory/constants.cjs.map +1 -0
  25. package/dist/cjs/memory/embeddings.cjs +151 -0
  26. package/dist/cjs/memory/embeddings.cjs.map +1 -0
  27. package/dist/cjs/memory/factory.cjs +95 -0
  28. package/dist/cjs/memory/factory.cjs.map +1 -0
  29. package/dist/cjs/memory/migrate.cjs +81 -0
  30. package/dist/cjs/memory/migrate.cjs.map +1 -0
  31. package/dist/cjs/memory/mmr.cjs +138 -0
  32. package/dist/cjs/memory/mmr.cjs.map +1 -0
  33. package/dist/cjs/memory/paths.cjs +217 -0
  34. package/dist/cjs/memory/paths.cjs.map +1 -0
  35. package/dist/cjs/memory/pgvectorStore.cjs +225 -0
  36. package/dist/cjs/memory/pgvectorStore.cjs.map +1 -0
  37. package/dist/cjs/memory/recallTracking.cjs +98 -0
  38. package/dist/cjs/memory/recallTracking.cjs.map +1 -0
  39. package/dist/cjs/memory/schema.sql +51 -0
  40. package/dist/cjs/memory/temporalDecay.cjs +118 -0
  41. package/dist/cjs/memory/temporalDecay.cjs.map +1 -0
  42. package/dist/cjs/nodes/ApprovalGateNode.cjs +1 -1
  43. package/dist/cjs/nodes/ApprovalGateNode.cjs.map +1 -1
  44. package/dist/cjs/prompts/memoryFlushPrompt.cjs +49 -0
  45. package/dist/cjs/prompts/memoryFlushPrompt.cjs.map +1 -0
  46. package/dist/cjs/run.cjs +16 -3
  47. package/dist/cjs/run.cjs.map +1 -1
  48. package/dist/cjs/stream.cjs +4 -4
  49. package/dist/cjs/stream.cjs.map +1 -1
  50. package/dist/cjs/tools/AskUser.cjs +6 -1
  51. package/dist/cjs/tools/AskUser.cjs.map +1 -1
  52. package/dist/cjs/tools/BrowserTools.cjs +1 -1
  53. package/dist/cjs/tools/BrowserTools.cjs.map +1 -1
  54. package/dist/cjs/tools/ToolNode.cjs +127 -10
  55. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  56. package/dist/cjs/tools/approval/constants.cjs +2 -2
  57. package/dist/cjs/tools/approval/constants.cjs.map +1 -1
  58. package/dist/cjs/tools/memory/index.cjs +58 -0
  59. package/dist/cjs/tools/memory/index.cjs.map +1 -0
  60. package/dist/cjs/tools/memory/memoryAppendTool.cjs +69 -0
  61. package/dist/cjs/tools/memory/memoryAppendTool.cjs.map +1 -0
  62. package/dist/cjs/tools/memory/memoryGetTool.cjs +49 -0
  63. package/dist/cjs/tools/memory/memoryGetTool.cjs.map +1 -0
  64. package/dist/cjs/tools/memory/memorySearchTool.cjs +65 -0
  65. package/dist/cjs/tools/memory/memorySearchTool.cjs.map +1 -0
  66. package/dist/cjs/tools/memory/shared.cjs +106 -0
  67. package/dist/cjs/tools/memory/shared.cjs.map +1 -0
  68. package/dist/cjs/types/graph.cjs.map +1 -1
  69. package/dist/cjs/utils/childAgentContext.cjs +242 -0
  70. package/dist/cjs/utils/childAgentContext.cjs.map +1 -0
  71. package/dist/cjs/utils/events.cjs +36 -4
  72. package/dist/cjs/utils/events.cjs.map +1 -1
  73. package/dist/cjs/utils/finishReasons.cjs +44 -0
  74. package/dist/cjs/utils/finishReasons.cjs.map +1 -0
  75. package/dist/cjs/utils/llm.cjs.map +1 -1
  76. package/dist/cjs/utils/logging.cjs +34 -0
  77. package/dist/cjs/utils/logging.cjs.map +1 -0
  78. package/dist/cjs/utils/toolCallNormalization.cjs +250 -0
  79. package/dist/cjs/utils/toolCallNormalization.cjs.map +1 -0
  80. package/dist/esm/agents/AgentContext.mjs +20 -3
  81. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  82. package/dist/esm/common/spawnPath.mjs +95 -0
  83. package/dist/esm/common/spawnPath.mjs.map +1 -0
  84. package/dist/esm/graphs/Graph.mjs +87 -31
  85. package/dist/esm/graphs/Graph.mjs.map +1 -1
  86. package/dist/esm/graphs/HandoffRegistry.mjs +141 -0
  87. package/dist/esm/graphs/HandoffRegistry.mjs.map +1 -0
  88. package/dist/esm/graphs/MultiAgentGraph.mjs +587 -184
  89. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  90. package/dist/esm/graphs/phases/flushLoop.mjs +209 -0
  91. package/dist/esm/graphs/phases/flushLoop.mjs.map +1 -0
  92. package/dist/esm/graphs/phases/memoryFlushPhase.mjs +99 -0
  93. package/dist/esm/graphs/phases/memoryFlushPhase.mjs.map +1 -0
  94. package/dist/esm/llm/bedrock/index.mjs +4 -3
  95. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  96. package/dist/esm/main.mjs +21 -0
  97. package/dist/esm/main.mjs.map +1 -1
  98. package/dist/esm/memory/citations.mjs +64 -0
  99. package/dist/esm/memory/citations.mjs.map +1 -0
  100. package/dist/esm/memory/compositeBackend.mjs +58 -0
  101. package/dist/esm/memory/compositeBackend.mjs.map +1 -0
  102. package/dist/esm/memory/constants.mjs +198 -0
  103. package/dist/esm/memory/constants.mjs.map +1 -0
  104. package/dist/esm/memory/embeddings.mjs +148 -0
  105. package/dist/esm/memory/embeddings.mjs.map +1 -0
  106. package/dist/esm/memory/factory.mjs +93 -0
  107. package/dist/esm/memory/factory.mjs.map +1 -0
  108. package/dist/esm/memory/migrate.mjs +78 -0
  109. package/dist/esm/memory/migrate.mjs.map +1 -0
  110. package/dist/esm/memory/mmr.mjs +130 -0
  111. package/dist/esm/memory/mmr.mjs.map +1 -0
  112. package/dist/esm/memory/paths.mjs +207 -0
  113. package/dist/esm/memory/paths.mjs.map +1 -0
  114. package/dist/esm/memory/pgvectorStore.mjs +223 -0
  115. package/dist/esm/memory/pgvectorStore.mjs.map +1 -0
  116. package/dist/esm/memory/recallTracking.mjs +94 -0
  117. package/dist/esm/memory/recallTracking.mjs.map +1 -0
  118. package/dist/esm/memory/schema.sql +51 -0
  119. package/dist/esm/memory/temporalDecay.mjs +110 -0
  120. package/dist/esm/memory/temporalDecay.mjs.map +1 -0
  121. package/dist/esm/nodes/ApprovalGateNode.mjs +1 -1
  122. package/dist/esm/nodes/ApprovalGateNode.mjs.map +1 -1
  123. package/dist/esm/prompts/memoryFlushPrompt.mjs +44 -0
  124. package/dist/esm/prompts/memoryFlushPrompt.mjs.map +1 -0
  125. package/dist/esm/run.mjs +16 -3
  126. package/dist/esm/run.mjs.map +1 -1
  127. package/dist/esm/stream.mjs +4 -4
  128. package/dist/esm/stream.mjs.map +1 -1
  129. package/dist/esm/tools/AskUser.mjs +6 -1
  130. package/dist/esm/tools/AskUser.mjs.map +1 -1
  131. package/dist/esm/tools/BrowserTools.mjs +1 -1
  132. package/dist/esm/tools/BrowserTools.mjs.map +1 -1
  133. package/dist/esm/tools/ToolNode.mjs +128 -11
  134. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  135. package/dist/esm/tools/approval/constants.mjs +2 -2
  136. package/dist/esm/tools/approval/constants.mjs.map +1 -1
  137. package/dist/esm/tools/memory/index.mjs +46 -0
  138. package/dist/esm/tools/memory/index.mjs.map +1 -0
  139. package/dist/esm/tools/memory/memoryAppendTool.mjs +67 -0
  140. package/dist/esm/tools/memory/memoryAppendTool.mjs.map +1 -0
  141. package/dist/esm/tools/memory/memoryGetTool.mjs +47 -0
  142. package/dist/esm/tools/memory/memoryGetTool.mjs.map +1 -0
  143. package/dist/esm/tools/memory/memorySearchTool.mjs +63 -0
  144. package/dist/esm/tools/memory/memorySearchTool.mjs.map +1 -0
  145. package/dist/esm/tools/memory/shared.mjs +98 -0
  146. package/dist/esm/tools/memory/shared.mjs.map +1 -0
  147. package/dist/esm/types/graph.mjs.map +1 -1
  148. package/dist/esm/utils/childAgentContext.mjs +237 -0
  149. package/dist/esm/utils/childAgentContext.mjs.map +1 -0
  150. package/dist/esm/utils/events.mjs +36 -5
  151. package/dist/esm/utils/events.mjs.map +1 -1
  152. package/dist/esm/utils/finishReasons.mjs +41 -0
  153. package/dist/esm/utils/finishReasons.mjs.map +1 -0
  154. package/dist/esm/utils/llm.mjs.map +1 -1
  155. package/dist/esm/utils/logging.mjs +31 -0
  156. package/dist/esm/utils/logging.mjs.map +1 -0
  157. package/dist/esm/utils/toolCallNormalization.mjs +247 -0
  158. package/dist/esm/utils/toolCallNormalization.mjs.map +1 -0
  159. package/dist/types/common/index.d.ts +1 -0
  160. package/dist/types/common/spawnPath.d.ts +59 -0
  161. package/dist/types/graphs/HandoffRegistry.d.ts +97 -0
  162. package/dist/types/graphs/MultiAgentGraph.d.ts +58 -18
  163. package/dist/types/graphs/index.d.ts +1 -0
  164. package/dist/types/graphs/phases/flushLoop.d.ts +106 -0
  165. package/dist/types/graphs/phases/memoryFlushPhase.d.ts +100 -0
  166. package/dist/types/index.d.ts +7 -0
  167. package/dist/types/memory/__tests__/mockBackend.d.ts +40 -0
  168. package/dist/types/memory/citations.d.ts +39 -0
  169. package/dist/types/memory/compositeBackend.d.ts +30 -0
  170. package/dist/types/memory/constants.d.ts +121 -0
  171. package/dist/types/memory/embeddings.d.ts +15 -0
  172. package/dist/types/memory/factory.d.ts +23 -0
  173. package/dist/types/memory/index.d.ts +21 -0
  174. package/dist/types/memory/migrate.d.ts +14 -0
  175. package/dist/types/memory/mmr.d.ts +50 -0
  176. package/dist/types/memory/paths.d.ts +107 -0
  177. package/dist/types/memory/pgvectorStore.d.ts +56 -0
  178. package/dist/types/memory/recallTracking.d.ts +30 -0
  179. package/dist/types/memory/temporalDecay.d.ts +53 -0
  180. package/dist/types/memory/types.d.ts +182 -0
  181. package/dist/types/prompts/memoryFlushPrompt.d.ts +54 -0
  182. package/dist/types/run.d.ts +1 -0
  183. package/dist/types/tools/AskUser.d.ts +1 -1
  184. package/dist/types/tools/BrowserTools.d.ts +2 -2
  185. package/dist/types/tools/approval/constants.d.ts +2 -2
  186. package/dist/types/tools/memory/index.d.ts +39 -0
  187. package/dist/types/tools/memory/memoryAppendTool.d.ts +27 -0
  188. package/dist/types/tools/memory/memoryGetTool.d.ts +22 -0
  189. package/dist/types/tools/memory/memorySearchTool.d.ts +22 -0
  190. package/dist/types/tools/memory/shared.d.ts +106 -0
  191. package/dist/types/types/graph.d.ts +16 -3
  192. package/dist/types/utils/childAgentContext.d.ts +99 -0
  193. package/dist/types/utils/events.d.ts +21 -0
  194. package/dist/types/utils/finishReasons.d.ts +32 -0
  195. package/dist/types/utils/logging.d.ts +2 -0
  196. package/dist/types/utils/toolCallNormalization.d.ts +44 -0
  197. package/package.json +6 -4
  198. package/src/agents/AgentContext.ts +26 -3
  199. package/src/common/__tests__/enum.test.ts +4 -2
  200. package/src/common/__tests__/spawnPath.test.ts +110 -0
  201. package/src/common/index.ts +1 -0
  202. package/src/common/spawnPath.ts +101 -0
  203. package/src/graphs/Graph.ts +94 -43
  204. package/src/graphs/HandoffRegistry.ts +199 -0
  205. package/src/graphs/MultiAgentGraph.ts +694 -226
  206. package/src/graphs/__tests__/HandoffRegistry.test.ts +410 -0
  207. package/src/graphs/__tests__/multi-agent-delegate.test.ts +61 -16
  208. package/src/graphs/__tests__/multi-agent-edges.test.ts +4 -2
  209. package/src/graphs/__tests__/multi-agent-nested-subgraph.test.ts +221 -0
  210. package/src/graphs/__tests__/structured-output.integration.test.ts +212 -118
  211. package/src/graphs/contextManagement.e2e.test.ts +1 -1
  212. package/src/graphs/index.ts +1 -0
  213. package/src/graphs/phases/__tests__/flushLoop.test.ts +264 -0
  214. package/src/graphs/phases/__tests__/memoryFlushPhase.test.ts +37 -0
  215. package/src/graphs/phases/__tests__/runMemoryFlush.test.ts +150 -0
  216. package/src/graphs/phases/flushLoop.ts +303 -0
  217. package/src/graphs/phases/memoryFlushPhase.ts +209 -0
  218. package/src/index.ts +30 -1
  219. package/src/llm/bedrock/index.ts +4 -5
  220. package/src/memory/__tests__/citations.test.ts +61 -0
  221. package/src/memory/__tests__/compositeBackend.test.ts +79 -0
  222. package/src/memory/__tests__/isolation.test.ts +206 -0
  223. package/src/memory/__tests__/mmr.test.ts +148 -0
  224. package/src/memory/__tests__/mockBackend.ts +161 -0
  225. package/src/memory/__tests__/paths.test.ts +168 -0
  226. package/src/memory/__tests__/recallTracking.test.ts +96 -0
  227. package/src/memory/__tests__/temporalDecay.test.ts +151 -0
  228. package/src/memory/citations.ts +80 -0
  229. package/src/memory/compositeBackend.ts +99 -0
  230. package/src/memory/constants.ts +229 -0
  231. package/src/memory/embeddings.ts +188 -0
  232. package/src/memory/factory.ts +111 -0
  233. package/src/memory/index.ts +46 -0
  234. package/src/memory/migrate.ts +116 -0
  235. package/src/memory/mmr.ts +161 -0
  236. package/src/memory/paths.ts +258 -0
  237. package/src/memory/pgvectorStore.ts +324 -0
  238. package/src/memory/recallTracking.ts +127 -0
  239. package/src/memory/schema.sql +51 -0
  240. package/src/memory/temporalDecay.ts +134 -0
  241. package/src/memory/types.ts +185 -0
  242. package/src/nodes/ApprovalGateNode.ts +4 -10
  243. package/src/nodes/__tests__/ApprovalGateNode.test.ts +11 -20
  244. package/src/prompts/memoryFlushPrompt.ts +78 -0
  245. package/src/run.ts +17 -6
  246. package/src/scripts/test-bedrock-handoff-autonomous.ts +56 -20
  247. package/src/specs/agent-handoffs-bedrock.integration.test.ts +8 -5
  248. package/src/specs/agent-handoffs.test.ts +8 -2
  249. package/src/stream.ts +4 -6
  250. package/src/tools/AskUser.ts +7 -2
  251. package/src/tools/BrowserTools.ts +3 -5
  252. package/src/tools/ToolNode.ts +150 -13
  253. package/src/tools/__tests__/ToolApproval.test.ts +22 -9
  254. package/src/tools/approval/__tests__/constants.test.ts +4 -4
  255. package/src/tools/approval/constants.ts +2 -2
  256. package/src/tools/memory/__tests__/memoryTools.test.ts +205 -0
  257. package/src/tools/memory/index.ts +96 -0
  258. package/src/tools/memory/memoryAppendTool.ts +101 -0
  259. package/src/tools/memory/memoryGetTool.ts +53 -0
  260. package/src/tools/memory/memorySearchTool.ts +80 -0
  261. package/src/tools/memory/shared.ts +169 -0
  262. package/src/tools/search/search.test.ts +6 -1
  263. package/src/types/graph.ts +16 -3
  264. package/src/utils/__tests__/childAgentContext.test.ts +217 -0
  265. package/src/utils/__tests__/finishReasons.test.ts +55 -0
  266. package/src/utils/__tests__/toolCallNormalization.test.ts +181 -0
  267. package/src/utils/childAgentContext.ts +259 -0
  268. package/src/utils/events.ts +37 -4
  269. package/src/utils/finishReasons.ts +40 -0
  270. package/src/utils/llm.ts +0 -1
  271. package/src/utils/logging.ts +45 -8
  272. package/src/utils/toolCallNormalization.ts +271 -0
@@ -33,6 +33,9 @@ var providers = require('../llm/providers.cjs');
33
33
  var ToolNode = require('../tools/ToolNode.cjs');
34
34
  var index = require('../llm/openai/index.cjs');
35
35
  var events = require('../utils/events.cjs');
36
+ var logging = require('../utils/logging.cjs');
37
+ var toolCallNormalization = require('../utils/toolCallNormalization.cjs');
38
+ var finishReasons = require('../utils/finishReasons.cjs');
36
39
  var schema = require('../tools/schema.cjs');
37
40
  var validate = require('../schemas/validate.cjs');
38
41
  var AgentContext = require('../agents/AgentContext.cjs');
@@ -797,7 +800,7 @@ class StandardGraph extends Graph {
797
800
  const resolved = agentContext.resolveStructuredOutputMode();
798
801
  method = resolved.method;
799
802
  if (resolved.warnings.length > 0) {
800
- console.warn('[Graph] Structured output mode warnings:', resolved.warnings);
803
+ logging.mwarn('[Graph] Structured output mode warnings:', resolved.warnings);
801
804
  }
802
805
  }
803
806
  else {
@@ -820,7 +823,7 @@ class StandardGraph extends Graph {
820
823
  const { schema: prepared, warnings } = validate.prepareSchemaForProvider(schema, provider, structuredOutputConfig.strict !== false);
821
824
  preparedSchema = prepared;
822
825
  if (warnings.length > 0) {
823
- console.warn('[Graph] Schema preparation warnings:', warnings);
826
+ logging.mwarn('[Graph] Schema preparation warnings:', warnings);
824
827
  }
825
828
  }
826
829
  // Use withStructuredOutput to bind the schema
@@ -890,7 +893,7 @@ class StandardGraph extends Graph {
890
893
  const errorMessage = typeof handleErrors === 'string'
891
894
  ? handleErrors
892
895
  : `The response did not match the expected schema. Error: ${lastError.message}. Please try again with a valid response.`;
893
- console.warn(`[Graph] Structured output attempt ${attempts} failed: ${lastError.message}. Retrying...`);
896
+ logging.mwarn(`[Graph] Structured output attempt ${attempts} failed: ${lastError.message}. Retrying...`);
894
897
  // Add the error as a human message for context
895
898
  finalMessages = [
896
899
  ...finalMessages,
@@ -1040,7 +1043,7 @@ class StandardGraph extends Graph {
1040
1043
  const cachedDiscoveries = this._toolDiscoveryCache.getNewDiscoveries(messages$1);
1041
1044
  if (cachedDiscoveries.length > 0) {
1042
1045
  agentContext.markToolsAsDiscovered(cachedDiscoveries);
1043
- console.debug(`[Graph:ToolDiscovery] Cached ${cachedDiscoveries.length} new tools (total: ${this._toolDiscoveryCache.size})`);
1046
+ logging.mlog(`[Graph:ToolDiscovery] Cached ${cachedDiscoveries.length} new tools (total: ${this._toolDiscoveryCache.size})`);
1044
1047
  }
1045
1048
  const toolsForBinding = agentContext.getToolsForBinding();
1046
1049
  // PERF: Detect subsequent ReAct iterations (tool results present in messages)
@@ -1058,6 +1061,11 @@ class StandardGraph extends Graph {
1058
1061
  provider: agentContext.provider,
1059
1062
  clientOptions: effectiveClientOptions,
1060
1063
  });
1064
+ // DEBUG: Log which model and tools each agent uses during handoff
1065
+ logging.mlog(`[createCallModel] Agent "${agentId}" invoking LLM | provider=${agentContext.provider} | ` +
1066
+ `model=${effectiveClientOptions.model ?? 'default'} | ` +
1067
+ `toolsForBinding=${toolsForBinding?.length ?? 0} | ` +
1068
+ `toolNames=[${(toolsForBinding ?? []).map((t) => t.name ?? 'unknown').join(', ')}]`);
1061
1069
  if (agentContext.systemRunnable) {
1062
1070
  model = agentContext.systemRunnable.pipe(model);
1063
1071
  }
@@ -1067,7 +1075,15 @@ class StandardGraph extends Graph {
1067
1075
  if (!config.signal) {
1068
1076
  config.signal = this.signal;
1069
1077
  }
1070
- this.config = config;
1078
+ // First-writer-wins: `this.config` is used ONLY as a "has a run started"
1079
+ // existence flag by the dispatch* methods (they never read its value —
1080
+ // they read the current RunnableConfig from LangChain AsyncLocalStorage).
1081
+ // Unconditionally reassigning here races across concurrent child
1082
+ // subgraph.invoke() calls under parallel multi-agent handoffs; the last
1083
+ // writer wins, and any dispatch firing between writes would historically
1084
+ // have been tagged with the wrong child's metadata. Keeping the first
1085
+ // write pinned makes this a true flag, eliminating the race.
1086
+ this.config ??= config;
1071
1087
  let messagesToUse = messages$1;
1072
1088
  // ====================================================================
1073
1089
  // PRE-PRUNING DELEGATION CHECK
@@ -1133,13 +1149,13 @@ class StandardGraph extends Graph {
1133
1149
  const oldMessages = messages$1.slice(messages$1[0]?.getType() === 'system' ? 1 : 0, Math.max(1, messages$1.length - recentTurnCount));
1134
1150
  if (oldMessages.length > 0) {
1135
1151
  this._summaryInFlight = true;
1136
- console.debug(`[Graph:ProactiveSummary] Context at ${utilization.toFixed(1)}% (threshold ${threshold}%) — summarizing ${oldMessages.length} older msgs in background`);
1152
+ logging.mlog(`[Graph:ProactiveSummary] Context at ${utilization.toFixed(1)}% (threshold ${threshold}%) — summarizing ${oldMessages.length} older msgs in background`);
1137
1153
  agentContext
1138
1154
  .summarizeCallback(oldMessages)
1139
1155
  .then((updated) => {
1140
1156
  if (updated != null && updated !== '') {
1141
1157
  this._cachedRunSummary = updated;
1142
- console.debug(`[Graph:ProactiveSummary] Background summary ready (len=${updated.length})`);
1158
+ logging.mlog(`[Graph:ProactiveSummary] Background summary ready (len=${updated.length})`);
1143
1159
  }
1144
1160
  })
1145
1161
  .catch((err) => {
@@ -1315,7 +1331,7 @@ class StandardGraph extends Graph {
1315
1331
  viewIdx++;
1316
1332
  }
1317
1333
  agentContext.indexTokenCountMap = viewTokenMap;
1318
- console.debug(`[Graph:Compaction] ${messages$1.length}→${viewParts.length} msgs | ` +
1334
+ logging.mlog(`[Graph:Compaction] ${messages$1.length}→${viewParts.length} msgs | ` +
1319
1335
  `compacted=${compactedMessages.length} window=${recentMessages.length} | ` +
1320
1336
  `summary=${summarySource} | budget=${usedTokens}/${recentBudget}` +
1321
1337
  (fileManifestTokens > 0
@@ -1329,7 +1345,7 @@ class StandardGraph extends Graph {
1329
1345
  if (shouldSummarize) {
1330
1346
  if (this._summaryInFlight) {
1331
1347
  this._pendingMessagesToRefine.push(...compactedMessages);
1332
- console.debug(`[Graph:Compaction] Summary in-flight, queued ${compactedMessages.length} msgs (pending=${this._pendingMessagesToRefine.length})`);
1348
+ logging.mlog(`[Graph:Compaction] Summary in-flight, queued ${compactedMessages.length} msgs (pending=${this._pendingMessagesToRefine.length})`);
1333
1349
  }
1334
1350
  else {
1335
1351
  this._summaryInFlight = true;
@@ -1370,7 +1386,7 @@ class StandardGraph extends Graph {
1370
1386
  const { messages: dedupedMessages, removedCount } = dedup.deduplicateSystemMessages(messagesToUse);
1371
1387
  if (removedCount > 0) {
1372
1388
  messagesToUse = dedupedMessages;
1373
- console.debug(`[Graph:Dedup] Removed ${removedCount} duplicate system message(s)`);
1389
+ logging.mlog(`[Graph:Dedup] Removed ${removedCount} duplicate system message(s)`);
1374
1390
  }
1375
1391
  let finalMessages = messagesToUse;
1376
1392
  if (agentContext.useLegacyContent) {
@@ -1544,8 +1560,8 @@ class StandardGraph extends Graph {
1544
1560
  errorMessage.includes('prompt is too long');
1545
1561
  // Log when we detect the error
1546
1562
  if (isInputTooLongError) {
1547
- console.warn('[Graph] Detected input too long error:', errorMessage.substring(0, 200));
1548
- console.warn('[Graph] Checking emergency pruning conditions:', {
1563
+ logging.mwarn('[Graph] Detected input too long error:', errorMessage.substring(0, 200));
1564
+ logging.mwarn('[Graph] Checking emergency pruning conditions:', {
1549
1565
  hasPruneMessages: !!agentContext.pruneMessages,
1550
1566
  hasTokenCounter: !!agentContext.tokenCounter,
1551
1567
  maxContextTokens: agentContext.maxContextTokens,
@@ -1565,12 +1581,12 @@ class StandardGraph extends Graph {
1565
1581
  if (result)
1566
1582
  break; // Exit if we got a result
1567
1583
  const reducedMaxTokens = Math.floor(agentContext.maxContextTokens * reductionFactor);
1568
- console.warn(`[Graph] Input too long. Retrying with ${reductionFactor * 100}% context (${reducedMaxTokens} tokens)...`);
1584
+ logging.mwarn(`[Graph] Input too long. Retrying with ${reductionFactor * 100}% context (${reducedMaxTokens} tokens)...`);
1569
1585
  // Build fresh indexTokenCountMap if missing/incomplete
1570
1586
  // This is needed when messages were dynamically added without updating the token map
1571
1587
  let tokenMapForPruning = agentContext.indexTokenCountMap;
1572
1588
  if (Object.keys(tokenMapForPruning).length < messages$1.length) {
1573
- console.warn('[Graph] Building fresh token count map for emergency pruning...');
1589
+ logging.mwarn('[Graph] Building fresh token count map for emergency pruning...');
1574
1590
  tokenMapForPruning = {};
1575
1591
  for (let i = 0; i < messages$1.length; i++) {
1576
1592
  tokenMapForPruning[i] = agentContext.tokenCounter(messages$1[i]);
@@ -1590,7 +1606,7 @@ class StandardGraph extends Graph {
1590
1606
  });
1591
1607
  // Skip if we can't fit any messages
1592
1608
  if (reducedMessages.length === 0) {
1593
- console.warn(`[Graph] Cannot fit any messages at ${reductionFactor * 100}% reduction, trying next level...`);
1609
+ logging.mwarn(`[Graph] Cannot fit any messages at ${reductionFactor * 100}% reduction, trying next level...`);
1594
1610
  continue;
1595
1611
  }
1596
1612
  // Calculate how many messages were pruned and estimate context timeframe
@@ -1650,7 +1666,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1650
1666
  retryErrorMsg.includes('context length') ||
1651
1667
  retryErrorMsg.includes('validationexception');
1652
1668
  if (stillTooLong && reductionFactor > 0.1) {
1653
- console.warn(`[Graph] Still too long at ${reductionFactor * 100}%, trying more aggressive pruning...`);
1669
+ logging.mwarn(`[Graph] Still too long at ${reductionFactor * 100}%, trying more aggressive pruning...`);
1654
1670
  }
1655
1671
  else {
1656
1672
  console.error(`[Graph] Retry at ${reductionFactor * 100}% failed:`, retryError.message);
@@ -1710,6 +1726,20 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1710
1726
  * handled everything — both paths become no-ops.
1711
1727
  */
1712
1728
  const responseMessage = result.messages?.[0];
1729
+ // Tool-call name normalization — catches LLM output that names tools
1730
+ // with wrong delimiters (outlook/operations), prefixes
1731
+ // (functions.outlook_operations), case drift, counter suffixes, or
1732
+ // empty names recoverable from the tool_call id. Mutates in place so
1733
+ // the downstream ToolNode dispatch sees the corrected names.
1734
+ if (responseMessage && agentContext.toolMap) {
1735
+ const allowedNames = new Set(Object.keys(agentContext.toolMap));
1736
+ if (allowedNames.size > 0) {
1737
+ const rewrote = toolCallNormalization.normalizeMessageToolCalls(responseMessage, allowedNames);
1738
+ if (rewrote) {
1739
+ logging.mlog(`[Graph] normalized tool_call names on agent "${agentId}" response`);
1740
+ }
1741
+ }
1742
+ }
1713
1743
  const toolCalls = responseMessage
1714
1744
  ?.tool_calls;
1715
1745
  const hasToolCalls = Array.isArray(toolCalls) && toolCalls.length > 0;
@@ -1796,12 +1826,20 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1796
1826
  const meta = finalMsg.response_metadata;
1797
1827
  // Bedrock streaming nests stopReason inside messageStop: { stopReason: '...' }
1798
1828
  const messageStop = meta.messageStop;
1799
- this.lastFinishReason =
1800
- meta.finish_reason ?? // OpenAI/Azure
1801
- meta.stop_reason ?? // Anthropic direct API
1802
- meta.stopReason ?? // Bedrock invoke (non-streaming)
1803
- messageStop?.stopReason ?? // Bedrock streaming
1804
- meta.finishReason; // VertexAI/Google
1829
+ const nextReason = meta.finish_reason ?? // OpenAI/Azure
1830
+ meta.stop_reason ?? // Anthropic direct API
1831
+ meta.stopReason ?? // Bedrock invoke (non-streaming)
1832
+ messageStop?.stopReason ?? // Bedrock streaming
1833
+ meta.finishReason; // VertexAI/Google
1834
+ // Sticky on truncation: a single Graph instance is reused across
1835
+ // every scoped-subgraph inner node invocation (see MultiAgentGraph
1836
+ // buildScopedSubgraph). If an earlier inner node hit max_tokens
1837
+ // but a later inner node finished cleanly, the host's continuation layer
1838
+ // would miss the truncation signal unless we preserve it. Keep the
1839
+ // truncation reason pinned so the outer caller can retry.
1840
+ if (!finishReasons.isTruncationReason(this.lastFinishReason)) {
1841
+ this.lastFinishReason = nextReason;
1842
+ }
1805
1843
  }
1806
1844
  this.cleanupSignalListener();
1807
1845
  // DEFERRED STRUCTURED OUTPUT: When the agent has tools AND structured output configured,
@@ -1849,7 +1887,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1849
1887
  // but we couldn't format the output as structured JSON.
1850
1888
  // Return the unstructured text response from attemptInvoke.
1851
1889
  console.error('[Graph] Deferred structured output failed after successful tool use:', structuredError);
1852
- console.warn('[Graph] Falling back to unstructured response from tool-use phase');
1890
+ logging.mwarn('[Graph] Falling back to unstructured response from tool-use phase');
1853
1891
  return result;
1854
1892
  }
1855
1893
  }
@@ -1865,7 +1903,10 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1865
1903
  const agentNode = `${AGENT}${agentId}`;
1866
1904
  const toolNode = `${TOOLS}${agentId}`;
1867
1905
  const routeMessage = (state, config) => {
1868
- this.config = config;
1906
+ // First-writer-wins — see note in createCallModel. `this.config` is an
1907
+ // existence flag only; assigning unconditionally would race under
1908
+ // parallel child subgraph.invoke().
1909
+ this.config ??= config;
1869
1910
  return ToolNode.toolsCondition(state, toolNode, this.invokedToolIds);
1870
1911
  };
1871
1912
  const StateAnnotation = langgraph.Annotation.Root({
@@ -1903,10 +1944,16 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1903
1944
  default: () => [],
1904
1945
  }),
1905
1946
  });
1947
+ // Pass compileOptions (including the HITL checkpointer) to the OUTER
1948
+ // workflow — not just the inner agent subgraph. hasInterrupts() calls
1949
+ // getState() on the outer compiled graph; without a checkpointer here,
1950
+ // getState reports zero tasks and the HITL interrupt/resume loop breaks
1951
+ // out immediately even though interrupt() fired correctly inside the
1952
+ // agent subgraph.
1906
1953
  const workflow = new langgraph.StateGraph(StateAnnotation)
1907
1954
  .addNode(this.defaultAgentId, agentNode, { ends: [langgraph.END] })
1908
1955
  .addEdge(langgraph.START, this.defaultAgentId)
1909
- .compile();
1956
+ .compile(this.compileOptions);
1910
1957
  return workflow;
1911
1958
  }
1912
1959
  /**
@@ -1977,12 +2024,16 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1977
2024
  }
1978
2025
  catch (_e) {
1979
2026
  /** If we can't get agent context, that's okay - agentId remains undefined */
1980
- console.debug(`[dispatchRunStep] Could not resolve agentId from metadata.langgraph_node="${metadata.langgraph_node}": ${_e.message}`);
2027
+ logging.mlog(`[dispatchRunStep] Could not resolve agentId from metadata.langgraph_node="${metadata.langgraph_node}": ${_e.message}`);
1981
2028
  }
1982
2029
  }
1983
2030
  this.contentData.push(runStep);
1984
2031
  this.contentIndexMap.set(stepId, runStep.index);
1985
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP, runStep, this.config);
2032
+ // Pass undefined so safeDispatchCustomEvent resolves the runnable config
2033
+ // from LangChain's AsyncLocalStorage. Using the shared `this.config` would
2034
+ // race across concurrent child subgraph.invoke calls under parallel
2035
+ // multi-agent handoffs and tag events with the wrong child's spawnKey.
2036
+ await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP, runStep);
1986
2037
  return stepId;
1987
2038
  }
1988
2039
  async handleToolCallCompleted(data, metadata, omitOutput) {
@@ -2090,7 +2141,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
2090
2141
  throw new Error('No config provided');
2091
2142
  }
2092
2143
  if (!data.id) {
2093
- console.warn('No Tool ID provided for Tool Error');
2144
+ logging.mwarn('No Tool ID provided for Tool Error');
2094
2145
  return;
2095
2146
  }
2096
2147
  const stepId = graph.toolCallStepIds.get(data.id) ?? '';
@@ -2138,7 +2189,10 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
2138
2189
  id,
2139
2190
  delta,
2140
2191
  };
2141
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP_DELTA, runStepDelta, this.config);
2192
+ // See dispatchRunStep note: do not pass `this.config`. The implicit
2193
+ // AsyncLocalStorage config is the correct per-async-branch source under
2194
+ // parallel handoffs.
2195
+ await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP_DELTA, runStepDelta);
2142
2196
  }
2143
2197
  async dispatchMessageDelta(id, delta) {
2144
2198
  if (!this.config) {
@@ -2148,7 +2202,8 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
2148
2202
  id,
2149
2203
  delta,
2150
2204
  };
2151
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_MESSAGE_DELTA, messageDelta, this.config);
2205
+ // See dispatchRunStep note.
2206
+ await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_MESSAGE_DELTA, messageDelta);
2152
2207
  }
2153
2208
  dispatchReasoningDelta = async (stepId, delta) => {
2154
2209
  if (!this.config) {
@@ -2158,7 +2213,8 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
2158
2213
  id: stepId,
2159
2214
  delta,
2160
2215
  };
2161
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_REASONING_DELTA, reasoningDelta, this.config);
2216
+ // See dispatchRunStep note.
2217
+ await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_REASONING_DELTA, reasoningDelta);
2162
2218
  };
2163
2219
  }
2164
2220