illuma-agents 1.0.2 → 1.0.4
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/LICENSE +25 -21
- package/dist/cjs/agents/AgentContext.cjs +222 -0
- package/dist/cjs/agents/AgentContext.cjs.map +1 -0
- package/dist/cjs/common/enum.cjs +5 -4
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/events.cjs +7 -5
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +328 -207
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +507 -0
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/ollama/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +35 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +3 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs +0 -2
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +12 -1
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +123 -0
- package/dist/cjs/messages/cache.cjs.map +1 -0
- package/dist/cjs/messages/content.cjs +53 -0
- package/dist/cjs/messages/content.cjs.map +1 -0
- package/dist/cjs/messages/format.cjs +17 -29
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/run.cjs +119 -74
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +77 -73
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/Calculator.cjs +45 -0
- package/dist/cjs/tools/Calculator.cjs.map +1 -0
- package/dist/cjs/tools/CodeExecutor.cjs +22 -22
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +5 -3
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +20 -20
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/utils/events.cjs +31 -0
- package/dist/cjs/utils/events.cjs.map +1 -0
- package/dist/cjs/utils/handlers.cjs +70 -0
- package/dist/cjs/utils/handlers.cjs.map +1 -0
- package/dist/cjs/utils/tokens.cjs +54 -7
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +220 -0
- package/dist/esm/agents/AgentContext.mjs.map +1 -0
- package/dist/esm/common/enum.mjs +5 -4
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/events.mjs +7 -5
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +330 -209
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +505 -0
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -0
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/ollama/index.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +35 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +3 -1
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs +0 -2
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +7 -2
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +120 -0
- package/dist/esm/messages/cache.mjs.map +1 -0
- package/dist/esm/messages/content.mjs +51 -0
- package/dist/esm/messages/content.mjs.map +1 -0
- package/dist/esm/messages/format.mjs +18 -29
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/run.mjs +119 -74
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +77 -73
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/Calculator.mjs +24 -0
- package/dist/esm/tools/Calculator.mjs.map +1 -0
- package/dist/esm/tools/CodeExecutor.mjs +22 -22
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +5 -3
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +20 -20
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/utils/events.mjs +29 -0
- package/dist/esm/utils/events.mjs.map +1 -0
- package/dist/esm/utils/handlers.mjs +68 -0
- package/dist/esm/utils/handlers.mjs.map +1 -0
- package/dist/esm/utils/tokens.mjs +54 -8
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +94 -0
- package/dist/types/common/enum.d.ts +7 -5
- package/dist/types/events.d.ts +3 -3
- package/dist/types/graphs/Graph.d.ts +60 -66
- package/dist/types/graphs/MultiAgentGraph.d.ts +47 -0
- package/dist/types/graphs/index.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/llm/openai/index.d.ts +10 -0
- package/dist/types/messages/cache.d.ts +20 -0
- package/dist/types/messages/content.d.ts +7 -0
- package/dist/types/messages/format.d.ts +1 -7
- package/dist/types/messages/index.d.ts +2 -0
- package/dist/types/messages/reducer.d.ts +9 -0
- package/dist/types/run.d.ts +16 -10
- package/dist/types/stream.d.ts +4 -3
- package/dist/types/tools/Calculator.d.ts +8 -0
- package/dist/types/tools/ToolNode.d.ts +1 -1
- package/dist/types/tools/handlers.d.ts +9 -7
- package/dist/types/tools/search/tool.d.ts +4 -4
- package/dist/types/types/graph.d.ts +124 -11
- package/dist/types/types/llm.d.ts +13 -9
- package/dist/types/types/messages.d.ts +4 -0
- package/dist/types/types/run.d.ts +46 -8
- package/dist/types/types/stream.d.ts +3 -2
- package/dist/types/utils/events.d.ts +6 -0
- package/dist/types/utils/handlers.d.ts +34 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/tokens.d.ts +24 -0
- package/package.json +162 -145
- package/src/agents/AgentContext.ts +323 -0
- package/src/common/enum.ts +177 -176
- package/src/events.ts +197 -191
- package/src/graphs/Graph.ts +1058 -846
- package/src/graphs/MultiAgentGraph.ts +598 -0
- package/src/graphs/index.ts +2 -1
- package/src/index.ts +25 -24
- package/src/llm/anthropic/index.ts +413 -413
- package/src/llm/google/index.ts +222 -222
- package/src/llm/google/utils/zod_to_genai_parameters.ts +86 -88
- package/src/llm/ollama/index.ts +92 -92
- package/src/llm/openai/index.ts +894 -853
- package/src/llm/openai/utils/index.ts +920 -918
- package/src/llm/openrouter/index.ts +60 -60
- package/src/llm/providers.ts +55 -57
- package/src/llm/vertexai/index.ts +360 -360
- package/src/messages/cache.test.ts +461 -0
- package/src/messages/cache.ts +151 -0
- package/src/messages/content.test.ts +362 -0
- package/src/messages/content.ts +63 -0
- package/src/messages/format.ts +611 -625
- package/src/messages/formatAgentMessages.test.ts +1144 -917
- package/src/messages/index.ts +6 -4
- package/src/messages/reducer.ts +80 -0
- package/src/run.ts +447 -381
- package/src/scripts/abort.ts +157 -138
- package/src/scripts/ant_web_search.ts +158 -158
- package/src/scripts/cli.ts +172 -167
- package/src/scripts/cli2.ts +133 -125
- package/src/scripts/cli3.ts +184 -178
- package/src/scripts/cli4.ts +191 -184
- package/src/scripts/cli5.ts +191 -184
- package/src/scripts/code_exec.ts +213 -214
- package/src/scripts/code_exec_simple.ts +147 -129
- package/src/scripts/content.ts +138 -120
- package/src/scripts/handoff-test.ts +135 -0
- package/src/scripts/multi-agent-chain.ts +278 -0
- package/src/scripts/multi-agent-conditional.ts +220 -0
- package/src/scripts/multi-agent-document-review-chain.ts +197 -0
- package/src/scripts/multi-agent-hybrid-flow.ts +310 -0
- package/src/scripts/multi-agent-parallel.ts +343 -0
- package/src/scripts/multi-agent-sequence.ts +212 -0
- package/src/scripts/multi-agent-supervisor.ts +364 -0
- package/src/scripts/multi-agent-test.ts +186 -0
- package/src/scripts/search.ts +146 -150
- package/src/scripts/simple.ts +225 -225
- package/src/scripts/stream.ts +140 -122
- package/src/scripts/test-custom-prompt-key.ts +145 -0
- package/src/scripts/test-handoff-input.ts +170 -0
- package/src/scripts/test-multi-agent-list-handoff.ts +261 -0
- package/src/scripts/test-tools-before-handoff.ts +222 -0
- package/src/scripts/tools.ts +153 -155
- package/src/specs/agent-handoffs.test.ts +889 -0
- package/src/specs/anthropic.simple.test.ts +320 -317
- package/src/specs/azure.simple.test.ts +325 -316
- package/src/specs/openai.simple.test.ts +311 -316
- package/src/specs/openrouter.simple.test.ts +107 -0
- package/src/specs/prune.test.ts +758 -763
- package/src/specs/reasoning.test.ts +201 -165
- package/src/specs/thinking-prune.test.ts +769 -703
- package/src/specs/token-memoization.test.ts +39 -0
- package/src/stream.ts +664 -651
- package/src/tools/Calculator.test.ts +278 -0
- package/src/tools/Calculator.ts +25 -0
- package/src/tools/CodeExecutor.ts +220 -220
- package/src/tools/ToolNode.ts +170 -170
- package/src/tools/handlers.ts +341 -336
- package/src/types/graph.ts +372 -185
- package/src/types/llm.ts +141 -140
- package/src/types/messages.ts +4 -0
- package/src/types/run.ts +128 -89
- package/src/types/stream.ts +401 -400
- package/src/utils/events.ts +32 -0
- package/src/utils/handlers.ts +107 -0
- package/src/utils/index.ts +6 -5
- package/src/utils/llmConfig.ts +183 -183
- package/src/utils/tokens.ts +129 -70
- package/dist/types/scripts/abort.d.ts +0 -1
- package/dist/types/scripts/ant_web_search.d.ts +0 -1
- package/dist/types/scripts/args.d.ts +0 -7
- package/dist/types/scripts/caching.d.ts +0 -1
- package/dist/types/scripts/cli.d.ts +0 -1
- package/dist/types/scripts/cli2.d.ts +0 -1
- package/dist/types/scripts/cli3.d.ts +0 -1
- package/dist/types/scripts/cli4.d.ts +0 -1
- package/dist/types/scripts/cli5.d.ts +0 -1
- package/dist/types/scripts/code_exec.d.ts +0 -1
- package/dist/types/scripts/code_exec_files.d.ts +0 -1
- package/dist/types/scripts/code_exec_simple.d.ts +0 -1
- package/dist/types/scripts/content.d.ts +0 -1
- package/dist/types/scripts/empty_input.d.ts +0 -1
- package/dist/types/scripts/image.d.ts +0 -1
- package/dist/types/scripts/memory.d.ts +0 -1
- package/dist/types/scripts/search.d.ts +0 -1
- package/dist/types/scripts/simple.d.ts +0 -1
- package/dist/types/scripts/stream.d.ts +0 -1
- package/dist/types/scripts/thinking.d.ts +0 -1
- package/dist/types/scripts/tools.d.ts +0 -1
- package/dist/types/specs/spec.utils.d.ts +0 -1
- package/dist/types/tools/example.d.ts +0 -78
- package/src/tools/example.ts +0 -129
|
@@ -4,28 +4,28 @@ var nanoid = require('nanoid');
|
|
|
4
4
|
var stream = require('@langchain/core/utils/stream');
|
|
5
5
|
var googleVertexai = require('@langchain/google-vertexai');
|
|
6
6
|
var langgraph = require('@langchain/langgraph');
|
|
7
|
-
var
|
|
7
|
+
var runnables = require('@langchain/core/runnables');
|
|
8
8
|
var messages = require('@langchain/core/messages');
|
|
9
9
|
var _enum = require('../common/enum.cjs');
|
|
10
|
-
var providers = require('../llm/providers.cjs');
|
|
11
|
-
var ToolNode = require('../tools/ToolNode.cjs');
|
|
12
10
|
var core = require('../messages/core.cjs');
|
|
13
11
|
var prune = require('../messages/prune.cjs');
|
|
12
|
+
var cache = require('../messages/cache.cjs');
|
|
13
|
+
var content = require('../messages/content.cjs');
|
|
14
14
|
var graph = require('../utils/graph.cjs');
|
|
15
15
|
var llm = require('../utils/llm.cjs');
|
|
16
16
|
var run = require('../utils/run.cjs');
|
|
17
17
|
require('js-tiktoken/lite');
|
|
18
|
+
var providers = require('../llm/providers.cjs');
|
|
19
|
+
var ToolNode = require('../tools/ToolNode.cjs');
|
|
18
20
|
var index = require('../llm/openai/index.cjs');
|
|
21
|
+
var events = require('../utils/events.cjs');
|
|
22
|
+
var AgentContext = require('../agents/AgentContext.cjs');
|
|
19
23
|
var fake = require('../llm/fake.cjs');
|
|
20
24
|
|
|
21
25
|
/* eslint-disable no-console */
|
|
22
26
|
// src/graphs/Graph.ts
|
|
23
27
|
const { AGENT, TOOLS } = _enum.GraphNodeKeys;
|
|
24
28
|
class Graph {
|
|
25
|
-
lastToken;
|
|
26
|
-
tokenTypeSwitch;
|
|
27
|
-
reasoningKey = 'reasoning_content';
|
|
28
|
-
currentTokenType = _enum.ContentTypes.TEXT;
|
|
29
29
|
messageStepHasToolCalls = new Map();
|
|
30
30
|
messageIdsByStepKey = new Map();
|
|
31
31
|
prelimMessageIdsByStepKey = new Map();
|
|
@@ -34,74 +34,37 @@ class Graph {
|
|
|
34
34
|
stepKeyIds = new Map();
|
|
35
35
|
contentIndexMap = new Map();
|
|
36
36
|
toolCallStepIds = new Map();
|
|
37
|
-
currentUsage;
|
|
38
|
-
indexTokenCountMap = {};
|
|
39
|
-
maxContextTokens;
|
|
40
|
-
pruneMessages;
|
|
41
|
-
/** The amount of time that should pass before another consecutive API call */
|
|
42
|
-
streamBuffer;
|
|
43
|
-
tokenCounter;
|
|
44
37
|
signal;
|
|
45
38
|
/** Set of invoked tool call IDs from non-message run steps completed mid-run, if any */
|
|
46
39
|
invokedToolIds;
|
|
47
40
|
handlerRegistry;
|
|
48
41
|
}
|
|
49
42
|
class StandardGraph extends Graph {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/** The last recorded timestamp that a stream API call was invoked */
|
|
54
|
-
lastStreamCall;
|
|
55
|
-
systemMessage;
|
|
43
|
+
overrideModel;
|
|
44
|
+
/** Optional compile options passed into workflow.compile() */
|
|
45
|
+
compileOptions;
|
|
56
46
|
messages = [];
|
|
57
47
|
runId;
|
|
58
|
-
tools;
|
|
59
|
-
toolMap;
|
|
60
48
|
startIndex = 0;
|
|
61
|
-
provider;
|
|
62
|
-
toolEnd;
|
|
63
49
|
signal;
|
|
64
|
-
|
|
50
|
+
/** Map of agent contexts by agent ID */
|
|
51
|
+
agentContexts = new Map();
|
|
52
|
+
/** Default agent ID to use */
|
|
53
|
+
defaultAgentId;
|
|
54
|
+
constructor({
|
|
55
|
+
// parent-level graph inputs
|
|
56
|
+
runId, signal, agents, tokenCounter, indexTokenCountMap, }) {
|
|
65
57
|
super();
|
|
66
58
|
this.runId = runId;
|
|
67
|
-
this.tools = tools;
|
|
68
59
|
this.signal = signal;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.provider = provider;
|
|
72
|
-
this.streamBuffer = streamBuffer;
|
|
73
|
-
this.clientOptions = clientOptions;
|
|
74
|
-
this.graphState = this.createGraphState();
|
|
75
|
-
this.boundModel = this.initializeModel();
|
|
76
|
-
if (reasoningKey) {
|
|
77
|
-
this.reasoningKey = reasoningKey;
|
|
60
|
+
if (agents.length === 0) {
|
|
61
|
+
throw new Error('At least one agent configuration is required');
|
|
78
62
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
finalInstructions != null && finalInstructions
|
|
83
|
-
? `${finalInstructions}\n\n${additional_instructions}`
|
|
84
|
-
: additional_instructions;
|
|
85
|
-
}
|
|
86
|
-
if (finalInstructions != null &&
|
|
87
|
-
finalInstructions &&
|
|
88
|
-
provider === _enum.Providers.ANTHROPIC &&
|
|
89
|
-
(clientOptions.clientOptions
|
|
90
|
-
?.defaultHeaders?.['anthropic-beta']?.includes('prompt-caching') ??
|
|
91
|
-
false)) {
|
|
92
|
-
finalInstructions = {
|
|
93
|
-
content: [
|
|
94
|
-
{
|
|
95
|
-
type: 'text',
|
|
96
|
-
text: instructions,
|
|
97
|
-
cache_control: { type: 'ephemeral' },
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
if (finalInstructions != null && finalInstructions !== '') {
|
|
103
|
-
this.systemMessage = new messages.SystemMessage(finalInstructions);
|
|
63
|
+
for (const agentConfig of agents) {
|
|
64
|
+
const agentContext = AgentContext.AgentContext.fromConfig(agentConfig, tokenCounter, indexTokenCountMap);
|
|
65
|
+
this.agentContexts.set(agentConfig.agentId, agentContext);
|
|
104
66
|
}
|
|
67
|
+
this.defaultAgentId = agents[0].agentId;
|
|
105
68
|
}
|
|
106
69
|
/* Init */
|
|
107
70
|
resetValues(keepContent) {
|
|
@@ -114,16 +77,12 @@ class StandardGraph extends Graph {
|
|
|
114
77
|
this.stepKeyIds = graph.resetIfNotEmpty(this.stepKeyIds, new Map());
|
|
115
78
|
this.toolCallStepIds = graph.resetIfNotEmpty(this.toolCallStepIds, new Map());
|
|
116
79
|
this.messageIdsByStepKey = graph.resetIfNotEmpty(this.messageIdsByStepKey, new Map());
|
|
117
|
-
this.messageStepHasToolCalls = graph.resetIfNotEmpty(this.
|
|
80
|
+
this.messageStepHasToolCalls = graph.resetIfNotEmpty(this.messageStepHasToolCalls, new Map());
|
|
118
81
|
this.prelimMessageIdsByStepKey = graph.resetIfNotEmpty(this.prelimMessageIdsByStepKey, new Map());
|
|
119
|
-
this.currentTokenType = graph.resetIfNotEmpty(this.currentTokenType, _enum.ContentTypes.TEXT);
|
|
120
|
-
this.lastToken = graph.resetIfNotEmpty(this.lastToken, undefined);
|
|
121
|
-
this.tokenTypeSwitch = graph.resetIfNotEmpty(this.tokenTypeSwitch, undefined);
|
|
122
|
-
this.indexTokenCountMap = graph.resetIfNotEmpty(this.indexTokenCountMap, {});
|
|
123
|
-
this.currentUsage = graph.resetIfNotEmpty(this.currentUsage, undefined);
|
|
124
|
-
this.tokenCounter = graph.resetIfNotEmpty(this.tokenCounter, undefined);
|
|
125
|
-
this.maxContextTokens = graph.resetIfNotEmpty(this.maxContextTokens, undefined);
|
|
126
82
|
this.invokedToolIds = graph.resetIfNotEmpty(this.invokedToolIds, undefined);
|
|
83
|
+
for (const context of this.agentContexts.values()) {
|
|
84
|
+
context.reset();
|
|
85
|
+
}
|
|
127
86
|
}
|
|
128
87
|
/* Run Step Processing */
|
|
129
88
|
getRunStep(stepId) {
|
|
@@ -133,6 +92,27 @@ class StandardGraph extends Graph {
|
|
|
133
92
|
}
|
|
134
93
|
return undefined;
|
|
135
94
|
}
|
|
95
|
+
getAgentContext(metadata) {
|
|
96
|
+
if (!metadata) {
|
|
97
|
+
throw new Error('No metadata provided to retrieve agent context');
|
|
98
|
+
}
|
|
99
|
+
const currentNode = metadata.langgraph_node;
|
|
100
|
+
if (!currentNode) {
|
|
101
|
+
throw new Error('No langgraph_node in metadata to retrieve agent context');
|
|
102
|
+
}
|
|
103
|
+
let agentId;
|
|
104
|
+
if (currentNode.startsWith(AGENT)) {
|
|
105
|
+
agentId = currentNode.substring(AGENT.length);
|
|
106
|
+
}
|
|
107
|
+
else if (currentNode.startsWith(TOOLS)) {
|
|
108
|
+
agentId = currentNode.substring(TOOLS.length);
|
|
109
|
+
}
|
|
110
|
+
const agentContext = this.agentContexts.get(agentId ?? '');
|
|
111
|
+
if (!agentContext) {
|
|
112
|
+
throw new Error(`No agent context found for agent ID ${agentId}`);
|
|
113
|
+
}
|
|
114
|
+
return agentContext;
|
|
115
|
+
}
|
|
136
116
|
getStepKey(metadata) {
|
|
137
117
|
if (!metadata)
|
|
138
118
|
return '';
|
|
@@ -178,11 +158,12 @@ class StandardGraph extends Graph {
|
|
|
178
158
|
metadata.langgraph_step,
|
|
179
159
|
metadata.checkpoint_ns,
|
|
180
160
|
];
|
|
181
|
-
|
|
182
|
-
|
|
161
|
+
const agentContext = this.getAgentContext(metadata);
|
|
162
|
+
if (agentContext.currentTokenType === _enum.ContentTypes.THINK ||
|
|
163
|
+
agentContext.currentTokenType === 'think_and_text') {
|
|
183
164
|
keyList.push('reasoning');
|
|
184
165
|
}
|
|
185
|
-
else if (
|
|
166
|
+
else if (agentContext.tokenTypeSwitch === 'content') {
|
|
186
167
|
keyList.push('post-reasoning');
|
|
187
168
|
}
|
|
188
169
|
if (this.invokedToolIds != null && this.invokedToolIds.size > 0) {
|
|
@@ -201,112 +182,158 @@ class StandardGraph extends Graph {
|
|
|
201
182
|
return core.convertMessagesToContent(this.messages.slice(this.startIndex));
|
|
202
183
|
}
|
|
203
184
|
/* Graph */
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
185
|
+
createSystemRunnable({ provider, clientOptions, instructions, additional_instructions, }) {
|
|
186
|
+
let finalInstructions = instructions;
|
|
187
|
+
if (additional_instructions != null && additional_instructions !== '') {
|
|
188
|
+
finalInstructions =
|
|
189
|
+
finalInstructions != null && finalInstructions
|
|
190
|
+
? `${finalInstructions}\n\n${additional_instructions}`
|
|
191
|
+
: additional_instructions;
|
|
192
|
+
}
|
|
193
|
+
if (finalInstructions != null &&
|
|
194
|
+
finalInstructions &&
|
|
195
|
+
provider === _enum.Providers.ANTHROPIC &&
|
|
196
|
+
(clientOptions.clientOptions
|
|
197
|
+
?.defaultHeaders?.['anthropic-beta']?.includes('prompt-caching') ??
|
|
198
|
+
false)) {
|
|
199
|
+
finalInstructions = {
|
|
200
|
+
content: [
|
|
201
|
+
{
|
|
202
|
+
type: 'text',
|
|
203
|
+
text: instructions,
|
|
204
|
+
cache_control: { type: 'ephemeral' },
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (finalInstructions != null && finalInstructions !== '') {
|
|
210
|
+
const systemMessage = new messages.SystemMessage(finalInstructions);
|
|
211
|
+
return runnables.RunnableLambda.from((messages) => {
|
|
212
|
+
return [systemMessage, ...messages];
|
|
213
|
+
}).withConfig({ runName: 'prompt' });
|
|
214
|
+
}
|
|
221
215
|
}
|
|
222
|
-
initializeTools() {
|
|
223
|
-
// return new ToolNode<t.BaseGraphState>(this.tools);
|
|
216
|
+
initializeTools({ currentTools, currentToolMap, }) {
|
|
224
217
|
return new ToolNode.ToolNode({
|
|
225
|
-
tools:
|
|
226
|
-
toolMap:
|
|
218
|
+
tools: currentTools ?? [],
|
|
219
|
+
toolMap: currentToolMap,
|
|
227
220
|
toolCallStepIds: this.toolCallStepIds,
|
|
228
221
|
errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata),
|
|
229
222
|
});
|
|
230
223
|
}
|
|
231
|
-
initializeModel() {
|
|
232
|
-
const ChatModelClass = providers.getChatModelClass(
|
|
233
|
-
const model = new ChatModelClass(
|
|
234
|
-
if (llm.isOpenAILike(
|
|
224
|
+
initializeModel({ provider, tools, clientOptions, }) {
|
|
225
|
+
const ChatModelClass = providers.getChatModelClass(provider);
|
|
226
|
+
const model = new ChatModelClass(clientOptions ?? {});
|
|
227
|
+
if (llm.isOpenAILike(provider) &&
|
|
235
228
|
(model instanceof index.ChatOpenAI || model instanceof index.AzureChatOpenAI)) {
|
|
236
|
-
model.temperature =
|
|
229
|
+
model.temperature = clientOptions
|
|
237
230
|
.temperature;
|
|
238
|
-
model.topP =
|
|
239
|
-
model.frequencyPenalty =
|
|
231
|
+
model.topP = clientOptions.topP;
|
|
232
|
+
model.frequencyPenalty = clientOptions
|
|
240
233
|
.frequencyPenalty;
|
|
241
|
-
model.presencePenalty =
|
|
234
|
+
model.presencePenalty = clientOptions
|
|
242
235
|
.presencePenalty;
|
|
243
|
-
model.n =
|
|
236
|
+
model.n = clientOptions.n;
|
|
244
237
|
}
|
|
245
|
-
else if (
|
|
238
|
+
else if (provider === _enum.Providers.VERTEXAI &&
|
|
246
239
|
model instanceof googleVertexai.ChatVertexAI) {
|
|
247
|
-
model.temperature =
|
|
240
|
+
model.temperature = clientOptions
|
|
248
241
|
.temperature;
|
|
249
|
-
model.topP =
|
|
250
|
-
|
|
251
|
-
model.
|
|
252
|
-
.topK;
|
|
253
|
-
model.topLogprobs = this.clientOptions
|
|
242
|
+
model.topP = clientOptions.topP;
|
|
243
|
+
model.topK = clientOptions.topK;
|
|
244
|
+
model.topLogprobs = clientOptions
|
|
254
245
|
.topLogprobs;
|
|
255
|
-
model.frequencyPenalty =
|
|
246
|
+
model.frequencyPenalty = clientOptions
|
|
256
247
|
.frequencyPenalty;
|
|
257
|
-
model.presencePenalty =
|
|
248
|
+
model.presencePenalty = clientOptions
|
|
258
249
|
.presencePenalty;
|
|
259
|
-
model.maxOutputTokens =
|
|
250
|
+
model.maxOutputTokens = clientOptions
|
|
260
251
|
.maxOutputTokens;
|
|
261
252
|
}
|
|
262
|
-
if (!
|
|
253
|
+
if (!tools || tools.length === 0) {
|
|
263
254
|
return model;
|
|
264
255
|
}
|
|
265
|
-
return model.bindTools(
|
|
256
|
+
return model.bindTools(tools);
|
|
266
257
|
}
|
|
267
258
|
overrideTestModel(responses, sleep, toolCalls) {
|
|
268
|
-
this.
|
|
259
|
+
this.overrideModel = fake.createFakeStreamingLLM({
|
|
269
260
|
responses,
|
|
270
261
|
sleep,
|
|
271
262
|
toolCalls,
|
|
272
263
|
});
|
|
273
264
|
}
|
|
274
|
-
getNewModel({ provider, clientOptions,
|
|
265
|
+
getNewModel({ provider, clientOptions, }) {
|
|
275
266
|
const ChatModelClass = providers.getChatModelClass(provider);
|
|
276
|
-
|
|
277
|
-
? Object.assign(Object.fromEntries(Object.entries(this.clientOptions).filter(([key]) => !omitOptions.has(key))), clientOptions)
|
|
278
|
-
: (clientOptions ?? this.clientOptions);
|
|
279
|
-
return new ChatModelClass(options);
|
|
267
|
+
return new ChatModelClass(clientOptions ?? {});
|
|
280
268
|
}
|
|
281
|
-
|
|
269
|
+
getUsageMetadata(finalMessage) {
|
|
282
270
|
if (finalMessage &&
|
|
283
271
|
'usage_metadata' in finalMessage &&
|
|
284
272
|
finalMessage.usage_metadata != null) {
|
|
285
|
-
|
|
273
|
+
return finalMessage.usage_metadata;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/** Execute model invocation with streaming support */
|
|
277
|
+
async attemptInvoke({ currentModel, finalMessages, provider, tools, }, config) {
|
|
278
|
+
const model = this.overrideModel ?? currentModel;
|
|
279
|
+
if (!model) {
|
|
280
|
+
throw new Error('No model found');
|
|
281
|
+
}
|
|
282
|
+
if ((tools?.length ?? 0) > 0 && providers.manualToolStreamProviders.has(provider)) {
|
|
283
|
+
if (!model.stream) {
|
|
284
|
+
throw new Error('Model does not support stream');
|
|
285
|
+
}
|
|
286
|
+
const stream$1 = await model.stream(finalMessages, config);
|
|
287
|
+
let finalChunk;
|
|
288
|
+
for await (const chunk of stream$1) {
|
|
289
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.CHAT_MODEL_STREAM, { chunk, emitted: true }, config);
|
|
290
|
+
finalChunk = finalChunk ? stream.concat(finalChunk, chunk) : chunk;
|
|
291
|
+
}
|
|
292
|
+
finalChunk = core.modifyDeltaProperties(provider, finalChunk);
|
|
293
|
+
return { messages: [finalChunk] };
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
const finalMessage = await model.invoke(finalMessages, config);
|
|
297
|
+
if ((finalMessage.tool_calls?.length ?? 0) > 0) {
|
|
298
|
+
finalMessage.tool_calls = finalMessage.tool_calls?.filter((tool_call) => !!tool_call.name);
|
|
299
|
+
}
|
|
300
|
+
return { messages: [finalMessage] };
|
|
286
301
|
}
|
|
287
302
|
}
|
|
288
|
-
cleanupSignalListener() {
|
|
303
|
+
cleanupSignalListener(currentModel) {
|
|
289
304
|
if (!this.signal) {
|
|
290
305
|
return;
|
|
291
306
|
}
|
|
292
|
-
|
|
307
|
+
const model = this.overrideModel ?? currentModel;
|
|
308
|
+
if (!model) {
|
|
293
309
|
return;
|
|
294
310
|
}
|
|
295
|
-
const client =
|
|
311
|
+
const client = model?.exposedClient;
|
|
296
312
|
if (!client?.abortHandler) {
|
|
297
313
|
return;
|
|
298
314
|
}
|
|
299
315
|
this.signal.removeEventListener('abort', client.abortHandler);
|
|
300
316
|
client.abortHandler = undefined;
|
|
301
317
|
}
|
|
302
|
-
createCallModel() {
|
|
318
|
+
createCallModel(agentId = 'default', currentModel) {
|
|
303
319
|
return async (state, config) => {
|
|
304
|
-
|
|
305
|
-
|
|
320
|
+
/**
|
|
321
|
+
* Get agent context - it must exist by this point
|
|
322
|
+
*/
|
|
323
|
+
const agentContext = this.agentContexts.get(agentId);
|
|
324
|
+
if (!agentContext) {
|
|
325
|
+
throw new Error(`Agent context not found for agentId: ${agentId}`);
|
|
326
|
+
}
|
|
327
|
+
const model = this.overrideModel ?? currentModel;
|
|
328
|
+
if (!model) {
|
|
306
329
|
throw new Error('No Graph model found');
|
|
307
330
|
}
|
|
308
|
-
if (!config
|
|
309
|
-
throw new Error(
|
|
331
|
+
if (!config) {
|
|
332
|
+
throw new Error('No config provided');
|
|
333
|
+
}
|
|
334
|
+
// Ensure token calculations are complete before proceeding
|
|
335
|
+
if (agentContext.tokenCalculationPromise) {
|
|
336
|
+
await agentContext.tokenCalculationPromise;
|
|
310
337
|
}
|
|
311
338
|
if (!config.signal) {
|
|
312
339
|
config.signal = this.signal;
|
|
@@ -314,120 +341,208 @@ class StandardGraph extends Graph {
|
|
|
314
341
|
this.config = config;
|
|
315
342
|
const { messages: messages$1 } = state;
|
|
316
343
|
let messagesToUse = messages$1;
|
|
317
|
-
if (!
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const isAnthropicWithThinking = (
|
|
322
|
-
|
|
344
|
+
if (!agentContext.pruneMessages &&
|
|
345
|
+
agentContext.tokenCounter &&
|
|
346
|
+
agentContext.maxContextTokens != null &&
|
|
347
|
+
agentContext.indexTokenCountMap[0] != null) {
|
|
348
|
+
const isAnthropicWithThinking = (agentContext.provider === _enum.Providers.ANTHROPIC &&
|
|
349
|
+
agentContext.clientOptions.thinking !=
|
|
323
350
|
null) ||
|
|
324
|
-
(
|
|
325
|
-
|
|
351
|
+
(agentContext.provider === _enum.Providers.BEDROCK &&
|
|
352
|
+
agentContext.clientOptions
|
|
326
353
|
.additionalModelRequestFields?.['thinking'] != null) ||
|
|
327
|
-
(
|
|
328
|
-
|
|
354
|
+
(agentContext.provider === _enum.Providers.OPENAI &&
|
|
355
|
+
agentContext.clientOptions.modelKwargs
|
|
329
356
|
?.thinking?.type === 'enabled');
|
|
330
|
-
|
|
331
|
-
provider: this.provider,
|
|
332
|
-
indexTokenCountMap: this.indexTokenCountMap,
|
|
333
|
-
maxTokens: this.maxContextTokens,
|
|
334
|
-
tokenCounter: this.tokenCounter,
|
|
357
|
+
agentContext.pruneMessages = prune.createPruneMessages({
|
|
335
358
|
startIndex: this.startIndex,
|
|
359
|
+
provider: agentContext.provider,
|
|
360
|
+
tokenCounter: agentContext.tokenCounter,
|
|
361
|
+
maxTokens: agentContext.maxContextTokens,
|
|
336
362
|
thinkingEnabled: isAnthropicWithThinking,
|
|
363
|
+
indexTokenCountMap: agentContext.indexTokenCountMap,
|
|
337
364
|
});
|
|
338
365
|
}
|
|
339
|
-
if (
|
|
340
|
-
const { context, indexTokenCountMap } =
|
|
366
|
+
if (agentContext.pruneMessages) {
|
|
367
|
+
const { context, indexTokenCountMap } = agentContext.pruneMessages({
|
|
341
368
|
messages: messages$1,
|
|
342
|
-
usageMetadata:
|
|
369
|
+
usageMetadata: agentContext.currentUsage,
|
|
343
370
|
// startOnMessageType: 'human',
|
|
344
371
|
});
|
|
345
|
-
|
|
372
|
+
agentContext.indexTokenCountMap = indexTokenCountMap;
|
|
346
373
|
messagesToUse = context;
|
|
347
374
|
}
|
|
348
|
-
|
|
375
|
+
let finalMessages = messagesToUse;
|
|
376
|
+
if (agentContext.useLegacyContent) {
|
|
377
|
+
finalMessages = content.formatContentStrings(finalMessages);
|
|
378
|
+
}
|
|
349
379
|
const lastMessageX = finalMessages.length >= 2
|
|
350
380
|
? finalMessages[finalMessages.length - 2]
|
|
351
381
|
: null;
|
|
352
382
|
const lastMessageY = finalMessages.length >= 1
|
|
353
383
|
? finalMessages[finalMessages.length - 1]
|
|
354
384
|
: null;
|
|
355
|
-
if (provider === _enum.Providers.BEDROCK &&
|
|
385
|
+
if (agentContext.provider === _enum.Providers.BEDROCK &&
|
|
356
386
|
lastMessageX instanceof messages.AIMessageChunk &&
|
|
357
387
|
lastMessageY instanceof messages.ToolMessage &&
|
|
358
388
|
typeof lastMessageX.content === 'string') {
|
|
359
389
|
finalMessages[finalMessages.length - 2].content = '';
|
|
360
390
|
}
|
|
361
391
|
const isLatestToolMessage = lastMessageY instanceof messages.ToolMessage;
|
|
362
|
-
if (isLatestToolMessage &&
|
|
392
|
+
if (isLatestToolMessage &&
|
|
393
|
+
agentContext.provider === _enum.Providers.ANTHROPIC) {
|
|
363
394
|
core.formatAnthropicArtifactContent(finalMessages);
|
|
364
395
|
}
|
|
365
396
|
else if (isLatestToolMessage &&
|
|
366
|
-
(llm.isOpenAILike(provider) ||
|
|
397
|
+
(llm.isOpenAILike(agentContext.provider) ||
|
|
398
|
+
llm.isGoogleLike(agentContext.provider))) {
|
|
367
399
|
core.formatArtifactPayload(finalMessages);
|
|
368
400
|
}
|
|
369
|
-
if (
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
401
|
+
if (agentContext.provider === _enum.Providers.ANTHROPIC) {
|
|
402
|
+
const anthropicOptions = agentContext.clientOptions;
|
|
403
|
+
const defaultHeaders = anthropicOptions?.clientOptions
|
|
404
|
+
?.defaultHeaders;
|
|
405
|
+
const anthropicBeta = defaultHeaders?.['anthropic-beta'];
|
|
406
|
+
if (typeof anthropicBeta === 'string' &&
|
|
407
|
+
anthropicBeta.includes('prompt-caching')) {
|
|
408
|
+
finalMessages = cache.addCacheControl(finalMessages);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
else if (agentContext.provider === _enum.Providers.BEDROCK) {
|
|
412
|
+
const bedrockOptions = agentContext.clientOptions;
|
|
413
|
+
if (bedrockOptions?.promptCache === true) {
|
|
414
|
+
finalMessages = cache.addBedrockCacheControl(finalMessages);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (agentContext.lastStreamCall != null &&
|
|
418
|
+
agentContext.streamBuffer != null) {
|
|
419
|
+
const timeSinceLastCall = Date.now() - agentContext.lastStreamCall;
|
|
420
|
+
if (timeSinceLastCall < agentContext.streamBuffer) {
|
|
421
|
+
const timeToWait = Math.ceil((agentContext.streamBuffer - timeSinceLastCall) / 1000) *
|
|
422
|
+
1000;
|
|
373
423
|
await run.sleep(timeToWait);
|
|
374
424
|
}
|
|
375
425
|
}
|
|
376
|
-
|
|
426
|
+
agentContext.lastStreamCall = Date.now();
|
|
377
427
|
let result;
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
428
|
+
const fallbacks = agentContext.clientOptions?.fallbacks ??
|
|
429
|
+
[];
|
|
430
|
+
if (finalMessages.length === 0) {
|
|
431
|
+
throw new Error(JSON.stringify({
|
|
432
|
+
type: 'empty_messages',
|
|
433
|
+
info: 'Message pruning removed all messages as none fit in the context window. Please increase the context window size or make your message shorter.',
|
|
434
|
+
}));
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
result = await this.attemptInvoke({
|
|
438
|
+
currentModel: model,
|
|
439
|
+
finalMessages,
|
|
440
|
+
provider: agentContext.provider,
|
|
441
|
+
tools: agentContext.tools,
|
|
442
|
+
}, config);
|
|
443
|
+
}
|
|
444
|
+
catch (primaryError) {
|
|
445
|
+
let lastError = primaryError;
|
|
446
|
+
for (const fb of fallbacks) {
|
|
447
|
+
try {
|
|
448
|
+
let model = this.getNewModel({
|
|
449
|
+
provider: fb.provider,
|
|
450
|
+
clientOptions: fb.clientOptions,
|
|
451
|
+
});
|
|
452
|
+
const bindableTools = agentContext.tools;
|
|
453
|
+
model = (!bindableTools || bindableTools.length === 0
|
|
454
|
+
? model
|
|
455
|
+
: model.bindTools(bindableTools));
|
|
456
|
+
result = await this.attemptInvoke({
|
|
457
|
+
currentModel: model,
|
|
458
|
+
finalMessages,
|
|
459
|
+
provider: fb.provider,
|
|
460
|
+
tools: agentContext.tools,
|
|
461
|
+
}, config);
|
|
462
|
+
lastError = undefined;
|
|
463
|
+
break;
|
|
386
464
|
}
|
|
387
|
-
|
|
388
|
-
|
|
465
|
+
catch (e) {
|
|
466
|
+
lastError = e;
|
|
467
|
+
continue;
|
|
389
468
|
}
|
|
390
469
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
else {
|
|
395
|
-
const finalMessage = (await this.boundModel.invoke(finalMessages, config));
|
|
396
|
-
if ((finalMessage.tool_calls?.length ?? 0) > 0) {
|
|
397
|
-
finalMessage.tool_calls = finalMessage.tool_calls?.filter((tool_call) => {
|
|
398
|
-
if (!tool_call.name) {
|
|
399
|
-
return false;
|
|
400
|
-
}
|
|
401
|
-
return true;
|
|
402
|
-
});
|
|
470
|
+
if (lastError !== undefined) {
|
|
471
|
+
throw lastError;
|
|
403
472
|
}
|
|
404
|
-
result = { messages: [finalMessage] };
|
|
405
473
|
}
|
|
406
|
-
|
|
474
|
+
if (!result) {
|
|
475
|
+
throw new Error('No result after model invocation');
|
|
476
|
+
}
|
|
477
|
+
agentContext.currentUsage = this.getUsageMetadata(result.messages?.[0]);
|
|
407
478
|
this.cleanupSignalListener();
|
|
408
479
|
return result;
|
|
409
480
|
};
|
|
410
481
|
}
|
|
411
|
-
|
|
482
|
+
createAgentNode(agentId) {
|
|
483
|
+
const agentContext = this.agentContexts.get(agentId);
|
|
484
|
+
if (!agentContext) {
|
|
485
|
+
throw new Error(`Agent context not found for agentId: ${agentId}`);
|
|
486
|
+
}
|
|
487
|
+
let currentModel = this.initializeModel({
|
|
488
|
+
tools: agentContext.tools,
|
|
489
|
+
provider: agentContext.provider,
|
|
490
|
+
clientOptions: agentContext.clientOptions,
|
|
491
|
+
});
|
|
492
|
+
if (agentContext.systemRunnable) {
|
|
493
|
+
currentModel = agentContext.systemRunnable.pipe(currentModel);
|
|
494
|
+
}
|
|
495
|
+
const agentNode = `${AGENT}${agentId}`;
|
|
496
|
+
const toolNode = `${TOOLS}${agentId}`;
|
|
412
497
|
const routeMessage = (state, config) => {
|
|
413
498
|
this.config = config;
|
|
414
|
-
return ToolNode.toolsCondition(state, this.invokedToolIds);
|
|
499
|
+
return ToolNode.toolsCondition(state, toolNode, this.invokedToolIds);
|
|
415
500
|
};
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
.
|
|
424
|
-
|
|
501
|
+
const StateAnnotation = langgraph.Annotation.Root({
|
|
502
|
+
messages: langgraph.Annotation({
|
|
503
|
+
reducer: langgraph.messagesStateReducer,
|
|
504
|
+
default: () => [],
|
|
505
|
+
}),
|
|
506
|
+
});
|
|
507
|
+
const workflow = new langgraph.StateGraph(StateAnnotation)
|
|
508
|
+
.addNode(agentNode, this.createCallModel(agentId, currentModel))
|
|
509
|
+
.addNode(toolNode, this.initializeTools({
|
|
510
|
+
currentTools: agentContext.tools,
|
|
511
|
+
currentToolMap: agentContext.toolMap,
|
|
512
|
+
}))
|
|
513
|
+
.addEdge(langgraph.START, agentNode)
|
|
514
|
+
.addConditionalEdges(agentNode, routeMessage)
|
|
515
|
+
.addEdge(toolNode, agentContext.toolEnd ? langgraph.END : agentNode);
|
|
516
|
+
// Cast to unknown to avoid tight coupling to external types; options are opt-in
|
|
517
|
+
return workflow.compile(this.compileOptions);
|
|
518
|
+
}
|
|
519
|
+
createWorkflow() {
|
|
520
|
+
/** Use the default (first) agent for now */
|
|
521
|
+
const agentNode = this.createAgentNode(this.defaultAgentId);
|
|
522
|
+
const StateAnnotation = langgraph.Annotation.Root({
|
|
523
|
+
messages: langgraph.Annotation({
|
|
524
|
+
reducer: (a, b) => {
|
|
525
|
+
if (!a.length) {
|
|
526
|
+
this.startIndex = a.length + b.length;
|
|
527
|
+
}
|
|
528
|
+
const result = langgraph.messagesStateReducer(a, b);
|
|
529
|
+
this.messages = result;
|
|
530
|
+
return result;
|
|
531
|
+
},
|
|
532
|
+
default: () => [],
|
|
533
|
+
}),
|
|
534
|
+
});
|
|
535
|
+
const workflow = new langgraph.StateGraph(StateAnnotation)
|
|
536
|
+
.addNode(this.defaultAgentId, agentNode, { ends: [langgraph.END] })
|
|
537
|
+
.addEdge(langgraph.START, this.defaultAgentId)
|
|
538
|
+
.compile();
|
|
539
|
+
return workflow;
|
|
425
540
|
}
|
|
426
541
|
/* Dispatchers */
|
|
427
542
|
/**
|
|
428
543
|
* Dispatches a run step to the client, returns the step ID
|
|
429
544
|
*/
|
|
430
|
-
dispatchRunStep(stepKey, stepDetails) {
|
|
545
|
+
async dispatchRunStep(stepKey, stepDetails) {
|
|
431
546
|
if (!this.config) {
|
|
432
547
|
throw new Error('No config provided');
|
|
433
548
|
}
|
|
@@ -455,17 +570,21 @@ class StandardGraph extends Graph {
|
|
|
455
570
|
}
|
|
456
571
|
this.contentData.push(runStep);
|
|
457
572
|
this.contentIndexMap.set(stepId, runStep.index);
|
|
458
|
-
|
|
573
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP, runStep, this.config);
|
|
459
574
|
return stepId;
|
|
460
575
|
}
|
|
461
|
-
handleToolCallCompleted(data, metadata, omitOutput) {
|
|
576
|
+
async handleToolCallCompleted(data, metadata, omitOutput) {
|
|
462
577
|
if (!this.config) {
|
|
463
578
|
throw new Error('No config provided');
|
|
464
579
|
}
|
|
465
580
|
if (!data.output) {
|
|
466
581
|
return;
|
|
467
582
|
}
|
|
468
|
-
const { input, output } = data;
|
|
583
|
+
const { input, output: _output } = data;
|
|
584
|
+
if (_output?.lg_name === 'Command') {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
const output = _output;
|
|
469
588
|
const { tool_call_id } = output;
|
|
470
589
|
const stepId = this.toolCallStepIds.get(tool_call_id) ?? '';
|
|
471
590
|
if (!stepId) {
|
|
@@ -486,7 +605,9 @@ class StandardGraph extends Graph {
|
|
|
486
605
|
output: omitOutput === true ? '' : dispatchedOutput,
|
|
487
606
|
progress: 1,
|
|
488
607
|
};
|
|
489
|
-
this.handlerRegistry
|
|
608
|
+
await this.handlerRegistry
|
|
609
|
+
?.getHandler(_enum.GraphEvents.ON_RUN_STEP_COMPLETED)
|
|
610
|
+
?.handle(_enum.GraphEvents.ON_RUN_STEP_COMPLETED, {
|
|
490
611
|
result: {
|
|
491
612
|
id: stepId,
|
|
492
613
|
index: runStep.index,
|
|
@@ -499,7 +620,7 @@ class StandardGraph extends Graph {
|
|
|
499
620
|
* Static version of handleToolCallError to avoid creating strong references
|
|
500
621
|
* that prevent garbage collection
|
|
501
622
|
*/
|
|
502
|
-
static handleToolCallErrorStatic(graph, data, metadata) {
|
|
623
|
+
static async handleToolCallErrorStatic(graph, data, metadata) {
|
|
503
624
|
if (!graph.config) {
|
|
504
625
|
throw new Error('No config provided');
|
|
505
626
|
}
|
|
@@ -523,7 +644,7 @@ class StandardGraph extends Graph {
|
|
|
523
644
|
output: `Error processing tool${error?.message != null ? `: ${error.message}` : ''}`,
|
|
524
645
|
progress: 1,
|
|
525
646
|
};
|
|
526
|
-
graph.handlerRegistry
|
|
647
|
+
await graph.handlerRegistry
|
|
527
648
|
?.getHandler(_enum.GraphEvents.ON_RUN_STEP_COMPLETED)
|
|
528
649
|
?.handle(_enum.GraphEvents.ON_RUN_STEP_COMPLETED, {
|
|
529
650
|
result: {
|
|
@@ -538,10 +659,10 @@ class StandardGraph extends Graph {
|
|
|
538
659
|
* Instance method that delegates to the static method
|
|
539
660
|
* Kept for backward compatibility
|
|
540
661
|
*/
|
|
541
|
-
handleToolCallError(data, metadata) {
|
|
542
|
-
StandardGraph.handleToolCallErrorStatic(this, data, metadata);
|
|
662
|
+
async handleToolCallError(data, metadata) {
|
|
663
|
+
await StandardGraph.handleToolCallErrorStatic(this, data, metadata);
|
|
543
664
|
}
|
|
544
|
-
dispatchRunStepDelta(id, delta) {
|
|
665
|
+
async dispatchRunStepDelta(id, delta) {
|
|
545
666
|
if (!this.config) {
|
|
546
667
|
throw new Error('No config provided');
|
|
547
668
|
}
|
|
@@ -552,9 +673,9 @@ class StandardGraph extends Graph {
|
|
|
552
673
|
id,
|
|
553
674
|
delta,
|
|
554
675
|
};
|
|
555
|
-
|
|
676
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP_DELTA, runStepDelta, this.config);
|
|
556
677
|
}
|
|
557
|
-
dispatchMessageDelta(id, delta) {
|
|
678
|
+
async dispatchMessageDelta(id, delta) {
|
|
558
679
|
if (!this.config) {
|
|
559
680
|
throw new Error('No config provided');
|
|
560
681
|
}
|
|
@@ -562,9 +683,9 @@ class StandardGraph extends Graph {
|
|
|
562
683
|
id,
|
|
563
684
|
delta,
|
|
564
685
|
};
|
|
565
|
-
|
|
686
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_MESSAGE_DELTA, messageDelta, this.config);
|
|
566
687
|
}
|
|
567
|
-
dispatchReasoningDelta = (stepId, delta) => {
|
|
688
|
+
dispatchReasoningDelta = async (stepId, delta) => {
|
|
568
689
|
if (!this.config) {
|
|
569
690
|
throw new Error('No config provided');
|
|
570
691
|
}
|
|
@@ -572,7 +693,7 @@ class StandardGraph extends Graph {
|
|
|
572
693
|
id: stepId,
|
|
573
694
|
delta,
|
|
574
695
|
};
|
|
575
|
-
|
|
696
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_REASONING_DELTA, reasoningDelta, this.config);
|
|
576
697
|
};
|
|
577
698
|
}
|
|
578
699
|
|