@librechat/agents 3.6.15 → 3.6.16

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 (117) hide show
  1. package/README.md +41 -0
  2. package/dist/cjs/agents/AgentContext.cjs +1 -1
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/graphs/Graph.cjs +9 -7
  5. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  6. package/dist/cjs/llm/init.cjs +1 -0
  7. package/dist/cjs/llm/init.cjs.map +1 -1
  8. package/dist/cjs/llm/invoke.cjs +9 -2
  9. package/dist/cjs/llm/invoke.cjs.map +1 -1
  10. package/dist/cjs/llm/openai/index.cjs +1 -1
  11. package/dist/cjs/llm/prepareProviderRequest.cjs +6 -3
  12. package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -1
  13. package/dist/cjs/llm/providerRegistry.cjs +69 -0
  14. package/dist/cjs/llm/providerRegistry.cjs.map +1 -0
  15. package/dist/cjs/llm/providers.cjs +38 -25
  16. package/dist/cjs/llm/providers.cjs.map +1 -1
  17. package/dist/cjs/llm/request.cjs +6 -4
  18. package/dist/cjs/llm/request.cjs.map +1 -1
  19. package/dist/cjs/llm/truncation.cjs +2 -1
  20. package/dist/cjs/llm/truncation.cjs.map +1 -1
  21. package/dist/cjs/main.cjs +18 -15
  22. package/dist/cjs/messages/format.cjs.map +1 -1
  23. package/dist/cjs/messages/prune.cjs +8 -4
  24. package/dist/cjs/messages/prune.cjs.map +1 -1
  25. package/dist/cjs/provider-registration.cjs +4 -0
  26. package/dist/cjs/run.cjs +2 -2
  27. package/dist/cjs/stream.cjs +1 -1
  28. package/dist/cjs/stream.cjs.map +1 -1
  29. package/dist/cjs/summarization/node.cjs +2 -2
  30. package/dist/cjs/summarization/node.cjs.map +1 -1
  31. package/dist/cjs/utils/llm.cjs +6 -4
  32. package/dist/cjs/utils/llm.cjs.map +1 -1
  33. package/dist/esm/agents/AgentContext.mjs +1 -1
  34. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  35. package/dist/esm/graphs/Graph.mjs +10 -8
  36. package/dist/esm/graphs/Graph.mjs.map +1 -1
  37. package/dist/esm/llm/init.mjs +1 -0
  38. package/dist/esm/llm/init.mjs.map +1 -1
  39. package/dist/esm/llm/invoke.mjs +9 -2
  40. package/dist/esm/llm/invoke.mjs.map +1 -1
  41. package/dist/esm/llm/openai/index.mjs +1 -1
  42. package/dist/esm/llm/prepareProviderRequest.mjs +7 -4
  43. package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -1
  44. package/dist/esm/llm/providerRegistry.mjs +64 -0
  45. package/dist/esm/llm/providerRegistry.mjs.map +1 -0
  46. package/dist/esm/llm/providers.mjs +36 -22
  47. package/dist/esm/llm/providers.mjs.map +1 -1
  48. package/dist/esm/llm/request.mjs +6 -4
  49. package/dist/esm/llm/request.mjs.map +1 -1
  50. package/dist/esm/llm/truncation.mjs +2 -1
  51. package/dist/esm/llm/truncation.mjs.map +1 -1
  52. package/dist/esm/main.mjs +12 -10
  53. package/dist/esm/messages/format.mjs.map +1 -1
  54. package/dist/esm/messages/prune.mjs +8 -4
  55. package/dist/esm/messages/prune.mjs.map +1 -1
  56. package/dist/esm/provider-registration.mjs +3 -0
  57. package/dist/esm/run.mjs +2 -2
  58. package/dist/esm/stream.mjs +1 -1
  59. package/dist/esm/stream.mjs.map +1 -1
  60. package/dist/esm/summarization/node.mjs +2 -2
  61. package/dist/esm/summarization/node.mjs.map +1 -1
  62. package/dist/esm/utils/llm.mjs +6 -4
  63. package/dist/esm/utils/llm.mjs.map +1 -1
  64. package/dist/types/agents/AgentContext.d.ts +5 -5
  65. package/dist/types/index.d.ts +2 -0
  66. package/dist/types/llm/contextOverflowRecovery.d.ts +2 -2
  67. package/dist/types/llm/init.d.ts +21 -14
  68. package/dist/types/llm/invoke.d.ts +5 -6
  69. package/dist/types/llm/prepareProviderRequest.d.ts +5 -6
  70. package/dist/types/llm/providerRegistry.d.ts +11 -0
  71. package/dist/types/llm/providers.d.ts +4 -5
  72. package/dist/types/llm/request.d.ts +2 -3
  73. package/dist/types/llm/truncation.d.ts +2 -2
  74. package/dist/types/messages/core.d.ts +1 -2
  75. package/dist/types/messages/format.d.ts +3 -3
  76. package/dist/types/messages/prune.d.ts +3 -2
  77. package/dist/types/provider-registration.d.ts +15 -0
  78. package/dist/types/stream.d.ts +1 -2
  79. package/dist/types/summarization/node.d.ts +1 -2
  80. package/dist/types/types/activityLabel.d.ts +3 -4
  81. package/dist/types/types/graph.d.ts +4 -5
  82. package/dist/types/types/llm.d.ts +54 -13
  83. package/dist/types/types/reasoningLabel.d.ts +2 -3
  84. package/dist/types/types/run.d.ts +3 -3
  85. package/dist/types/types/summarize.d.ts +2 -2
  86. package/dist/types/utils/errors.d.ts +3 -3
  87. package/dist/types/utils/llm.d.ts +4 -4
  88. package/dist/types/utils/llmConfig.d.ts +2 -2
  89. package/package.json +9 -1
  90. package/src/agents/AgentContext.ts +27 -26
  91. package/src/graphs/Graph.ts +14 -14
  92. package/src/index.ts +5 -0
  93. package/src/llm/contextOverflowRecovery.ts +2 -2
  94. package/src/llm/init.ts +40 -17
  95. package/src/llm/invoke.ts +36 -21
  96. package/src/llm/prepareProviderRequest.ts +19 -18
  97. package/src/llm/providerRegistry.ts +134 -0
  98. package/src/llm/providers.ts +73 -30
  99. package/src/llm/request.ts +10 -6
  100. package/src/llm/truncation.ts +9 -3
  101. package/src/messages/core.ts +2 -2
  102. package/src/messages/format.ts +14 -16
  103. package/src/messages/prune.ts +22 -17
  104. package/src/provider-registration.ts +29 -0
  105. package/src/run.ts +1 -1
  106. package/src/session/AgentSession.ts +1 -1
  107. package/src/stream.ts +7 -8
  108. package/src/summarization/node.ts +7 -7
  109. package/src/types/activityLabel.ts +3 -4
  110. package/src/types/graph.ts +5 -5
  111. package/src/types/llm.ts +95 -13
  112. package/src/types/reasoningLabel.ts +2 -3
  113. package/src/types/run.ts +3 -3
  114. package/src/types/summarize.ts +2 -2
  115. package/src/utils/errors.ts +3 -3
  116. package/src/utils/llm.ts +22 -15
  117. package/src/utils/llmConfig.ts +4 -4
