@librechat/agents 2.4.322 → 3.0.0-rc10

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 (279) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +218 -0
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -0
  3. package/dist/cjs/common/enum.cjs +15 -5
  4. package/dist/cjs/common/enum.cjs.map +1 -1
  5. package/dist/cjs/events.cjs +10 -6
  6. package/dist/cjs/events.cjs.map +1 -1
  7. package/dist/cjs/graphs/Graph.cjs +309 -213
  8. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  9. package/dist/cjs/graphs/MultiAgentGraph.cjs +507 -0
  10. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -0
  11. package/dist/cjs/llm/anthropic/index.cjs +54 -9
  12. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  13. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  14. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +52 -6
  15. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  16. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +22 -2
  17. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  18. package/dist/cjs/llm/anthropic/utils/tools.cjs +29 -0
  19. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -0
  20. package/dist/cjs/llm/google/index.cjs +144 -0
  21. package/dist/cjs/llm/google/index.cjs.map +1 -0
  22. package/dist/cjs/llm/google/utils/common.cjs +477 -0
  23. package/dist/cjs/llm/google/utils/common.cjs.map +1 -0
  24. package/dist/cjs/llm/ollama/index.cjs +67 -0
  25. package/dist/cjs/llm/ollama/index.cjs.map +1 -0
  26. package/dist/cjs/llm/ollama/utils.cjs +158 -0
  27. package/dist/cjs/llm/ollama/utils.cjs.map +1 -0
  28. package/dist/cjs/llm/openai/index.cjs +422 -3
  29. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  30. package/dist/cjs/llm/openai/utils/index.cjs +672 -0
  31. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -0
  32. package/dist/cjs/llm/providers.cjs +15 -15
  33. package/dist/cjs/llm/providers.cjs.map +1 -1
  34. package/dist/cjs/llm/text.cjs +14 -3
  35. package/dist/cjs/llm/text.cjs.map +1 -1
  36. package/dist/cjs/llm/vertexai/index.cjs +330 -0
  37. package/dist/cjs/llm/vertexai/index.cjs.map +1 -0
  38. package/dist/cjs/main.cjs +11 -0
  39. package/dist/cjs/main.cjs.map +1 -1
  40. package/dist/cjs/run.cjs +137 -85
  41. package/dist/cjs/run.cjs.map +1 -1
  42. package/dist/cjs/stream.cjs +86 -52
  43. package/dist/cjs/stream.cjs.map +1 -1
  44. package/dist/cjs/tools/ToolNode.cjs +10 -4
  45. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  46. package/dist/cjs/tools/handlers.cjs +119 -13
  47. package/dist/cjs/tools/handlers.cjs.map +1 -1
  48. package/dist/cjs/tools/search/anthropic.cjs +40 -0
  49. package/dist/cjs/tools/search/anthropic.cjs.map +1 -0
  50. package/dist/cjs/tools/search/firecrawl.cjs +55 -9
  51. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  52. package/dist/cjs/tools/search/format.cjs +6 -6
  53. package/dist/cjs/tools/search/format.cjs.map +1 -1
  54. package/dist/cjs/tools/search/rerankers.cjs +7 -29
  55. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  56. package/dist/cjs/tools/search/search.cjs +86 -16
  57. package/dist/cjs/tools/search/search.cjs.map +1 -1
  58. package/dist/cjs/tools/search/tool.cjs +4 -2
  59. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  60. package/dist/cjs/tools/search/utils.cjs +1 -1
  61. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  62. package/dist/cjs/utils/events.cjs +31 -0
  63. package/dist/cjs/utils/events.cjs.map +1 -0
  64. package/dist/cjs/utils/title.cjs +57 -21
  65. package/dist/cjs/utils/title.cjs.map +1 -1
  66. package/dist/cjs/utils/tokens.cjs +54 -7
  67. package/dist/cjs/utils/tokens.cjs.map +1 -1
  68. package/dist/esm/agents/AgentContext.mjs +216 -0
  69. package/dist/esm/agents/AgentContext.mjs.map +1 -0
  70. package/dist/esm/common/enum.mjs +16 -6
  71. package/dist/esm/common/enum.mjs.map +1 -1
  72. package/dist/esm/events.mjs +10 -6
  73. package/dist/esm/events.mjs.map +1 -1
  74. package/dist/esm/graphs/Graph.mjs +311 -215
  75. package/dist/esm/graphs/Graph.mjs.map +1 -1
  76. package/dist/esm/graphs/MultiAgentGraph.mjs +505 -0
  77. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -0
  78. package/dist/esm/llm/anthropic/index.mjs +54 -9
  79. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  80. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  81. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +52 -6
  82. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  83. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +22 -2
  84. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  85. package/dist/esm/llm/anthropic/utils/tools.mjs +27 -0
  86. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -0
  87. package/dist/esm/llm/google/index.mjs +142 -0
  88. package/dist/esm/llm/google/index.mjs.map +1 -0
  89. package/dist/esm/llm/google/utils/common.mjs +471 -0
  90. package/dist/esm/llm/google/utils/common.mjs.map +1 -0
  91. package/dist/esm/llm/ollama/index.mjs +65 -0
  92. package/dist/esm/llm/ollama/index.mjs.map +1 -0
  93. package/dist/esm/llm/ollama/utils.mjs +155 -0
  94. package/dist/esm/llm/ollama/utils.mjs.map +1 -0
  95. package/dist/esm/llm/openai/index.mjs +421 -4
  96. package/dist/esm/llm/openai/index.mjs.map +1 -1
  97. package/dist/esm/llm/openai/utils/index.mjs +666 -0
  98. package/dist/esm/llm/openai/utils/index.mjs.map +1 -0
  99. package/dist/esm/llm/providers.mjs +5 -5
  100. package/dist/esm/llm/providers.mjs.map +1 -1
  101. package/dist/esm/llm/text.mjs +14 -3
  102. package/dist/esm/llm/text.mjs.map +1 -1
  103. package/dist/esm/llm/vertexai/index.mjs +328 -0
  104. package/dist/esm/llm/vertexai/index.mjs.map +1 -0
  105. package/dist/esm/main.mjs +6 -5
  106. package/dist/esm/main.mjs.map +1 -1
  107. package/dist/esm/run.mjs +138 -87
  108. package/dist/esm/run.mjs.map +1 -1
  109. package/dist/esm/stream.mjs +88 -55
  110. package/dist/esm/stream.mjs.map +1 -1
  111. package/dist/esm/tools/ToolNode.mjs +10 -4
  112. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  113. package/dist/esm/tools/handlers.mjs +119 -15
  114. package/dist/esm/tools/handlers.mjs.map +1 -1
  115. package/dist/esm/tools/search/anthropic.mjs +37 -0
  116. package/dist/esm/tools/search/anthropic.mjs.map +1 -0
  117. package/dist/esm/tools/search/firecrawl.mjs +55 -9
  118. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  119. package/dist/esm/tools/search/format.mjs +7 -7
  120. package/dist/esm/tools/search/format.mjs.map +1 -1
  121. package/dist/esm/tools/search/rerankers.mjs +7 -29
  122. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  123. package/dist/esm/tools/search/search.mjs +86 -16
  124. package/dist/esm/tools/search/search.mjs.map +1 -1
  125. package/dist/esm/tools/search/tool.mjs +4 -2
  126. package/dist/esm/tools/search/tool.mjs.map +1 -1
  127. package/dist/esm/tools/search/utils.mjs +1 -1
  128. package/dist/esm/tools/search/utils.mjs.map +1 -1
  129. package/dist/esm/utils/events.mjs +29 -0
  130. package/dist/esm/utils/events.mjs.map +1 -0
  131. package/dist/esm/utils/title.mjs +57 -22
  132. package/dist/esm/utils/title.mjs.map +1 -1
  133. package/dist/esm/utils/tokens.mjs +54 -8
  134. package/dist/esm/utils/tokens.mjs.map +1 -1
  135. package/dist/types/agents/AgentContext.d.ts +91 -0
  136. package/dist/types/common/enum.d.ts +17 -7
  137. package/dist/types/events.d.ts +5 -4
  138. package/dist/types/graphs/Graph.d.ts +64 -67
  139. package/dist/types/graphs/MultiAgentGraph.d.ts +47 -0
  140. package/dist/types/graphs/index.d.ts +1 -0
  141. package/dist/types/llm/anthropic/index.d.ts +11 -0
  142. package/dist/types/llm/anthropic/types.d.ts +9 -3
  143. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
  144. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +4 -4
  145. package/dist/types/llm/anthropic/utils/tools.d.ts +3 -0
  146. package/dist/types/llm/google/index.d.ts +13 -0
  147. package/dist/types/llm/google/types.d.ts +32 -0
  148. package/dist/types/llm/google/utils/common.d.ts +19 -0
  149. package/dist/types/llm/google/utils/tools.d.ts +10 -0
  150. package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +14 -0
  151. package/dist/types/llm/ollama/index.d.ts +7 -0
  152. package/dist/types/llm/ollama/utils.d.ts +7 -0
  153. package/dist/types/llm/openai/index.d.ts +82 -3
  154. package/dist/types/llm/openai/types.d.ts +10 -0
  155. package/dist/types/llm/openai/utils/index.d.ts +20 -0
  156. package/dist/types/llm/text.d.ts +1 -1
  157. package/dist/types/llm/vertexai/index.d.ts +293 -0
  158. package/dist/types/messages/reducer.d.ts +9 -0
  159. package/dist/types/run.d.ts +19 -12
  160. package/dist/types/stream.d.ts +10 -3
  161. package/dist/types/tools/CodeExecutor.d.ts +2 -2
  162. package/dist/types/tools/ToolNode.d.ts +1 -1
  163. package/dist/types/tools/handlers.d.ts +17 -4
  164. package/dist/types/tools/search/anthropic.d.ts +16 -0
  165. package/dist/types/tools/search/firecrawl.d.ts +15 -0
  166. package/dist/types/tools/search/rerankers.d.ts +0 -1
  167. package/dist/types/tools/search/types.d.ts +30 -9
  168. package/dist/types/types/graph.d.ts +129 -15
  169. package/dist/types/types/llm.d.ts +25 -10
  170. package/dist/types/types/run.d.ts +50 -8
  171. package/dist/types/types/stream.d.ts +16 -2
  172. package/dist/types/types/tools.d.ts +1 -1
  173. package/dist/types/utils/events.d.ts +6 -0
  174. package/dist/types/utils/title.d.ts +2 -1
  175. package/dist/types/utils/tokens.d.ts +24 -0
  176. package/package.json +41 -17
  177. package/src/agents/AgentContext.ts +315 -0
  178. package/src/common/enum.ts +15 -5
  179. package/src/events.ts +24 -13
  180. package/src/graphs/Graph.ts +495 -313
  181. package/src/graphs/MultiAgentGraph.ts +598 -0
  182. package/src/graphs/index.ts +2 -1
  183. package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
  184. package/src/llm/anthropic/index.ts +78 -13
  185. package/src/llm/anthropic/llm.spec.ts +491 -115
  186. package/src/llm/anthropic/types.ts +39 -3
  187. package/src/llm/anthropic/utils/message_inputs.ts +67 -11
  188. package/src/llm/anthropic/utils/message_outputs.ts +21 -2
  189. package/src/llm/anthropic/utils/output_parsers.ts +25 -6
  190. package/src/llm/anthropic/utils/tools.ts +29 -0
  191. package/src/llm/google/index.ts +218 -0
  192. package/src/llm/google/types.ts +43 -0
  193. package/src/llm/google/utils/common.ts +646 -0
  194. package/src/llm/google/utils/tools.ts +160 -0
  195. package/src/llm/google/utils/zod_to_genai_parameters.ts +86 -0
  196. package/src/llm/ollama/index.ts +89 -0
  197. package/src/llm/ollama/utils.ts +193 -0
  198. package/src/llm/openai/index.ts +641 -14
  199. package/src/llm/openai/types.ts +24 -0
  200. package/src/llm/openai/utils/index.ts +912 -0
  201. package/src/llm/openai/utils/isReasoningModel.test.ts +90 -0
  202. package/src/llm/providers.ts +10 -9
  203. package/src/llm/text.ts +26 -7
  204. package/src/llm/vertexai/index.ts +360 -0
  205. package/src/messages/reducer.ts +80 -0
  206. package/src/run.ts +196 -116
  207. package/src/scripts/ant_web_search.ts +158 -0
  208. package/src/scripts/args.ts +12 -8
  209. package/src/scripts/cli4.ts +29 -21
  210. package/src/scripts/cli5.ts +29 -21
  211. package/src/scripts/code_exec.ts +54 -23
  212. package/src/scripts/code_exec_files.ts +48 -17
  213. package/src/scripts/code_exec_simple.ts +46 -27
  214. package/src/scripts/handoff-test.ts +135 -0
  215. package/src/scripts/image.ts +52 -20
  216. package/src/scripts/multi-agent-chain.ts +278 -0
  217. package/src/scripts/multi-agent-conditional.ts +220 -0
  218. package/src/scripts/multi-agent-document-review-chain.ts +197 -0
  219. package/src/scripts/multi-agent-hybrid-flow.ts +310 -0
  220. package/src/scripts/multi-agent-parallel.ts +341 -0
  221. package/src/scripts/multi-agent-sequence.ts +212 -0
  222. package/src/scripts/multi-agent-supervisor.ts +362 -0
  223. package/src/scripts/multi-agent-test.ts +186 -0
  224. package/src/scripts/search.ts +1 -9
  225. package/src/scripts/simple.ts +25 -10
  226. package/src/scripts/test-custom-prompt-key.ts +145 -0
  227. package/src/scripts/test-handoff-input.ts +170 -0
  228. package/src/scripts/test-multi-agent-list-handoff.ts +261 -0
  229. package/src/scripts/test-tools-before-handoff.ts +233 -0
  230. package/src/scripts/tools.ts +48 -18
  231. package/src/specs/anthropic.simple.test.ts +150 -34
  232. package/src/specs/azure.simple.test.ts +325 -0
  233. package/src/specs/openai.simple.test.ts +140 -33
  234. package/src/specs/openrouter.simple.test.ts +107 -0
  235. package/src/specs/prune.test.ts +4 -9
  236. package/src/specs/reasoning.test.ts +80 -44
  237. package/src/specs/token-memoization.test.ts +39 -0
  238. package/src/stream.test.ts +94 -0
  239. package/src/stream.ts +143 -61
  240. package/src/tools/ToolNode.ts +21 -7
  241. package/src/tools/handlers.ts +192 -18
  242. package/src/tools/search/anthropic.ts +51 -0
  243. package/src/tools/search/firecrawl.ts +69 -20
  244. package/src/tools/search/format.ts +6 -8
  245. package/src/tools/search/rerankers.ts +7 -40
  246. package/src/tools/search/search.ts +97 -16
  247. package/src/tools/search/tool.ts +5 -2
  248. package/src/tools/search/types.ts +30 -10
  249. package/src/tools/search/utils.ts +1 -1
  250. package/src/types/graph.ts +318 -103
  251. package/src/types/llm.ts +26 -12
  252. package/src/types/run.ts +56 -13
  253. package/src/types/stream.ts +22 -1
  254. package/src/types/tools.ts +16 -10
  255. package/src/utils/events.ts +32 -0
  256. package/src/utils/llmConfig.ts +19 -7
  257. package/src/utils/title.ts +104 -30
  258. package/src/utils/tokens.ts +69 -10
  259. package/dist/types/scripts/abort.d.ts +0 -1
  260. package/dist/types/scripts/args.d.ts +0 -6
  261. package/dist/types/scripts/caching.d.ts +0 -1
  262. package/dist/types/scripts/cli.d.ts +0 -1
  263. package/dist/types/scripts/cli2.d.ts +0 -1
  264. package/dist/types/scripts/cli3.d.ts +0 -1
  265. package/dist/types/scripts/cli4.d.ts +0 -1
  266. package/dist/types/scripts/cli5.d.ts +0 -1
  267. package/dist/types/scripts/code_exec.d.ts +0 -1
  268. package/dist/types/scripts/code_exec_files.d.ts +0 -1
  269. package/dist/types/scripts/code_exec_simple.d.ts +0 -1
  270. package/dist/types/scripts/content.d.ts +0 -1
  271. package/dist/types/scripts/empty_input.d.ts +0 -1
  272. package/dist/types/scripts/image.d.ts +0 -1
  273. package/dist/types/scripts/memory.d.ts +0 -1
  274. package/dist/types/scripts/search.d.ts +0 -1
  275. package/dist/types/scripts/simple.d.ts +0 -1
  276. package/dist/types/scripts/stream.d.ts +0 -1
  277. package/dist/types/scripts/thinking.d.ts +0 -1
  278. package/dist/types/scripts/tools.d.ts +0 -1
  279. package/dist/types/specs/spec.utils.d.ts +0 -1
