@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.
- package/dist/cjs/agents/AgentContext.cjs +20 -3
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/spawnPath.cjs +104 -0
- package/dist/cjs/common/spawnPath.cjs.map +1 -0
- package/dist/cjs/graphs/Graph.cjs +87 -31
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/HandoffRegistry.cjs +143 -0
- package/dist/cjs/graphs/HandoffRegistry.cjs.map +1 -0
- package/dist/cjs/graphs/MultiAgentGraph.cjs +587 -184
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/graphs/phases/flushLoop.cjs +214 -0
- package/dist/cjs/graphs/phases/flushLoop.cjs.map +1 -0
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs +102 -0
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs.map +1 -0
- package/dist/cjs/llm/bedrock/index.cjs +4 -3
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +115 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/memory/citations.cjs +69 -0
- package/dist/cjs/memory/citations.cjs.map +1 -0
- package/dist/cjs/memory/compositeBackend.cjs +60 -0
- package/dist/cjs/memory/compositeBackend.cjs.map +1 -0
- package/dist/cjs/memory/constants.cjs +232 -0
- package/dist/cjs/memory/constants.cjs.map +1 -0
- package/dist/cjs/memory/embeddings.cjs +151 -0
- package/dist/cjs/memory/embeddings.cjs.map +1 -0
- package/dist/cjs/memory/factory.cjs +95 -0
- package/dist/cjs/memory/factory.cjs.map +1 -0
- package/dist/cjs/memory/migrate.cjs +81 -0
- package/dist/cjs/memory/migrate.cjs.map +1 -0
- package/dist/cjs/memory/mmr.cjs +138 -0
- package/dist/cjs/memory/mmr.cjs.map +1 -0
- package/dist/cjs/memory/paths.cjs +217 -0
- package/dist/cjs/memory/paths.cjs.map +1 -0
- package/dist/cjs/memory/pgvectorStore.cjs +225 -0
- package/dist/cjs/memory/pgvectorStore.cjs.map +1 -0
- package/dist/cjs/memory/recallTracking.cjs +98 -0
- package/dist/cjs/memory/recallTracking.cjs.map +1 -0
- package/dist/cjs/memory/schema.sql +51 -0
- package/dist/cjs/memory/temporalDecay.cjs +118 -0
- package/dist/cjs/memory/temporalDecay.cjs.map +1 -0
- package/dist/cjs/nodes/ApprovalGateNode.cjs +1 -1
- package/dist/cjs/nodes/ApprovalGateNode.cjs.map +1 -1
- package/dist/cjs/prompts/memoryFlushPrompt.cjs +49 -0
- package/dist/cjs/prompts/memoryFlushPrompt.cjs.map +1 -0
- package/dist/cjs/run.cjs +16 -3
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +4 -4
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/AskUser.cjs +6 -1
- package/dist/cjs/tools/AskUser.cjs.map +1 -1
- package/dist/cjs/tools/BrowserTools.cjs +1 -1
- package/dist/cjs/tools/BrowserTools.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +127 -10
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/approval/constants.cjs +2 -2
- package/dist/cjs/tools/approval/constants.cjs.map +1 -1
- package/dist/cjs/tools/memory/index.cjs +58 -0
- package/dist/cjs/tools/memory/index.cjs.map +1 -0
- package/dist/cjs/tools/memory/memoryAppendTool.cjs +69 -0
- package/dist/cjs/tools/memory/memoryAppendTool.cjs.map +1 -0
- package/dist/cjs/tools/memory/memoryGetTool.cjs +49 -0
- package/dist/cjs/tools/memory/memoryGetTool.cjs.map +1 -0
- package/dist/cjs/tools/memory/memorySearchTool.cjs +65 -0
- package/dist/cjs/tools/memory/memorySearchTool.cjs.map +1 -0
- package/dist/cjs/tools/memory/shared.cjs +106 -0
- package/dist/cjs/tools/memory/shared.cjs.map +1 -0
- package/dist/cjs/types/graph.cjs.map +1 -1
- package/dist/cjs/utils/childAgentContext.cjs +242 -0
- package/dist/cjs/utils/childAgentContext.cjs.map +1 -0
- package/dist/cjs/utils/events.cjs +36 -4
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/cjs/utils/finishReasons.cjs +44 -0
- package/dist/cjs/utils/finishReasons.cjs.map +1 -0
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/logging.cjs +34 -0
- package/dist/cjs/utils/logging.cjs.map +1 -0
- package/dist/cjs/utils/toolCallNormalization.cjs +250 -0
- package/dist/cjs/utils/toolCallNormalization.cjs.map +1 -0
- package/dist/esm/agents/AgentContext.mjs +20 -3
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/spawnPath.mjs +95 -0
- package/dist/esm/common/spawnPath.mjs.map +1 -0
- package/dist/esm/graphs/Graph.mjs +87 -31
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/HandoffRegistry.mjs +141 -0
- package/dist/esm/graphs/HandoffRegistry.mjs.map +1 -0
- package/dist/esm/graphs/MultiAgentGraph.mjs +587 -184
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/graphs/phases/flushLoop.mjs +209 -0
- package/dist/esm/graphs/phases/flushLoop.mjs.map +1 -0
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs +99 -0
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs.map +1 -0
- package/dist/esm/llm/bedrock/index.mjs +4 -3
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/main.mjs +21 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/memory/citations.mjs +64 -0
- package/dist/esm/memory/citations.mjs.map +1 -0
- package/dist/esm/memory/compositeBackend.mjs +58 -0
- package/dist/esm/memory/compositeBackend.mjs.map +1 -0
- package/dist/esm/memory/constants.mjs +198 -0
- package/dist/esm/memory/constants.mjs.map +1 -0
- package/dist/esm/memory/embeddings.mjs +148 -0
- package/dist/esm/memory/embeddings.mjs.map +1 -0
- package/dist/esm/memory/factory.mjs +93 -0
- package/dist/esm/memory/factory.mjs.map +1 -0
- package/dist/esm/memory/migrate.mjs +78 -0
- package/dist/esm/memory/migrate.mjs.map +1 -0
- package/dist/esm/memory/mmr.mjs +130 -0
- package/dist/esm/memory/mmr.mjs.map +1 -0
- package/dist/esm/memory/paths.mjs +207 -0
- package/dist/esm/memory/paths.mjs.map +1 -0
- package/dist/esm/memory/pgvectorStore.mjs +223 -0
- package/dist/esm/memory/pgvectorStore.mjs.map +1 -0
- package/dist/esm/memory/recallTracking.mjs +94 -0
- package/dist/esm/memory/recallTracking.mjs.map +1 -0
- package/dist/esm/memory/schema.sql +51 -0
- package/dist/esm/memory/temporalDecay.mjs +110 -0
- package/dist/esm/memory/temporalDecay.mjs.map +1 -0
- package/dist/esm/nodes/ApprovalGateNode.mjs +1 -1
- package/dist/esm/nodes/ApprovalGateNode.mjs.map +1 -1
- package/dist/esm/prompts/memoryFlushPrompt.mjs +44 -0
- package/dist/esm/prompts/memoryFlushPrompt.mjs.map +1 -0
- package/dist/esm/run.mjs +16 -3
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +4 -4
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/AskUser.mjs +6 -1
- package/dist/esm/tools/AskUser.mjs.map +1 -1
- package/dist/esm/tools/BrowserTools.mjs +1 -1
- package/dist/esm/tools/BrowserTools.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +128 -11
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/approval/constants.mjs +2 -2
- package/dist/esm/tools/approval/constants.mjs.map +1 -1
- package/dist/esm/tools/memory/index.mjs +46 -0
- package/dist/esm/tools/memory/index.mjs.map +1 -0
- package/dist/esm/tools/memory/memoryAppendTool.mjs +67 -0
- package/dist/esm/tools/memory/memoryAppendTool.mjs.map +1 -0
- package/dist/esm/tools/memory/memoryGetTool.mjs +47 -0
- package/dist/esm/tools/memory/memoryGetTool.mjs.map +1 -0
- package/dist/esm/tools/memory/memorySearchTool.mjs +63 -0
- package/dist/esm/tools/memory/memorySearchTool.mjs.map +1 -0
- package/dist/esm/tools/memory/shared.mjs +98 -0
- package/dist/esm/tools/memory/shared.mjs.map +1 -0
- package/dist/esm/types/graph.mjs.map +1 -1
- package/dist/esm/utils/childAgentContext.mjs +237 -0
- package/dist/esm/utils/childAgentContext.mjs.map +1 -0
- package/dist/esm/utils/events.mjs +36 -5
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/esm/utils/finishReasons.mjs +41 -0
- package/dist/esm/utils/finishReasons.mjs.map +1 -0
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/logging.mjs +31 -0
- package/dist/esm/utils/logging.mjs.map +1 -0
- package/dist/esm/utils/toolCallNormalization.mjs +247 -0
- package/dist/esm/utils/toolCallNormalization.mjs.map +1 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/common/spawnPath.d.ts +59 -0
- package/dist/types/graphs/HandoffRegistry.d.ts +97 -0
- package/dist/types/graphs/MultiAgentGraph.d.ts +58 -18
- package/dist/types/graphs/index.d.ts +1 -0
- package/dist/types/graphs/phases/flushLoop.d.ts +106 -0
- package/dist/types/graphs/phases/memoryFlushPhase.d.ts +100 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/memory/__tests__/mockBackend.d.ts +40 -0
- package/dist/types/memory/citations.d.ts +39 -0
- package/dist/types/memory/compositeBackend.d.ts +30 -0
- package/dist/types/memory/constants.d.ts +121 -0
- package/dist/types/memory/embeddings.d.ts +15 -0
- package/dist/types/memory/factory.d.ts +23 -0
- package/dist/types/memory/index.d.ts +21 -0
- package/dist/types/memory/migrate.d.ts +14 -0
- package/dist/types/memory/mmr.d.ts +50 -0
- package/dist/types/memory/paths.d.ts +107 -0
- package/dist/types/memory/pgvectorStore.d.ts +56 -0
- package/dist/types/memory/recallTracking.d.ts +30 -0
- package/dist/types/memory/temporalDecay.d.ts +53 -0
- package/dist/types/memory/types.d.ts +182 -0
- package/dist/types/prompts/memoryFlushPrompt.d.ts +54 -0
- package/dist/types/run.d.ts +1 -0
- package/dist/types/tools/AskUser.d.ts +1 -1
- package/dist/types/tools/BrowserTools.d.ts +2 -2
- package/dist/types/tools/approval/constants.d.ts +2 -2
- package/dist/types/tools/memory/index.d.ts +39 -0
- package/dist/types/tools/memory/memoryAppendTool.d.ts +27 -0
- package/dist/types/tools/memory/memoryGetTool.d.ts +22 -0
- package/dist/types/tools/memory/memorySearchTool.d.ts +22 -0
- package/dist/types/tools/memory/shared.d.ts +106 -0
- package/dist/types/types/graph.d.ts +16 -3
- package/dist/types/utils/childAgentContext.d.ts +99 -0
- package/dist/types/utils/events.d.ts +21 -0
- package/dist/types/utils/finishReasons.d.ts +32 -0
- package/dist/types/utils/logging.d.ts +2 -0
- package/dist/types/utils/toolCallNormalization.d.ts +44 -0
- package/package.json +6 -4
- package/src/agents/AgentContext.ts +26 -3
- package/src/common/__tests__/enum.test.ts +4 -2
- package/src/common/__tests__/spawnPath.test.ts +110 -0
- package/src/common/index.ts +1 -0
- package/src/common/spawnPath.ts +101 -0
- package/src/graphs/Graph.ts +94 -43
- package/src/graphs/HandoffRegistry.ts +199 -0
- package/src/graphs/MultiAgentGraph.ts +694 -226
- package/src/graphs/__tests__/HandoffRegistry.test.ts +410 -0
- package/src/graphs/__tests__/multi-agent-delegate.test.ts +61 -16
- package/src/graphs/__tests__/multi-agent-edges.test.ts +4 -2
- package/src/graphs/__tests__/multi-agent-nested-subgraph.test.ts +221 -0
- package/src/graphs/__tests__/structured-output.integration.test.ts +212 -118
- package/src/graphs/contextManagement.e2e.test.ts +1 -1
- package/src/graphs/index.ts +1 -0
- package/src/graphs/phases/__tests__/flushLoop.test.ts +264 -0
- package/src/graphs/phases/__tests__/memoryFlushPhase.test.ts +37 -0
- package/src/graphs/phases/__tests__/runMemoryFlush.test.ts +150 -0
- package/src/graphs/phases/flushLoop.ts +303 -0
- package/src/graphs/phases/memoryFlushPhase.ts +209 -0
- package/src/index.ts +30 -1
- package/src/llm/bedrock/index.ts +4 -5
- package/src/memory/__tests__/citations.test.ts +61 -0
- package/src/memory/__tests__/compositeBackend.test.ts +79 -0
- package/src/memory/__tests__/isolation.test.ts +206 -0
- package/src/memory/__tests__/mmr.test.ts +148 -0
- package/src/memory/__tests__/mockBackend.ts +161 -0
- package/src/memory/__tests__/paths.test.ts +168 -0
- package/src/memory/__tests__/recallTracking.test.ts +96 -0
- package/src/memory/__tests__/temporalDecay.test.ts +151 -0
- package/src/memory/citations.ts +80 -0
- package/src/memory/compositeBackend.ts +99 -0
- package/src/memory/constants.ts +229 -0
- package/src/memory/embeddings.ts +188 -0
- package/src/memory/factory.ts +111 -0
- package/src/memory/index.ts +46 -0
- package/src/memory/migrate.ts +116 -0
- package/src/memory/mmr.ts +161 -0
- package/src/memory/paths.ts +258 -0
- package/src/memory/pgvectorStore.ts +324 -0
- package/src/memory/recallTracking.ts +127 -0
- package/src/memory/schema.sql +51 -0
- package/src/memory/temporalDecay.ts +134 -0
- package/src/memory/types.ts +185 -0
- package/src/nodes/ApprovalGateNode.ts +4 -10
- package/src/nodes/__tests__/ApprovalGateNode.test.ts +11 -20
- package/src/prompts/memoryFlushPrompt.ts +78 -0
- package/src/run.ts +17 -6
- package/src/scripts/test-bedrock-handoff-autonomous.ts +56 -20
- package/src/specs/agent-handoffs-bedrock.integration.test.ts +8 -5
- package/src/specs/agent-handoffs.test.ts +8 -2
- package/src/stream.ts +4 -6
- package/src/tools/AskUser.ts +7 -2
- package/src/tools/BrowserTools.ts +3 -5
- package/src/tools/ToolNode.ts +150 -13
- package/src/tools/__tests__/ToolApproval.test.ts +22 -9
- package/src/tools/approval/__tests__/constants.test.ts +4 -4
- package/src/tools/approval/constants.ts +2 -2
- package/src/tools/memory/__tests__/memoryTools.test.ts +205 -0
- package/src/tools/memory/index.ts +96 -0
- package/src/tools/memory/memoryAppendTool.ts +101 -0
- package/src/tools/memory/memoryGetTool.ts +53 -0
- package/src/tools/memory/memorySearchTool.ts +80 -0
- package/src/tools/memory/shared.ts +169 -0
- package/src/tools/search/search.test.ts +6 -1
- package/src/types/graph.ts +16 -3
- package/src/utils/__tests__/childAgentContext.test.ts +217 -0
- package/src/utils/__tests__/finishReasons.test.ts +55 -0
- package/src/utils/__tests__/toolCallNormalization.test.ts +181 -0
- package/src/utils/childAgentContext.ts +259 -0
- package/src/utils/events.ts +37 -4
- package/src/utils/finishReasons.ts +40 -0
- package/src/utils/llm.ts +0 -1
- package/src/utils/logging.ts +45 -8
- package/src/utils/toolCallNormalization.ts +271 -0
|
@@ -31,6 +31,9 @@ import { getChatModelClass, manualToolStreamProviders } from '../llm/providers.m
|
|
|
31
31
|
import { ToolNode, toolsCondition } from '../tools/ToolNode.mjs';
|
|
32
32
|
import { ChatOpenAI, AzureChatOpenAI } from '../llm/openai/index.mjs';
|
|
33
33
|
import { safeDispatchCustomEvent } from '../utils/events.mjs';
|
|
34
|
+
import { mwarn, mlog } from '../utils/logging.mjs';
|
|
35
|
+
import { normalizeMessageToolCalls } from '../utils/toolCallNormalization.mjs';
|
|
36
|
+
import { isTruncationReason } from '../utils/finishReasons.mjs';
|
|
34
37
|
import { createSchemaOnlyTools } from '../tools/schema.mjs';
|
|
35
38
|
import { prepareSchemaForProvider } from '../schemas/validate.mjs';
|
|
36
39
|
import { AgentContext } from '../agents/AgentContext.mjs';
|
|
@@ -795,7 +798,7 @@ class StandardGraph extends Graph {
|
|
|
795
798
|
const resolved = agentContext.resolveStructuredOutputMode();
|
|
796
799
|
method = resolved.method;
|
|
797
800
|
if (resolved.warnings.length > 0) {
|
|
798
|
-
|
|
801
|
+
mwarn('[Graph] Structured output mode warnings:', resolved.warnings);
|
|
799
802
|
}
|
|
800
803
|
}
|
|
801
804
|
else {
|
|
@@ -818,7 +821,7 @@ class StandardGraph extends Graph {
|
|
|
818
821
|
const { schema: prepared, warnings } = prepareSchemaForProvider(schema, provider, structuredOutputConfig.strict !== false);
|
|
819
822
|
preparedSchema = prepared;
|
|
820
823
|
if (warnings.length > 0) {
|
|
821
|
-
|
|
824
|
+
mwarn('[Graph] Schema preparation warnings:', warnings);
|
|
822
825
|
}
|
|
823
826
|
}
|
|
824
827
|
// Use withStructuredOutput to bind the schema
|
|
@@ -888,7 +891,7 @@ class StandardGraph extends Graph {
|
|
|
888
891
|
const errorMessage = typeof handleErrors === 'string'
|
|
889
892
|
? handleErrors
|
|
890
893
|
: `The response did not match the expected schema. Error: ${lastError.message}. Please try again with a valid response.`;
|
|
891
|
-
|
|
894
|
+
mwarn(`[Graph] Structured output attempt ${attempts} failed: ${lastError.message}. Retrying...`);
|
|
892
895
|
// Add the error as a human message for context
|
|
893
896
|
finalMessages = [
|
|
894
897
|
...finalMessages,
|
|
@@ -1038,7 +1041,7 @@ class StandardGraph extends Graph {
|
|
|
1038
1041
|
const cachedDiscoveries = this._toolDiscoveryCache.getNewDiscoveries(messages);
|
|
1039
1042
|
if (cachedDiscoveries.length > 0) {
|
|
1040
1043
|
agentContext.markToolsAsDiscovered(cachedDiscoveries);
|
|
1041
|
-
|
|
1044
|
+
mlog(`[Graph:ToolDiscovery] Cached ${cachedDiscoveries.length} new tools (total: ${this._toolDiscoveryCache.size})`);
|
|
1042
1045
|
}
|
|
1043
1046
|
const toolsForBinding = agentContext.getToolsForBinding();
|
|
1044
1047
|
// PERF: Detect subsequent ReAct iterations (tool results present in messages)
|
|
@@ -1056,6 +1059,11 @@ class StandardGraph extends Graph {
|
|
|
1056
1059
|
provider: agentContext.provider,
|
|
1057
1060
|
clientOptions: effectiveClientOptions,
|
|
1058
1061
|
});
|
|
1062
|
+
// DEBUG: Log which model and tools each agent uses during handoff
|
|
1063
|
+
mlog(`[createCallModel] Agent "${agentId}" invoking LLM | provider=${agentContext.provider} | ` +
|
|
1064
|
+
`model=${effectiveClientOptions.model ?? 'default'} | ` +
|
|
1065
|
+
`toolsForBinding=${toolsForBinding?.length ?? 0} | ` +
|
|
1066
|
+
`toolNames=[${(toolsForBinding ?? []).map((t) => t.name ?? 'unknown').join(', ')}]`);
|
|
1059
1067
|
if (agentContext.systemRunnable) {
|
|
1060
1068
|
model = agentContext.systemRunnable.pipe(model);
|
|
1061
1069
|
}
|
|
@@ -1065,7 +1073,15 @@ class StandardGraph extends Graph {
|
|
|
1065
1073
|
if (!config.signal) {
|
|
1066
1074
|
config.signal = this.signal;
|
|
1067
1075
|
}
|
|
1068
|
-
this.config
|
|
1076
|
+
// First-writer-wins: `this.config` is used ONLY as a "has a run started"
|
|
1077
|
+
// existence flag by the dispatch* methods (they never read its value —
|
|
1078
|
+
// they read the current RunnableConfig from LangChain AsyncLocalStorage).
|
|
1079
|
+
// Unconditionally reassigning here races across concurrent child
|
|
1080
|
+
// subgraph.invoke() calls under parallel multi-agent handoffs; the last
|
|
1081
|
+
// writer wins, and any dispatch firing between writes would historically
|
|
1082
|
+
// have been tagged with the wrong child's metadata. Keeping the first
|
|
1083
|
+
// write pinned makes this a true flag, eliminating the race.
|
|
1084
|
+
this.config ??= config;
|
|
1069
1085
|
let messagesToUse = messages;
|
|
1070
1086
|
// ====================================================================
|
|
1071
1087
|
// PRE-PRUNING DELEGATION CHECK
|
|
@@ -1131,13 +1147,13 @@ class StandardGraph extends Graph {
|
|
|
1131
1147
|
const oldMessages = messages.slice(messages[0]?.getType() === 'system' ? 1 : 0, Math.max(1, messages.length - recentTurnCount));
|
|
1132
1148
|
if (oldMessages.length > 0) {
|
|
1133
1149
|
this._summaryInFlight = true;
|
|
1134
|
-
|
|
1150
|
+
mlog(`[Graph:ProactiveSummary] Context at ${utilization.toFixed(1)}% (threshold ${threshold}%) — summarizing ${oldMessages.length} older msgs in background`);
|
|
1135
1151
|
agentContext
|
|
1136
1152
|
.summarizeCallback(oldMessages)
|
|
1137
1153
|
.then((updated) => {
|
|
1138
1154
|
if (updated != null && updated !== '') {
|
|
1139
1155
|
this._cachedRunSummary = updated;
|
|
1140
|
-
|
|
1156
|
+
mlog(`[Graph:ProactiveSummary] Background summary ready (len=${updated.length})`);
|
|
1141
1157
|
}
|
|
1142
1158
|
})
|
|
1143
1159
|
.catch((err) => {
|
|
@@ -1313,7 +1329,7 @@ class StandardGraph extends Graph {
|
|
|
1313
1329
|
viewIdx++;
|
|
1314
1330
|
}
|
|
1315
1331
|
agentContext.indexTokenCountMap = viewTokenMap;
|
|
1316
|
-
|
|
1332
|
+
mlog(`[Graph:Compaction] ${messages.length}→${viewParts.length} msgs | ` +
|
|
1317
1333
|
`compacted=${compactedMessages.length} window=${recentMessages.length} | ` +
|
|
1318
1334
|
`summary=${summarySource} | budget=${usedTokens}/${recentBudget}` +
|
|
1319
1335
|
(fileManifestTokens > 0
|
|
@@ -1327,7 +1343,7 @@ class StandardGraph extends Graph {
|
|
|
1327
1343
|
if (shouldSummarize) {
|
|
1328
1344
|
if (this._summaryInFlight) {
|
|
1329
1345
|
this._pendingMessagesToRefine.push(...compactedMessages);
|
|
1330
|
-
|
|
1346
|
+
mlog(`[Graph:Compaction] Summary in-flight, queued ${compactedMessages.length} msgs (pending=${this._pendingMessagesToRefine.length})`);
|
|
1331
1347
|
}
|
|
1332
1348
|
else {
|
|
1333
1349
|
this._summaryInFlight = true;
|
|
@@ -1368,7 +1384,7 @@ class StandardGraph extends Graph {
|
|
|
1368
1384
|
const { messages: dedupedMessages, removedCount } = deduplicateSystemMessages(messagesToUse);
|
|
1369
1385
|
if (removedCount > 0) {
|
|
1370
1386
|
messagesToUse = dedupedMessages;
|
|
1371
|
-
|
|
1387
|
+
mlog(`[Graph:Dedup] Removed ${removedCount} duplicate system message(s)`);
|
|
1372
1388
|
}
|
|
1373
1389
|
let finalMessages = messagesToUse;
|
|
1374
1390
|
if (agentContext.useLegacyContent) {
|
|
@@ -1542,8 +1558,8 @@ class StandardGraph extends Graph {
|
|
|
1542
1558
|
errorMessage.includes('prompt is too long');
|
|
1543
1559
|
// Log when we detect the error
|
|
1544
1560
|
if (isInputTooLongError) {
|
|
1545
|
-
|
|
1546
|
-
|
|
1561
|
+
mwarn('[Graph] Detected input too long error:', errorMessage.substring(0, 200));
|
|
1562
|
+
mwarn('[Graph] Checking emergency pruning conditions:', {
|
|
1547
1563
|
hasPruneMessages: !!agentContext.pruneMessages,
|
|
1548
1564
|
hasTokenCounter: !!agentContext.tokenCounter,
|
|
1549
1565
|
maxContextTokens: agentContext.maxContextTokens,
|
|
@@ -1563,12 +1579,12 @@ class StandardGraph extends Graph {
|
|
|
1563
1579
|
if (result)
|
|
1564
1580
|
break; // Exit if we got a result
|
|
1565
1581
|
const reducedMaxTokens = Math.floor(agentContext.maxContextTokens * reductionFactor);
|
|
1566
|
-
|
|
1582
|
+
mwarn(`[Graph] Input too long. Retrying with ${reductionFactor * 100}% context (${reducedMaxTokens} tokens)...`);
|
|
1567
1583
|
// Build fresh indexTokenCountMap if missing/incomplete
|
|
1568
1584
|
// This is needed when messages were dynamically added without updating the token map
|
|
1569
1585
|
let tokenMapForPruning = agentContext.indexTokenCountMap;
|
|
1570
1586
|
if (Object.keys(tokenMapForPruning).length < messages.length) {
|
|
1571
|
-
|
|
1587
|
+
mwarn('[Graph] Building fresh token count map for emergency pruning...');
|
|
1572
1588
|
tokenMapForPruning = {};
|
|
1573
1589
|
for (let i = 0; i < messages.length; i++) {
|
|
1574
1590
|
tokenMapForPruning[i] = agentContext.tokenCounter(messages[i]);
|
|
@@ -1588,7 +1604,7 @@ class StandardGraph extends Graph {
|
|
|
1588
1604
|
});
|
|
1589
1605
|
// Skip if we can't fit any messages
|
|
1590
1606
|
if (reducedMessages.length === 0) {
|
|
1591
|
-
|
|
1607
|
+
mwarn(`[Graph] Cannot fit any messages at ${reductionFactor * 100}% reduction, trying next level...`);
|
|
1592
1608
|
continue;
|
|
1593
1609
|
}
|
|
1594
1610
|
// Calculate how many messages were pruned and estimate context timeframe
|
|
@@ -1648,7 +1664,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1648
1664
|
retryErrorMsg.includes('context length') ||
|
|
1649
1665
|
retryErrorMsg.includes('validationexception');
|
|
1650
1666
|
if (stillTooLong && reductionFactor > 0.1) {
|
|
1651
|
-
|
|
1667
|
+
mwarn(`[Graph] Still too long at ${reductionFactor * 100}%, trying more aggressive pruning...`);
|
|
1652
1668
|
}
|
|
1653
1669
|
else {
|
|
1654
1670
|
console.error(`[Graph] Retry at ${reductionFactor * 100}% failed:`, retryError.message);
|
|
@@ -1708,6 +1724,20 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1708
1724
|
* handled everything — both paths become no-ops.
|
|
1709
1725
|
*/
|
|
1710
1726
|
const responseMessage = result.messages?.[0];
|
|
1727
|
+
// Tool-call name normalization — catches LLM output that names tools
|
|
1728
|
+
// with wrong delimiters (outlook/operations), prefixes
|
|
1729
|
+
// (functions.outlook_operations), case drift, counter suffixes, or
|
|
1730
|
+
// empty names recoverable from the tool_call id. Mutates in place so
|
|
1731
|
+
// the downstream ToolNode dispatch sees the corrected names.
|
|
1732
|
+
if (responseMessage && agentContext.toolMap) {
|
|
1733
|
+
const allowedNames = new Set(Object.keys(agentContext.toolMap));
|
|
1734
|
+
if (allowedNames.size > 0) {
|
|
1735
|
+
const rewrote = normalizeMessageToolCalls(responseMessage, allowedNames);
|
|
1736
|
+
if (rewrote) {
|
|
1737
|
+
mlog(`[Graph] normalized tool_call names on agent "${agentId}" response`);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1711
1741
|
const toolCalls = responseMessage
|
|
1712
1742
|
?.tool_calls;
|
|
1713
1743
|
const hasToolCalls = Array.isArray(toolCalls) && toolCalls.length > 0;
|
|
@@ -1794,12 +1824,20 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1794
1824
|
const meta = finalMsg.response_metadata;
|
|
1795
1825
|
// Bedrock streaming nests stopReason inside messageStop: { stopReason: '...' }
|
|
1796
1826
|
const messageStop = meta.messageStop;
|
|
1797
|
-
|
|
1798
|
-
meta.
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1827
|
+
const nextReason = meta.finish_reason ?? // OpenAI/Azure
|
|
1828
|
+
meta.stop_reason ?? // Anthropic direct API
|
|
1829
|
+
meta.stopReason ?? // Bedrock invoke (non-streaming)
|
|
1830
|
+
messageStop?.stopReason ?? // Bedrock streaming
|
|
1831
|
+
meta.finishReason; // VertexAI/Google
|
|
1832
|
+
// Sticky on truncation: a single Graph instance is reused across
|
|
1833
|
+
// every scoped-subgraph inner node invocation (see MultiAgentGraph
|
|
1834
|
+
// buildScopedSubgraph). If an earlier inner node hit max_tokens
|
|
1835
|
+
// but a later inner node finished cleanly, the host's continuation layer
|
|
1836
|
+
// would miss the truncation signal unless we preserve it. Keep the
|
|
1837
|
+
// truncation reason pinned so the outer caller can retry.
|
|
1838
|
+
if (!isTruncationReason(this.lastFinishReason)) {
|
|
1839
|
+
this.lastFinishReason = nextReason;
|
|
1840
|
+
}
|
|
1803
1841
|
}
|
|
1804
1842
|
this.cleanupSignalListener();
|
|
1805
1843
|
// DEFERRED STRUCTURED OUTPUT: When the agent has tools AND structured output configured,
|
|
@@ -1847,7 +1885,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1847
1885
|
// but we couldn't format the output as structured JSON.
|
|
1848
1886
|
// Return the unstructured text response from attemptInvoke.
|
|
1849
1887
|
console.error('[Graph] Deferred structured output failed after successful tool use:', structuredError);
|
|
1850
|
-
|
|
1888
|
+
mwarn('[Graph] Falling back to unstructured response from tool-use phase');
|
|
1851
1889
|
return result;
|
|
1852
1890
|
}
|
|
1853
1891
|
}
|
|
@@ -1863,7 +1901,10 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1863
1901
|
const agentNode = `${AGENT}${agentId}`;
|
|
1864
1902
|
const toolNode = `${TOOLS}${agentId}`;
|
|
1865
1903
|
const routeMessage = (state, config) => {
|
|
1866
|
-
this.config
|
|
1904
|
+
// First-writer-wins — see note in createCallModel. `this.config` is an
|
|
1905
|
+
// existence flag only; assigning unconditionally would race under
|
|
1906
|
+
// parallel child subgraph.invoke().
|
|
1907
|
+
this.config ??= config;
|
|
1867
1908
|
return toolsCondition(state, toolNode, this.invokedToolIds);
|
|
1868
1909
|
};
|
|
1869
1910
|
const StateAnnotation = Annotation.Root({
|
|
@@ -1901,10 +1942,16 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1901
1942
|
default: () => [],
|
|
1902
1943
|
}),
|
|
1903
1944
|
});
|
|
1945
|
+
// Pass compileOptions (including the HITL checkpointer) to the OUTER
|
|
1946
|
+
// workflow — not just the inner agent subgraph. hasInterrupts() calls
|
|
1947
|
+
// getState() on the outer compiled graph; without a checkpointer here,
|
|
1948
|
+
// getState reports zero tasks and the HITL interrupt/resume loop breaks
|
|
1949
|
+
// out immediately even though interrupt() fired correctly inside the
|
|
1950
|
+
// agent subgraph.
|
|
1904
1951
|
const workflow = new StateGraph(StateAnnotation)
|
|
1905
1952
|
.addNode(this.defaultAgentId, agentNode, { ends: [END] })
|
|
1906
1953
|
.addEdge(START, this.defaultAgentId)
|
|
1907
|
-
.compile();
|
|
1954
|
+
.compile(this.compileOptions);
|
|
1908
1955
|
return workflow;
|
|
1909
1956
|
}
|
|
1910
1957
|
/**
|
|
@@ -1975,12 +2022,16 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1975
2022
|
}
|
|
1976
2023
|
catch (_e) {
|
|
1977
2024
|
/** If we can't get agent context, that's okay - agentId remains undefined */
|
|
1978
|
-
|
|
2025
|
+
mlog(`[dispatchRunStep] Could not resolve agentId from metadata.langgraph_node="${metadata.langgraph_node}": ${_e.message}`);
|
|
1979
2026
|
}
|
|
1980
2027
|
}
|
|
1981
2028
|
this.contentData.push(runStep);
|
|
1982
2029
|
this.contentIndexMap.set(stepId, runStep.index);
|
|
1983
|
-
|
|
2030
|
+
// Pass undefined so safeDispatchCustomEvent resolves the runnable config
|
|
2031
|
+
// from LangChain's AsyncLocalStorage. Using the shared `this.config` would
|
|
2032
|
+
// race across concurrent child subgraph.invoke calls under parallel
|
|
2033
|
+
// multi-agent handoffs and tag events with the wrong child's spawnKey.
|
|
2034
|
+
await safeDispatchCustomEvent(GraphEvents.ON_RUN_STEP, runStep);
|
|
1984
2035
|
return stepId;
|
|
1985
2036
|
}
|
|
1986
2037
|
async handleToolCallCompleted(data, metadata, omitOutput) {
|
|
@@ -2088,7 +2139,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
2088
2139
|
throw new Error('No config provided');
|
|
2089
2140
|
}
|
|
2090
2141
|
if (!data.id) {
|
|
2091
|
-
|
|
2142
|
+
mwarn('No Tool ID provided for Tool Error');
|
|
2092
2143
|
return;
|
|
2093
2144
|
}
|
|
2094
2145
|
const stepId = graph.toolCallStepIds.get(data.id) ?? '';
|
|
@@ -2136,7 +2187,10 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
2136
2187
|
id,
|
|
2137
2188
|
delta,
|
|
2138
2189
|
};
|
|
2139
|
-
|
|
2190
|
+
// See dispatchRunStep note: do not pass `this.config`. The implicit
|
|
2191
|
+
// AsyncLocalStorage config is the correct per-async-branch source under
|
|
2192
|
+
// parallel handoffs.
|
|
2193
|
+
await safeDispatchCustomEvent(GraphEvents.ON_RUN_STEP_DELTA, runStepDelta);
|
|
2140
2194
|
}
|
|
2141
2195
|
async dispatchMessageDelta(id, delta) {
|
|
2142
2196
|
if (!this.config) {
|
|
@@ -2146,7 +2200,8 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
2146
2200
|
id,
|
|
2147
2201
|
delta,
|
|
2148
2202
|
};
|
|
2149
|
-
|
|
2203
|
+
// See dispatchRunStep note.
|
|
2204
|
+
await safeDispatchCustomEvent(GraphEvents.ON_MESSAGE_DELTA, messageDelta);
|
|
2150
2205
|
}
|
|
2151
2206
|
dispatchReasoningDelta = async (stepId, delta) => {
|
|
2152
2207
|
if (!this.config) {
|
|
@@ -2156,7 +2211,8 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
2156
2211
|
id: stepId,
|
|
2157
2212
|
delta,
|
|
2158
2213
|
};
|
|
2159
|
-
|
|
2214
|
+
// See dispatchRunStep note.
|
|
2215
|
+
await safeDispatchCustomEvent(GraphEvents.ON_REASONING_DELTA, reasoningDelta);
|
|
2160
2216
|
};
|
|
2161
2217
|
}
|
|
2162
2218
|
|