@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
@@ -0,0 +1,672 @@
1
+ 'use strict';
2
+
3
+ var messages = require('@langchain/core/messages');
4
+ var outputs = require('@langchain/core/outputs');
5
+ var openai_tools = require('@langchain/core/output_parsers/openai_tools');
6
+
7
+ function extractGenericMessageCustomRole(message) {
8
+ if (message.role !== 'system' &&
9
+ message.role !== 'developer' &&
10
+ message.role !== 'assistant' &&
11
+ message.role !== 'user' &&
12
+ message.role !== 'function' &&
13
+ message.role !== 'tool') {
14
+ console.warn(`Unknown message role: ${message.role}`);
15
+ }
16
+ return message.role;
17
+ }
18
+ function messageToOpenAIRole(message) {
19
+ const type = message._getType();
20
+ switch (type) {
21
+ case 'system':
22
+ return 'system';
23
+ case 'ai':
24
+ return 'assistant';
25
+ case 'human':
26
+ return 'user';
27
+ case 'function':
28
+ return 'function';
29
+ case 'tool':
30
+ return 'tool';
31
+ case 'generic': {
32
+ if (!messages.ChatMessage.isInstance(message))
33
+ throw new Error('Invalid generic chat message');
34
+ return extractGenericMessageCustomRole(message);
35
+ }
36
+ default:
37
+ throw new Error(`Unknown message type: ${type}`);
38
+ }
39
+ }
40
+ const completionsApiContentBlockConverter = {
41
+ providerName: 'ChatOpenAI',
42
+ fromStandardTextBlock(block) {
43
+ return { type: 'text', text: block.text };
44
+ },
45
+ fromStandardImageBlock(block) {
46
+ if (block.source_type === 'url') {
47
+ return {
48
+ type: 'image_url',
49
+ image_url: {
50
+ url: block.url,
51
+ ...(block.metadata?.detail
52
+ ? { detail: block.metadata.detail }
53
+ : {}),
54
+ },
55
+ };
56
+ }
57
+ if (block.source_type === 'base64') {
58
+ const url = `data:${block.mime_type ?? ''};base64,${block.data}`;
59
+ return {
60
+ type: 'image_url',
61
+ image_url: {
62
+ url,
63
+ ...(block.metadata?.detail
64
+ ? { detail: block.metadata.detail }
65
+ : {}),
66
+ },
67
+ };
68
+ }
69
+ throw new Error(`Image content blocks with source_type ${block.source_type} are not supported for ChatOpenAI`);
70
+ },
71
+ fromStandardAudioBlock(block) {
72
+ if (block.source_type === 'url') {
73
+ const data = messages.parseBase64DataUrl({ dataUrl: block.url });
74
+ if (!data) {
75
+ throw new Error(`URL audio blocks with source_type ${block.source_type} must be formatted as a data URL for ChatOpenAI`);
76
+ }
77
+ const rawMimeType = data.mime_type || block.mime_type || '';
78
+ let mimeType;
79
+ try {
80
+ mimeType = messages.parseMimeType(rawMimeType);
81
+ }
82
+ catch {
83
+ throw new Error(`Audio blocks with source_type ${block.source_type} must have mime type of audio/wav or audio/mp3`);
84
+ }
85
+ if (mimeType.type !== 'audio' ||
86
+ (mimeType.subtype !== 'wav' && mimeType.subtype !== 'mp3')) {
87
+ throw new Error(`Audio blocks with source_type ${block.source_type} must have mime type of audio/wav or audio/mp3`);
88
+ }
89
+ return {
90
+ type: 'input_audio',
91
+ input_audio: {
92
+ format: mimeType.subtype,
93
+ data: data.data,
94
+ },
95
+ };
96
+ }
97
+ if (block.source_type === 'base64') {
98
+ let mimeType;
99
+ try {
100
+ mimeType = messages.parseMimeType(block.mime_type ?? '');
101
+ }
102
+ catch {
103
+ throw new Error(`Audio blocks with source_type ${block.source_type} must have mime type of audio/wav or audio/mp3`);
104
+ }
105
+ if (mimeType.type !== 'audio' ||
106
+ (mimeType.subtype !== 'wav' && mimeType.subtype !== 'mp3')) {
107
+ throw new Error(`Audio blocks with source_type ${block.source_type} must have mime type of audio/wav or audio/mp3`);
108
+ }
109
+ return {
110
+ type: 'input_audio',
111
+ input_audio: {
112
+ format: mimeType.subtype,
113
+ data: block.data,
114
+ },
115
+ };
116
+ }
117
+ throw new Error(`Audio content blocks with source_type ${block.source_type} are not supported for ChatOpenAI`);
118
+ },
119
+ fromStandardFileBlock(block) {
120
+ if (block.source_type === 'url') {
121
+ const data = messages.parseBase64DataUrl({ dataUrl: block.url });
122
+ if (!data) {
123
+ throw new Error(`URL file blocks with source_type ${block.source_type} must be formatted as a data URL for ChatOpenAI`);
124
+ }
125
+ return {
126
+ type: 'file',
127
+ file: {
128
+ file_data: block.url, // formatted as base64 data URL
129
+ ...(block.metadata?.filename || block.metadata?.name
130
+ ? {
131
+ filename: (block.metadata.filename ||
132
+ block.metadata.name),
133
+ }
134
+ : {}),
135
+ },
136
+ };
137
+ }
138
+ if (block.source_type === 'base64') {
139
+ return {
140
+ type: 'file',
141
+ file: {
142
+ file_data: `data:${block.mime_type ?? ''};base64,${block.data}`,
143
+ ...(block.metadata?.filename ||
144
+ block.metadata?.name ||
145
+ block.metadata?.title
146
+ ? {
147
+ filename: (block.metadata.filename ||
148
+ block.metadata.name ||
149
+ block.metadata.title),
150
+ }
151
+ : {}),
152
+ },
153
+ };
154
+ }
155
+ if (block.source_type === 'id') {
156
+ return {
157
+ type: 'file',
158
+ file: {
159
+ file_id: block.id,
160
+ },
161
+ };
162
+ }
163
+ throw new Error(`File content blocks with source_type ${block.source_type} are not supported for ChatOpenAI`);
164
+ },
165
+ };
166
+ // Used in LangSmith, export is important here
167
+ function _convertMessagesToOpenAIParams(messages$1, model) {
168
+ // TODO: Function messages do not support array content, fix cast
169
+ return messages$1.flatMap((message) => {
170
+ let role = messageToOpenAIRole(message);
171
+ if (role === 'system' && isReasoningModel(model)) {
172
+ role = 'developer';
173
+ }
174
+ const content = typeof message.content === 'string'
175
+ ? message.content
176
+ : message.content.map((m) => {
177
+ if (messages.isDataContentBlock(m)) {
178
+ return messages.convertToProviderContentBlock(m, completionsApiContentBlockConverter);
179
+ }
180
+ return m;
181
+ });
182
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
+ const completionParam = {
184
+ role,
185
+ content,
186
+ };
187
+ if (message.name != null) {
188
+ completionParam.name = message.name;
189
+ }
190
+ if (message.additional_kwargs.function_call != null) {
191
+ completionParam.function_call = message.additional_kwargs.function_call;
192
+ completionParam.content = '';
193
+ }
194
+ if (messages.isAIMessage(message) && !!message.tool_calls?.length) {
195
+ completionParam.tool_calls = message.tool_calls.map(openai_tools.convertLangChainToolCallToOpenAI);
196
+ completionParam.content = '';
197
+ }
198
+ else {
199
+ if (message.additional_kwargs.tool_calls != null) {
200
+ completionParam.tool_calls = message.additional_kwargs.tool_calls;
201
+ }
202
+ if (message.tool_call_id != null) {
203
+ completionParam.tool_call_id = message.tool_call_id;
204
+ }
205
+ }
206
+ if (message.additional_kwargs.audio &&
207
+ typeof message.additional_kwargs.audio === 'object' &&
208
+ 'id' in message.additional_kwargs.audio) {
209
+ const audioMessage = {
210
+ role: 'assistant',
211
+ audio: {
212
+ id: message.additional_kwargs.audio.id,
213
+ },
214
+ };
215
+ return [completionParam, audioMessage];
216
+ }
217
+ return completionParam;
218
+ });
219
+ }
220
+ const _FUNCTION_CALL_IDS_MAP_KEY = '__openai_function_call_ids__';
221
+ function _convertReasoningSummaryToOpenAIResponsesParams(reasoning) {
222
+ // combine summary parts that have the the same index and then remove the indexes
223
+ const summary = (reasoning.summary.length > 1
224
+ ? reasoning.summary.reduce((acc, curr) => {
225
+ const last = acc.at(-1);
226
+ if (last.index === curr.index) {
227
+ last.text += curr.text;
228
+ }
229
+ else {
230
+ acc.push(curr);
231
+ }
232
+ return acc;
233
+ }, [{ ...reasoning.summary[0] }])
234
+ : reasoning.summary).map((s) => Object.fromEntries(Object.entries(s).filter(([k]) => k !== 'index')));
235
+ return {
236
+ ...reasoning,
237
+ summary,
238
+ };
239
+ }
240
+ function _convertMessagesToOpenAIResponsesParams(messages$1, model, zdrEnabled) {
241
+ return messages$1.flatMap((lcMsg) => {
242
+ const additional_kwargs = lcMsg.additional_kwargs;
243
+ let role = messageToOpenAIRole(lcMsg);
244
+ if (role === 'system' && isReasoningModel(model))
245
+ role = 'developer';
246
+ if (role === 'function') {
247
+ throw new Error('Function messages are not supported in Responses API');
248
+ }
249
+ if (role === 'tool') {
250
+ const toolMessage = lcMsg;
251
+ // Handle computer call output
252
+ if (additional_kwargs.type === 'computer_call_output') {
253
+ const output = (() => {
254
+ if (typeof toolMessage.content === 'string') {
255
+ return {
256
+ type: 'computer_screenshot',
257
+ image_url: toolMessage.content,
258
+ };
259
+ }
260
+ if (Array.isArray(toolMessage.content)) {
261
+ const oaiScreenshot = toolMessage.content.find((i) => i.type === 'computer_screenshot');
262
+ if (oaiScreenshot)
263
+ return oaiScreenshot;
264
+ const lcImage = toolMessage.content.find((i) => i.type === 'image_url');
265
+ if (lcImage) {
266
+ return {
267
+ type: 'computer_screenshot',
268
+ image_url: typeof lcImage.image_url === 'string'
269
+ ? lcImage.image_url
270
+ : lcImage.image_url.url,
271
+ };
272
+ }
273
+ }
274
+ throw new Error('Invalid computer call output');
275
+ })();
276
+ return {
277
+ type: 'computer_call_output',
278
+ output,
279
+ call_id: toolMessage.tool_call_id,
280
+ };
281
+ }
282
+ return {
283
+ type: 'function_call_output',
284
+ call_id: toolMessage.tool_call_id,
285
+ id: toolMessage.id?.startsWith('fc_') ? toolMessage.id : undefined,
286
+ output: typeof toolMessage.content !== 'string'
287
+ ? JSON.stringify(toolMessage.content)
288
+ : toolMessage.content,
289
+ };
290
+ }
291
+ if (role === 'assistant') {
292
+ // if we have the original response items, just reuse them
293
+ if (!zdrEnabled &&
294
+ lcMsg.response_metadata.output != null &&
295
+ Array.isArray(lcMsg.response_metadata.output) &&
296
+ lcMsg.response_metadata.output.length > 0 &&
297
+ lcMsg.response_metadata.output.every((item) => 'type' in item)) {
298
+ return lcMsg.response_metadata.output;
299
+ }
300
+ // otherwise, try to reconstruct the response from what we have
301
+ const input = [];
302
+ // reasoning items
303
+ if (additional_kwargs.reasoning && !zdrEnabled) {
304
+ const reasoningItem = _convertReasoningSummaryToOpenAIResponsesParams(additional_kwargs.reasoning);
305
+ input.push(reasoningItem);
306
+ }
307
+ // ai content
308
+ let { content } = lcMsg;
309
+ if (additional_kwargs.refusal) {
310
+ if (typeof content === 'string') {
311
+ content = [{ type: 'output_text', text: content, annotations: [] }];
312
+ }
313
+ content = [
314
+ ...content,
315
+ { type: 'refusal', refusal: additional_kwargs.refusal },
316
+ ];
317
+ }
318
+ input.push({
319
+ type: 'message',
320
+ role: 'assistant',
321
+ ...(lcMsg.id && !zdrEnabled ? { id: lcMsg.id } : {}),
322
+ content: typeof content === 'string'
323
+ ? content
324
+ : content.flatMap((item) => {
325
+ if (item.type === 'text') {
326
+ return {
327
+ type: 'output_text',
328
+ text: item.text,
329
+ // @ts-expect-error TODO: add types for `annotations`
330
+ annotations: item.annotations ?? [],
331
+ };
332
+ }
333
+ if (item.type === 'output_text' || item.type === 'refusal') {
334
+ return item;
335
+ }
336
+ return [];
337
+ }),
338
+ });
339
+ const functionCallIds = additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY];
340
+ if (messages.isAIMessage(lcMsg) && !!lcMsg.tool_calls?.length) {
341
+ input.push(...lcMsg.tool_calls.map((toolCall) => ({
342
+ type: 'function_call',
343
+ name: toolCall.name,
344
+ arguments: JSON.stringify(toolCall.args),
345
+ call_id: toolCall.id,
346
+ ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
347
+ })));
348
+ }
349
+ else if (additional_kwargs.tool_calls) {
350
+ input.push(...additional_kwargs.tool_calls.map((toolCall) => ({
351
+ type: 'function_call',
352
+ name: toolCall.function.name,
353
+ call_id: toolCall.id,
354
+ arguments: toolCall.function.arguments,
355
+ ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
356
+ })));
357
+ }
358
+ const toolOutputs = (lcMsg.response_metadata.output?.length ?? 0) > 0
359
+ ? lcMsg.response_metadata.output
360
+ : additional_kwargs.tool_outputs;
361
+ const fallthroughCallTypes = [
362
+ 'computer_call',
363
+ /** @ts-ignore */
364
+ 'mcp_call',
365
+ /** @ts-ignore */
366
+ 'code_interpreter_call',
367
+ /** @ts-ignore */
368
+ 'image_generation_call',
369
+ ];
370
+ if (toolOutputs != null) {
371
+ const castToolOutputs = toolOutputs;
372
+ const fallthroughCalls = castToolOutputs.filter((item) => fallthroughCallTypes.includes(item.type));
373
+ if (fallthroughCalls.length > 0)
374
+ input.push(...fallthroughCalls);
375
+ }
376
+ return input;
377
+ }
378
+ if (role === 'user' || role === 'system' || role === 'developer') {
379
+ if (typeof lcMsg.content === 'string') {
380
+ return { type: 'message', role, content: lcMsg.content };
381
+ }
382
+ const messages$1 = [];
383
+ const content = lcMsg.content.flatMap((item) => {
384
+ if (item.type === 'mcp_approval_response') {
385
+ messages$1.push({
386
+ // @ts-ignore
387
+ type: 'mcp_approval_response',
388
+ approval_request_id: item.approval_request_id,
389
+ approve: item.approve,
390
+ });
391
+ }
392
+ if (messages.isDataContentBlock(item)) {
393
+ return messages.convertToProviderContentBlock(item, completionsApiContentBlockConverter);
394
+ }
395
+ if (item.type === 'text') {
396
+ return {
397
+ type: 'input_text',
398
+ text: item.text,
399
+ };
400
+ }
401
+ if (item.type === 'image_url') {
402
+ return {
403
+ type: 'input_image',
404
+ image_url: typeof item.image_url === 'string'
405
+ ? item.image_url
406
+ : item.image_url.url,
407
+ detail: typeof item.image_url === 'string'
408
+ ? 'auto'
409
+ : item.image_url.detail,
410
+ };
411
+ }
412
+ if (item.type === 'input_text' ||
413
+ item.type === 'input_image' ||
414
+ item.type === 'input_file') {
415
+ return item;
416
+ }
417
+ return [];
418
+ });
419
+ if (content.length > 0) {
420
+ messages$1.push({ type: 'message', role, content });
421
+ }
422
+ return messages$1;
423
+ }
424
+ console.warn(`Unsupported role found when converting to OpenAI Responses API: ${role}`);
425
+ return [];
426
+ });
427
+ }
428
+ function isReasoningModel(model) {
429
+ return model != null && model !== '' && /\b(o\d|gpt-[5-9])\b/i.test(model);
430
+ }
431
+ function _convertOpenAIResponsesMessageToBaseMessage(response) {
432
+ if (response.error) {
433
+ // TODO: add support for `addLangChainErrorFields`
434
+ const error = new Error(response.error.message);
435
+ error.name = response.error.code;
436
+ throw error;
437
+ }
438
+ let messageId;
439
+ const content = [];
440
+ const tool_calls = [];
441
+ const invalid_tool_calls = [];
442
+ const response_metadata = {
443
+ model: response.model,
444
+ created_at: response.created_at,
445
+ id: response.id,
446
+ incomplete_details: response.incomplete_details,
447
+ metadata: response.metadata,
448
+ object: response.object,
449
+ status: response.status,
450
+ user: response.user,
451
+ service_tier: response.service_tier,
452
+ // for compatibility with chat completion calls.
453
+ model_name: response.model,
454
+ };
455
+ const additional_kwargs = {};
456
+ for (const item of response.output) {
457
+ if (item.type === 'message') {
458
+ messageId = item.id;
459
+ content.push(...item.content.flatMap((part) => {
460
+ if (part.type === 'output_text') {
461
+ if ('parsed' in part && part.parsed != null) {
462
+ additional_kwargs.parsed = part.parsed;
463
+ }
464
+ return {
465
+ type: 'text',
466
+ text: part.text,
467
+ annotations: part.annotations,
468
+ };
469
+ }
470
+ if (part.type === 'refusal') {
471
+ additional_kwargs.refusal = part.refusal;
472
+ return [];
473
+ }
474
+ return part;
475
+ }));
476
+ }
477
+ else if (item.type === 'function_call') {
478
+ const fnAdapter = {
479
+ function: { name: item.name, arguments: item.arguments },
480
+ id: item.call_id,
481
+ };
482
+ try {
483
+ tool_calls.push(openai_tools.parseToolCall(fnAdapter, { returnId: true }));
484
+ }
485
+ catch (e) {
486
+ let errMessage;
487
+ if (typeof e === 'object' &&
488
+ e != null &&
489
+ 'message' in e &&
490
+ typeof e.message === 'string') {
491
+ errMessage = e.message;
492
+ }
493
+ invalid_tool_calls.push(openai_tools.makeInvalidToolCall(fnAdapter, errMessage));
494
+ }
495
+ additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY] ??= {};
496
+ if (item.id) {
497
+ additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY][item.call_id] = item.id;
498
+ }
499
+ }
500
+ else if (item.type === 'reasoning') {
501
+ additional_kwargs.reasoning = item;
502
+ }
503
+ else {
504
+ additional_kwargs.tool_outputs ??= [];
505
+ additional_kwargs.tool_outputs.push(item);
506
+ }
507
+ }
508
+ return new messages.AIMessage({
509
+ id: messageId,
510
+ content,
511
+ tool_calls,
512
+ invalid_tool_calls,
513
+ usage_metadata: response.usage,
514
+ additional_kwargs,
515
+ response_metadata,
516
+ });
517
+ }
518
+ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
519
+ const content = [];
520
+ let generationInfo = {};
521
+ let usage_metadata;
522
+ const tool_call_chunks = [];
523
+ const response_metadata = {};
524
+ const additional_kwargs = {};
525
+ let id;
526
+ if (chunk.type === 'response.output_text.delta') {
527
+ content.push({
528
+ type: 'text',
529
+ text: chunk.delta,
530
+ index: chunk.content_index,
531
+ });
532
+ /** @ts-ignore */
533
+ }
534
+ else if (chunk.type === 'response.output_text_annotation.added') {
535
+ content.push({
536
+ type: 'text',
537
+ text: '',
538
+ /** @ts-ignore */
539
+ annotations: [chunk.annotation],
540
+ /** @ts-ignore */
541
+ index: chunk.content_index,
542
+ });
543
+ }
544
+ else if (chunk.type === 'response.output_item.added' &&
545
+ chunk.item.type === 'message') {
546
+ id = chunk.item.id;
547
+ }
548
+ else if (chunk.type === 'response.output_item.added' &&
549
+ chunk.item.type === 'function_call') {
550
+ tool_call_chunks.push({
551
+ type: 'tool_call_chunk',
552
+ name: chunk.item.name,
553
+ args: chunk.item.arguments,
554
+ id: chunk.item.call_id,
555
+ index: chunk.output_index,
556
+ });
557
+ additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY] = {
558
+ [chunk.item.call_id]: chunk.item.id,
559
+ };
560
+ }
561
+ else if (chunk.type === 'response.output_item.done' &&
562
+ [
563
+ 'web_search_call',
564
+ 'file_search_call',
565
+ 'computer_call',
566
+ 'code_interpreter_call',
567
+ 'mcp_call',
568
+ 'mcp_list_tools',
569
+ 'mcp_approval_request',
570
+ 'image_generation_call',
571
+ ].includes(chunk.item.type)) {
572
+ additional_kwargs.tool_outputs = [chunk.item];
573
+ }
574
+ else if (chunk.type === 'response.created') {
575
+ response_metadata.id = chunk.response.id;
576
+ response_metadata.model_name = chunk.response.model;
577
+ response_metadata.model = chunk.response.model;
578
+ }
579
+ else if (chunk.type === 'response.completed') {
580
+ const msg = _convertOpenAIResponsesMessageToBaseMessage(chunk.response);
581
+ usage_metadata = chunk.response.usage;
582
+ if (chunk.response.text?.format?.type === 'json_schema') {
583
+ additional_kwargs.parsed ??= JSON.parse(msg.text);
584
+ }
585
+ for (const [key, value] of Object.entries(chunk.response)) {
586
+ if (key !== 'id')
587
+ response_metadata[key] = value;
588
+ }
589
+ }
590
+ else if (chunk.type === 'response.function_call_arguments.delta') {
591
+ tool_call_chunks.push({
592
+ type: 'tool_call_chunk',
593
+ args: chunk.delta,
594
+ index: chunk.output_index,
595
+ });
596
+ }
597
+ else if (chunk.type === 'response.web_search_call.completed' ||
598
+ chunk.type === 'response.file_search_call.completed') {
599
+ generationInfo = {
600
+ tool_outputs: {
601
+ id: chunk.item_id,
602
+ type: chunk.type.replace('response.', '').replace('.completed', ''),
603
+ status: 'completed',
604
+ },
605
+ };
606
+ }
607
+ else if (chunk.type === 'response.refusal.done') {
608
+ additional_kwargs.refusal = chunk.refusal;
609
+ }
610
+ else if (chunk.type === 'response.output_item.added' &&
611
+ 'item' in chunk &&
612
+ chunk.item.type === 'reasoning') {
613
+ const summary = chunk
614
+ .item.summary
615
+ ? chunk.item.summary.map((s, index) => ({
616
+ ...s,
617
+ index,
618
+ }))
619
+ : undefined;
620
+ additional_kwargs.reasoning = {
621
+ // We only capture ID in the first chunk or else the concatenated result of all chunks will
622
+ // have an ID field that is repeated once per chunk. There is special handling for the `type`
623
+ // field that prevents this, however.
624
+ id: chunk.item.id,
625
+ type: chunk.item.type,
626
+ ...(summary ? { summary } : {}),
627
+ };
628
+ }
629
+ else if (chunk.type === 'response.reasoning_summary_part.added') {
630
+ additional_kwargs.reasoning = {
631
+ type: 'reasoning',
632
+ summary: [{ ...chunk.part, index: chunk.summary_index }],
633
+ };
634
+ }
635
+ else if (chunk.type === 'response.reasoning_summary_text.delta') {
636
+ additional_kwargs.reasoning = {
637
+ type: 'reasoning',
638
+ summary: [
639
+ { text: chunk.delta, type: 'summary_text', index: chunk.summary_index },
640
+ ],
641
+ };
642
+ /** @ts-ignore */
643
+ }
644
+ else if (chunk.type === 'response.image_generation_call.partial_image') {
645
+ // noop/fixme: retaining partial images in a message chunk means that _all_
646
+ // partial images get kept in history, so we don't do anything here.
647
+ return null;
648
+ }
649
+ else {
650
+ return null;
651
+ }
652
+ return new outputs.ChatGenerationChunk({
653
+ // Legacy reasons, `onLLMNewToken` should pulls this out
654
+ text: content.map((part) => part.text).join(''),
655
+ message: new messages.AIMessageChunk({
656
+ id,
657
+ content,
658
+ tool_call_chunks,
659
+ usage_metadata,
660
+ additional_kwargs,
661
+ response_metadata,
662
+ }),
663
+ generationInfo,
664
+ });
665
+ }
666
+
667
+ exports._convertMessagesToOpenAIParams = _convertMessagesToOpenAIParams;
668
+ exports._convertMessagesToOpenAIResponsesParams = _convertMessagesToOpenAIResponsesParams;
669
+ exports._convertOpenAIResponsesDeltaToBaseMessageChunk = _convertOpenAIResponsesDeltaToBaseMessageChunk;
670
+ exports.isReasoningModel = isReasoningModel;
671
+ exports.messageToOpenAIRole = messageToOpenAIRole;
672
+ //# sourceMappingURL=index.cjs.map