@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.
Files changed (229) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +6 -2
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +23 -2
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/graphs/MultiAgentGraph.cjs +108 -17
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  7. package/dist/cjs/instrumentation.cjs +21 -0
  8. package/dist/cjs/instrumentation.cjs.map +1 -0
  9. package/dist/cjs/llm/anthropic/index.cjs +21 -2
  10. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  11. package/dist/cjs/llm/google/index.cjs +3 -0
  12. package/dist/cjs/llm/google/index.cjs.map +1 -1
  13. package/dist/cjs/llm/google/utils/common.cjs +13 -0
  14. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  15. package/dist/cjs/llm/ollama/index.cjs +3 -0
  16. package/dist/cjs/llm/ollama/index.cjs.map +1 -1
  17. package/dist/cjs/llm/openai/index.cjs +18 -3
  18. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  19. package/dist/cjs/llm/openai/utils/index.cjs +6 -1
  20. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  21. package/dist/cjs/llm/openrouter/index.cjs +5 -1
  22. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  23. package/dist/cjs/llm/vertexai/index.cjs +1 -1
  24. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  25. package/dist/cjs/main.cjs +8 -2
  26. package/dist/cjs/main.cjs.map +1 -1
  27. package/dist/cjs/messages/cache.cjs +49 -0
  28. package/dist/cjs/messages/cache.cjs.map +1 -0
  29. package/dist/cjs/messages/content.cjs +53 -0
  30. package/dist/cjs/messages/content.cjs.map +1 -0
  31. package/dist/cjs/messages/core.cjs +5 -1
  32. package/dist/cjs/messages/core.cjs.map +1 -1
  33. package/dist/cjs/messages/format.cjs +50 -59
  34. package/dist/cjs/messages/format.cjs.map +1 -1
  35. package/dist/cjs/messages/prune.cjs +28 -0
  36. package/dist/cjs/messages/prune.cjs.map +1 -1
  37. package/dist/cjs/run.cjs +57 -5
  38. package/dist/cjs/run.cjs.map +1 -1
  39. package/dist/cjs/stream.cjs +7 -0
  40. package/dist/cjs/stream.cjs.map +1 -1
  41. package/dist/cjs/tools/ToolNode.cjs +2 -0
  42. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  43. package/dist/cjs/tools/search/firecrawl.cjs +3 -1
  44. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  45. package/dist/cjs/tools/search/rerankers.cjs +8 -6
  46. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  47. package/dist/cjs/tools/search/search.cjs +5 -5
  48. package/dist/cjs/tools/search/search.cjs.map +1 -1
  49. package/dist/cjs/tools/search/serper-scraper.cjs +132 -0
  50. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -0
  51. package/dist/cjs/tools/search/tool.cjs +46 -9
  52. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  53. package/dist/cjs/utils/handlers.cjs +70 -0
  54. package/dist/cjs/utils/handlers.cjs.map +1 -0
  55. package/dist/cjs/utils/misc.cjs +8 -1
  56. package/dist/cjs/utils/misc.cjs.map +1 -1
  57. package/dist/cjs/utils/title.cjs +54 -25
  58. package/dist/cjs/utils/title.cjs.map +1 -1
  59. package/dist/esm/agents/AgentContext.mjs +6 -2
  60. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  61. package/dist/esm/graphs/Graph.mjs +23 -2
  62. package/dist/esm/graphs/Graph.mjs.map +1 -1
  63. package/dist/esm/graphs/MultiAgentGraph.mjs +108 -17
  64. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  65. package/dist/esm/instrumentation.mjs +19 -0
  66. package/dist/esm/instrumentation.mjs.map +1 -0
  67. package/dist/esm/llm/anthropic/index.mjs +21 -2
  68. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  69. package/dist/esm/llm/google/index.mjs +3 -0
  70. package/dist/esm/llm/google/index.mjs.map +1 -1
  71. package/dist/esm/llm/google/utils/common.mjs +13 -0
  72. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  73. package/dist/esm/llm/ollama/index.mjs +3 -0
  74. package/dist/esm/llm/ollama/index.mjs.map +1 -1
  75. package/dist/esm/llm/openai/index.mjs +18 -3
  76. package/dist/esm/llm/openai/index.mjs.map +1 -1
  77. package/dist/esm/llm/openai/utils/index.mjs +6 -1
  78. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  79. package/dist/esm/llm/openrouter/index.mjs +5 -1
  80. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  81. package/dist/esm/llm/vertexai/index.mjs +1 -1
  82. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  83. package/dist/esm/main.mjs +5 -2
  84. package/dist/esm/main.mjs.map +1 -1
  85. package/dist/esm/messages/cache.mjs +47 -0
  86. package/dist/esm/messages/cache.mjs.map +1 -0
  87. package/dist/esm/messages/content.mjs +51 -0
  88. package/dist/esm/messages/content.mjs.map +1 -0
  89. package/dist/esm/messages/core.mjs +5 -1
  90. package/dist/esm/messages/core.mjs.map +1 -1
  91. package/dist/esm/messages/format.mjs +50 -58
  92. package/dist/esm/messages/format.mjs.map +1 -1
  93. package/dist/esm/messages/prune.mjs +28 -0
  94. package/dist/esm/messages/prune.mjs.map +1 -1
  95. package/dist/esm/run.mjs +57 -5
  96. package/dist/esm/run.mjs.map +1 -1
  97. package/dist/esm/stream.mjs +7 -0
  98. package/dist/esm/stream.mjs.map +1 -1
  99. package/dist/esm/tools/ToolNode.mjs +2 -0
  100. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  101. package/dist/esm/tools/search/firecrawl.mjs +3 -1
  102. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  103. package/dist/esm/tools/search/rerankers.mjs +8 -6
  104. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  105. package/dist/esm/tools/search/search.mjs +5 -5
  106. package/dist/esm/tools/search/search.mjs.map +1 -1
  107. package/dist/esm/tools/search/serper-scraper.mjs +129 -0
  108. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -0
  109. package/dist/esm/tools/search/tool.mjs +46 -9
  110. package/dist/esm/tools/search/tool.mjs.map +1 -1
  111. package/dist/esm/utils/handlers.mjs +68 -0
  112. package/dist/esm/utils/handlers.mjs.map +1 -0
  113. package/dist/esm/utils/misc.mjs +8 -2
  114. package/dist/esm/utils/misc.mjs.map +1 -1
  115. package/dist/esm/utils/title.mjs +54 -25
  116. package/dist/esm/utils/title.mjs.map +1 -1
  117. package/dist/types/agents/AgentContext.d.ts +4 -1
  118. package/dist/types/graphs/MultiAgentGraph.d.ts +11 -1
  119. package/dist/types/llm/anthropic/index.d.ts +3 -0
  120. package/dist/types/llm/google/index.d.ts +1 -0
  121. package/dist/types/llm/ollama/index.d.ts +1 -0
  122. package/dist/types/llm/openai/index.d.ts +4 -0
  123. package/dist/types/llm/openrouter/index.d.ts +4 -2
  124. package/dist/types/llm/vertexai/index.d.ts +1 -1
  125. package/dist/types/messages/cache.d.ts +8 -0
  126. package/dist/types/messages/content.d.ts +7 -0
  127. package/dist/types/messages/format.d.ts +22 -25
  128. package/dist/types/messages/index.d.ts +2 -0
  129. package/dist/types/run.d.ts +2 -1
  130. package/dist/types/tools/search/firecrawl.d.ts +2 -1
  131. package/dist/types/tools/search/rerankers.d.ts +4 -1
  132. package/dist/types/tools/search/search.d.ts +1 -2
  133. package/dist/types/tools/search/serper-scraper.d.ts +59 -0
  134. package/dist/types/tools/search/tool.d.ts +25 -4
  135. package/dist/types/tools/search/types.d.ts +31 -1
  136. package/dist/types/types/graph.d.ts +3 -1
  137. package/dist/types/types/messages.d.ts +4 -0
  138. package/dist/types/utils/handlers.d.ts +34 -0
  139. package/dist/types/utils/index.d.ts +1 -0
  140. package/dist/types/utils/misc.d.ts +1 -0
  141. package/package.json +8 -2
  142. package/src/agents/AgentContext.ts +8 -0
  143. package/src/graphs/Graph.ts +31 -2
  144. package/src/graphs/MultiAgentGraph.ts +125 -18
  145. package/src/instrumentation.ts +22 -0
  146. package/src/llm/anthropic/index.ts +23 -2
  147. package/src/llm/anthropic/llm.spec.ts +1 -1
  148. package/src/llm/google/index.ts +4 -0
  149. package/src/llm/google/utils/common.ts +14 -0
  150. package/src/llm/ollama/index.ts +3 -0
  151. package/src/llm/openai/index.ts +17 -4
  152. package/src/llm/openai/utils/index.ts +7 -1
  153. package/src/llm/openrouter/index.ts +15 -6
  154. package/src/llm/vertexai/index.ts +2 -2
  155. package/src/messages/cache.test.ts +262 -0
  156. package/src/messages/cache.ts +56 -0
  157. package/src/messages/content.test.ts +362 -0
  158. package/src/messages/content.ts +63 -0
  159. package/src/messages/core.ts +5 -2
  160. package/src/messages/format.ts +65 -71
  161. package/src/messages/formatMessage.test.ts +418 -2
  162. package/src/messages/index.ts +2 -0
  163. package/src/messages/prune.ts +51 -0
  164. package/src/run.ts +82 -10
  165. package/src/scripts/ant_web_search.ts +1 -1
  166. package/src/scripts/handoff-test.ts +1 -1
  167. package/src/scripts/multi-agent-chain.ts +278 -0
  168. package/src/scripts/multi-agent-conditional.ts +4 -4
  169. package/src/scripts/multi-agent-document-review-chain.ts +197 -0
  170. package/src/scripts/multi-agent-hybrid-flow.ts +310 -0
  171. package/src/scripts/multi-agent-parallel.ts +10 -8
  172. package/src/scripts/multi-agent-sequence.ts +3 -3
  173. package/src/scripts/multi-agent-supervisor.ts +5 -3
  174. package/src/scripts/multi-agent-test.ts +2 -2
  175. package/src/scripts/search.ts +5 -1
  176. package/src/scripts/simple.ts +8 -0
  177. package/src/scripts/test-custom-prompt-key.ts +4 -4
  178. package/src/scripts/test-handoff-input.ts +3 -3
  179. package/src/scripts/test-multi-agent-list-handoff.ts +2 -2
  180. package/src/scripts/tools.ts +4 -1
  181. package/src/specs/agent-handoffs.test.ts +889 -0
  182. package/src/stream.ts +9 -2
  183. package/src/tools/search/firecrawl.ts +5 -2
  184. package/src/tools/search/jina-reranker.test.ts +126 -0
  185. package/src/tools/search/rerankers.ts +11 -5
  186. package/src/tools/search/search.ts +6 -8
  187. package/src/tools/search/serper-scraper.ts +155 -0
  188. package/src/tools/search/tool.ts +49 -8
  189. package/src/tools/search/types.ts +46 -0
  190. package/src/types/graph.ts +6 -1
  191. package/src/types/messages.ts +4 -0
  192. package/src/utils/handlers.ts +107 -0
  193. package/src/utils/index.ts +2 -1
  194. package/src/utils/llmConfig.ts +35 -1
  195. package/src/utils/misc.ts +33 -21
  196. package/src/utils/title.ts +80 -40
  197. package/dist/types/scripts/ant_web_search.d.ts +0 -1
  198. package/dist/types/scripts/args.d.ts +0 -7
  199. package/dist/types/scripts/caching.d.ts +0 -1
  200. package/dist/types/scripts/cli.d.ts +0 -1
  201. package/dist/types/scripts/cli2.d.ts +0 -1
  202. package/dist/types/scripts/cli3.d.ts +0 -1
  203. package/dist/types/scripts/cli4.d.ts +0 -1
  204. package/dist/types/scripts/cli5.d.ts +0 -1
  205. package/dist/types/scripts/code_exec.d.ts +0 -1
  206. package/dist/types/scripts/code_exec_files.d.ts +0 -1
  207. package/dist/types/scripts/code_exec_simple.d.ts +0 -1
  208. package/dist/types/scripts/content.d.ts +0 -1
  209. package/dist/types/scripts/empty_input.d.ts +0 -1
  210. package/dist/types/scripts/handoff-test.d.ts +0 -1
  211. package/dist/types/scripts/image.d.ts +0 -1
  212. package/dist/types/scripts/memory.d.ts +0 -1
  213. package/dist/types/scripts/multi-agent-conditional.d.ts +0 -1
  214. package/dist/types/scripts/multi-agent-parallel.d.ts +0 -1
  215. package/dist/types/scripts/multi-agent-sequence.d.ts +0 -1
  216. package/dist/types/scripts/multi-agent-supervisor.d.ts +0 -1
  217. package/dist/types/scripts/multi-agent-test.d.ts +0 -1
  218. package/dist/types/scripts/search.d.ts +0 -1
  219. package/dist/types/scripts/simple.d.ts +0 -1
  220. package/dist/types/scripts/stream.d.ts +0 -1
  221. package/dist/types/scripts/test-custom-prompt-key.d.ts +0 -2
  222. package/dist/types/scripts/test-handoff-input.d.ts +0 -1
  223. package/dist/types/scripts/test-multi-agent-list-handoff.d.ts +0 -2
  224. package/dist/types/scripts/test-tools-before-handoff.d.ts +0 -1
  225. package/dist/types/scripts/thinking.d.ts +0 -1
  226. package/dist/types/scripts/tools.d.ts +0 -1
  227. package/dist/types/specs/spec.utils.d.ts +0 -1
  228. package/src/scripts/multi-agent-example-output.md +0 -110
  229. /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
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './graph';
2
2
  export * from './llm';
