@librechat/agents 3.1.86 → 3.1.88
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/README.md +69 -0
- package/dist/cjs/events.cjs +23 -0
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +133 -18
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/index.cjs +251 -53
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +1 -5
- package/dist/cjs/llm/init.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +113 -24
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +3 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +18 -5
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/openai/index.cjs +253 -0
- package/dist/cjs/openai/index.cjs.map +1 -0
- package/dist/cjs/responses/index.cjs +448 -0
- package/dist/cjs/responses/index.cjs.map +1 -0
- package/dist/cjs/run.cjs +108 -7
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/AgentSession.cjs +1057 -0
- package/dist/cjs/session/AgentSession.cjs.map +1 -0
- package/dist/cjs/session/JsonlSessionStore.cjs +425 -0
- package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -0
- package/dist/cjs/session/handlers.cjs +221 -0
- package/dist/cjs/session/handlers.cjs.map +1 -0
- package/dist/cjs/session/ids.cjs +22 -0
- package/dist/cjs/session/ids.cjs.map +1 -0
- package/dist/cjs/session/messageSerialization.cjs +179 -0
- package/dist/cjs/session/messageSerialization.cjs.map +1 -0
- package/dist/cjs/stream.cjs +475 -11
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +1 -1
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +177 -59
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/eagerEventExecution.cjs +113 -0
- package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -0
- package/dist/cjs/tools/handlers.cjs +1 -1
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/tools/streamedToolCallSeals.cjs +42 -0
- package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -0
- package/dist/esm/events.mjs +23 -1
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +133 -18
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/llm/anthropic/index.mjs +251 -53
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +1 -5
- package/dist/esm/llm/init.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +113 -25
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +4 -2
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/main.mjs +5 -1
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/openai/index.mjs +246 -0
- package/dist/esm/openai/index.mjs.map +1 -0
- package/dist/esm/responses/index.mjs +440 -0
- package/dist/esm/responses/index.mjs.map +1 -0
- package/dist/esm/run.mjs +108 -7
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/AgentSession.mjs +1054 -0
- package/dist/esm/session/AgentSession.mjs.map +1 -0
- package/dist/esm/session/JsonlSessionStore.mjs +422 -0
- package/dist/esm/session/JsonlSessionStore.mjs.map +1 -0
- package/dist/esm/session/handlers.mjs +219 -0
- package/dist/esm/session/handlers.mjs.map +1 -0
- package/dist/esm/session/ids.mjs +17 -0
- package/dist/esm/session/ids.mjs.map +1 -0
- package/dist/esm/session/messageSerialization.mjs +173 -0
- package/dist/esm/session/messageSerialization.mjs.map +1 -0
- package/dist/esm/stream.mjs +476 -12
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +1 -1
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +177 -59
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/eagerEventExecution.mjs +107 -0
- package/dist/esm/tools/eagerEventExecution.mjs.map +1 -0
- package/dist/esm/tools/handlers.mjs +1 -1
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/tools/streamedToolCallSeals.mjs +36 -0
- package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -0
- package/dist/types/events.d.ts +1 -0
- package/dist/types/graphs/Graph.d.ts +24 -9
- package/dist/types/index.d.ts +1 -0
- package/dist/types/llm/openai/index.d.ts +1 -0
- package/dist/types/openai/index.d.ts +75 -0
- package/dist/types/responses/index.d.ts +97 -0
- package/dist/types/run.d.ts +2 -0
- package/dist/types/session/AgentSession.d.ts +32 -0
- package/dist/types/session/JsonlSessionStore.d.ts +67 -0
- package/dist/types/session/handlers.d.ts +8 -0
- package/dist/types/session/ids.d.ts +4 -0
- package/dist/types/session/index.d.ts +5 -0
- package/dist/types/session/messageSerialization.d.ts +7 -0
- package/dist/types/session/types.d.ts +191 -0
- package/dist/types/tools/ToolNode.d.ts +12 -1
- package/dist/types/tools/eagerEventExecution.d.ts +23 -0
- package/dist/types/tools/streamedToolCallSeals.d.ts +13 -0
- package/dist/types/types/hitl.d.ts +4 -0
- package/dist/types/types/run.d.ts +11 -1
- package/dist/types/types/tools.d.ts +36 -0
- package/package.json +19 -2
- package/src/__tests__/stream.eagerEventExecution.test.ts +2571 -0
- package/src/events.ts +29 -0
- package/src/graphs/Graph.ts +224 -50
- package/src/graphs/MultiAgentGraph.ts +1 -1
- package/src/graphs/__tests__/composition.smoke.test.ts +30 -0
- package/src/index.ts +3 -0
- package/src/llm/anthropic/index.ts +356 -84
- package/src/llm/anthropic/llm.spec.ts +64 -0
- package/src/llm/custom-chat-models.smoke.test.ts +175 -4
- package/src/llm/openai/contentBlocks.test.ts +35 -0
- package/src/llm/openai/deepseek.test.ts +201 -2
- package/src/llm/openai/index.ts +171 -26
- package/src/llm/openai/utils/index.ts +22 -0
- package/src/llm/openrouter/index.ts +4 -2
- package/src/openai/__tests__/openai.test.ts +337 -0
- package/src/openai/index.ts +404 -0
- package/src/responses/__tests__/responses.test.ts +652 -0
- package/src/responses/index.ts +677 -0
- package/src/run.ts +158 -8
- package/src/scripts/compare_pi_vs_ours.ts +592 -173
- package/src/scripts/session_live.ts +548 -0
- package/src/session/AgentSession.ts +1432 -0
- package/src/session/JsonlSessionStore.ts +572 -0
- package/src/session/__tests__/JsonlSessionStore.test.ts +1410 -0
- package/src/session/__tests__/handlers.test.ts +161 -0
- package/src/session/handlers.ts +272 -0
- package/src/session/ids.ts +17 -0
- package/src/session/index.ts +44 -0
- package/src/session/messageSerialization.ts +207 -0
- package/src/session/types.ts +275 -0
- package/src/specs/custom-event-await.test.ts +89 -0
- package/src/specs/summarization.test.ts +1 -1
- package/src/stream.ts +756 -48
- package/src/summarization/node.ts +1 -1
- package/src/tools/ToolNode.ts +299 -126
- package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +373 -0
- package/src/tools/__tests__/handlers.test.ts +2 -1
- package/src/tools/__tests__/hitl.test.ts +206 -110
- package/src/tools/eagerEventExecution.ts +153 -0
- package/src/tools/handlers.ts +8 -4
- package/src/tools/streamedToolCallSeals.ts +57 -0
- package/src/types/hitl.ts +4 -0
- package/src/types/run.ts +11 -0
- package/src/types/tools.ts +36 -0
- package/dist/cjs/llm/text.cjs +0 -69
- package/dist/cjs/llm/text.cjs.map +0 -1
- package/dist/esm/llm/text.mjs +0 -67
- package/dist/esm/llm/text.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -46,6 +46,75 @@ const content = await run.processStream(
|
|
|
46
46
|
);
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
## Programmatic Sessions
|
|
50
|
+
|
|
51
|
+
For scripts, CI, and programmatic integrations, use the session facade. It
|
|
52
|
+
keeps a JSONL session tree by default, so runs can be resumed, cloned, forked,
|
|
53
|
+
branched in place, compacted, and inspected later.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { Providers, createAgentSession } from '@librechat/agents';
|
|
57
|
+
|
|
58
|
+
const session = await createAgentSession({
|
|
59
|
+
checkpointing: true,
|
|
60
|
+
graphConfig: {
|
|
61
|
+
type: 'standard',
|
|
62
|
+
instructions: 'You are a concise coding assistant.',
|
|
63
|
+
llmConfig: {
|
|
64
|
+
provider: Providers.OPENAI,
|
|
65
|
+
model: 'gpt-4o-mini',
|
|
66
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const result = await session.run('Summarize this repository.');
|
|
72
|
+
console.log(result.text);
|
|
73
|
+
console.log(session.sessionPath); // durable .jsonl session file
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
When `checkpointing` is enabled, the session injects a shared LangGraph
|
|
77
|
+
checkpointer into `compileOptions`, records checkpoint IDs in JSONL, and uses
|
|
78
|
+
checkpoint state for later turns on the same `thread_id`. When HITL is enabled
|
|
79
|
+
(`humanInTheLoop: { enabled: true }`), sessions also get a `MemorySaver` by
|
|
80
|
+
default so `resumeInterrupt()` can reuse the same saver instead of relying on a
|
|
81
|
+
per-run fallback. JSONL still owns portable replay, clone, fork, and audit
|
|
82
|
+
records.
|
|
83
|
+
|
|
84
|
+
Sessions expose tree operations inspired by Pi-style workflows:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const store = session.getSessionStore();
|
|
88
|
+
const forkPoint = store?.getForkPoints()[0];
|
|
89
|
+
|
|
90
|
+
if (forkPoint) {
|
|
91
|
+
const forked = await session.fork(forkPoint.id, { position: 'before' });
|
|
92
|
+
await forked.run('Try a different approach from here.');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const cloned = await session.clone();
|
|
96
|
+
await cloned.compact({ instructions: 'Keep only implementation decisions.' });
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`session.stream()` projects the SDK's existing graph events, and
|
|
100
|
+
`session.compact()` uses the same summarization node, hooks, and provider
|
|
101
|
+
logic as normal runs. JSONL is the durable journal; the graph remains the
|
|
102
|
+
execution engine.
|
|
103
|
+
|
|
104
|
+
OpenAI-compatible streaming helpers are available as experimental subpaths:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { composeEventHandlers } from '@librechat/agents';
|
|
108
|
+
import { createOpenAIHandlers } from '@librechat/agents/openai';
|
|
109
|
+
import { createResponsesEventHandlers } from '@librechat/agents/responses';
|
|
110
|
+
|
|
111
|
+
const customHandlers = composeEventHandlers(
|
|
112
|
+
createOpenAIHandlers(openAIConfig),
|
|
113
|
+
createResponsesEventHandlers(responsesConfig),
|
|
114
|
+
hostHandlers
|
|
115
|
+
);
|
|
116
|
+
```
|
|
117
|
+
|
|
49
118
|
## Development
|
|
50
119
|
|
|
51
120
|
```bash
|
package/dist/cjs/events.cjs
CHANGED
|
@@ -11,6 +11,28 @@ class HandlerRegistry {
|
|
|
11
11
|
return this.handlers.get(eventType);
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
function composeEventHandlers(...handlerSets) {
|
|
15
|
+
const composed = {};
|
|
16
|
+
for (const handlerSet of handlerSets) {
|
|
17
|
+
if (!handlerSet) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
for (const [eventType, handler] of Object.entries(handlerSet)) {
|
|
21
|
+
const previous = composed[eventType];
|
|
22
|
+
if (previous === undefined) {
|
|
23
|
+
composed[eventType] = handler;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
composed[eventType] = {
|
|
27
|
+
handle: async (...args) => {
|
|
28
|
+
await previous.handle(...args);
|
|
29
|
+
await handler.handle(...args);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return composed;
|
|
35
|
+
}
|
|
14
36
|
class ModelEndHandler {
|
|
15
37
|
collectedUsage;
|
|
16
38
|
constructor(collectedUsage) {
|
|
@@ -154,5 +176,6 @@ exports.ModelEndHandler = ModelEndHandler;
|
|
|
154
176
|
exports.TestChatStreamHandler = TestChatStreamHandler;
|
|
155
177
|
exports.TestLLMStreamHandler = TestLLMStreamHandler;
|
|
156
178
|
exports.ToolEndHandler = ToolEndHandler;
|
|
179
|
+
exports.composeEventHandlers = composeEventHandlers;
|
|
157
180
|
exports.createMetadataAggregator = createMetadataAggregator;
|
|
158
181
|
//# sourceMappingURL=events.cjs.map
|
package/dist/cjs/events.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.cjs","sources":["../../src/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/events.ts\nimport type {\n BaseMessageFields,\n UsageMetadata,\n} from '@langchain/core/messages';\nimport type { MultiAgentGraph, StandardGraph } from '@/graphs';\nimport type { Logger } from 'winston';\nimport type * as t from '@/types';\nimport { Constants } from '@/common';\n\nexport class HandlerRegistry {\n private handlers: Map<string, t.EventHandler> = new Map();\n\n register(eventType: string, handler: t.EventHandler): void {\n this.handlers.set(eventType, handler);\n }\n\n getHandler(eventType: string): t.EventHandler | undefined {\n return this.handlers.get(eventType);\n }\n}\n\nexport class ModelEndHandler implements t.EventHandler {\n collectedUsage?: UsageMetadata[];\n constructor(collectedUsage?: UsageMetadata[]) {\n if (collectedUsage && !Array.isArray(collectedUsage)) {\n throw new Error('collectedUsage must be an array');\n }\n this.collectedUsage = collectedUsage;\n }\n\n async handle(\n event: string,\n data: t.ModelEndData,\n metadata?: Record<string, unknown>,\n graph?: StandardGraph | MultiAgentGraph\n ): Promise<void> {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n const usage = data?.output?.usage_metadata;\n if (usage != null && this.collectedUsage != null) {\n this.collectedUsage.push(usage);\n }\n }\n}\n\nexport class ToolEndHandler implements t.EventHandler {\n private callback?: t.ToolEndCallback;\n private logger?: Logger;\n constructor(callback?: t.ToolEndCallback, logger?: Logger) {\n this.callback = callback;\n this.logger = logger;\n }\n\n /**\n * Handles on_tool_end events from the for-await stream consumer.\n *\n * This handler is now purely a consumer callback — tool completion\n * (ON_RUN_STEP_COMPLETED dispatch + session context storage) is handled\n * in graph context by ToolNode directly, eliminating the race between\n * the stream consumer and graph execution.\n */\n async handle(\n event: string,\n data: t.StreamEventData | undefined,\n metadata?: Record<string, unknown>,\n graph?: StandardGraph | MultiAgentGraph\n ): Promise<void> {\n try {\n if (!graph || !metadata) {\n if (this.logger) {\n this.logger.warn(`Graph or metadata not found in ${event} event`);\n } else {\n console.warn(`Graph or metadata not found in ${event} event`);\n }\n return;\n }\n\n const toolEndData = data as t.ToolEndData | undefined;\n if (!toolEndData?.output) {\n if (this.logger) {\n this.logger.warn('No output found in tool_end event');\n } else {\n console.warn('No output found in tool_end event');\n }\n return;\n }\n\n if (\n metadata[Constants.PROGRAMMATIC_TOOL_CALLING] === true ||\n metadata[Constants.BASH_PROGRAMMATIC_TOOL_CALLING] === true\n ) {\n return;\n }\n\n if (this.callback) {\n await this.callback(toolEndData, metadata);\n }\n } catch (error) {\n if (this.logger) {\n this.logger.error('Error handling tool_end event:', error);\n } else {\n console.error('Error handling tool_end event:', error);\n }\n }\n }\n}\n\nexport class TestLLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk ? chunk.message : undefined;\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n}\n\nexport class TestChatStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isContentChunk = !!(chunk && 'content' in chunk);\n if (!isContentChunk) {\n return;\n }\n\n const content = chunk.content;\n\n if (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) {\n console.dir(chunk.tool_call_chunks, { depth: null });\n }\n\n if (typeof content === 'string') {\n process.stdout.write(content);\n } else {\n console.dir(content, { depth: null });\n }\n }\n}\n\nexport class LLMStreamHandler implements t.EventHandler {\n handle(\n event: string,\n data: t.StreamEventData | undefined,\n metadata?: Record<string, unknown>\n ): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk ? chunk.message : undefined;\n if (metadata) {\n console.log(metadata);\n }\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n}\n\nexport const createMetadataAggregator = (\n _collected?: Record<\n string,\n NonNullable<BaseMessageFields['response_metadata']>\n >[]\n): t.MetadataAggregatorResult => {\n const collected = _collected || [];\n\n const handleLLMEnd: t.HandleLLMEnd = (output) => {\n const { generations } = output;\n const lastMessageOutput = (\n generations[generations.length - 1] as\n | (t.StreamGeneration | undefined)[]\n | undefined\n )?.[0];\n if (!lastMessageOutput) {\n return;\n }\n const { message } = lastMessageOutput;\n if (message?.response_metadata) {\n collected.push(message.response_metadata);\n }\n };\n\n return { handleLLMEnd, collected };\n};\n"],"names":["Constants"],"mappings":";;;;MAWa,eAAe,CAAA;AAClB,IAAA,QAAQ,GAAgC,IAAI,GAAG,EAAE;IAEzD,QAAQ,CAAC,SAAiB,EAAE,OAAuB,EAAA;QACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC;IACvC;AAEA,IAAA,UAAU,CAAC,SAAiB,EAAA;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;IACrC;AACD;MAEY,eAAe,CAAA;AAC1B,IAAA,cAAc;AACd,IAAA,WAAA,CAAY,cAAgC,EAAA;QAC1C,IAAI,cAAc,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE;AACpD,YAAA,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC;QACpD;AACA,QAAA,IAAI,CAAC,cAAc,GAAG,cAAc;IACtC;IAEA,MAAM,MAAM,CACV,KAAa,EACb,IAAoB,EACpB,QAAkC,EAClC,KAAuC,EAAA;AAEvC,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE;AACvB,YAAA,OAAO,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAA,MAAA,CAAQ,CAAC;YAC7D;QACF;AAEA,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,MAAM,EAAE,cAAc;QAC1C,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE;AAChD,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QACjC;IACF;AACD;MAEY,cAAc,CAAA;AACjB,IAAA,QAAQ;AACR,IAAA,MAAM;IACd,WAAA,CAAY,QAA4B,EAAE,MAAe,EAAA;AACvD,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;AACxB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;IACtB;AAEA;;;;;;;AAOG;IACH,MAAM,MAAM,CACV,KAAa,EACb,IAAmC,EACnC,QAAkC,EAClC,KAAuC,EAAA;AAEvC,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE;AACvB,gBAAA,IAAI,IAAI,CAAC,MAAM,EAAE;oBACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,+BAAA,EAAkC,KAAK,CAAA,MAAA,CAAQ,CAAC;gBACnE;qBAAO;AACL,oBAAA,OAAO,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAA,MAAA,CAAQ,CAAC;gBAC/D;gBACA;YACF;YAEA,MAAM,WAAW,GAAG,IAAiC;AACrD,YAAA,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AACxB,gBAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,oBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC;gBACvD;qBAAO;AACL,oBAAA,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC;gBACnD;gBACA;YACF;AAEA,YAAA,IACE,QAAQ,CAACA,eAAS,CAAC,yBAAyB,CAAC,KAAK,IAAI;gBACtD,QAAQ,CAACA,eAAS,CAAC,8BAA8B,CAAC,KAAK,IAAI,EAC3D;gBACA;YACF;AAEA,YAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACjB,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC;YAC5C;QACF;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,IAAI,CAAC,MAAM,EAAE;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC;YAC5D;iBAAO;AACL,gBAAA,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC;YACxD;QACF;IACF;AACD;MAEY,oBAAoB,CAAA;IAC/B,MAAM,CAAC,KAAa,EAAE,IAAmC,EAAA;AACvD,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK;QACzB,MAAM,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC;AACtD,QAAA,MAAM,GAAG,GAAG,cAAc,GAAG,KAAK,CAAC,OAAO,GAAG,SAAS;AACtD,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAClE,YAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACnC;aAAO,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE;YACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;QACnC;IACF;AACD;MAEY,qBAAqB,CAAA;IAChC,MAAM,CAAC,KAAa,EAAE,IAAmC,EAAA;AACvD,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK;QACzB,MAAM,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC;QACtD,IAAI,CAAC,cAAc,EAAE;YACnB;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;AAE7B,QAAA,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAC/D,YAAA,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACtD;AAEA,QAAA,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;AAC/B,YAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;QAC/B;aAAO;YACL,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACvC;IACF;AACD;MAEY,gBAAgB,CAAA;AAC3B,IAAA,MAAM,CACJ,KAAa,EACb,IAAmC,EACnC,QAAkC,EAAA;AAElC,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK;QACzB,MAAM,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC;AACtD,QAAA,MAAM,GAAG,GAAG,cAAc,GAAG,KAAK,CAAC,OAAO,GAAG,SAAS;QACtD,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QACvB;AACA,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAClE,YAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACnC;aAAO,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE;YACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;QACnC;IACF;AACD;AAEM,MAAM,wBAAwB,GAAG,CACtC,UAGG,KAC2B;AAC9B,IAAA,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE;AAElC,IAAA,MAAM,YAAY,GAAmB,CAAC,MAAM,KAAI;AAC9C,QAAA,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM;AAC9B,QAAA,MAAM,iBAAiB,GACrB,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAGnC,GAAG,CAAC,CAAC;QACN,IAAI,CAAC,iBAAiB,EAAE;YACtB;QACF;AACA,QAAA,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB;AACrC,QAAA,IAAI,OAAO,EAAE,iBAAiB,EAAE;AAC9B,YAAA,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC;QAC3C;AACF,IAAA,CAAC;AAED,IAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE;AACpC;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"events.cjs","sources":["../../src/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/events.ts\nimport type {\n BaseMessageFields,\n UsageMetadata,\n} from '@langchain/core/messages';\nimport type { MultiAgentGraph, StandardGraph } from '@/graphs';\nimport type { Logger } from 'winston';\nimport type * as t from '@/types';\nimport { Constants } from '@/common';\n\nexport class HandlerRegistry {\n private handlers: Map<string, t.EventHandler> = new Map();\n\n register(eventType: string, handler: t.EventHandler): void {\n this.handlers.set(eventType, handler);\n }\n\n getHandler(eventType: string): t.EventHandler | undefined {\n return this.handlers.get(eventType);\n }\n}\n\nexport function composeEventHandlers(\n ...handlerSets: Array<Record<string, t.EventHandler> | undefined>\n): Record<string, t.EventHandler> {\n const composed: Partial<Record<string, t.EventHandler>> = {};\n\n for (const handlerSet of handlerSets) {\n if (!handlerSet) {\n continue;\n }\n for (const [eventType, handler] of Object.entries(handlerSet)) {\n const previous = composed[eventType];\n if (previous === undefined) {\n composed[eventType] = handler;\n continue;\n }\n composed[eventType] = {\n handle: async (\n ...args: Parameters<t.EventHandler['handle']>\n ): Promise<void> => {\n await previous.handle(...args);\n await handler.handle(...args);\n },\n };\n }\n }\n\n return composed as Record<string, t.EventHandler>;\n}\n\nexport class ModelEndHandler implements t.EventHandler {\n collectedUsage?: UsageMetadata[];\n constructor(collectedUsage?: UsageMetadata[]) {\n if (collectedUsage && !Array.isArray(collectedUsage)) {\n throw new Error('collectedUsage must be an array');\n }\n this.collectedUsage = collectedUsage;\n }\n\n async handle(\n event: string,\n data: t.ModelEndData,\n metadata?: Record<string, unknown>,\n graph?: StandardGraph | MultiAgentGraph\n ): Promise<void> {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n const usage = data?.output?.usage_metadata;\n if (usage != null && this.collectedUsage != null) {\n this.collectedUsage.push(usage);\n }\n }\n}\n\nexport class ToolEndHandler implements t.EventHandler {\n private callback?: t.ToolEndCallback;\n private logger?: Logger;\n constructor(callback?: t.ToolEndCallback, logger?: Logger) {\n this.callback = callback;\n this.logger = logger;\n }\n\n /**\n * Handles on_tool_end events from the for-await stream consumer.\n *\n * This handler is now purely a consumer callback — tool completion\n * (ON_RUN_STEP_COMPLETED dispatch + session context storage) is handled\n * in graph context by ToolNode directly, eliminating the race between\n * the stream consumer and graph execution.\n */\n async handle(\n event: string,\n data: t.StreamEventData | undefined,\n metadata?: Record<string, unknown>,\n graph?: StandardGraph | MultiAgentGraph\n ): Promise<void> {\n try {\n if (!graph || !metadata) {\n if (this.logger) {\n this.logger.warn(`Graph or metadata not found in ${event} event`);\n } else {\n console.warn(`Graph or metadata not found in ${event} event`);\n }\n return;\n }\n\n const toolEndData = data as t.ToolEndData | undefined;\n if (!toolEndData?.output) {\n if (this.logger) {\n this.logger.warn('No output found in tool_end event');\n } else {\n console.warn('No output found in tool_end event');\n }\n return;\n }\n\n if (\n metadata[Constants.PROGRAMMATIC_TOOL_CALLING] === true ||\n metadata[Constants.BASH_PROGRAMMATIC_TOOL_CALLING] === true\n ) {\n return;\n }\n\n if (this.callback) {\n await this.callback(toolEndData, metadata);\n }\n } catch (error) {\n if (this.logger) {\n this.logger.error('Error handling tool_end event:', error);\n } else {\n console.error('Error handling tool_end event:', error);\n }\n }\n }\n}\n\nexport class TestLLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk ? chunk.message : undefined;\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n}\n\nexport class TestChatStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isContentChunk = !!(chunk && 'content' in chunk);\n if (!isContentChunk) {\n return;\n }\n\n const content = chunk.content;\n\n if (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) {\n console.dir(chunk.tool_call_chunks, { depth: null });\n }\n\n if (typeof content === 'string') {\n process.stdout.write(content);\n } else {\n console.dir(content, { depth: null });\n }\n }\n}\n\nexport class LLMStreamHandler implements t.EventHandler {\n handle(\n event: string,\n data: t.StreamEventData | undefined,\n metadata?: Record<string, unknown>\n ): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk ? chunk.message : undefined;\n if (metadata) {\n console.log(metadata);\n }\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n}\n\nexport const createMetadataAggregator = (\n _collected?: Record<\n string,\n NonNullable<BaseMessageFields['response_metadata']>\n >[]\n): t.MetadataAggregatorResult => {\n const collected = _collected || [];\n\n const handleLLMEnd: t.HandleLLMEnd = (output) => {\n const { generations } = output;\n const lastMessageOutput = (\n generations[generations.length - 1] as\n | (t.StreamGeneration | undefined)[]\n | undefined\n )?.[0];\n if (!lastMessageOutput) {\n return;\n }\n const { message } = lastMessageOutput;\n if (message?.response_metadata) {\n collected.push(message.response_metadata);\n }\n };\n\n return { handleLLMEnd, collected };\n};\n"],"names":["Constants"],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ var reducer = require('../messages/reducer.cjs');
|
|
|
16
16
|
var _enum = require('../common/enum.cjs');
|
|
17
17
|
var graph = require('../utils/graph.cjs');
|
|
18
18
|
var llm = require('../utils/llm.cjs');
|
|
19
|
-
|
|
19
|
+
require('../stream.cjs');
|
|
20
20
|
var run = require('../utils/run.cjs');
|
|
21
21
|
require('ai-tokenizer');
|
|
22
22
|
require('zod-to-json-schema');
|
|
@@ -31,6 +31,7 @@ var node = require('../summarization/node.cjs');
|
|
|
31
31
|
var schema = require('../tools/schema.cjs');
|
|
32
32
|
var AgentContext = require('../agents/AgentContext.cjs');
|
|
33
33
|
var fake = require('../llm/fake.cjs');
|
|
34
|
+
var handlers = require('../tools/handlers.cjs');
|
|
34
35
|
require('../tools/local/CompileCheckTool.cjs');
|
|
35
36
|
require('path');
|
|
36
37
|
require('fs/promises');
|
|
@@ -53,6 +54,9 @@ var toolCache = require('../llm/openrouter/toolCache.cjs');
|
|
|
53
54
|
const { AGENT, TOOLS, SUMMARIZE } = _enum.GraphNodeKeys;
|
|
54
55
|
/** Minimum relative variance before calibrated toolSchemaTokens overrides current value. */
|
|
55
56
|
const CALIBRATION_VARIANCE_THRESHOLD = 0.15;
|
|
57
|
+
function getHandlerDispatchedEventKey(eventName, stepId) {
|
|
58
|
+
return `${eventName}:${stepId}`;
|
|
59
|
+
}
|
|
56
60
|
class Graph {
|
|
57
61
|
messageStepHasToolCalls = new Map();
|
|
58
62
|
messageIdsByStepKey = new Map();
|
|
@@ -63,11 +67,12 @@ class Graph {
|
|
|
63
67
|
contentIndexMap = new Map();
|
|
64
68
|
toolCallStepIds = new Map();
|
|
65
69
|
/**
|
|
66
|
-
* Step IDs
|
|
67
|
-
*
|
|
68
|
-
*
|
|
70
|
+
* Step IDs dispatched through the handler registry during this run.
|
|
71
|
+
* Event echo suppression is tracked separately so repeated deltas for
|
|
72
|
+
* the same step are scoped to the active custom event dispatch.
|
|
69
73
|
*/
|
|
70
74
|
handlerDispatchedStepIds = new Set();
|
|
75
|
+
handlerDispatchedEventCounts = new Map();
|
|
71
76
|
signal;
|
|
72
77
|
/** Set of invoked tool call IDs from non-message run steps completed mid-run, if any */
|
|
73
78
|
invokedToolIds;
|
|
@@ -86,6 +91,16 @@ class Graph {
|
|
|
86
91
|
* graph compiles.
|
|
87
92
|
*/
|
|
88
93
|
toolOutputReferences;
|
|
94
|
+
/**
|
|
95
|
+
* Run-scoped opt-in for eager event-driven tool execution. The stream
|
|
96
|
+
* handler may prestart eligible event-driven tools; ToolNode later
|
|
97
|
+
* consumes the settled promises while preserving final ToolMessage order.
|
|
98
|
+
*/
|
|
99
|
+
eagerEventToolExecution;
|
|
100
|
+
eagerEventToolExecutions = new Map();
|
|
101
|
+
eagerEventToolUsageCount = new Map();
|
|
102
|
+
eagerEventToolUsageCountsByAgentId = new Map();
|
|
103
|
+
eagerEventToolCallChunks = new Map();
|
|
89
104
|
/**
|
|
90
105
|
* Run-scoped execution backend for built-in code tools. Defaults to the
|
|
91
106
|
* remote Code API sandbox when unset.
|
|
@@ -124,7 +139,12 @@ class Graph {
|
|
|
124
139
|
this.hookRegistry = undefined;
|
|
125
140
|
this.humanInTheLoop = undefined;
|
|
126
141
|
this.toolOutputReferences = undefined;
|
|
142
|
+
this.eagerEventToolExecution = undefined;
|
|
143
|
+
this.eagerEventToolExecutions.clear();
|
|
144
|
+
this.clearEagerEventToolUsageCounts();
|
|
145
|
+
this.eagerEventToolCallChunks.clear();
|
|
127
146
|
this.toolExecution = undefined;
|
|
147
|
+
this.handlerDispatchedEventCounts.clear();
|
|
128
148
|
/**
|
|
129
149
|
* ToolNodes compiled from this graph captured the registry
|
|
130
150
|
* instance at construction time, so simply dropping the Graph's
|
|
@@ -154,6 +174,39 @@ class Graph {
|
|
|
154
174
|
this._compiledToolNodes.clear();
|
|
155
175
|
this.sessions.clear();
|
|
156
176
|
}
|
|
177
|
+
getEagerEventToolUsageCount(agentId) {
|
|
178
|
+
if (agentId == null || agentId === '') {
|
|
179
|
+
return this.eagerEventToolUsageCount;
|
|
180
|
+
}
|
|
181
|
+
let usageCount = this.eagerEventToolUsageCountsByAgentId.get(agentId);
|
|
182
|
+
if (usageCount == null) {
|
|
183
|
+
usageCount = new Map();
|
|
184
|
+
this.eagerEventToolUsageCountsByAgentId.set(agentId, usageCount);
|
|
185
|
+
}
|
|
186
|
+
return usageCount;
|
|
187
|
+
}
|
|
188
|
+
clearEagerEventToolUsageCounts() {
|
|
189
|
+
this.eagerEventToolUsageCount.clear();
|
|
190
|
+
for (const usageCount of this.eagerEventToolUsageCountsByAgentId.values()) {
|
|
191
|
+
usageCount.clear();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
markHandlerDispatchedEvent(eventName, stepId) {
|
|
195
|
+
const key = getHandlerDispatchedEventKey(eventName, stepId);
|
|
196
|
+
this.handlerDispatchedEventCounts.set(key, (this.handlerDispatchedEventCounts.get(key) ?? 0) + 1);
|
|
197
|
+
return () => {
|
|
198
|
+
const count = this.handlerDispatchedEventCounts.get(key) ?? 0;
|
|
199
|
+
if (count <= 1) {
|
|
200
|
+
this.handlerDispatchedEventCounts.delete(key);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
this.handlerDispatchedEventCounts.set(key, count - 1);
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
hasHandlerDispatchedEvent(eventName, stepId) {
|
|
207
|
+
const key = getHandlerDispatchedEventKey(eventName, stepId);
|
|
208
|
+
return (this.handlerDispatchedEventCounts.get(key) ?? 0) > 0;
|
|
209
|
+
}
|
|
157
210
|
/**
|
|
158
211
|
* Subclass hook to register a freshly compiled ToolNode so
|
|
159
212
|
* `clearHeavyState` can flush its per-Run direct-path turn cache
|
|
@@ -284,7 +337,11 @@ class StandardGraph extends Graph {
|
|
|
284
337
|
* a stale reference on 2nd+ processStream calls.
|
|
285
338
|
*/
|
|
286
339
|
this.toolCallStepIds.clear();
|
|
340
|
+
this.eagerEventToolExecutions.clear();
|
|
341
|
+
this.clearEagerEventToolUsageCounts();
|
|
342
|
+
this.eagerEventToolCallChunks.clear();
|
|
287
343
|
this.handlerDispatchedStepIds = graph.resetIfNotEmpty(this.handlerDispatchedStepIds, new Set());
|
|
344
|
+
this.handlerDispatchedEventCounts = graph.resetIfNotEmpty(this.handlerDispatchedEventCounts, new Map());
|
|
288
345
|
this.messageIdsByStepKey = graph.resetIfNotEmpty(this.messageIdsByStepKey, new Map());
|
|
289
346
|
this.messageStepHasToolCalls = graph.resetIfNotEmpty(this.messageStepHasToolCalls, new Map());
|
|
290
347
|
this.prelimMessageIdsByStepKey = graph.resetIfNotEmpty(this.prelimMessageIdsByStepKey, new Map());
|
|
@@ -508,6 +565,9 @@ class StandardGraph extends Graph {
|
|
|
508
565
|
toolRegistry: agentContext?.toolRegistry,
|
|
509
566
|
hookRegistry: this.hookRegistry,
|
|
510
567
|
humanInTheLoop: this.humanInTheLoop,
|
|
568
|
+
eagerEventToolExecution: this.eagerEventToolExecution,
|
|
569
|
+
eagerEventToolExecutions: this.eagerEventToolExecutions,
|
|
570
|
+
eagerEventToolUsageCount: this.getEagerEventToolUsageCount(agentContext?.agentId),
|
|
511
571
|
toolExecution: this.toolExecution,
|
|
512
572
|
directToolNames: directToolNames.size > 0 ? directToolNames : undefined,
|
|
513
573
|
maxContextTokens: agentContext?.maxContextTokens,
|
|
@@ -958,7 +1018,7 @@ class StandardGraph extends Graph {
|
|
|
958
1018
|
if (typeof content === 'string') {
|
|
959
1019
|
await this.dispatchMessageDelta(stepId, {
|
|
960
1020
|
content: [{ type: _enum.ContentTypes.TEXT, text: content }],
|
|
961
|
-
});
|
|
1021
|
+
}, metadata);
|
|
962
1022
|
}
|
|
963
1023
|
else if (Array.isArray(content) &&
|
|
964
1024
|
content.every((c) => typeof c === 'object' &&
|
|
@@ -967,7 +1027,7 @@ class StandardGraph extends Graph {
|
|
|
967
1027
|
c.type.startsWith('text'))) {
|
|
968
1028
|
await this.dispatchMessageDelta(stepId, {
|
|
969
1029
|
content: content,
|
|
970
|
-
});
|
|
1030
|
+
}, metadata);
|
|
971
1031
|
}
|
|
972
1032
|
}
|
|
973
1033
|
}
|
|
@@ -997,7 +1057,7 @@ class StandardGraph extends Graph {
|
|
|
997
1057
|
if (typeof content === 'string') {
|
|
998
1058
|
await this.dispatchMessageDelta(stepId, {
|
|
999
1059
|
content: [{ type: _enum.ContentTypes.TEXT, text: content }],
|
|
1000
|
-
});
|
|
1060
|
+
}, metadata);
|
|
1001
1061
|
}
|
|
1002
1062
|
else if (Array.isArray(content) &&
|
|
1003
1063
|
content.every((c) => typeof c === 'object' &&
|
|
@@ -1006,7 +1066,7 @@ class StandardGraph extends Graph {
|
|
|
1006
1066
|
c.type.startsWith('text'))) {
|
|
1007
1067
|
await this.dispatchMessageDelta(stepId, {
|
|
1008
1068
|
content: content,
|
|
1009
|
-
});
|
|
1069
|
+
}, metadata);
|
|
1010
1070
|
}
|
|
1011
1071
|
}
|
|
1012
1072
|
}
|
|
@@ -1176,8 +1236,16 @@ class StandardGraph extends Graph {
|
|
|
1176
1236
|
await handler.handle(_enum.GraphEvents.ON_RUN_STEP, runStep, resolvedConfig?.configurable, this);
|
|
1177
1237
|
this.handlerDispatchedStepIds.add(runStep.id);
|
|
1178
1238
|
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1239
|
+
const unmarkHandlerDispatchedEvent = handler
|
|
1240
|
+
? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_RUN_STEP, runStep.id)
|
|
1241
|
+
: undefined;
|
|
1242
|
+
try {
|
|
1243
|
+
if (resolvedConfig) {
|
|
1244
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP, runStep, resolvedConfig);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
finally {
|
|
1248
|
+
unmarkHandlerDispatchedEvent?.();
|
|
1181
1249
|
}
|
|
1182
1250
|
},
|
|
1183
1251
|
dispatchRunStepCompleted: async (stepId, result, nodeConfig) => {
|
|
@@ -1208,7 +1276,7 @@ class StandardGraph extends Graph {
|
|
|
1208
1276
|
const StateAnnotation = langgraph.Annotation.Root({
|
|
1209
1277
|
messages: langgraph.Annotation({
|
|
1210
1278
|
reducer: (a, b) => {
|
|
1211
|
-
if (!
|
|
1279
|
+
if (!this.messages.length) {
|
|
1212
1280
|
this.startIndex = a.length + b.length;
|
|
1213
1281
|
}
|
|
1214
1282
|
const result = reducer.messagesStateReducer(a, b);
|
|
@@ -1305,7 +1373,15 @@ class StandardGraph extends Graph {
|
|
|
1305
1373
|
// but the primary dispatch above guarantees the event reaches the handler.
|
|
1306
1374
|
// The customEventCallback in run.ts skips events already dispatched above
|
|
1307
1375
|
// to prevent double handling.
|
|
1308
|
-
|
|
1376
|
+
const unmarkHandlerDispatchedEvent = handler
|
|
1377
|
+
? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_RUN_STEP, stepId)
|
|
1378
|
+
: undefined;
|
|
1379
|
+
try {
|
|
1380
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP, runStep, this.config);
|
|
1381
|
+
}
|
|
1382
|
+
finally {
|
|
1383
|
+
unmarkHandlerDispatchedEvent?.();
|
|
1384
|
+
}
|
|
1309
1385
|
return stepId;
|
|
1310
1386
|
}
|
|
1311
1387
|
/**
|
|
@@ -1354,7 +1430,7 @@ class StandardGraph extends Graph {
|
|
|
1354
1430
|
async handleToolCallError(data, metadata) {
|
|
1355
1431
|
await StandardGraph.handleToolCallErrorStatic(this, data, metadata);
|
|
1356
1432
|
}
|
|
1357
|
-
async dispatchRunStepDelta(id, delta) {
|
|
1433
|
+
async dispatchRunStepDelta(id, delta, metadata) {
|
|
1358
1434
|
if (!this.config) {
|
|
1359
1435
|
throw new Error('No config provided');
|
|
1360
1436
|
}
|
|
@@ -1365,9 +1441,22 @@ class StandardGraph extends Graph {
|
|
|
1365
1441
|
id,
|
|
1366
1442
|
delta,
|
|
1367
1443
|
};
|
|
1368
|
-
|
|
1444
|
+
const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_RUN_STEP_DELTA);
|
|
1445
|
+
if (handler) {
|
|
1446
|
+
await handler.handle(_enum.GraphEvents.ON_RUN_STEP_DELTA, runStepDelta, metadata, this);
|
|
1447
|
+
this.handlerDispatchedStepIds.add(id);
|
|
1448
|
+
}
|
|
1449
|
+
const unmarkHandlerDispatchedEvent = handler
|
|
1450
|
+
? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_RUN_STEP_DELTA, id)
|
|
1451
|
+
: undefined;
|
|
1452
|
+
try {
|
|
1453
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP_DELTA, runStepDelta, this.config);
|
|
1454
|
+
}
|
|
1455
|
+
finally {
|
|
1456
|
+
unmarkHandlerDispatchedEvent?.();
|
|
1457
|
+
}
|
|
1369
1458
|
}
|
|
1370
|
-
async dispatchMessageDelta(id, delta) {
|
|
1459
|
+
async dispatchMessageDelta(id, delta, metadata) {
|
|
1371
1460
|
if (!this.config) {
|
|
1372
1461
|
throw new Error('No config provided');
|
|
1373
1462
|
}
|
|
@@ -1375,9 +1464,22 @@ class StandardGraph extends Graph {
|
|
|
1375
1464
|
id,
|
|
1376
1465
|
delta,
|
|
1377
1466
|
};
|
|
1378
|
-
|
|
1467
|
+
const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_MESSAGE_DELTA);
|
|
1468
|
+
if (handler) {
|
|
1469
|
+
await handler.handle(_enum.GraphEvents.ON_MESSAGE_DELTA, messageDelta, metadata, this);
|
|
1470
|
+
this.handlerDispatchedStepIds.add(id);
|
|
1471
|
+
}
|
|
1472
|
+
const unmarkHandlerDispatchedEvent = handler
|
|
1473
|
+
? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_MESSAGE_DELTA, id)
|
|
1474
|
+
: undefined;
|
|
1475
|
+
try {
|
|
1476
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_MESSAGE_DELTA, messageDelta, this.config);
|
|
1477
|
+
}
|
|
1478
|
+
finally {
|
|
1479
|
+
unmarkHandlerDispatchedEvent?.();
|
|
1480
|
+
}
|
|
1379
1481
|
}
|
|
1380
|
-
dispatchReasoningDelta = async (stepId, delta) => {
|
|
1482
|
+
dispatchReasoningDelta = async (stepId, delta, metadata) => {
|
|
1381
1483
|
if (!this.config) {
|
|
1382
1484
|
throw new Error('No config provided');
|
|
1383
1485
|
}
|
|
@@ -1385,7 +1487,20 @@ class StandardGraph extends Graph {
|
|
|
1385
1487
|
id: stepId,
|
|
1386
1488
|
delta,
|
|
1387
1489
|
};
|
|
1388
|
-
|
|
1490
|
+
const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_REASONING_DELTA);
|
|
1491
|
+
if (handler) {
|
|
1492
|
+
await handler.handle(_enum.GraphEvents.ON_REASONING_DELTA, reasoningDelta, metadata, this);
|
|
1493
|
+
this.handlerDispatchedStepIds.add(stepId);
|
|
1494
|
+
}
|
|
1495
|
+
const unmarkHandlerDispatchedEvent = handler
|
|
1496
|
+
? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_REASONING_DELTA, stepId)
|
|
1497
|
+
: undefined;
|
|
1498
|
+
try {
|
|
1499
|
+
await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_REASONING_DELTA, reasoningDelta, this.config);
|
|
1500
|
+
}
|
|
1501
|
+
finally {
|
|
1502
|
+
unmarkHandlerDispatchedEvent?.();
|
|
1503
|
+
}
|
|
1389
1504
|
};
|
|
1390
1505
|
}
|
|
1391
1506
|
|