@librechat/agents 3.6.15 → 3.7.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 (180) hide show
  1. package/README.md +41 -0
  2. package/dist/cjs/_virtual/_rolldown/runtime.cjs +10 -0
  3. package/dist/cjs/agents/AgentContext.cjs +1 -1
  4. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  5. package/dist/cjs/graphs/Graph.cjs +13 -13
  6. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  7. package/dist/cjs/lazyRequire.cjs +33 -0
  8. package/dist/cjs/lazyRequire.cjs.map +1 -0
  9. package/dist/cjs/llm/anthropic/index.cjs +13 -0
  10. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  11. package/dist/cjs/llm/bedrock/index.cjs +10 -1
  12. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  13. package/dist/cjs/llm/bedrock/toolCache.cjs +3 -2
  14. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  15. package/dist/cjs/llm/google/index.cjs +10 -1
  16. package/dist/cjs/llm/google/index.cjs.map +1 -1
  17. package/dist/cjs/llm/init.cjs +7 -4
  18. package/dist/cjs/llm/init.cjs.map +1 -1
  19. package/dist/cjs/llm/invoke.cjs +9 -2
  20. package/dist/cjs/llm/invoke.cjs.map +1 -1
  21. package/dist/cjs/llm/mistral/index.cjs +9 -0
  22. package/dist/cjs/llm/mistral/index.cjs.map +1 -1
  23. package/dist/cjs/llm/openai/index.cjs +41 -1
  24. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  25. package/dist/cjs/llm/openrouter/index.cjs +12 -3
  26. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  27. package/dist/cjs/llm/openrouter/toolCache.cjs +3 -2
  28. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  29. package/dist/cjs/llm/prepareProviderRequest.cjs +6 -3
  30. package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -1
  31. package/dist/cjs/llm/providerRegistry.cjs +81 -0
  32. package/dist/cjs/llm/providerRegistry.cjs.map +1 -0
  33. package/dist/cjs/llm/providers.cjs +37 -28
  34. package/dist/cjs/llm/providers.cjs.map +1 -1
  35. package/dist/cjs/llm/providers.eager.cjs +21 -0
  36. package/dist/cjs/llm/providers.eager.cjs.map +1 -0
  37. package/dist/cjs/llm/request.cjs +6 -4
  38. package/dist/cjs/llm/request.cjs.map +1 -1
  39. package/dist/cjs/llm/truncation.cjs +2 -1
  40. package/dist/cjs/llm/truncation.cjs.map +1 -1
  41. package/dist/cjs/llm/vertexai/index.cjs +17 -0
  42. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  43. package/dist/cjs/main.cjs +19 -18
  44. package/dist/cjs/messages/core.cjs +9 -4
  45. package/dist/cjs/messages/core.cjs.map +1 -1
  46. package/dist/cjs/messages/format.cjs.map +1 -1
  47. package/dist/cjs/messages/prune.cjs +50 -12
  48. package/dist/cjs/messages/prune.cjs.map +1 -1
  49. package/dist/cjs/provider-registration.cjs +4 -0
  50. package/dist/cjs/run.cjs +9 -4
  51. package/dist/cjs/run.cjs.map +1 -1
  52. package/dist/cjs/stream.cjs +1 -1
  53. package/dist/cjs/stream.cjs.map +1 -1
  54. package/dist/cjs/summarization/node.cjs +2 -2
  55. package/dist/cjs/summarization/node.cjs.map +1 -1
  56. package/dist/cjs/tools/Calculator.cjs +7 -4
  57. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  58. package/dist/cjs/tools/CodeExecutor.cjs +1 -1
  59. package/dist/cjs/utils/llm.cjs +22 -4
  60. package/dist/cjs/utils/llm.cjs.map +1 -1
  61. package/dist/esm/_virtual/_rolldown/runtime.mjs +14 -0
  62. package/dist/esm/agents/AgentContext.mjs +1 -1
  63. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  64. package/dist/esm/graphs/Graph.mjs +13 -13
  65. package/dist/esm/graphs/Graph.mjs.map +1 -1
  66. package/dist/esm/lazyRequire.mjs +30 -0
  67. package/dist/esm/lazyRequire.mjs.map +1 -0
  68. package/dist/esm/llm/anthropic/index.mjs +6 -1
  69. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  70. package/dist/esm/llm/bedrock/index.mjs +4 -2
  71. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  72. package/dist/esm/llm/bedrock/toolCache.mjs +3 -2
  73. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  74. package/dist/esm/llm/google/index.mjs +4 -2
  75. package/dist/esm/llm/google/index.mjs.map +1 -1
  76. package/dist/esm/llm/init.mjs +8 -5
  77. package/dist/esm/llm/init.mjs.map +1 -1
  78. package/dist/esm/llm/invoke.mjs +9 -2
  79. package/dist/esm/llm/invoke.mjs.map +1 -1
  80. package/dist/esm/llm/mistral/index.mjs +3 -1
  81. package/dist/esm/llm/mistral/index.mjs.map +1 -1
  82. package/dist/esm/llm/openai/index.mjs +31 -9
  83. package/dist/esm/llm/openai/index.mjs.map +1 -1
  84. package/dist/esm/llm/openrouter/index.mjs +3 -1
  85. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  86. package/dist/esm/llm/openrouter/toolCache.mjs +3 -2
  87. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  88. package/dist/esm/llm/prepareProviderRequest.mjs +7 -4
  89. package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -1
  90. package/dist/esm/llm/providerRegistry.mjs +76 -0
  91. package/dist/esm/llm/providerRegistry.mjs.map +1 -0
  92. package/dist/esm/llm/providers.eager.mjs +22 -0
  93. package/dist/esm/llm/providers.eager.mjs.map +1 -0
  94. package/dist/esm/llm/providers.mjs +38 -28
  95. package/dist/esm/llm/providers.mjs.map +1 -1
  96. package/dist/esm/llm/request.mjs +6 -4
  97. package/dist/esm/llm/request.mjs.map +1 -1
  98. package/dist/esm/llm/truncation.mjs +2 -1
  99. package/dist/esm/llm/truncation.mjs.map +1 -1
  100. package/dist/esm/llm/vertexai/index.mjs +8 -1
  101. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  102. package/dist/esm/main.mjs +12 -13
  103. package/dist/esm/messages/core.mjs +9 -5
  104. package/dist/esm/messages/core.mjs.map +1 -1
  105. package/dist/esm/messages/format.mjs.map +1 -1
  106. package/dist/esm/messages/prune.mjs +50 -13
  107. package/dist/esm/messages/prune.mjs.map +1 -1
  108. package/dist/esm/provider-registration.mjs +3 -0
  109. package/dist/esm/run.mjs +10 -5
  110. package/dist/esm/run.mjs.map +1 -1
  111. package/dist/esm/stream.mjs +1 -1
  112. package/dist/esm/stream.mjs.map +1 -1
  113. package/dist/esm/summarization/node.mjs +2 -2
  114. package/dist/esm/summarization/node.mjs.map +1 -1
  115. package/dist/esm/tools/Calculator.mjs +7 -2
  116. package/dist/esm/tools/Calculator.mjs.map +1 -1
  117. package/dist/esm/tools/CodeExecutor.mjs +1 -1
  118. package/dist/esm/utils/llm.mjs +21 -5
  119. package/dist/esm/utils/llm.mjs.map +1 -1
  120. package/dist/types/agents/AgentContext.d.ts +5 -5
  121. package/dist/types/index.d.ts +5 -3
  122. package/dist/types/lazyRequire.d.ts +8 -0
  123. package/dist/types/llm/contextOverflowRecovery.d.ts +2 -2
  124. package/dist/types/llm/init.d.ts +21 -14
  125. package/dist/types/llm/invoke.d.ts +5 -6
  126. package/dist/types/llm/prepareProviderRequest.d.ts +5 -6
  127. package/dist/types/llm/providerRegistry.d.ts +22 -0
  128. package/dist/types/llm/providers.d.ts +4 -5
  129. package/dist/types/llm/providers.eager.d.ts +1 -0
  130. package/dist/types/llm/request.d.ts +2 -3
  131. package/dist/types/llm/truncation.d.ts +2 -2
  132. package/dist/types/messages/core.d.ts +3 -2
  133. package/dist/types/messages/format.d.ts +3 -3
  134. package/dist/types/messages/prune.d.ts +8 -6
  135. package/dist/types/provider-registration.d.ts +15 -0
  136. package/dist/types/stream.d.ts +1 -2
  137. package/dist/types/summarization/node.d.ts +1 -2
  138. package/dist/types/types/activityLabel.d.ts +3 -4
  139. package/dist/types/types/graph.d.ts +4 -5
  140. package/dist/types/types/llm.d.ts +54 -13
  141. package/dist/types/types/reasoningLabel.d.ts +2 -3
  142. package/dist/types/types/run.d.ts +3 -3
  143. package/dist/types/types/summarize.d.ts +2 -2
  144. package/dist/types/utils/errors.d.ts +3 -3
  145. package/dist/types/utils/llm.d.ts +14 -4
  146. package/dist/types/utils/llmConfig.d.ts +2 -2
  147. package/package.json +66 -1
  148. package/src/agents/AgentContext.ts +27 -26
  149. package/src/graphs/Graph.ts +16 -22
  150. package/src/index.ts +8 -3
  151. package/src/lazyRequire.ts +67 -0
  152. package/src/llm/bedrock/toolCache.ts +6 -2
  153. package/src/llm/contextOverflowRecovery.ts +2 -2
  154. package/src/llm/init.ts +55 -25
  155. package/src/llm/invoke.ts +36 -21
  156. package/src/llm/openrouter/toolCache.ts +8 -2
  157. package/src/llm/prepareProviderRequest.ts +19 -18
  158. package/src/llm/providerRegistry.ts +174 -0
  159. package/src/llm/providers.eager.ts +24 -0
  160. package/src/llm/providers.ts +99 -42
  161. package/src/llm/request.ts +10 -6
  162. package/src/llm/truncation.ts +9 -3
  163. package/src/messages/core.ts +18 -13
  164. package/src/messages/format.ts +14 -16
  165. package/src/messages/prune.ts +108 -28
  166. package/src/provider-registration.ts +29 -0
  167. package/src/run.ts +15 -7
  168. package/src/session/AgentSession.ts +1 -1
  169. package/src/stream.ts +7 -8
  170. package/src/summarization/node.ts +7 -7
  171. package/src/tools/Calculator.ts +9 -2
  172. package/src/types/activityLabel.ts +3 -4
  173. package/src/types/graph.ts +5 -5
  174. package/src/types/llm.ts +95 -13
  175. package/src/types/reasoningLabel.ts +2 -3
  176. package/src/types/run.ts +3 -3
  177. package/src/types/summarize.ts +2 -2
  178. package/src/utils/errors.ts +3 -3
  179. package/src/utils/llm.ts +61 -15
  180. package/src/utils/llmConfig.ts +4 -4
