@librechat/agents 3.0.0-rc8 → 3.0.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 +6 -2
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +23 -2
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +108 -17
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +21 -0
- package/dist/cjs/instrumentation.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/index.cjs +21 -2
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs +3 -0
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +13 -0
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/ollama/index.cjs +3 -0
- package/dist/cjs/llm/ollama/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +18 -3
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +6 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +5 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +1 -1
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +8 -2
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +49 -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/core.cjs +5 -1
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +50 -59
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +28 -0
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +57 -5
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +7 -0
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +2 -0
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs +3 -1
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs +8 -6
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +5 -5
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/serper-scraper.cjs +132 -0
- package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +46 -9
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/utils/handlers.cjs +70 -0
- package/dist/cjs/utils/handlers.cjs.map +1 -0
- package/dist/cjs/utils/misc.cjs +8 -1
- package/dist/cjs/utils/misc.cjs.map +1 -1
- package/dist/cjs/utils/title.cjs +54 -25
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +6 -2
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +23 -2
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +108 -17
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +19 -0
- package/dist/esm/instrumentation.mjs.map +1 -0
- package/dist/esm/llm/anthropic/index.mjs +21 -2
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +3 -0
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +13 -0
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/ollama/index.mjs +3 -0
- package/dist/esm/llm/ollama/index.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +18 -3
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +6 -1
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +5 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +1 -1
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +5 -2
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +47 -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/core.mjs +5 -1
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +50 -58
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +28 -0
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +57 -5
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +7 -0
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +2 -0
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs +3 -1
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs +8 -6
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +5 -5
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/serper-scraper.mjs +129 -0
- package/dist/esm/tools/search/serper-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +46 -9
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/utils/handlers.mjs +68 -0
- package/dist/esm/utils/handlers.mjs.map +1 -0
- package/dist/esm/utils/misc.mjs +8 -2
- package/dist/esm/utils/misc.mjs.map +1 -1
- package/dist/esm/utils/title.mjs +54 -25
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +4 -1
- package/dist/types/graphs/MultiAgentGraph.d.ts +11 -1
- package/dist/types/llm/anthropic/index.d.ts +3 -0
- package/dist/types/llm/google/index.d.ts +1 -0
- package/dist/types/llm/ollama/index.d.ts +1 -0
- package/dist/types/llm/openai/index.d.ts +4 -0
- package/dist/types/llm/openrouter/index.d.ts +4 -2
- package/dist/types/llm/vertexai/index.d.ts +1 -1
- package/dist/types/messages/cache.d.ts +8 -0
- package/dist/types/messages/content.d.ts +7 -0
- package/dist/types/messages/format.d.ts +22 -25
- package/dist/types/messages/index.d.ts +2 -0
- package/dist/types/run.d.ts +2 -1
- package/dist/types/tools/search/firecrawl.d.ts +2 -1
- package/dist/types/tools/search/rerankers.d.ts +4 -1
- package/dist/types/tools/search/search.d.ts +1 -2
- package/dist/types/tools/search/serper-scraper.d.ts +59 -0
- package/dist/types/tools/search/tool.d.ts +25 -4
- package/dist/types/tools/search/types.d.ts +31 -1
- package/dist/types/types/graph.d.ts +3 -1
- package/dist/types/types/messages.d.ts +4 -0
- package/dist/types/utils/handlers.d.ts +34 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/misc.d.ts +1 -0
- package/package.json +8 -2
- package/src/agents/AgentContext.ts +8 -0
- package/src/graphs/Graph.ts +31 -2
- package/src/graphs/MultiAgentGraph.ts +125 -18
- package/src/instrumentation.ts +22 -0
- package/src/llm/anthropic/index.ts +23 -2
- package/src/llm/anthropic/llm.spec.ts +1 -1
- package/src/llm/google/index.ts +4 -0
- package/src/llm/google/utils/common.ts +14 -0
- package/src/llm/ollama/index.ts +3 -0
- package/src/llm/openai/index.ts +17 -4
- package/src/llm/openai/utils/index.ts +7 -1
- package/src/llm/openrouter/index.ts +15 -6
- package/src/llm/vertexai/index.ts +2 -2
- package/src/messages/cache.test.ts +262 -0
- package/src/messages/cache.ts +56 -0
- package/src/messages/content.test.ts +362 -0
- package/src/messages/content.ts +63 -0
- package/src/messages/core.ts +5 -2
- package/src/messages/format.ts +65 -71
- package/src/messages/formatMessage.test.ts +418 -2
- package/src/messages/index.ts +2 -0
- package/src/messages/prune.ts +51 -0
- package/src/run.ts +82 -10
- package/src/scripts/ant_web_search.ts +1 -1
- package/src/scripts/handoff-test.ts +1 -1
- package/src/scripts/multi-agent-chain.ts +278 -0
- package/src/scripts/multi-agent-conditional.ts +4 -4
- 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 +10 -8
- package/src/scripts/multi-agent-sequence.ts +3 -3
- package/src/scripts/multi-agent-supervisor.ts +5 -3
- package/src/scripts/multi-agent-test.ts +2 -2
- package/src/scripts/search.ts +5 -1
- package/src/scripts/simple.ts +8 -0
- package/src/scripts/test-custom-prompt-key.ts +4 -4
- package/src/scripts/test-handoff-input.ts +3 -3
- package/src/scripts/test-multi-agent-list-handoff.ts +2 -2
- package/src/scripts/tools.ts +4 -1
- package/src/specs/agent-handoffs.test.ts +889 -0
- package/src/stream.ts +9 -2
- package/src/tools/search/firecrawl.ts +5 -2
- package/src/tools/search/jina-reranker.test.ts +126 -0
- package/src/tools/search/rerankers.ts +11 -5
- package/src/tools/search/search.ts +6 -8
- package/src/tools/search/serper-scraper.ts +155 -0
- package/src/tools/search/tool.ts +49 -8
- package/src/tools/search/types.ts +46 -0
- package/src/types/graph.ts +6 -1
- package/src/types/messages.ts +4 -0
- package/src/utils/handlers.ts +107 -0
- package/src/utils/index.ts +2 -1
- package/src/utils/llmConfig.ts +35 -1
- package/src/utils/misc.ts +33 -21
- package/src/utils/title.ts +80 -40
- 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/handoff-test.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/multi-agent-conditional.d.ts +0 -1
- package/dist/types/scripts/multi-agent-parallel.d.ts +0 -1
- package/dist/types/scripts/multi-agent-sequence.d.ts +0 -1
- package/dist/types/scripts/multi-agent-supervisor.d.ts +0 -1
- package/dist/types/scripts/multi-agent-test.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/test-custom-prompt-key.d.ts +0 -2
- package/dist/types/scripts/test-handoff-input.d.ts +0 -1
- package/dist/types/scripts/test-multi-agent-list-handoff.d.ts +0 -2
- package/dist/types/scripts/test-tools-before-handoff.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/src/scripts/multi-agent-example-output.md +0 -110
- /package/dist/types/{scripts/abort.d.ts → instrumentation.d.ts} +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent Handler Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides a simple helper to create handlers with content aggregation for multi-agent scripts.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const { contentParts, aggregateContent, handlers } = createHandlers();
|
|
9
|
+
*
|
|
10
|
+
* // With callbacks
|
|
11
|
+
* const { contentParts, aggregateContent, handlers } = createHandlers({
|
|
12
|
+
* onRunStep: (event, data) => console.log('Step:', data),
|
|
13
|
+
* onRunStepCompleted: (event, data) => console.log('Completed:', data)
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { GraphEvents } from '@/common';
|
|
19
|
+
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
20
|
+
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
21
|
+
import type * as t from '@/types';
|
|
22
|
+
|
|
23
|
+
interface HandlerCallbacks {
|
|
24
|
+
onRunStep?: (event: GraphEvents.ON_RUN_STEP, data: t.StreamEventData) => void;
|
|
25
|
+
onRunStepCompleted?: (
|
|
26
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
27
|
+
data: t.StreamEventData
|
|
28
|
+
) => void;
|
|
29
|
+
onRunStepDelta?: (
|
|
30
|
+
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
31
|
+
data: t.StreamEventData
|
|
32
|
+
) => void;
|
|
33
|
+
onMessageDelta?: (
|
|
34
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
35
|
+
data: t.StreamEventData
|
|
36
|
+
) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Creates handlers with content aggregation for multi-agent scripts
|
|
41
|
+
*/
|
|
42
|
+
export function createHandlers(callbacks?: HandlerCallbacks): {
|
|
43
|
+
contentParts: Array<t.MessageContentComplex | undefined>;
|
|
44
|
+
aggregateContent: ReturnType<
|
|
45
|
+
typeof createContentAggregator
|
|
46
|
+
>['aggregateContent'];
|
|
47
|
+
handlers: Record<string, t.EventHandler>;
|
|
48
|
+
} {
|
|
49
|
+
// Set up content aggregator
|
|
50
|
+
const { contentParts, aggregateContent } = createContentAggregator();
|
|
51
|
+
|
|
52
|
+
// Create the handlers object
|
|
53
|
+
const handlers = {
|
|
54
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
55
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
56
|
+
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
57
|
+
|
|
58
|
+
[GraphEvents.ON_RUN_STEP]: {
|
|
59
|
+
handle: (
|
|
60
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
61
|
+
data: t.StreamEventData
|
|
62
|
+
): void => {
|
|
63
|
+
aggregateContent({ event, data: data as t.RunStep });
|
|
64
|
+
callbacks?.onRunStep?.(event, data);
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
69
|
+
handle: (
|
|
70
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
71
|
+
data: t.StreamEventData
|
|
72
|
+
): void => {
|
|
73
|
+
aggregateContent({
|
|
74
|
+
event,
|
|
75
|
+
data: data as unknown as { result: t.ToolEndEvent },
|
|
76
|
+
});
|
|
77
|
+
callbacks?.onRunStepCompleted?.(event, data);
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
82
|
+
handle: (
|
|
83
|
+
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
84
|
+
data: t.StreamEventData
|
|
85
|
+
): void => {
|
|
86
|
+
aggregateContent({ event, data: data as t.RunStepDeltaEvent });
|
|
87
|
+
callbacks?.onRunStepDelta?.(event, data);
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
92
|
+
handle: (
|
|
93
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
94
|
+
data: t.StreamEventData
|
|
95
|
+
): void => {
|
|
96
|
+
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
97
|
+
callbacks?.onMessageDelta?.(event, data);
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
contentParts,
|
|
104
|
+
aggregateContent,
|
|
105
|
+
handlers,
|
|
106
|
+
};
|
|
107
|
+
}
|
package/src/utils/index.ts
CHANGED
package/src/utils/llmConfig.ts
CHANGED
|
@@ -12,6 +12,30 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
|
|
|
12
12
|
streamUsage: true,
|
|
13
13
|
// disableStreaming: true,
|
|
14
14
|
},
|
|
15
|
+
anthropicLITELLM: {
|
|
16
|
+
provider: Providers.OPENAI,
|
|
17
|
+
streaming: true,
|
|
18
|
+
streamUsage: false,
|
|
19
|
+
apiKey: 'sk-1234',
|
|
20
|
+
model: 'claude-sonnet-4',
|
|
21
|
+
maxTokens: 8192,
|
|
22
|
+
modelKwargs: {
|
|
23
|
+
metadata: {
|
|
24
|
+
user_id: 'some_user_id',
|
|
25
|
+
},
|
|
26
|
+
thinking: {
|
|
27
|
+
type: 'enabled',
|
|
28
|
+
budget_tokens: 2000,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
configuration: {
|
|
32
|
+
baseURL: 'http://host.docker.internal:4000/v1',
|
|
33
|
+
defaultHeaders: {
|
|
34
|
+
'anthropic-beta': 'prompt-caching-2024-07-31,context-1m-2025-08-07',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
// disableStreaming: true,
|
|
38
|
+
},
|
|
15
39
|
[Providers.XAI]: {
|
|
16
40
|
provider: Providers.XAI,
|
|
17
41
|
model: 'grok-2-latest',
|
|
@@ -70,6 +94,16 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
|
|
|
70
94
|
baseURL: 'http://192.168.254.183:1233/v1',
|
|
71
95
|
},
|
|
72
96
|
},
|
|
97
|
+
zhipu: {
|
|
98
|
+
provider: Providers.OPENAI,
|
|
99
|
+
streaming: true,
|
|
100
|
+
streamUsage: false,
|
|
101
|
+
model: 'glm-4.5-air',
|
|
102
|
+
apiKey: process.env.ZHIPU_API_KEY,
|
|
103
|
+
configuration: {
|
|
104
|
+
baseURL: 'https://open.bigmodel.cn/api/paas/v4',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
73
107
|
[Providers.DEEPSEEK]: {
|
|
74
108
|
provider: Providers.DEEPSEEK,
|
|
75
109
|
model: 'deepseek-reasoner',
|
|
@@ -78,7 +112,7 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
|
|
|
78
112
|
},
|
|
79
113
|
[Providers.ANTHROPIC]: {
|
|
80
114
|
provider: Providers.ANTHROPIC,
|
|
81
|
-
model: 'claude-
|
|
115
|
+
model: 'claude-sonnet-4-5',
|
|
82
116
|
streaming: true,
|
|
83
117
|
streamUsage: true,
|
|
84
118
|
},
|
package/src/utils/misc.ts
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
|
+
export function isPresent(value: string | null | undefined): value is string {
|
|
2
|
+
return value != null && value !== '';
|
|
3
|
+
}
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
6
|
* Unescapes a c-escaped string
|
|
3
7
|
* @param str The string to unescape
|
|
4
8
|
* @returns The unescaped string
|
|
5
9
|
*/
|
|
6
|
-
const unescapeString = (string: string): string =>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
10
|
+
const unescapeString = (string: string): string =>
|
|
11
|
+
string.replace(/\\(.)/g, (_, char) => {
|
|
12
|
+
switch (char) {
|
|
13
|
+
case 'n':
|
|
14
|
+
return '\n';
|
|
15
|
+
case 't':
|
|
16
|
+
return '\t';
|
|
17
|
+
case 'r':
|
|
18
|
+
return '\r';
|
|
19
|
+
case '"':
|
|
20
|
+
return '"';
|
|
21
|
+
case '\'':
|
|
22
|
+
return '\'';
|
|
23
|
+
case '\\':
|
|
24
|
+
return '\\';
|
|
25
|
+
default:
|
|
26
|
+
return char;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
24
29
|
|
|
25
30
|
/**
|
|
26
31
|
* Recursively unescapes all string values in an object
|
|
@@ -36,10 +41,17 @@ export function unescapeObject(obj: unknown, key?: string): unknown {
|
|
|
36
41
|
return unescaped;
|
|
37
42
|
}
|
|
38
43
|
if (Array.isArray(obj)) {
|
|
39
|
-
return obj.map((value) =>
|
|
44
|
+
return obj.map((value) =>
|
|
45
|
+
unescapeObject(value, key === 'contextPaths' ? 'filePath' : '')
|
|
46
|
+
);
|
|
40
47
|
}
|
|
41
48
|
if (typeof obj === 'object' && obj !== null) {
|
|
42
|
-
return Object.fromEntries(
|
|
49
|
+
return Object.fromEntries(
|
|
50
|
+
Object.entries(obj).map(([key, value]) => [
|
|
51
|
+
key,
|
|
52
|
+
unescapeObject(value, key),
|
|
53
|
+
])
|
|
54
|
+
);
|
|
43
55
|
}
|
|
44
56
|
return obj;
|
|
45
|
-
}
|
|
57
|
+
}
|
package/src/utils/title.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { RunnableLambda } from '@langchain/core/runnables';
|
|
3
2
|
import { ChatPromptTemplate } from '@langchain/core/prompts';
|
|
3
|
+
import { RunnableLambda, RunnableSequence } from '@langchain/core/runnables';
|
|
4
4
|
import type { Runnable, RunnableConfig } from '@langchain/core/runnables';
|
|
5
|
+
import type { AIMessage } from '@langchain/core/messages';
|
|
5
6
|
import type * as t from '@/types';
|
|
6
7
|
import { ContentTypes } from '@/common';
|
|
7
8
|
|
|
@@ -42,7 +43,55 @@ export const createTitleRunnable = async (
|
|
|
42
43
|
|
|
43
44
|
const titlePrompt = ChatPromptTemplate.fromTemplate(
|
|
44
45
|
_titlePrompt ?? defaultTitlePrompt
|
|
45
|
-
);
|
|
46
|
+
).withConfig({ runName: 'TitlePrompt' });
|
|
47
|
+
|
|
48
|
+
const titleOnlyInnerChain = RunnableSequence.from([titlePrompt, titleLLM]);
|
|
49
|
+
const combinedInnerChain = RunnableSequence.from([titlePrompt, combinedLLM]);
|
|
50
|
+
|
|
51
|
+
/** Wrap titleOnlyChain in RunnableLambda to create parent span */
|
|
52
|
+
const titleOnlyChain = new RunnableLambda({
|
|
53
|
+
func: async (
|
|
54
|
+
input: { convo: string },
|
|
55
|
+
config?: Partial<RunnableConfig>
|
|
56
|
+
): Promise<{ title: string }> => {
|
|
57
|
+
return await titleOnlyInnerChain.invoke(input, config);
|
|
58
|
+
},
|
|
59
|
+
}).withConfig({ runName: 'TitleOnlyChain' });
|
|
60
|
+
|
|
61
|
+
/** Wrap combinedChain in RunnableLambda to create parent span */
|
|
62
|
+
const combinedChain = new RunnableLambda({
|
|
63
|
+
func: async (
|
|
64
|
+
input: { convo: string },
|
|
65
|
+
config?: Partial<RunnableConfig>
|
|
66
|
+
): Promise<{ language: string; title: string }> => {
|
|
67
|
+
return await combinedInnerChain.invoke(input, config);
|
|
68
|
+
},
|
|
69
|
+
}).withConfig({ runName: 'TitleLanguageChain' });
|
|
70
|
+
|
|
71
|
+
/** Runnable to add default values if needed */
|
|
72
|
+
const addDefaults = new RunnableLambda({
|
|
73
|
+
func: (
|
|
74
|
+
result: { language: string; title: string } | undefined
|
|
75
|
+
): { language: string; title: string } => ({
|
|
76
|
+
language: result?.language ?? 'English',
|
|
77
|
+
title: result?.title ?? '',
|
|
78
|
+
}),
|
|
79
|
+
}).withConfig({ runName: 'AddDefaults' });
|
|
80
|
+
|
|
81
|
+
const combinedChainInner = RunnableSequence.from([
|
|
82
|
+
combinedChain,
|
|
83
|
+
addDefaults,
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
/** Wrap combinedChainWithDefaults in RunnableLambda to create parent span */
|
|
87
|
+
const combinedChainWithDefaults = new RunnableLambda({
|
|
88
|
+
func: async (
|
|
89
|
+
input: { convo: string },
|
|
90
|
+
config?: Partial<RunnableConfig>
|
|
91
|
+
): Promise<{ language: string; title: string }> => {
|
|
92
|
+
return await combinedChainInner.invoke(input, config);
|
|
93
|
+
},
|
|
94
|
+
}).withConfig({ runName: 'CombinedChainWithDefaults' });
|
|
46
95
|
|
|
47
96
|
return new RunnableLambda({
|
|
48
97
|
func: async (
|
|
@@ -53,28 +102,17 @@ export const createTitleRunnable = async (
|
|
|
53
102
|
},
|
|
54
103
|
config?: Partial<RunnableConfig>
|
|
55
104
|
): Promise<{ language: string; title: string } | { title: string }> => {
|
|
105
|
+
const invokeInput = { convo: input.convo };
|
|
106
|
+
|
|
56
107
|
if (input.skipLanguage) {
|
|
57
|
-
return (await
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
},
|
|
61
|
-
config
|
|
62
|
-
)) as { title: string };
|
|
108
|
+
return (await titleOnlyChain.invoke(invokeInput, config)) as {
|
|
109
|
+
title: string;
|
|
110
|
+
};
|
|
63
111
|
}
|
|
64
112
|
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
convo: input.convo,
|
|
68
|
-
},
|
|
69
|
-
config
|
|
70
|
-
)) as { language: string; title: string } | undefined;
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
language: result?.language ?? 'English',
|
|
74
|
-
title: result?.title ?? '',
|
|
75
|
-
};
|
|
113
|
+
return await combinedChainWithDefaults.invoke(invokeInput, config);
|
|
76
114
|
},
|
|
77
|
-
});
|
|
115
|
+
}).withConfig({ runName: 'TitleGenerator' });
|
|
78
116
|
};
|
|
79
117
|
|
|
80
118
|
const defaultCompletionPrompt = `Provide a concise, 5-word-or-less title for the conversation, using title case conventions. Only return the title itself.
|
|
@@ -88,22 +126,11 @@ export const createCompletionTitleRunnable = async (
|
|
|
88
126
|
): Promise<Runnable> => {
|
|
89
127
|
const completionPrompt = ChatPromptTemplate.fromTemplate(
|
|
90
128
|
titlePrompt ?? defaultCompletionPrompt
|
|
91
|
-
);
|
|
129
|
+
).withConfig({ runName: 'CompletionTitlePrompt' });
|
|
92
130
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
convo: string;
|
|
97
|
-
inputText: string;
|
|
98
|
-
skipLanguage: boolean;
|
|
99
|
-
},
|
|
100
|
-
config?: Partial<RunnableConfig>
|
|
101
|
-
): Promise<{ title: string }> => {
|
|
102
|
-
const promptOutput = await completionPrompt.invoke({
|
|
103
|
-
convo: input.convo,
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const response = await model.invoke(promptOutput, config);
|
|
131
|
+
/** Runnable to extract content from model response */
|
|
132
|
+
const extractContent = new RunnableLambda({
|
|
133
|
+
func: (response: AIMessage): { title: string } => {
|
|
107
134
|
let content = '';
|
|
108
135
|
if (typeof response.content === 'string') {
|
|
109
136
|
content = response.content;
|
|
@@ -116,10 +143,23 @@ export const createCompletionTitleRunnable = async (
|
|
|
116
143
|
.map((part) => part.text)
|
|
117
144
|
.join('');
|
|
118
145
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
146
|
+
return { title: content.trim() };
|
|
147
|
+
},
|
|
148
|
+
}).withConfig({ runName: 'ExtractTitle' });
|
|
149
|
+
|
|
150
|
+
const innerChain = RunnableSequence.from([
|
|
151
|
+
completionPrompt,
|
|
152
|
+
model,
|
|
153
|
+
extractContent,
|
|
154
|
+
]);
|
|
155
|
+
|
|
156
|
+
/** Wrap in RunnableLambda to create a parent span for LangFuse */
|
|
157
|
+
return new RunnableLambda({
|
|
158
|
+
func: async (
|
|
159
|
+
input: { convo: string },
|
|
160
|
+
config?: Partial<RunnableConfig>
|
|
161
|
+
): Promise<{ title: string }> => {
|
|
162
|
+
return await innerChain.invoke(input, config);
|
|
123
163
|
},
|
|
124
|
-
});
|
|
164
|
+
}).withConfig({ runName: 'CompletionTitleChain' });
|
|
125
165
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function capitalizeFirstLetter(string: string): string;
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
# Multi-Agent Test Scripts - Example Output
|
|
2
|
-
|
|
3
|
-
## multi-agent-test.ts
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
Testing Multi-Agent Handoff System...
|
|
7
|
-
|
|
8
|
-
Invoking multi-agent graph...
|
|
9
|
-
|
|
10
|
-
====== ON_RUN_STEP ======
|
|
11
|
-
{ name: 'flight_assistant', type: 'agent', ... }
|
|
12
|
-
[flight_assistant] Starting...
|
|
13
|
-
|
|
14
|
-
====== CHAT_MODEL_STREAM ======
|
|
15
|
-
I'll help you book a flight from Boston to New York...
|
|
16
|
-
|
|
17
|
-
====== TOOL_START ======
|
|
18
|
-
{ name: 'transfer_to_hotel_assistant', ... }
|
|
19
|
-
|
|
20
|
-
====== ON_RUN_STEP_COMPLETED ======
|
|
21
|
-
[flight_assistant] Completed
|
|
22
|
-
|
|
23
|
-
====== ON_RUN_STEP ======
|
|
24
|
-
{ name: 'hotel_assistant', type: 'agent', ... }
|
|
25
|
-
[hotel_assistant] Starting...
|
|
26
|
-
|
|
27
|
-
====== CHAT_MODEL_STREAM ======
|
|
28
|
-
Great! I'll help you find a hotel near Times Square...
|
|
29
|
-
|
|
30
|
-
Final content parts:
|
|
31
|
-
[
|
|
32
|
-
{ type: 'text', text: "I'll help you book a flight..." },
|
|
33
|
-
{ type: 'tool_use', name: 'transfer_to_hotel_assistant', ... },
|
|
34
|
-
{ type: 'text', text: "Great! I'll help you find a hotel..." }
|
|
35
|
-
]
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## multi-agent-parallel.ts
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
Testing Parallel Multi-Agent System (Fan-in/Fan-out)...
|
|
42
|
-
|
|
43
|
-
Invoking parallel multi-agent graph...
|
|
44
|
-
|
|
45
|
-
====== ON_RUN_STEP ======
|
|
46
|
-
[researcher] Starting analysis...
|
|
47
|
-
|
|
48
|
-
====== ON_RUN_STEP ======
|
|
49
|
-
[analyst1] Starting analysis...
|
|
50
|
-
[analyst2] Starting analysis...
|
|
51
|
-
[analyst3] Starting analysis...
|
|
52
|
-
|
|
53
|
-
====== CHAT_MODEL_STREAM ======
|
|
54
|
-
[analyst1] From a financial perspective...
|
|
55
|
-
[analyst2] From a technical perspective...
|
|
56
|
-
[analyst3] From a market perspective...
|
|
57
|
-
|
|
58
|
-
====== ON_RUN_STEP_COMPLETED ======
|
|
59
|
-
[analyst1] Completed analysis
|
|
60
|
-
[analyst2] Completed analysis
|
|
61
|
-
[analyst3] Completed analysis
|
|
62
|
-
|
|
63
|
-
====== ON_RUN_STEP ======
|
|
64
|
-
[summarizer] Starting analysis...
|
|
65
|
-
|
|
66
|
-
Final content parts: 5 parts
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## multi-agent-conditional.ts
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
Testing Conditional Multi-Agent System...
|
|
73
|
-
|
|
74
|
-
--- Processing: "How do I implement a binary search tree in Python?" ---
|
|
75
|
-
|
|
76
|
-
====== ON_RUN_STEP ======
|
|
77
|
-
{ name: 'classifier', type: 'agent', ... }
|
|
78
|
-
|
|
79
|
-
====== ON_RUN_STEP ======
|
|
80
|
-
{ name: 'technical_expert', type: 'agent', ... }
|
|
81
|
-
Routing to: technical_expert
|
|
82
|
-
|
|
83
|
-
====== CHAT_MODEL_STREAM ======
|
|
84
|
-
To implement a binary search tree in Python, you'll need to create a Node class...
|
|
85
|
-
|
|
86
|
-
Expert used: technical_expert
|
|
87
|
-
Content parts: 2
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
--- Processing: "What are the key strategies for market expansion?" ---
|
|
91
|
-
|
|
92
|
-
Routing to: business_expert
|
|
93
|
-
...
|
|
94
|
-
|
|
95
|
-
--- Processing: "What is the capital of France?" ---
|
|
96
|
-
|
|
97
|
-
Routing to: general_assistant
|
|
98
|
-
...
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## Key Features of Updated Scripts
|
|
102
|
-
|
|
103
|
-
1. **Proper Event Handling**: All GraphEvents are properly handled with custom handlers
|
|
104
|
-
2. **Content Aggregation**: Using `createContentAggregator()` to collect all content parts
|
|
105
|
-
3. **Stream Output**: Real-time token streaming via `ChatModelStreamHandler`
|
|
106
|
-
4. **Debug Logging**: Comprehensive event logging for debugging multi-agent flows
|
|
107
|
-
5. **Conversation History**: Proper tracking of messages across agent interactions
|
|
108
|
-
6. **Return Content**: `returnContent: true` ensures content parts are returned
|
|
109
|
-
|
|
110
|
-
The scripts now follow the same patterns as `simple.ts` and `tools.ts`, providing consistent behavior and comprehensive event handling across all multi-agent scenarios.
|
|
File without changes
|