3
3
  export * from './misc';
4
+ export * from './handlers';
4
5
  export * from './run';
5
- export * from './tokens';
6
+ export * from './tokens';
@@ -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-3-5-sonnet-20240620',
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 => string.replace(/\\(.)/g, (_, char) => {
7
- switch (char) {
8
- case 'n':
9
- return '\n';
10
- case 't':
11
- return '\t';
12
- case 'r':
13
- return '\r';
14
- case '"':
15
- return '"';
16
- case '\'':
17
- return '\'';
18
- case '\\':
19
- return '\\';
20
- default:
21
- return char;
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) => unescapeObject(value, key === 'contextPaths' ? 'filePath' : ''));
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(Object.entries(obj).map(([key, value]) => [key, unescapeObject(value, key)]));
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
+ }
@@ -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 titlePrompt.pipe(titleLLM).invoke(
58
- {
59
- convo: input.convo,
60
- },
61
- config
62
- )) as { title: string };
108
+ return (await titleOnlyChain.invoke(invokeInput, config)) as {
109
+ title: string;
110
+ };
63
111
  }
64
112
 
65
- const result = (await titlePrompt.pipe(combinedLLM).invoke(
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
- return new RunnableLambda({
94
- func: async (
95
- input: {
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
- const title = content.trim();
120
- return {
121
- title,
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,7 +0,0 @@
1
- import { Providers } from '@/common';
2
- export declare function getArgs(): Promise<{
3
- userName: string;
4
- location: string;
5
- provider: Providers;
6
- currentDate: string;
7
- }>;
@@ -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,2 +0,0 @@
1
- #!/usr/bin/env bun
2
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env bun
2
- 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.