@@ -1,5 +1,12 @@
1
- import * as math from 'mathjs';
2
1
  import { Tool } from '@langchain/core/tools';
2
+ import { requireLazyModule } from '@/lazyRequire';
3
+
4
+ /** mathjs costs ~150ms of module init; a calculator that is never invoked never pays it. */
5
+ let math: typeof import('mathjs') | undefined;
6
+ const evaluateExpression = (input: string): string => {
7
+ math ??= requireLazyModule<typeof import('mathjs')>('mathjs');
8
+ return math.evaluate(input).toString();
9
+ };
3
10
 
4
11
  export const CalculatorToolName = 'calculator';
5
12
 
@@ -36,7 +43,7 @@ export class Calculator extends Tool {
36
43
 
37
44
  async _call(input: string): Promise<string> {
38
45
  try {
39
- return math.evaluate(input).toString();
46
+ return evaluateExpression(input);
40
47
  } catch {
41
48
  return 'I don\'t know how to do that.';
42
49
  }
@@ -1,7 +1,6 @@
1
1
  import type { RunnableConfig } from '@langchain/core/runnables';
2
2
  import type { AssistantTextPhase } from '@/types/assistantPhase';
3
- import type { ClientOptions } from '@/types/llm';
4
- import type { Providers } from '@/common';
3
+ import type { ClientOptions, ProviderName } from '@/types/llm';
5
4
 
6
5
  /** One tool call's contribution to the label payload (host-assembled). */
7
6
  export type ActivityLabelToolEntry = {
@@ -25,7 +24,7 @@ export type ActivityLabelToolEntry = {
25
24
  * `activity_label` content type's formatter exclusions.
26
25
  */
27
26
  export type RunActivityLabelOptions = {
28
- provider: Providers;
27
+ provider: ProviderName;
29
28
  clientOptions?: ClientOptions;
30
29
  /**
31
30
  * Agent that executed the labeled batch. Selects that agent's Langfuse
@@ -85,7 +84,7 @@ export type ActivityPhaseEntry = {
85
84
 
86
85
  /** Options for `Run.generateActivityPhaseLabel`. */
87
86
  export type RunActivityPhaseLabelOptions = {
88
- provider: Providers;
87
+ provider: ProviderName;
89
88
  clientOptions?: ClientOptions;
90
89
  /**
91
90
  * Logical activities in run order. The SDK requires at least two so hosts
@@ -40,10 +40,10 @@ import type {
40
40
  StreamPreemption,
41
41
  TokenBudgetBreakdown,
42
42
  } from '@/types/run';
43
- import type { Providers, Callback, GraphNodeKeys } from '@/common';
44
43
  import type { SubagentTaskConfig } from '@/types/subagentTasks';
45
44
  import type { StandardGraph, MultiAgentGraph } from '@/graphs';
46
- import type { ClientOptions } from '@/types/llm';
45
+ import type { ProviderClientOptionsConfig } from '@/types/llm';
46
+ import type { Callback, GraphNodeKeys } from '@/common';
47
47
 
48
48
  /** Interface for bound model with stream and invoke methods */
49
49
  export interface ChatModel {
@@ -824,7 +824,7 @@ export interface LangfuseConfig {
824
824
  deterministicTraceId?: boolean;
825
825
  }
826
826
 
827
- export interface AgentInputs {
827
+ interface AgentInputFields {
828
828
  agentId: string;
829
829
  /**
830
830
  * Partition key for transient code-session ids and file refs. Agents with
@@ -839,12 +839,10 @@ export interface AgentInputs {
839
839
  toolEnd?: boolean;
840
840
  toolMap?: ToolMap;
841
841
  tools?: GraphTools;
842
- provider: Providers;
843
842
  /** Stable/cacheable system instructions. */
844
843
  instructions?: string;
845
844
  streamBuffer?: number;
846
845
  maxContextTokens?: number;
847
- clientOptions?: ClientOptions;
848
846
  /** Per-agent Langfuse tracing configuration. */
849
847
  langfuse?: LangfuseConfig;
850
848
  /** Dynamic system tail appended after stable instructions without provider cache markers. */
@@ -914,6 +912,8 @@ export interface AgentInputs {
914
912
  graphTools?: GenericTool[];
915
913
  }
916
914
 
915
+ export type AgentInputs = AgentInputFields & ProviderClientOptionsConfig;
916
+
917
917
  export interface ContextPruningConfig {
918
918
  enabled?: boolean;
919
919
  keepLastAssistants?: number;
package/src/types/llm.ts CHANGED
@@ -8,6 +8,7 @@ import type {
8
8
  } from '@langchain/openai';
9
9
  import type {
10
10
  BindToolsInput,
11
+ BaseChatModel,
11
12
  BaseChatModelParams,
12
13
  } from '@langchain/core/language_models/chat_models';
13
14
  import type { GoogleGenerativeAIChatInput } from '@langchain/google-genai';
@@ -21,6 +22,7 @@ import type { AnthropicInput } from '@langchain/anthropic';
21
22
  import type { Runnable } from '@langchain/core/runnables';
22
23
  import type { OpenAI as OpenAIClient } from 'openai';
23
24
  import type { ChatXAIInput } from '@langchain/xai';
25
+ import type { CustomProviderOptionsMap } from '../provider-registration';
24
26
  import type { ChatOpenRouterCallOptions } from '@/llm/openrouter';
25
27
  import type { PromptCacheTtl } from '@/messages/cache';
26
28
  import {
@@ -138,7 +140,7 @@ export type DeepSeekClientOptions = Partial<ChatDeepSeekInput> &
138
140
  StreamSmoothingOptions;
139
141
  export type XAIClientOptions = ChatXAIInput & StreamSmoothingOptions;
140
142
 
141
- export type ClientOptions =
143
+ export type BuiltInClientOptions =
142
144
  | OpenAIClientOptions
143
145
  | AzureClientOptions
144
146
  | AnthropicClientOptions
@@ -149,24 +151,86 @@ export type ClientOptions =
149
151
  | DeepSeekClientOptions
150
152
  | XAIClientOptions;
151
153
 
152
- export type SharedLLMConfig = {
153
- provider: Providers;
154
+ type CustomProviderName = Extract<keyof CustomProviderOptionsMap, string>;
155
+
156
+ type LooseRuntimeProviderName = string & {
157
+ readonly __runtimeProviderName?: never;
158
+ };
159
+
160
+ export type ProviderName =
161
+ | keyof ProviderOptionsMap
162
+ | CustomProviderName
163
+ | LooseRuntimeProviderName;
164
+
165
+ declare const RUNTIME_PROVIDER_NAME: unique symbol;
166
+
167
+ /** A runtime provider without declaration-merged option types. */
168
+ export type RuntimeProviderName = string & {
169
+ readonly [RUNTIME_PROVIDER_NAME]: true;
170
+ };
171
+
172
+ export type ClientOptions =
173
+ | BuiltInClientOptions
174
+ | CustomProviderOptionsMap[CustomProviderName];
175
+
176
+ export type SharedLLMConfig<
177
+ P extends
178
+ | keyof ProviderOptionsMap
179
+ | CustomProviderName
180
+ | RuntimeProviderName = keyof ProviderOptionsMap,
181
+ > = {
182
+ provider: P;
183
+ model?: string;
154
184
  _lc_stream_delay?: number;
155
185
  };
156
186
 
157
- export interface FallbackConfig {
158
- provider: Providers;
159
- clientOptions?: ClientOptions;
187
+ type CustomProviderClientOptionsConfig<P extends CustomProviderName> = {
188
+ provider: P;
189
+ } & (object extends CustomProviderOptionsMap[P]
190
+ ? { clientOptions?: CustomProviderOptionsMap[P] }
191
+ : { clientOptions: CustomProviderOptionsMap[P] });
192
+
193
+ export type ProviderClientOptionsConfig =
194
+ | {
195
+ provider: keyof ProviderOptionsMap;
196
+ clientOptions?: BuiltInClientOptions;
197
+ }
198
+ | {
199
+ [P in CustomProviderName]: CustomProviderClientOptionsConfig<P>;
200
+ }[CustomProviderName]
201
+ | {
202
+ provider: RuntimeProviderName;
203
+ clientOptions: ClientOptions;
204
+ };
205
+
206
+ export type FallbackConfig = ProviderClientOptionsConfig & {
160
207
  /** Context window used to corroborate ambiguous fallback overflow errors. */
161
208
  maxContextTokens?: number;
162
- }
209
+ };
210
+
211
+ type LLMConfigFor<P extends CustomProviderName> = SharedLLMConfig<P> &
212
+ CustomProviderOptionsMap[P] & {
213
+ /** Optional provider fallbacks in order of attempt */
214
+ fallbacks?: FallbackConfig[];
215
+ };
163
216
 
164
- export type LLMConfig = SharedLLMConfig &
165
- ClientOptions & {
217
+ export type BuiltInLLMConfig = SharedLLMConfig &
218
+ BuiltInClientOptions & {
166
219
  /** Optional provider fallbacks in order of attempt */
167
220
  fallbacks?: FallbackConfig[];
168
221
  };
169
222
 
223
+ export type LLMConfig =
224
+ | BuiltInLLMConfig
225
+ | {
226
+ [P in CustomProviderName]: LLMConfigFor<P>;
227
+ }[CustomProviderName]
228
+ | (SharedLLMConfig<RuntimeProviderName> &
229
+ ClientOptions & {
230
+ /** Optional provider fallbacks in order of attempt */
231
+ fallbacks?: FallbackConfig[];
232
+ });
233
+
170
234
  export type ProviderOptionsMap = {
171
235
  [Providers.AZURE]: AzureClientOptions;
172
236
  [Providers.OPENAI]: OpenAIClientOptions;
@@ -182,7 +246,7 @@ export type ProviderOptionsMap = {
182
246
  [Providers.MOONSHOT]: OpenAIClientOptions;
183
247
  };
184
248
 
185
- export type ChatModelMap = {
249
+ export interface ChatModelMap {
186
250
  [Providers.XAI]: ChatXAI;
187
251
  [Providers.OPENAI]: ChatOpenAI;
188
252
  [Providers.AZURE]: AzureChatOpenAI;
@@ -195,14 +259,32 @@ export type ChatModelMap = {
195
259
  [Providers.BEDROCK]: CustomChatBedrockConverse;
196
260
  [Providers.GOOGLE]: CustomChatGoogleGenerativeAI;
197
261
  [Providers.MOONSHOT]: ChatMoonshot;
198
- };
262
+ }
263
+
264
+ export type ProviderOptionsFor<P extends ProviderName> =
265
+ P extends keyof ProviderOptionsMap
266
+ ? ProviderOptionsMap[P]
267
+ : P extends CustomProviderName
268
+ ? CustomProviderOptionsMap[P]
269
+ : BuiltInClientOptions;
270
+
271
+ export type ProviderModelFor<P extends ProviderName> =
272
+ P extends keyof ChatModelMap
273
+ ? ChatModelMap[P] & BaseChatModel
274
+ : BaseChatModel;
275
+
276
+ export type ProviderModelConstructor<P extends ProviderName> = new (
277
+ config: ProviderOptionsFor<P>
278
+ ) => ProviderModelFor<P>;
199
279
 
200
280
  export type ChatModelConstructorMap = {
201
281
  [P in Providers]: new (config: ProviderOptionsMap[P]) => ChatModelMap[P];
202
282
  };
203
283
 
204
- export type ChatModelInstance = ChatModelMap[Providers];
284
+ export type ChatModelInstance = BaseChatModel;
205
285
 
206
- export type ModelWithTools = ChatModelInstance & {
286
+ export type ModelWithTools = BaseChatModel & {
207
287
  bindTools(tools: CommonToolType[]): Runnable;
208
288
  };
289
+
290
+ export type { CustomProviderOptionsMap } from '../provider-registration';
@@ -1,7 +1,6 @@
1
1
  import type { RunnableConfig } from '@langchain/core/runnables';
2
2
  import type { UsageMetadata } from '@langchain/core/messages';
3
- import type { ClientOptions } from '@/types/llm';
4
- import type { Providers } from '@/common';
3
+ import type { ClientOptions, ProviderName } from '@/types/llm';
5
4
 
6
5
  /** Lifecycle state of the visible reasoning snapshot being labeled. */
7
6
  export type ReasoningLabelStatus = 'streaming' | 'complete';
@@ -15,7 +14,7 @@ export type ReasoningLabelResult = {
15
14
 
16
15
  /** Options for `Run.generateReasoningLabel`. */
17
16
  export type RunReasoningLabelOptions = {
18
- provider: Providers;
17
+ provider: ProviderName;
19
18
  clientOptions?: ClientOptions;
20
19
  /**
21
20
  * Complete user-visible reasoning accumulated for this step so far. Hidden
package/src/types/run.ts CHANGED
@@ -22,7 +22,7 @@ import type * as l from '@/types/llm';
22
22
  export type ZodObjectAny = z.ZodObject<any, any, any, any>;
23
23
  export type BaseGraphConfig = {
24
24
  llmConfig: l.LLMConfig;
25
- provider?: e.Providers;
25
+ provider?: l.ProviderName;
26
26
  clientOptions?: l.ClientOptions;
27
27
  /** Optional compile options for workflow.compile() */
28
28
  compileOptions?: g.CompileOptions;
@@ -47,7 +47,7 @@ export type SupervisedGraphConfig = BaseGraphConfig & {
47
47
  routingPolicies?: Array<{
48
48
  stage: string;
49
49
  agents?: string[];
50
- model?: e.Providers;
50
+ model?: l.ProviderName;
51
51
  parallel?: boolean;
52
52
  /** Optional simple condition on content/tools */
53
53
  when?:
@@ -70,7 +70,7 @@ export type SupervisedGraphConfig = BaseGraphConfig & {
70
70
 
71
71
  export type RunTitleOptions = {
72
72
  inputText: string;
73
- provider: e.Providers;
73
+ provider: l.ProviderName;
74
74
  contentParts: (s.MessageContentComplex | undefined)[];
75
75
  titlePrompt?: string;
76
76
  skipLanguage?: boolean;
@@ -1,5 +1,5 @@
1
1
  import type { SummaryContentBlock } from '@/types/stream';
2
- import type { Providers } from '@/common';
2
+ import type { ProviderName } from '@/types/llm';
3
3
 
4
4
  export type SummarizationTrigger = {
5
5
  type:
@@ -35,7 +35,7 @@ export type RetainRecentConfig = {
35
35
  };
36
36
 
37
37
  export type SummarizationConfig = {
38
- provider?: Providers;
38
+ provider?: ProviderName;
39
39
  model?: string;
40
40
  parameters?: Record<string, unknown>;
41
41
  prompt?: string;
@@ -12,7 +12,7 @@
12
12
  * into a forced summarization pass instead of surfacing the error.
13
13
  */
14
14
  import { ContextOverflowError } from '@langchain/core/errors';
15
- import type { Providers } from '@/common';
15
+ import type { ProviderName } from '@/types';
16
16
 
17
17
  /**
18
18
  * Why the request was rejected. Both kinds are fixed by shrinking the
@@ -49,7 +49,7 @@ export interface ContextOverflowInfo {
49
49
  promptTokens?: number;
50
50
  /** Which layer produced the verdict. Surfaced in logs and asserted in tests. */
51
51
  source: 'langchain' | 'pattern';
52
- provider?: Providers;
52
+ provider?: ProviderName;
53
53
  }
54
54
 
55
55
  interface OverflowPattern {
@@ -80,7 +80,7 @@ interface OverflowPattern {
80
80
  const CONTEXT_PRESSURE_RATIO = 0.8;
81
81
 
82
82
  export interface ContextOverflowContext {
83
- provider?: Providers;
83
+ provider?: ProviderName;
84
84
  /** Our own estimate of the prompt size for the call that failed. */
85
85
  estimatedPromptTokens?: number;
86
86
  /** The budget we believed applied when we built that prompt. */
package/src/utils/llm.ts CHANGED
@@ -1,37 +1,83 @@
1
1
  // src/utils/llm.ts
2
+ import type { ProviderName } from '@/types';
3
+ import { getProviderFamily } from '@/llm/providerRegistry';
2
4
  import { Providers } from '@/common';
3
5
 
4
- export function isOpenAILike(provider?: string | Providers): boolean {
6
+ const OPENAI_FAMILY_LC_NAMES: ReadonlySet<string> = new Set([
7
+ 'LibreChatOpenAI',
8
+ 'LibreChatAzureOpenAI',
9
+ ]);
10
+
11
+ /** Walks the constructor chain for LangChain's `lc_name` serialization ids.
12
+ * Constructor identity is unusable across lazily loaded module formats — the
13
+ * CJS and ESM builds carry distinct classes — so guards match on the ids the
14
+ * relevant classes declare instead of on `instanceof`. */
15
+ export function constructorChainHasLcName(
16
+ model: unknown,
17
+ names: ReadonlySet<string>
18
+ ): boolean {
19
+ if (typeof model !== 'object' || model == null) {
20
+ return false;
21
+ }
22
+ let ctor: unknown = model.constructor;
23
+ while (typeof ctor === 'function') {
24
+ const lcName = (ctor as { lc_name?: () => string }).lc_name?.();
25
+ if (lcName != null && names.has(lcName)) {
26
+ return true;
27
+ }
28
+ ctor = Object.getPrototypeOf(ctor);
29
+ }
30
+ return false;
31
+ }
32
+
33
+ /** Matches exactly the instances that were `instanceof` this package's
34
+ * `ChatOpenAI`/`AzureChatOpenAI`: only those classes declare the
35
+ * `LibreChatOpenAI`/`LibreChatAzureOpenAI` ids, their subclasses keep them in
36
+ * the chain, and upstream `@langchain/openai` classes never carry them. */
37
+ export function isLibreChatOpenAIModel(
38
+ model: unknown
39
+ ): model is
40
+ | import('@/llm/openai').ChatOpenAI
41
+ | import('@/llm/openai').AzureChatOpenAI {
42
+ return constructorChainHasLcName(model, OPENAI_FAMILY_LC_NAMES);
43
+ }
44
+
45
+ export function isOpenAILike(provider?: ProviderName): boolean {
5
46
  if (provider == null) {
6
47
  return false;
7
48
  }
8
49
  return (
9
- [
10
- Providers.OPENAI,
11
- Providers.AZURE,
12
- Providers.OPENROUTER,
13
- Providers.XAI,
14
- Providers.DEEPSEEK,
15
- ] as string[]
16
- ).includes(provider);
50
+ getProviderFamily(provider) === 'openai' ||
51
+ (
52
+ [
53
+ Providers.OPENAI,
54
+ Providers.AZURE,
55
+ Providers.OPENROUTER,
56
+ Providers.XAI,
57
+ Providers.DEEPSEEK,
58
+ ] as string[]
59
+ ).includes(provider)
60
+ );
17
61
  }
18
62
 
19
- export function isGoogleLike(provider?: string | Providers): boolean {
63
+ export function isGoogleLike(provider?: ProviderName): boolean {
20
64
  if (provider == null) {
21
65
  return false;
22
66
  }
23
- return ([Providers.GOOGLE, Providers.VERTEXAI] as string[]).includes(
24
- provider
67
+ return (
68
+ getProviderFamily(provider) === 'google' ||
69
+ ([Providers.GOOGLE, Providers.VERTEXAI] as string[]).includes(provider)
25
70
  );
26
71
  }
27
72
 
28
73
  /** Returns true for native Anthropic or Bedrock running a Claude model. */
29
74
  export function isAnthropicLike(
30
- provider?: string | Providers,
75
+ provider?: ProviderName,
31
76
  clientOptions?: { model?: string }
32
77
  ): boolean {
33
- if (provider === Providers.ANTHROPIC) return true;
34
- if (provider === Providers.BEDROCK) {
78
+ const family = provider == null ? undefined : getProviderFamily(provider);
79
+ if (provider === Providers.ANTHROPIC || family === 'anthropic') return true;
80
+ if (provider === Providers.BEDROCK || family === 'bedrock') {
35
81
  return (
36
82
  clientOptions?.model == null ||
37
83
  /claude/i.test(String(clientOptions.model))
@@ -3,7 +3,7 @@ import type * as or from '@/llm/openrouter';
3
3
  import type * as t from '@/types';
4
4
  import { Providers } from '@/common';
5
5
 
6
- export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
6
+ export const llmConfigs: Record<string, t.BuiltInLLMConfig | undefined> = {
7
7
  [Providers.OPENAI]: {
8
8
  provider: Providers.OPENAI,
9
9
  model: 'gpt-4.1',
@@ -68,7 +68,7 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
68
68
  modelKwargs: {
69
69
  max_tokens: 10000,
70
70
  },
71
- } as or.ChatOpenRouterCallOptions & t.LLMConfig,
71
+ } as or.ChatOpenRouterCallOptions & t.BuiltInLLMConfig,
72
72
  [Providers.AZURE]: {
73
73
  provider: Providers.AZURE,
74
74
  temperature: 0.7,
@@ -159,7 +159,7 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
159
159
  // location: 'global',
160
160
  // thinkingBudget: -1,
161
161
  // includeThoughts: true,
162
- } as t.VertexAIClientOptions & t.LLMConfig,
162
+ } as t.VertexAIClientOptions & t.BuiltInLLMConfig,
163
163
  [Providers.GOOGLE]: {
164
164
  provider: Providers.GOOGLE,
165
165
  model: 'gemini-2.5-flash',
@@ -194,7 +194,7 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
194
194
  },
195
195
  };
196
196
 
197
- export function getLLMConfig(provider: string): t.LLMConfig {
197
+ export function getLLMConfig(provider: string): t.BuiltInLLMConfig {
198
198
  const config = llmConfigs[provider];
199
199
  if (config === undefined) {
200
200
  throw new Error(`Unsupported provider: ${provider}`);