@@ -3,11 +3,10 @@ import type { RunnableConfig } from '@langchain/core/runnables';
3
3
  import type { BaseMessage } from '@langchain/core/messages';
4
4
  import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
5
5
  import type { PreparedProviderRequest } from '@/llm/prepareProviderRequest';
6
- import type { StreamLimitState } from '@/llm/streamLimits';
7
6
  import type { ContextOverflowContext } from '@/utils/errors';
7
+ import type { StreamLimitState } from '@/llm/streamLimits';
8
8
  import type * as t from '@/types';
9
9
  import { ChatModelStreamHandler } from '@/stream';
10
- import { Providers } from '@/common';
11
10
  export { projectMessagesForProvider, resolveServingModelId, usesNativeOpenAIResponses, } from '@/llm/prepareProviderRequest';
12
11
  export type { PreparedProviderRequest, PrepareProviderRequestParams, ProviderMessageProjectionMode, ProviderPayloadMeasurement, ProviderRequestContext, } from '@/llm/prepareProviderRequest';
13
12
  /**
@@ -75,7 +74,7 @@ type AttemptInvokeParams = AttemptInvokeCommonParams & ({
75
74
  request?: never;
76
75
  model: t.ChatModel;
77
76
  messages: BaseMessage[];
78
- provider: Providers;
77
+ provider: t.ProviderName;
79
78
  });
80
79
  /**
81
80
  * One model attempt. Stamps the attempt identity into callback metadata
@@ -92,7 +91,7 @@ export declare function attemptInvoke(params: AttemptInvokeParams, config?: Runn
92
91
  * differ, which is the whole reason a fallback exists.
93
92
  */
94
93
  export interface FallbackErrorContext {
95
- provider: Providers;
94
+ provider: t.ProviderName;
96
95
  clientOptions?: t.ClientOptions;
97
96
  maxContextTokens?: number;
98
97
  }