@@ -8,6 +8,8 @@ import type {
8
8
  } from '@langchain/core/messages';
9
9
  import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
10
10
  import type { LLMResult, Generation } from '@langchain/core/outputs';
11
+ import type { AnthropicContentBlock } from '@/llm/anthropic/types';
12
+ import type { Command } from '@langchain/langgraph';
11
13
  import type { ToolEndEvent } from '@/types/tools';
12
14
  import { StepTypes, ContentTypes, GraphEvents } from '@/common/enum';
13
15
 
@@ -103,7 +105,7 @@ export type MessageCreationDetails = {
103
105
 
104
106
  export type ToolEndData = {
105
107
  input: string | Record<string, unknown>;
106
- output?: ToolMessage;
108
+ output?: ToolMessage | Command;
107
109
  };
108
110
  export type ToolErrorData = {
109
111
  id: string;
@@ -251,6 +253,12 @@ export type ReasoningContentText = {
251
253
  think: string;
252
254
  };
253
255
 
256
+ /** Vertex AI / Google Common - Reasoning Content Block Format */
257
+ export type GoogleReasoningContentText = {
258
+ type: ContentTypes.REASONING;
259
+ reasoning: string;
260
+ };
261
+
254
262
  /** Anthropic's Reasoning Content Block Format */
255
263
  export type ThinkingContentText = {
256
264
  type: ContentTypes.THINKING;
@@ -293,7 +301,20 @@ export type ToolCallContent = {
293
301
  tool_call?: ToolCallPart;
294
302
  };
295
303
 
304
+ export type ToolResultContent = {
305
+ content:
306
+ | string
307
+ | Record<string, unknown>
308
+ | Array<string | Record<string, unknown>>
309
+ | AnthropicContentBlock[];
310
+ type: 'tool_result' | 'web_search_result' | 'web_search_tool_result';
311
+ tool_use_id?: string;
312
+ input?: string | Record<string, unknown>;
313
+ index?: number;
314
+ };
315
+
296
316
  export type MessageContentComplex = (
317
+ | ToolResultContent
297
318
  | ThinkingContentText
298
319
  | AgentUpdate
299
320
  | ToolCallContent
@@ -1,6 +1,6 @@
1
1
  // src/types/tools.ts
2
- import type { RunnableToolLike } from '@langchain/core/runnables';
3
2
  import type { StructuredToolInterface } from '@langchain/core/tools';
3
+ import type { RunnableToolLike } from '@langchain/core/runnables';
4
4
  import type { ToolCall } from '@langchain/core/messages/tool';
5
5
  import type { ToolErrorData } from './stream';
6
6
  import { EnvVar } from '@/common';
@@ -13,9 +13,10 @@ export type CustomToolCall = {
13
13
  id?: string;
14
14
  type?: 'tool_call';
15
15
  output?: string;
16
- }
16
+ };
17
17
 
18
18
  export type GenericTool = StructuredToolInterface | RunnableToolLike;
19
+
19
20
  export type ToolMap = Map<string, GenericTool>;
20
21
  export type ToolRefs = {
21
22
  tools: GenericTool[];
@@ -30,7 +31,10 @@ export type ToolNodeOptions = {
30
31
  handleToolErrors?: boolean;
31
32
  loadRuntimeTools?: ToolRefGenerator;
32
33
  toolCallStepIds?: Map<string, string>;
33
- errorHandler?: (data: ToolErrorData, metadata?: Record<string, unknown>) => void
34
+ errorHandler?: (
35
+ data: ToolErrorData,
36
+ metadata?: Record<string, unknown>
37
+ ) => void;
34
38
  };
35
39
 
36
40
  export type ToolNodeConstructorParams = ToolRefs & ToolNodeOptions;
@@ -50,13 +54,15 @@ export type CodeEnvFile = {
50
54
  session_id: string;
51
55
  };
52
56
 
53
- export type CodeExecutionToolParams = undefined | {
54
- session_id?: string;
55
- user_id?: string;
56
- apiKey?: string;
57
- files?: CodeEnvFile[];
58
- [EnvVar.CODE_API_KEY]?: string;
59
- }
57
+ export type CodeExecutionToolParams =
58
+ | undefined
59
+ | {
60
+ session_id?: string;
61
+ user_id?: string;
62
+ apiKey?: string;
63
+ files?: CodeEnvFile[];
64
+ [EnvVar.CODE_API_KEY]?: string;
65
+ };
60
66
 
61
67
  export type FileRef = {
62
68
  id: string;
@@ -0,0 +1,32 @@
1
+ /* eslint-disable no-console */
2
+ // src/utils/events.ts
3
+ import { dispatchCustomEvent } from '@langchain/core/callbacks/dispatch';
4
+ import type { RunnableConfig } from '@langchain/core/runnables';
5
+
6
+ /**
7
+ * Safely dispatches a custom event and properly awaits it to avoid
8
+ * race conditions where events are dispatched after run cleanup.
9
+ */
10
+ export async function safeDispatchCustomEvent(
11
+ event: string,
12
+ payload: unknown,
13
+ config?: RunnableConfig
14
+ ): Promise<void> {
15
+ try {
16
+ await dispatchCustomEvent(event, payload, config);
17
+ } catch (e) {
18
+ // Check if this is the known EventStreamCallbackHandler error
19
+ if (
20
+ e instanceof Error &&
21
+ e.message.includes('handleCustomEvent: Run ID') &&
22
+ e.message.includes('not found in run map')
23
+ ) {
24
+ // Suppress this specific error - it's expected during parallel execution
25
+ // when EventStreamCallbackHandler loses track of run IDs
26
+ // console.debug('Suppressed error dispatching custom event:', e);
27
+ return;
28
+ }
29
+ // Log other errors
30
+ console.error('Error dispatching custom event:', e);
31
+ }
32
+ }
@@ -7,7 +7,7 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
7
7
  [Providers.OPENAI]: {
8
8
  provider: Providers.OPENAI,
9
9
  model: 'gpt-4.1',
10
- temperature: 0.7,
10
+ // temperature: 0.7,
11
11
  streaming: true,
12
12
  streamUsage: true,
13
13
  // disableStreaming: true,
@@ -32,7 +32,7 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
32
32
  provider: Providers.OPENROUTER,
33
33
  streaming: true,
34
34
  streamUsage: true,
35
- model: 'deepseek/deepseek-r1',
35
+ model: 'openai/gpt-4.1',
36
36
  openAIApiKey: process.env.OPENROUTER_API_KEY,
37
37
  configuration: {
38
38
  baseURL: process.env.OPENROUTER_BASE_URL,
@@ -56,10 +56,19 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
56
56
  },
57
57
  [Providers.OLLAMA]: {
58
58
  provider: Providers.OLLAMA,
59
- model: 'llama3.2',
59
+ model: 'gpt-oss:20b',
60
60
  streaming: true,
61
61
  streamUsage: true,
62
- baseUrl: 'http://host.docker.internal:11434',
62
+ baseUrl: 'http://localhost:11434',
63
+ },
64
+ lmstudio: {
65
+ provider: Providers.OPENAI,
66
+ model: 'gpt-oss-20b',
67
+ streaming: true,
68
+ streamUsage: true,
69
+ configuration: {
70
+ baseURL: 'http://192.168.254.183:1233/v1',
71
+ },
63
72
  },
64
73
  [Providers.DEEPSEEK]: {
65
74
  provider: Providers.DEEPSEEK,
@@ -93,21 +102,24 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
93
102
  },
94
103
  [Providers.VERTEXAI]: {
95
104
  provider: Providers.VERTEXAI,
96
- modelName: 'gemini-2.0-flash-001',
105
+ model: 'gemini-2.5-flash',
97
106
  streaming: true,
98
107
  streamUsage: true,
99
108
  keyFile: process.env.VERTEXAI_KEY_FILE,
100
109
  } as t.VertexAIClientOptions & t.LLMConfig,
101
110
  [Providers.GOOGLE]: {
102
111
  provider: Providers.GOOGLE,
103
- model: 'gemini-2.5-pro-exp-03-25',
112
+ model: 'gemini-2.5-flash',
104
113
  streaming: true,
105
114
  streamUsage: true,
106
115
  },
107
116
  [Providers.BEDROCK]: {
108
117
  provider: Providers.BEDROCK,
109
118
  // model: 'anthropic.claude-3-sonnet-20240229-v1:0',
110
- model: 'us.anthropic.claude-3-5-sonnet-20241022-v2:0',
119
+ // model: 'us.anthropic.claude-3-5-sonnet-20241022-v2:0',
120
+ // model: 'us.amazon.nova-pro-v1:0',
121
+ model: 'us.anthropic.claude-sonnet-4-20250514-v1:0',
122
+ // additionalModelRequestFields: { thinking: { type: 'enabled', budget_tokens: 2000 } },
111
123
  region: process.env.BEDROCK_AWS_REGION,
112
124
  credentials: {
113
125
  accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!,
@@ -1,51 +1,125 @@
1
1
  import { z } from 'zod';
2
- import { ChatPromptTemplate } from '@langchain/core/prompts';
3
2
  import { RunnableLambda } from '@langchain/core/runnables';
4
- import type { Runnable } from '@langchain/core/runnables';
5
- import * as t from '@/types';
6
-
7
- const defaultTitlePrompt = `Write a concise title for this conversation in the detected language. Title in 5 Words or Less. No Punctuation or Quotation.
8
- {convo}`;
3
+ import { ChatPromptTemplate } from '@langchain/core/prompts';
4
+ import type { Runnable, RunnableConfig } from '@langchain/core/runnables';
5
+ import type * as t from '@/types';
6
+ import { ContentTypes } from '@/common';
9
7
 
10
- const languageInstructions = 'Detect the language used in the following text. Note: words may be misspelled or cut off; use context clues to identify the language:\n{text}';
8
+ const defaultTitlePrompt = `Analyze this conversation and provide:
9
+ 1. The detected language of the conversation
10
+ 2. A concise title in the detected language (5 words or less, no punctuation or quotation)
11
11
 
12
- const languagePrompt = ChatPromptTemplate.fromTemplate(languageInstructions);
12
+ {convo}`;
13
13
 
14
- const languageSchema = z.object({
15
- language: z.string().describe('The detected language of the conversation')
14
+ const titleSchema = z.object({
15
+ title: z
16
+ .string()
17
+ .describe(
18
+ 'A concise title for the conversation in 5 words or less, without punctuation or quotation'
19
+ ),
16
20
  });
17
21
 
18
- const titleSchema = z.object({
19
- title: z.string().describe('A concise title for the conversation in 5 words or less, without punctuation or quotation'),
22
+ const combinedSchema = z.object({
23
+ language: z.string().describe('The detected language of the conversation'),
24
+ title: z
25
+ .string()
26
+ .describe(
27
+ 'A concise title for the conversation in 5 words or less, without punctuation or quotation'
28
+ ),
20
29
  });
21
30
 
22
- export const createTitleRunnable = async (model: t.ChatModelInstance, _titlePrompt?: string): Promise<Runnable> => {
31
+ export const createTitleRunnable = async (
32
+ model: t.ChatModelInstance,
33
+ _titlePrompt?: string
34
+ ): Promise<Runnable> => {
23
35
  // Disabled since this works fine
24
36
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
37
  /* @ts-ignore */
26
- const languageLLM = model.withStructuredOutput(languageSchema);
38
+ const titleLLM = model.withStructuredOutput(titleSchema);
27
39
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
28
40
  /* @ts-ignore */
29
- const titleLLM = model.withStructuredOutput(titleSchema);
41
+ const combinedLLM = model.withStructuredOutput(combinedSchema);
30
42
 
31
- const languageChain = languagePrompt.pipe(languageLLM);
32
-
33
- const titlePrompt = ChatPromptTemplate.fromTemplate(_titlePrompt ?? defaultTitlePrompt);
43
+ const titlePrompt = ChatPromptTemplate.fromTemplate(
44
+ _titlePrompt ?? defaultTitlePrompt
45
+ );
34
46
 
35
47
  return new RunnableLambda({
36
- func: async (input: { convo: string, inputText: string, skipLanguage: boolean }): Promise<{ language: string; title: string } | { title: string }> => {
48
+ func: async (
49
+ input: {
50
+ convo: string;
51
+ inputText: string;
52
+ skipLanguage: boolean;
53
+ },
54
+ config?: Partial<RunnableConfig>
55
+ ): Promise<{ language: string; title: string } | { title: string }> => {
37
56
  if (input.skipLanguage) {
38
- return await titlePrompt.pipe(titleLLM).invoke({
39
- convo: input.convo
40
- }) as { title: string };
57
+ return (await titlePrompt.pipe(titleLLM).invoke(
58
+ {
59
+ convo: input.convo,
60
+ },
61
+ config
62
+ )) as { title: string };
63
+ }
64
+
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
+ };
76
+ },
77
+ });
78
+ };
79
+
80
+ const defaultCompletionPrompt = `Provide a concise, 5-word-or-less title for the conversation, using title case conventions. Only return the title itself.
81
+
82
+ Conversation:
83
+ {convo}`;
84
+
85
+ export const createCompletionTitleRunnable = async (
86
+ model: t.ChatModelInstance,
87
+ titlePrompt?: string
88
+ ): Promise<Runnable> => {
89
+ const completionPrompt = ChatPromptTemplate.fromTemplate(
90
+ titlePrompt ?? defaultCompletionPrompt
91
+ );
92
+
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);
107
+ let content = '';
108
+ if (typeof response.content === 'string') {
109
+ content = response.content;
110
+ } else if (Array.isArray(response.content)) {
111
+ content = response.content
112
+ .filter(
113
+ (part): part is { type: ContentTypes.TEXT; text: string } =>
114
+ part.type === ContentTypes.TEXT
115
+ )
116
+ .map((part) => part.text)
117
+ .join('');
41
118
  }
42
- const languageResult = await languageChain.invoke({ text: input.inputText }) as { language: string } | undefined;
43
- const language = languageResult?.language ?? 'English';
44
- const titleResult = await titlePrompt.pipe(titleLLM).invoke({
45
- language,
46
- convo: input.convo
47
- }) as { title: string } | undefined;
48
- return { language, title: titleResult?.title ?? '' };
119
+ const title = content.trim();
120
+ return {
121
+ title,
122
+ };
49
123
  },
50
124
  });
51
- };
125
+ };
@@ -2,7 +2,10 @@ import { Tiktoken } from 'js-tiktoken/lite';
2
2
  import type { BaseMessage } from '@langchain/core/messages';
3
3
  import { ContentTypes } from '@/common/enum';
4
4
 
5
- export function getTokenCountForMessage(message: BaseMessage, getTokenCount: (text: string) => number): number {
5
+ export function getTokenCountForMessage(
6
+ message: BaseMessage,
7
+ getTokenCount: (text: string) => number
8
+ ): number {
6
9
  const tokensPerMessage = 3;
7
10
 
8
11
  const processValue = (value: unknown): void => {
@@ -57,14 +60,70 @@ export function getTokenCountForMessage(message: BaseMessage, getTokenCount: (te
57
60
  return numTokens;
58
61
  }
59
62
 
60
- export const createTokenCounter = async () => {
61
- const res = await fetch('https://tiktoken.pages.dev/js/o200k_base.json');
62
- const o200k_base = await res.json();
63
+ let encoderPromise: Promise<Tiktoken> | undefined;
64
+ let tokenCounterPromise: Promise<(message: BaseMessage) => number> | undefined;
63
65
 
64
- const countTokens = (text: string): number => {
65
- const enc = new Tiktoken(o200k_base);
66
- return enc.encode(text).length;
67
- };
66
+ async function getSharedEncoder(): Promise<Tiktoken> {
67
+ if (encoderPromise) {
68
+ return encoderPromise;
69
+ }
70
+ encoderPromise = (async (): Promise<Tiktoken> => {
71
+ const res = await fetch('https://tiktoken.pages.dev/js/o200k_base.json');
72
+ const o200k_base = await res.json();
73
+ return new Tiktoken(o200k_base);
74
+ })();
75
+ return encoderPromise;
76
+ }
77
+
78
+ /**
79
+ * Creates a singleton token counter function that reuses the same encoder instance.
80
+ * This avoids creating multiple function closures and prevents potential memory issues.
81
+ */
82
+ export const createTokenCounter = async (): Promise<
83
+ (message: BaseMessage) => number
84
+ > => {
85
+ if (tokenCounterPromise) {
86
+ return tokenCounterPromise;
87
+ }
88
+
89
+ tokenCounterPromise = (async (): Promise<
90
+ (message: BaseMessage) => number
91
+ > => {
92
+ const enc = await getSharedEncoder();
93
+ const countTokens = (text: string): number => enc.encode(text).length;
94
+ return (message: BaseMessage): number =>
95
+ getTokenCountForMessage(message, countTokens);
96
+ })();
97
+
98
+ return tokenCounterPromise;
99
+ };
100
+
101
+ /**
102
+ * Utility to manage the token encoder lifecycle explicitly.
103
+ * Useful for applications that need fine-grained control over resource management.
104
+ */
105
+ export const TokenEncoderManager = {
106
+ /**
107
+ * Pre-initializes the encoder. This can be called during app startup
108
+ * to avoid lazy loading delays later.
109
+ */
110
+ async initialize(): Promise<void> {
111
+ await getSharedEncoder();
112
+ },
113
+
114
+ /**
115
+ * Clears the cached encoder and token counter.
116
+ * Useful for testing or when you need to force a fresh reload.
117
+ */
118
+ reset(): void {
119
+ encoderPromise = undefined;
120
+ tokenCounterPromise = undefined;
121
+ },
68
122
 
69
- return (message: BaseMessage): number => getTokenCountForMessage(message, countTokens);
70
- };
123
+ /**
124
+ * Checks if the encoder has been initialized.
125
+ */
126
+ isInitialized(): boolean {
127
+ return encoderPromise !== undefined;
128
+ },
129
+ };
@@ -1 +0,0 @@
1
- export {};
@@ -1,6 +0,0 @@
1
- export declare function getArgs(): Promise<{
2
- userName: string;
3
- location: string;
4
- provider: string;
5
- currentDate: string;
6
- }>;
@@ -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;