@@ -138,7 +137,7 @@ export declare function tryFallbackProviders({ fallbacks, tools, messages, confi
138
137
  prepareProviderRequest?: (input: {
139
138
  model: t.ChatModel;
140
139
  messages: BaseMessage[];
141
- provider: Providers;
140
+ provider: t.ProviderName;
142
141
  clientOptions?: t.ClientOptions;
143
142
  maxContextTokens?: number;
144
143
  config?: RunnableConfig;
@@ -147,7 +146,7 @@ export declare function tryFallbackProviders({ fallbacks, tools, messages, confi
147
146
  prepareProviderMessages?: (input: {
148
147
  model: t.ChatModel;
149
148
  messages: BaseMessage[];
150
- provider: Providers;
149
+ provider: t.ProviderName;
151
150
  clientOptions?: t.ClientOptions;
152
151
  maxContextTokens?: number;
153
152
  config?: RunnableConfig;
@@ -2,7 +2,6 @@ import type { RunnableConfig } from '@langchain/core/runnables';
2
2
  import type { BaseMessage } from '@langchain/core/messages';
3
3
  import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
4
4
  import type * as t from '@/types';
5
- import { Providers } from '@/common';
6
5
  declare const preparedProviderRequestBrand: unique symbol;
7
6
  export type ProviderMessageProjectionMode = 'chat-messages' | 'openai-responses';
8
7
  export interface ProviderPayloadMeasurement {
@@ -15,7 +14,7 @@ export interface ProviderPayloadMeasurement {
15
14
  export interface PreparedProviderRequest {
16
15
  readonly model: t.ChatModel;
17
16
  readonly modelId?: string;
18
- readonly provider: Providers;
17
+ readonly provider: t.ProviderName;
19
18
  readonly projectionMode: ProviderMessageProjectionMode;
20
19
  readonly messages: BaseMessage[];
21
20
  readonly measurement?: ProviderPayloadMeasurement;
@@ -28,17 +27,17 @@ export interface ProviderRequestContext {
28
27
  export interface PrepareProviderRequestParams {
29
28
  model: t.ChatModel;
30
29
  messages: BaseMessage[];
31
- provider: Providers;
30
+ provider: t.ProviderName;
32
31
  context?: ProviderRequestContext;
33
32
  config?: RunnableConfig;
34
33
  maxToolResultChars?: number;
35
34
  measure?: (messages: BaseMessage[]) => ProviderPayloadMeasurement;
36
35
  }
37
- export declare function usesNativeOpenAIResponses(model: t.ChatModel, provider: Providers, callOptions?: unknown): boolean;
36
+ export declare function usesNativeOpenAIResponses(model: t.ChatModel, provider: t.ProviderName, callOptions?: unknown): boolean;
38
37
  interface ProjectMessagesForProviderParams {
39
38
  model: t.ChatModel;
40
39
  messages: BaseMessage[];
41
- provider: Providers;
40
+ provider: t.ProviderName;
42
41
  maxToolResultChars?: number;
43
42
  callOptions?: unknown;
44
43
  }
@@ -51,5 +50,5 @@ export declare function resolveServingModelId(model: unknown): string | undefine
51
50
  * will be passed to LangChain. Source messages remain untouched.
52
51
  */
53
52
  export declare function prepareProviderRequest({ model, messages, provider, context, config, maxToolResultChars, measure, }: PrepareProviderRequestParams): PreparedProviderRequest;
54
- export declare function assertPreparedProviderRequestFor(request: PreparedProviderRequest, model: t.ChatModel, provider: Providers, config?: RunnableConfig): void;
53
+ export declare function assertPreparedProviderRequestFor(request: PreparedProviderRequest, model: t.ChatModel, provider: t.ProviderName, config?: RunnableConfig): void;
55
54
  export {};
@@ -0,0 +1,11 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { ProviderFamily, ProviderRegistrationOptions } from '../provider-registration';
3
+ import type { ProviderModelConstructor, ProviderName } from '@/types';
4
+ /** Registers one host provider until the returned disposer is called. */
5
+ export declare function registerProvider<TOptions extends object, TModel extends BaseChatModel>(options: ProviderRegistrationOptions<TOptions, TModel>): () => void;
6
+ /** Initializes one built-in for the current package module graph. */
7
+ export declare function registerBuiltInProvider<TOptions extends object, TModel extends BaseChatModel>(options: ProviderRegistrationOptions<TOptions, TModel>): void;
8
+ export declare function getRegisteredChatModelClass<P extends ProviderName>(provider: P): ProviderModelConstructor<P>;
9
+ export declare function getProviderFamily(provider: ProviderName): ProviderFamily | undefined;
10
+ export declare function providerUsesManualToolStream(provider: ProviderName): boolean;
11
+ export declare function providerRequiresStrictAlternation(provider: ProviderName): boolean;
@@ -1,5 +1,4 @@
1
- import type { ChatModelConstructorMap, ProviderOptionsMap, ChatModelMap } from '@/types';
2
- import { Providers } from '@/common';
3
- export declare const llmProviders: Partial<ChatModelConstructorMap>;
4
- export declare const manualToolStreamProviders: Set<string>;
5
- export declare const getChatModelClass: <P extends Providers>(provider: P) => new (config: ProviderOptionsMap[P]) => ChatModelMap[P];
1
+ import type { ProviderModelConstructor, ProviderName } from '@/types';
2
+ export declare const getChatModelClass: <P extends ProviderName>(provider: P) => ProviderModelConstructor<P>;
3
+ export { getProviderFamily, providerRequiresStrictAlternation, providerUsesManualToolStream, registerProvider, } from '@/llm/providerRegistry';
4
+ export type { ProviderFamily, ProviderRegistrationOptions, } from '../provider-registration';
@@ -1,14 +1,13 @@
1
1
  import type * as t from '@/types';
2
- import { Providers } from '@/common';
3
2
  /**
4
3
  * Returns true when the provider + clientOptions indicate extended thinking
5
4
  * is enabled. Works across Anthropic (direct), Bedrock (additionalModelRequestFields),
6
5
  * and OpenAI-compat (modelKwargs.thinking).
7
6
  */
8
- export declare function isThinkingEnabled(provider: Providers, clientOptions?: t.ClientOptions): boolean;
7
+ export declare function isThinkingEnabled(provider: t.ProviderName, clientOptions?: t.ClientOptions): boolean;
9
8
  /**
10
9
  * Returns the correct key for setting max output tokens on the model
11
10
  * constructor options. Google/Vertex use `maxOutputTokens`, all others
12
11
  * use `maxTokens`.
13
12
  */
14
- export declare function getMaxOutputTokensKey(provider: Providers | string): 'maxOutputTokens' | 'maxTokens';
13
+ export declare function getMaxOutputTokensKey(provider: t.ProviderName): 'maxOutputTokens' | 'maxTokens';
@@ -1,5 +1,5 @@
1
1
  import type { AIMessageChunk, BaseMessage } from '@langchain/core/messages';
2
- import { Providers } from '@/common';
2
+ import type { ProviderName } from '@/types';
3
3
  /**
4
4
  * Normalized truncation reasons across providers. Providers disagree on the
5
5
  * key and the value: Anthropic/Bedrock use `max_tokens`, OpenAI uses `length`,
@@ -42,4 +42,4 @@ export declare class OutputTruncationError extends Error {
42
42
  * providers that deliver complete tool calls atomically (Google/Vertex), where
43
43
  * `MAX_TOKENS` does not imply the arguments were cut off.
44
44
  */
45
- export declare function assertNotTruncatedToolCall(message: AIMessageChunk | BaseMessage | undefined | null, provider?: Providers): void;
45
+ export declare function assertNotTruncatedToolCall(message: AIMessageChunk | BaseMessage | undefined | null, provider?: ProviderName): void;
@@ -1,12 +1,11 @@
1
1
  import { AIMessage, BaseMessage, ToolMessage, HumanMessage, AIMessageChunk } from '@langchain/core/messages';
2
2
  import type * as t from '@/types';
3
- import { Providers } from '@/common';
4
3
  export declare function getConverseOverrideMessage({ userMessage, lastMessageX, lastMessageY, }: {
5
4
  userMessage: string[];
6
5
  lastMessageX: AIMessageChunk | null;
7
6
  lastMessageY: ToolMessage;
8
7
  }): HumanMessage;
9
- export declare function modifyDeltaProperties(provider: Providers, obj?: AIMessageChunk): AIMessageChunk | undefined;
8
+ export declare function modifyDeltaProperties(provider: t.ProviderName, obj?: AIMessageChunk): AIMessageChunk | undefined;
10
9
  export declare function formatAnthropicMessage(message: AIMessageChunk): AIMessage;
11
10
  export declare function convertMessagesToContent(messages: BaseMessage[]): t.MessageContentComplex[];
12
11
  type ResponsesReplayProjection = 'fallback' | 'native';
@@ -1,7 +1,7 @@
1
1
  import { AIMessage, ToolMessage, BaseMessage, HumanMessage, SystemMessage } from '@langchain/core/messages';
2
2
  import type { MessageContentImageUrl } from '@langchain/core/messages';
3
3
  import type { RunnableConfig } from '@langchain/core/runnables';
4
- import type { MessageContentComplex, TPayload } from '@/types';
4
+ import type { MessageContentComplex, TPayload, ProviderName } from '@/types';
5
5
  import { Providers } from '@/common';
6
6
  interface MediaMessageParams {
7
7
  message: {
@@ -90,7 +90,7 @@ interface LangChainMessage {
90
90
  */
91
91
  export declare const formatFromLangChain: (message: LangChainMessage) => Record<string, any>;
92
92
  interface FormatAgentMessagesOptions {
93
- provider?: Providers;
93
+ provider?: ProviderName;
94
94
  /** Reconstruct hidden `reasoning_content` from `THINK` parts onto prior
95
95
  * tool-call messages. Explicit opt-in for OpenAI-compatible endpoints that
96
96
  * replay reasoning across turns; defaults to on for DeepSeek thinking-mode. */
@@ -189,7 +189,7 @@ export declare function compactSyntheticProviderContextMessage(message: HumanMes
189
189
  * compatibility for callers that don't yet pass the boundary.
190
190
  * @returns The messages array with tool sequences converted to buffer strings if necessary
191
191
  */
192
- export declare function ensureThinkingBlockInMessages(messages: BaseMessage[], _provider: Providers, config?: RunnableConfig, runStartIndex?: number): BaseMessage[];
192
+ export declare function ensureThinkingBlockInMessages(messages: BaseMessage[], _provider: ProviderName, config?: RunnableConfig, runStartIndex?: number): BaseMessage[];
193
193
  /**
194
194
  * Folds tool_use / tool_result content into plain text for an agent that binds
195
195
  * no tools.
@@ -1,7 +1,8 @@
1
1
  import { BaseMessage, UsageMetadata } from '@langchain/core/messages';
2
2
  import type { ContextPruningConfig } from '@/types/graph';
3
3
  import type { TokenCounter } from '@/types/run';
4
- import { ContentTypes, Providers } from '@/common';
4
+ import type { ProviderName } from '@/types';
5
+ import { ContentTypes } from '@/common';
5
6
  /** Default fraction of the token budget reserved as headroom (5 %). */
6
7
  export declare const DEFAULT_RESERVE_RATIO = 0.05;
7
8
  /** Provider framing reserved for the assistant reply label. */
@@ -25,7 +26,7 @@ export declare const CALIBRATION_RATIO_MAX = 5;
25
26
  /** Keeps provider/local token calibration within the shared safe range. */
26
27
  export declare function clampCalibrationRatio(ratio: number): number;
27
28
  export type PruneMessagesFactoryParams = {
28
- provider?: Providers;
29
+ provider?: ProviderName;
29
30
  maxTokens: number;
30
31
  /** Per-tool-result character cap applied while reconciling cached counts. */
31
32
  maxToolResultChars?: number;
@@ -0,0 +1,15 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ declare const CUSTOM_PROVIDER_OPTIONS_TYPE: unique symbol;
3
+ /** Declaration-merge this map to type host-registered provider options. */
4
+ export interface CustomProviderOptionsMap {
5
+ readonly [CUSTOM_PROVIDER_OPTIONS_TYPE]?: never;
6
+ }
7
+ export type ProviderFamily = 'openai' | 'anthropic' | 'bedrock' | 'google' | 'mistral' | 'generic';
8
+ export interface ProviderRegistrationOptions<TOptions extends object, TModel extends BaseChatModel> {
9
+ provider: string;
10
+ model: new (config: TOptions) => TModel;
11
+ family?: ProviderFamily;
12
+ manualToolStream?: boolean;
13
+ strictAlternation?: boolean;
14
+ }
15
+ export { registerProvider } from './llm/providers';
@@ -2,10 +2,9 @@ import type { AIMessageChunk } from '@langchain/core/messages';
2
2
  import type { AgentContext } from '@/agents/AgentContext';
3
3
  import type { StandardGraph } from '@/graphs';
4
4
  import type * as t from '@/types';
5
- import { Providers } from '@/common';
6
5
  export declare function getChunkContent({ chunk, provider, reasoningKey, }: {
7
6
  chunk?: Partial<AIMessageChunk>;
8
- provider?: Providers;
7
+ provider?: t.ProviderName;
9
8
  reasoningKey: 'reasoning_content' | 'reasoning';
10
9
  }): string | t.MessageContentComplex[] | undefined;
11
10
  /**
@@ -5,7 +5,6 @@ import type { AgentContext } from '@/agents/AgentContext';
5
5
  import type { HookRegistry } from '@/hooks';
6
6
  import type { OnChunk } from '@/llm/invoke';
7
7
  import type * as t from '@/types';
8
- import { Providers } from '@/common';
9
8
  /** Structured checkpoint prompt for fresh summarization (no prior summary). */
10
9
  export declare const DEFAULT_SUMMARIZATION_PROMPT = "Hold on, before you continue I need you to write me a checkpoint of everything so far. Your context window is filling up and this checkpoint replaces the messages above, so capture everything you need to pick right back up.\n\nDon't second-guess or fact-check anything you did, your tool results reflect exactly what happened. If a tool result appears truncated, that's just a display artifact from context management: the tool executed fully. Just record what you did and what you observed. Only the checkpoint, don't respond to me or continue the conversation.\n\n## Checkpoint\n\n## Goal\nWhat I asked you to do and any sub-goals you identified.\n\n## Constraints & Preferences\nAny rules, preferences, or configuration I established.\n\n## Progress\n### Done\n- What you completed and the outcomes\n\n### In Progress\n- What you're currently working on\n\n## Key Decisions\nDecisions you made and why.\n\n## Next Steps\nConcrete task actions remaining, in priority order.\n\n## Critical Context\nExact identifiers, names, error messages, URLs, and details you need to preserve verbatim.\n\nRules:\n- Record what you did and observed, don't judge or re-evaluate it\n- For each tool call: the tool name, key inputs, and the outcome\n- Preserve exact identifiers, names, errors, and references verbatim\n- Short declarative sentences\n- Skip empty sections";
11
10
  /** Prompt for re-compaction when a prior summary exists. */
@@ -53,7 +52,7 @@ export declare function createSummarizeNode({ agentContext, graph: adapterGraph,
53
52
  export declare function createSummarizationChunkHandler({ stepId, config, provider, reasoningKey, graph, }: {
54
53
  stepId?: string;
55
54
  config?: RunnableConfig;
56
- provider?: Providers;
55
+ provider?: t.ProviderName;
57
56
  reasoningKey?: 'reasoning_content' | 'reasoning';
58
57
  graph?: StreamLimitState & {
59
58
  getBreakerController?: () => AbortController;
@@ -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
  /** One tool call's contribution to the label payload (host-assembled). */
6
5
  export type ActivityLabelToolEntry = {
7
6
  toolName: string;
@@ -23,7 +22,7 @@ export type ActivityLabelToolEntry = {
23
22
  * `activity_label` content type's formatter exclusions.
24
23
  */
25
24
  export type RunActivityLabelOptions = {
26
- provider: Providers;
25
+ provider: ProviderName;
27
26
  clientOptions?: ClientOptions;
28
27
  /**
29
28
  * Agent that executed the labeled batch. Selects that agent's Langfuse
@@ -81,7 +80,7 @@ export type ActivityPhaseEntry = {
81
80
  };
82
81
  /** Options for `Run.generateActivityPhaseLabel`. */
83
82
  export type RunActivityPhaseLabelOptions = {
84
- provider: Providers;
83
+ provider: ProviderName;
85
84
  clientOptions?: ClientOptions;
86
85
  /**
87
86
  * Logical activities in run order. The SDK requires at least two so hosts
@@ -8,10 +8,10 @@ import type { SummarizationNodeInput, SummarizeCompleteEvent, SummarizationConfi
8
8
  import type { RunStep, RunStepDeltaEvent, RunStepResumeState, RunStepClosedEvent, MessageDeltaEvent, ReasoningDeltaEvent } from '@/types/stream';
9
9
  import type { ToolMap, ToolSessionMap, ToolEndEvent, GenericTool, LCTool, ToolExecutionConfig, ToolExecuteBatchRequest } from '@/types/tools';
10
10
  import type { TokenCounter, StreamLimits, StreamPreemption, TokenBudgetBreakdown } from '@/types/run';
11
- import type { Providers, Callback, GraphNodeKeys } from '@/common';
12
11
  import type { SubagentTaskConfig } from '@/types/subagentTasks';
13
12
  import type { StandardGraph, MultiAgentGraph } from '@/graphs';
14
- import type { ClientOptions } from '@/types/llm';
13
+ import type { ProviderClientOptionsConfig } from '@/types/llm';
14
+ import type { Callback, GraphNodeKeys } from '@/common';
15
15
  /** Interface for bound model with stream and invoke methods */
16
16
  export interface ChatModel {
17
17
  stream?: (messages: BaseMessage[], config?: RunnableConfig) => Promise<AsyncIterable<AIMessageChunk>>;
@@ -647,7 +647,7 @@ export interface LangfuseConfig {
647
647
  */
648
648
  deterministicTraceId?: boolean;
649
649
  }
650
- export interface AgentInputs {
650
+ interface AgentInputFields {
651
651
  agentId: string;
652
652
  /**
653
653
  * Partition key for transient code-session ids and file refs. Agents with
@@ -662,12 +662,10 @@ export interface AgentInputs {
662
662
  toolEnd?: boolean;
663
663
  toolMap?: ToolMap;
664
664
  tools?: GraphTools;
665
- provider: Providers;
666
665
  /** Stable/cacheable system instructions. */
667
666
  instructions?: string;
668
667
  streamBuffer?: number;
669
668
  maxContextTokens?: number;
670
- clientOptions?: ClientOptions;
671
669
  /** Per-agent Langfuse tracing configuration. */
672
670
  langfuse?: LangfuseConfig;
673
671
  /** Dynamic system tail appended after stable instructions without provider cache markers. */
@@ -739,6 +737,7 @@ export interface AgentInputs {
739
737
  */
740
738
  graphTools?: GenericTool[];
741
739
  }
740
+ export type AgentInputs = AgentInputFields & ProviderClientOptionsConfig;
742
741
  export interface ContextPruningConfig {
743
742
  enabled?: boolean;
744
743
  keepLastAssistants?: number;
@@ -1,6 +1,6 @@
1
1
  import { ChatMistralAI } from '@langchain/mistralai';
2
2
  import type { OpenAIChatInput, ChatOpenAIFields, AzureOpenAIInput, ClientOptions as OAIClientOptions } from '@langchain/openai';
3
- import type { BindToolsInput, BaseChatModelParams } from '@langchain/core/language_models/chat_models';
3
+ import type { BindToolsInput, BaseChatModel, BaseChatModelParams } from '@langchain/core/language_models/chat_models';
4
4
  import type { GoogleGenerativeAIChatInput } from '@langchain/google-genai';
5
5
  import type { ChatVertexAIInput } from '@langchain/google-vertexai';
6
6
  import type { ChatBedrockConverseInput } from '@langchain/aws';
@@ -12,6 +12,7 @@ import type { AnthropicInput } from '@langchain/anthropic';
12
12
  import type { Runnable } from '@langchain/core/runnables';
13
13
  import type { OpenAI as OpenAIClient } from 'openai';
14
14
  import type { ChatXAIInput } from '@langchain/xai';
15
+ import type { CustomProviderOptionsMap } from '../provider-registration';
15
16
  import type { ChatOpenRouterCallOptions } from '@/llm/openrouter';
16
17
  import type { PromptCacheTtl } from '@/messages/cache';
17
18
  import { AzureChatOpenAI, ChatDeepSeek, ChatMoonshot, ChatOpenAI, ChatXAI } from '@/llm/openai';
@@ -105,21 +106,57 @@ export type GoogleClientOptions = GoogleGenerativeAIChatInput & StreamSmoothingO
105
106
  };
106
107
  export type DeepSeekClientOptions = Partial<ChatDeepSeekInput> & StreamSmoothingOptions;
107
108
  export type XAIClientOptions = ChatXAIInput & StreamSmoothingOptions;
108
- export type ClientOptions = OpenAIClientOptions | AzureClientOptions | AnthropicClientOptions | MistralAIClientOptions | VertexAIClientOptions | BedrockConverseClientOptions | GoogleClientOptions | DeepSeekClientOptions | XAIClientOptions;
109
- export type SharedLLMConfig = {
110
- provider: Providers;
109
+ export type BuiltInClientOptions = OpenAIClientOptions | AzureClientOptions | AnthropicClientOptions | MistralAIClientOptions | VertexAIClientOptions | BedrockConverseClientOptions | GoogleClientOptions | DeepSeekClientOptions | XAIClientOptions;
110
+ type CustomProviderName = Extract<keyof CustomProviderOptionsMap, string>;
111
+ type LooseRuntimeProviderName = string & {
112
+ readonly __runtimeProviderName?: never;
113
+ };
114
+ export type ProviderName = keyof ProviderOptionsMap | CustomProviderName | LooseRuntimeProviderName;
115
+ declare const RUNTIME_PROVIDER_NAME: unique symbol;
116
+ /** A runtime provider without declaration-merged option types. */
117
+ export type RuntimeProviderName = string & {
118
+ readonly [RUNTIME_PROVIDER_NAME]: true;
119
+ };
120
+ export type ClientOptions = BuiltInClientOptions | CustomProviderOptionsMap[CustomProviderName];
121
+ export type SharedLLMConfig<P extends keyof ProviderOptionsMap | CustomProviderName | RuntimeProviderName = keyof ProviderOptionsMap> = {
122
+ provider: P;
123
+ model?: string;
111
124
  _lc_stream_delay?: number;
112
125
  };
113
- export interface FallbackConfig {
114
- provider: Providers;
115
- clientOptions?: ClientOptions;
126
+ type CustomProviderClientOptionsConfig<P extends CustomProviderName> = {
127
+ provider: P;
128
+ } & (object extends CustomProviderOptionsMap[P] ? {
129
+ clientOptions?: CustomProviderOptionsMap[P];
130
+ } : {
131
+ clientOptions: CustomProviderOptionsMap[P];
132
+ });
133
+ export type ProviderClientOptionsConfig = {
134
+ provider: keyof ProviderOptionsMap;
135
+ clientOptions?: BuiltInClientOptions;
136
+ } | {
137
+ [P in CustomProviderName]: CustomProviderClientOptionsConfig<P>;
138
+ }[CustomProviderName] | {
139
+ provider: RuntimeProviderName;
140
+ clientOptions: ClientOptions;
141
+ };
142
+ export type FallbackConfig = ProviderClientOptionsConfig & {
116
143
  /** Context window used to corroborate ambiguous fallback overflow errors. */
117
144
  maxContextTokens?: number;
118
- }
119
- export type LLMConfig = SharedLLMConfig & ClientOptions & {
145
+ };
146
+ type LLMConfigFor<P extends CustomProviderName> = SharedLLMConfig<P> & CustomProviderOptionsMap[P] & {
147
+ /** Optional provider fallbacks in order of attempt */
148
+ fallbacks?: FallbackConfig[];
149
+ };
150
+ export type BuiltInLLMConfig = SharedLLMConfig & BuiltInClientOptions & {
120
151
  /** Optional provider fallbacks in order of attempt */
121
152
  fallbacks?: FallbackConfig[];
122
153
  };
154
+ export type LLMConfig = BuiltInLLMConfig | {
155
+ [P in CustomProviderName]: LLMConfigFor<P>;
156
+ }[CustomProviderName] | (SharedLLMConfig<RuntimeProviderName> & ClientOptions & {
157
+ /** Optional provider fallbacks in order of attempt */
158
+ fallbacks?: FallbackConfig[];
159
+ });
123
160
  export type ProviderOptionsMap = {
124
161
  [Providers.AZURE]: AzureClientOptions;
125
162
  [Providers.OPENAI]: OpenAIClientOptions;
@@ -134,7 +171,7 @@ export type ProviderOptionsMap = {
134
171
  [Providers.XAI]: XAIClientOptions;
135
172
  [Providers.MOONSHOT]: OpenAIClientOptions;
136
173
  };
137
- export type ChatModelMap = {
174
+ export interface ChatModelMap {
138
175
  [Providers.XAI]: ChatXAI;
139
176
  [Providers.OPENAI]: ChatOpenAI;
140
177
  [Providers.AZURE]: AzureChatOpenAI;
@@ -147,11 +184,15 @@ export type ChatModelMap = {
147
184
  [Providers.BEDROCK]: CustomChatBedrockConverse;
148
185
  [Providers.GOOGLE]: CustomChatGoogleGenerativeAI;
149
186
  [Providers.MOONSHOT]: ChatMoonshot;
150
- };
187
+ }
188
+ export type ProviderOptionsFor<P extends ProviderName> = P extends keyof ProviderOptionsMap ? ProviderOptionsMap[P] : P extends CustomProviderName ? CustomProviderOptionsMap[P] : BuiltInClientOptions;
189
+ export type ProviderModelFor<P extends ProviderName> = P extends keyof ChatModelMap ? ChatModelMap[P] & BaseChatModel : BaseChatModel;
190
+ export type ProviderModelConstructor<P extends ProviderName> = new (config: ProviderOptionsFor<P>) => ProviderModelFor<P>;
151
191
  export type ChatModelConstructorMap = {
152
192
  [P in Providers]: new (config: ProviderOptionsMap[P]) => ChatModelMap[P];
153
193
  };
154
- export type ChatModelInstance = ChatModelMap[Providers];
155
- export type ModelWithTools = ChatModelInstance & {
194
+ export type ChatModelInstance = BaseChatModel;
195
+ export type ModelWithTools = BaseChatModel & {
156
196
  bindTools(tools: CommonToolType[]): Runnable;
157
197
  };
198
+ 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
  /** Lifecycle state of the visible reasoning snapshot being labeled. */
6
5
  export type ReasoningLabelStatus = 'streaming' | 'complete';
7
6
  /** Result of one reasoning-label revision. */
@@ -12,7 +11,7 @@ export type ReasoningLabelResult = {
12
11
  };
13
12
  /** Options for `Run.generateReasoningLabel`. */
14
13
  export type RunReasoningLabelOptions = {
15
- provider: Providers;
14
+ provider: ProviderName;
16
15
  clientOptions?: ClientOptions;
17
16
  /**
18
17
  * Complete user-visible reasoning accumulated for this step so far. Hidden
@@ -14,7 +14,7 @@ import type * as l from '@/types/llm';
14
14
  export type ZodObjectAny = z.ZodObject<any, any, any, any>;
15
15
  export type BaseGraphConfig = {
16
16
  llmConfig: l.LLMConfig;
17
- provider?: e.Providers;
17
+ provider?: l.ProviderName;
18
18
  clientOptions?: l.ClientOptions;
19
19
  /** Optional compile options for workflow.compile() */
20
20
  compileOptions?: g.CompileOptions;
@@ -34,7 +34,7 @@ export type SupervisedGraphConfig = BaseGraphConfig & {
34
34
  routingPolicies?: Array<{
35
35
  stage: string;
36
36
  agents?: string[];
37
- model?: e.Providers;
37
+ model?: l.ProviderName;
38
38
  parallel?: boolean;
39
39
  /** Optional simple condition on content/tools */
40
40
  when?: 'always' | 'has_tools' | 'no_tools' | {
@@ -55,7 +55,7 @@ export type SupervisedGraphConfig = BaseGraphConfig & {
55
55
  } & Omit<g.StandardGraphInput, 'provider' | 'clientOptions'>;
56
56
  export type RunTitleOptions = {
57
57
  inputText: string;
58
- provider: e.Providers;
58
+ provider: l.ProviderName;
59
59
  contentParts: (s.MessageContentComplex | undefined)[];
60
60
  titlePrompt?: string;
61
61
  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
  export type SummarizationTrigger = {
4
4
  type: 'token_ratio' | 'remaining_tokens' | 'messages_to_refine' | (string & {});
5
5
  value: number;
@@ -28,7 +28,7 @@ export type RetainRecentConfig = {
28
28
  tokens?: number;
29
29
  };
30
30
  export type SummarizationConfig = {
31
- provider?: Providers;
31
+ provider?: ProviderName;
32
32
  model?: string;
33
33
  parameters?: Record<string, unknown>;
34
34
  prompt?: string;
@@ -1,4 +1,4 @@
1
- import type { Providers } from '@/common';
1
+ import type { ProviderName } from '@/types';
2
2
  /**
3
3
  * Why the request was rejected. Both kinds are fixed by shrinking the
4
4
  * prompt, which is what makes them recoverable; they are distinguished
@@ -33,10 +33,10 @@ export interface ContextOverflowInfo {
33
33
  promptTokens?: number;
34
34
  /** Which layer produced the verdict. Surfaced in logs and asserted in tests. */
35
35
  source: 'langchain' | 'pattern';
36
- provider?: Providers;
36
+ provider?: ProviderName;
37
37
  }
38
38
  export interface ContextOverflowContext {
39
- provider?: Providers;
39
+ provider?: ProviderName;
40
40
  /** Our own estimate of the prompt size for the call that failed. */
41
41
  estimatedPromptTokens?: number;
42
42
  /** The budget we believed applied when we built that prompt. */
@@ -1,7 +1,7 @@
1
- import { Providers } from '@/common';
2
- export declare function isOpenAILike(provider?: string | Providers): boolean;
3
- export declare function isGoogleLike(provider?: string | Providers): boolean;
1
+ import type { ProviderName } from '@/types';
2
+ export declare function isOpenAILike(provider?: ProviderName): boolean;
3
+ export declare function isGoogleLike(provider?: ProviderName): boolean;
4
4
  /** Returns true for native Anthropic or Bedrock running a Claude model. */
5
- export declare function isAnthropicLike(provider?: string | Providers, clientOptions?: {
5
+ export declare function isAnthropicLike(provider?: ProviderName, clientOptions?: {
6
6
  model?: string;
7
7
  }): boolean;
@@ -1,3 +1,3 @@
1
1
  import type * as t from '@/types';
2
- export declare const llmConfigs: Record<string, t.LLMConfig | undefined>;
3
- export declare function getLLMConfig(provider: string): t.LLMConfig;
2
+ export declare const llmConfigs: Record<string, t.BuiltInLLMConfig | undefined>;
3
+ export declare function getLLMConfig(provider: string): t.BuiltInLLMConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.6.15",
3
+ "version": "3.6.16",
4
4
  "reova": {
5
5
  "enabled": true,
6
6
  "endpoint": "https://telemetry.reo.dev/data"
@@ -14,6 +14,11 @@
14
14
  "import": "./dist/esm/main.mjs",
15
15
  "require": "./dist/cjs/main.cjs"
16
16
  },
17
+ "./provider-registration": {
18
+ "types": "./dist/types/provider-registration.d.ts",
19
+ "import": "./dist/esm/provider-registration.mjs",
20
+ "require": "./dist/cjs/provider-registration.cjs"
21
+ },
17
22
  "./openai": {
18
23
  "types": "./dist/types/openai/index.d.ts",
19
24
  "import": "./dist/esm/openai/index.mjs",
@@ -77,6 +82,9 @@
77
82
  },
78
83
  "typesVersions": {
79
84
  "*": {
85
+ "provider-registration": [
86
+ "dist/types/provider-registration.d.ts"
87
+ ],
80
88
  "langchain": [
81
89
  "dist/types/langchain/index.d.ts"
82
90
  ],