@librechat/agents 3.1.75 → 3.1.77-dev.1
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.
- package/dist/cjs/graphs/Graph.cjs +22 -3
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/hitl/askUserQuestion.cjs +67 -0
- package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -0
- package/dist/cjs/hooks/HookRegistry.cjs +54 -0
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
- package/dist/cjs/hooks/createToolPolicyHook.cjs +115 -0
- package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -0
- package/dist/cjs/hooks/executeHooks.cjs +40 -1
- package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
- package/dist/cjs/hooks/types.cjs +1 -0
- package/dist/cjs/hooks/types.cjs.map +1 -1
- package/dist/cjs/langchain/google-common.cjs +3 -0
- package/dist/cjs/langchain/google-common.cjs.map +1 -0
- package/dist/cjs/langchain/index.cjs +86 -0
- package/dist/cjs/langchain/index.cjs.map +1 -0
- package/dist/cjs/langchain/language_models/chat_models.cjs +3 -0
- package/dist/cjs/langchain/language_models/chat_models.cjs.map +1 -0
- package/dist/cjs/langchain/messages/tool.cjs +3 -0
- package/dist/cjs/langchain/messages/tool.cjs.map +1 -0
- package/dist/cjs/langchain/messages.cjs +51 -0
- package/dist/cjs/langchain/messages.cjs.map +1 -0
- package/dist/cjs/langchain/openai.cjs +3 -0
- package/dist/cjs/langchain/openai.cjs.map +1 -0
- package/dist/cjs/langchain/prompts.cjs +11 -0
- package/dist/cjs/langchain/prompts.cjs.map +1 -0
- package/dist/cjs/langchain/runnables.cjs +19 -0
- package/dist/cjs/langchain/runnables.cjs.map +1 -0
- package/dist/cjs/langchain/tools.cjs +23 -0
- package/dist/cjs/langchain/tools.cjs.map +1 -0
- package/dist/cjs/langchain/utils/env.cjs +11 -0
- package/dist/cjs/langchain/utils/env.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/index.cjs +145 -52
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +21 -14
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +84 -70
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +1 -1
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +213 -3
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +2 -1
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +5 -4
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +519 -655
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +20 -458
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +57 -175
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +5 -3
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +112 -3
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +2 -1
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +7 -6
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +73 -15
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/langchain.cjs +26 -0
- package/dist/cjs/messages/langchain.cjs.map +1 -0
- package/dist/cjs/messages/prune.cjs +7 -6
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +400 -42
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +556 -56
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +55 -66
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tavily-scraper.cjs +189 -0
- package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/tavily-search.cjs +372 -0
- package/dist/cjs/tools/search/tavily-search.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +26 -4
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +10 -3
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +22 -3
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/hitl/askUserQuestion.mjs +65 -0
- package/dist/esm/hitl/askUserQuestion.mjs.map +1 -0
- package/dist/esm/hooks/HookRegistry.mjs +54 -0
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
- package/dist/esm/hooks/createToolPolicyHook.mjs +113 -0
- package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -0
- package/dist/esm/hooks/executeHooks.mjs +40 -1
- package/dist/esm/hooks/executeHooks.mjs.map +1 -1
- package/dist/esm/hooks/types.mjs +1 -0
- package/dist/esm/hooks/types.mjs.map +1 -1
- package/dist/esm/langchain/google-common.mjs +2 -0
- package/dist/esm/langchain/google-common.mjs.map +1 -0
- package/dist/esm/langchain/index.mjs +5 -0
- package/dist/esm/langchain/index.mjs.map +1 -0
- package/dist/esm/langchain/language_models/chat_models.mjs +2 -0
- package/dist/esm/langchain/language_models/chat_models.mjs.map +1 -0
- package/dist/esm/langchain/messages/tool.mjs +2 -0
- package/dist/esm/langchain/messages/tool.mjs.map +1 -0
- package/dist/esm/langchain/messages.mjs +2 -0
- package/dist/esm/langchain/messages.mjs.map +1 -0
- package/dist/esm/langchain/openai.mjs +2 -0
- package/dist/esm/langchain/openai.mjs.map +1 -0
- package/dist/esm/langchain/prompts.mjs +2 -0
- package/dist/esm/langchain/prompts.mjs.map +1 -0
- package/dist/esm/langchain/runnables.mjs +2 -0
- package/dist/esm/langchain/runnables.mjs.map +1 -0
- package/dist/esm/langchain/tools.mjs +2 -0
- package/dist/esm/langchain/tools.mjs.map +1 -0
- package/dist/esm/langchain/utils/env.mjs +2 -0
- package/dist/esm/langchain/utils/env.mjs.map +1 -0
- package/dist/esm/llm/anthropic/index.mjs +146 -54
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +21 -14
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +84 -71
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +1 -1
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +214 -4
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs +2 -1
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +5 -4
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +520 -656
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +23 -459
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +57 -175
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +5 -3
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +7 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +2 -1
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +7 -6
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +73 -15
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/langchain.mjs +23 -0
- package/dist/esm/messages/langchain.mjs.map +1 -0
- package/dist/esm/messages/prune.mjs +7 -6
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +400 -42
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +557 -57
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +55 -66
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tavily-scraper.mjs +186 -0
- package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/tavily-search.mjs +370 -0
- package/dist/esm/tools/search/tavily-search.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +26 -4
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +10 -3
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +7 -0
- package/dist/types/hitl/askUserQuestion.d.ts +55 -0
- package/dist/types/hitl/index.d.ts +6 -0
- package/dist/types/hooks/HookRegistry.d.ts +58 -0
- package/dist/types/hooks/createToolPolicyHook.d.ts +87 -0
- package/dist/types/hooks/index.d.ts +4 -1
- package/dist/types/hooks/types.d.ts +109 -3
- package/dist/types/index.d.ts +10 -0
- package/dist/types/langchain/google-common.d.ts +1 -0
- package/dist/types/langchain/index.d.ts +8 -0
- package/dist/types/langchain/language_models/chat_models.d.ts +1 -0
- package/dist/types/langchain/messages/tool.d.ts +1 -0
- package/dist/types/langchain/messages.d.ts +2 -0
- package/dist/types/langchain/openai.d.ts +1 -0
- package/dist/types/langchain/prompts.d.ts +1 -0
- package/dist/types/langchain/runnables.d.ts +2 -0
- package/dist/types/langchain/tools.d.ts +2 -0
- package/dist/types/langchain/utils/env.d.ts +1 -0
- package/dist/types/llm/anthropic/index.d.ts +22 -9
- package/dist/types/llm/anthropic/types.d.ts +5 -1
- package/dist/types/llm/anthropic/utils/message_outputs.d.ts +13 -6
- package/dist/types/llm/anthropic/utils/output_parsers.d.ts +1 -1
- package/dist/types/llm/openai/index.d.ts +21 -24
- package/dist/types/llm/openrouter/index.d.ts +11 -9
- package/dist/types/llm/vertexai/index.d.ts +1 -0
- package/dist/types/messages/cache.d.ts +4 -1
- package/dist/types/messages/format.d.ts +4 -1
- package/dist/types/messages/langchain.d.ts +27 -0
- package/dist/types/run.d.ts +117 -1
- package/dist/types/tools/ToolNode.d.ts +26 -1
- package/dist/types/tools/search/tavily-scraper.d.ts +19 -0
- package/dist/types/tools/search/tavily-search.d.ts +4 -0
- package/dist/types/tools/search/types.d.ts +99 -5
- package/dist/types/tools/search/utils.d.ts +2 -2
- package/dist/types/types/graph.d.ts +23 -37
- package/dist/types/types/hitl.d.ts +272 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/llm.d.ts +3 -3
- package/dist/types/types/run.d.ts +33 -0
- package/dist/types/types/stream.d.ts +1 -1
- package/dist/types/types/tools.d.ts +19 -0
- package/package.json +80 -17
- package/src/graphs/Graph.ts +33 -4
- package/src/graphs/__tests__/composition.smoke.test.ts +188 -0
- package/src/hitl/askUserQuestion.ts +72 -0
- package/src/hitl/index.ts +7 -0
- package/src/hooks/HookRegistry.ts +71 -0
- package/src/hooks/__tests__/createToolPolicyHook.test.ts +259 -0
- package/src/hooks/createToolPolicyHook.ts +184 -0
- package/src/hooks/executeHooks.ts +50 -1
- package/src/hooks/index.ts +6 -0
- package/src/hooks/types.ts +112 -0
- package/src/index.ts +22 -0
- package/src/langchain/google-common.ts +1 -0
- package/src/langchain/index.ts +8 -0
- package/src/langchain/language_models/chat_models.ts +1 -0
- package/src/langchain/messages/tool.ts +5 -0
- package/src/langchain/messages.ts +21 -0
- package/src/langchain/openai.ts +1 -0
- package/src/langchain/prompts.ts +1 -0
- package/src/langchain/runnables.ts +7 -0
- package/src/langchain/tools.ts +8 -0
- package/src/langchain/utils/env.ts +1 -0
- package/src/llm/anthropic/index.ts +252 -84
- package/src/llm/anthropic/llm.spec.ts +751 -102
- package/src/llm/anthropic/types.ts +9 -1
- package/src/llm/anthropic/utils/message_inputs.ts +37 -19
- package/src/llm/anthropic/utils/message_outputs.ts +119 -101
- package/src/llm/bedrock/index.ts +2 -2
- package/src/llm/bedrock/llm.spec.ts +341 -0
- package/src/llm/bedrock/utils/message_inputs.ts +303 -4
- package/src/llm/bedrock/utils/message_outputs.ts +2 -1
- package/src/llm/custom-chat-models.smoke.test.ts +836 -0
- package/src/llm/google/llm.spec.ts +339 -57
- package/src/llm/google/utils/common.ts +53 -48
- package/src/llm/openai/contentBlocks.test.ts +346 -0
- package/src/llm/openai/index.ts +856 -833
- package/src/llm/openai/utils/index.ts +107 -78
- package/src/llm/openai/utils/messages.test.ts +159 -0
- package/src/llm/openrouter/index.ts +124 -247
- package/src/llm/openrouter/reasoning.test.ts +8 -1
- package/src/llm/vertexai/index.ts +11 -5
- package/src/llm/vertexai/llm.spec.ts +28 -1
- package/src/messages/cache.test.ts +4 -3
- package/src/messages/cache.ts +3 -2
- package/src/messages/core.ts +16 -9
- package/src/messages/format.ts +96 -16
- package/src/messages/formatAgentMessages.test.ts +166 -1
- package/src/messages/langchain.ts +39 -0
- package/src/messages/prune.ts +12 -8
- package/src/run.ts +456 -47
- package/src/scripts/caching.ts +2 -3
- package/src/specs/summarization.test.ts +51 -58
- package/src/tools/ToolNode.ts +706 -63
- package/src/tools/__tests__/hitl.test.ts +3593 -0
- package/src/tools/search/search.ts +83 -73
- package/src/tools/search/tavily-scraper.ts +235 -0
- package/src/tools/search/tavily-search.ts +424 -0
- package/src/tools/search/tavily.test.ts +965 -0
- package/src/tools/search/tool.ts +36 -26
- package/src/tools/search/types.ts +133 -8
- package/src/tools/search/utils.ts +13 -5
- package/src/types/graph.ts +32 -87
- package/src/types/hitl.ts +303 -0
- package/src/types/index.ts +1 -0
- package/src/types/llm.ts +3 -3
- package/src/types/run.ts +33 -0
- package/src/types/stream.ts +1 -1
- package/src/types/tools.ts +19 -0
- package/src/utils/llmConfig.ts +1 -6
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { AzureOpenAI } from 'openai';
|
|
2
2
|
import { ChatXAI as ChatXAI$1 } from '@langchain/xai';
|
|
3
3
|
import { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
4
|
-
import { AIMessage, AIMessageChunk } from '@langchain/core/messages';
|
|
4
|
+
import { isAIMessage, AIMessage, AIMessageChunk } from '@langchain/core/messages';
|
|
5
5
|
import '@langchain/core/utils/function_calling';
|
|
6
6
|
import { ChatDeepSeek as ChatDeepSeek$1 } from '@langchain/deepseek';
|
|
7
|
-
import { getEndpoint, AzureChatOpenAI as AzureChatOpenAI$1, ChatOpenAI as ChatOpenAI$1, OpenAIClient } from '@langchain/openai';
|
|
8
|
-
import {
|
|
7
|
+
import { getEndpoint, AzureChatOpenAI as AzureChatOpenAI$1, ChatOpenAI as ChatOpenAI$1, OpenAIClient, AzureChatOpenAICompletions, AzureChatOpenAIResponses, ChatOpenAIResponses, ChatOpenAICompletions, getHeadersWithUserAgent } from '@langchain/openai';
|
|
8
|
+
import { isReasoningModel, _convertMessagesToOpenAIParams } from './utils/index.mjs';
|
|
9
9
|
import '../../common/enum.mjs';
|
|
10
10
|
import 'nanoid';
|
|
11
11
|
import '../../messages/core.mjs';
|
|
@@ -51,6 +51,153 @@ function normalizeHeaders(headers) {
|
|
|
51
51
|
});
|
|
52
52
|
return Object.fromEntries(output.entries());
|
|
53
53
|
}
|
|
54
|
+
function getExposedOpenAIClient(completions, responses, preferResponses) {
|
|
55
|
+
const responsesClient = responses.client;
|
|
56
|
+
if (responsesClient?.abortHandler != null) {
|
|
57
|
+
return responsesClient;
|
|
58
|
+
}
|
|
59
|
+
const completionsClient = completions.client;
|
|
60
|
+
if (completionsClient?.abortHandler != null) {
|
|
61
|
+
return completionsClient;
|
|
62
|
+
}
|
|
63
|
+
const delegate = preferResponses ? responses : completions;
|
|
64
|
+
delegate._getClientOptions(undefined);
|
|
65
|
+
return delegate.client;
|
|
66
|
+
}
|
|
67
|
+
function getReasoningParams(baseReasoning, options) {
|
|
68
|
+
let reasoning;
|
|
69
|
+
if (baseReasoning !== undefined) {
|
|
70
|
+
reasoning = {
|
|
71
|
+
...reasoning,
|
|
72
|
+
...baseReasoning,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (options?.reasoning !== undefined) {
|
|
76
|
+
reasoning = {
|
|
77
|
+
...reasoning,
|
|
78
|
+
...options.reasoning,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (options?.reasoningEffort !== undefined &&
|
|
82
|
+
reasoning?.effort === undefined) {
|
|
83
|
+
reasoning = {
|
|
84
|
+
...reasoning,
|
|
85
|
+
effort: options.reasoningEffort,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return reasoning;
|
|
89
|
+
}
|
|
90
|
+
function getGatedReasoningParams(model, baseReasoning, options) {
|
|
91
|
+
if (!isReasoningModel(model)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
return getReasoningParams(baseReasoning, options);
|
|
95
|
+
}
|
|
96
|
+
function isObject(value) {
|
|
97
|
+
return typeof value === 'object' && value !== null;
|
|
98
|
+
}
|
|
99
|
+
function isOpenAIChatCompletionChunk(value) {
|
|
100
|
+
if (!isObject(value)) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
// Intentionally loose: downstream handlers already tolerate empty choices.
|
|
104
|
+
const { choices } = value;
|
|
105
|
+
return Array.isArray(choices);
|
|
106
|
+
}
|
|
107
|
+
function getOpenAIChatCompletionChunk(value) {
|
|
108
|
+
if (isOpenAIChatCompletionChunk(value)) {
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
const { data } = value;
|
|
112
|
+
if (isOpenAIChatCompletionChunk(data)) {
|
|
113
|
+
return data;
|
|
114
|
+
}
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
async function* filterOpenAIChatCompletionStream(stream) {
|
|
118
|
+
for await (const item of stream) {
|
|
119
|
+
const chunk = getOpenAIChatCompletionChunk(item);
|
|
120
|
+
if (chunk == null) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
yield chunk;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function completionWithFilteredOpenAIStream(request, requestOptions, completionWithRetry) {
|
|
127
|
+
if (request.stream !== true) {
|
|
128
|
+
return (await completionWithRetry(request, requestOptions));
|
|
129
|
+
}
|
|
130
|
+
const stream = await completionWithRetry(request, requestOptions);
|
|
131
|
+
return filterOpenAIChatCompletionStream(stream);
|
|
132
|
+
}
|
|
133
|
+
function attachLibreChatDeltaFields(chunk, delta) {
|
|
134
|
+
if (!AIMessageChunk.isInstance(chunk)) {
|
|
135
|
+
return chunk;
|
|
136
|
+
}
|
|
137
|
+
const libreChatDelta = delta;
|
|
138
|
+
if (libreChatDelta.reasoning != null &&
|
|
139
|
+
chunk.additional_kwargs.reasoning_content == null) {
|
|
140
|
+
chunk.additional_kwargs.reasoning_content = libreChatDelta.reasoning;
|
|
141
|
+
}
|
|
142
|
+
if (libreChatDelta.reasoning_details != null) {
|
|
143
|
+
chunk.additional_kwargs.reasoning_details =
|
|
144
|
+
libreChatDelta.reasoning_details;
|
|
145
|
+
}
|
|
146
|
+
if (libreChatDelta.provider_specific_fields != null) {
|
|
147
|
+
chunk.additional_kwargs.provider_specific_fields =
|
|
148
|
+
libreChatDelta.provider_specific_fields;
|
|
149
|
+
}
|
|
150
|
+
return chunk;
|
|
151
|
+
}
|
|
152
|
+
function attachLibreChatMessageFields(message, rawMessage) {
|
|
153
|
+
if (!isAIMessage(message)) {
|
|
154
|
+
return message;
|
|
155
|
+
}
|
|
156
|
+
if (rawMessage.reasoning != null &&
|
|
157
|
+
message.additional_kwargs.reasoning_content == null) {
|
|
158
|
+
message.additional_kwargs.reasoning_content = rawMessage.reasoning;
|
|
159
|
+
}
|
|
160
|
+
if (rawMessage.reasoning_details != null) {
|
|
161
|
+
message.additional_kwargs.reasoning_details = rawMessage.reasoning_details;
|
|
162
|
+
}
|
|
163
|
+
if (rawMessage.provider_specific_fields != null) {
|
|
164
|
+
message.additional_kwargs.provider_specific_fields =
|
|
165
|
+
rawMessage.provider_specific_fields;
|
|
166
|
+
}
|
|
167
|
+
return message;
|
|
168
|
+
}
|
|
169
|
+
function getCustomOpenAIClientOptions(owner, options) {
|
|
170
|
+
if (!owner.client) {
|
|
171
|
+
const openAIEndpointConfig = {
|
|
172
|
+
baseURL: owner.clientConfig.baseURL,
|
|
173
|
+
};
|
|
174
|
+
const endpoint = getEndpoint(openAIEndpointConfig);
|
|
175
|
+
const params = {
|
|
176
|
+
...owner.clientConfig,
|
|
177
|
+
baseURL: endpoint,
|
|
178
|
+
timeout: owner.timeout,
|
|
179
|
+
maxRetries: 0,
|
|
180
|
+
};
|
|
181
|
+
if (params.baseURL == null) {
|
|
182
|
+
delete params.baseURL;
|
|
183
|
+
}
|
|
184
|
+
params.defaultHeaders = getHeadersWithUserAgent(params.defaultHeaders);
|
|
185
|
+
owner.client = new CustomOpenAIClient(params);
|
|
186
|
+
}
|
|
187
|
+
const requestOptions = {
|
|
188
|
+
...owner.clientConfig,
|
|
189
|
+
...options,
|
|
190
|
+
};
|
|
191
|
+
return requestOptions;
|
|
192
|
+
}
|
|
193
|
+
async function* delayStreamChunks(chunks, delay) {
|
|
194
|
+
for await (const chunk of chunks) {
|
|
195
|
+
yield chunk;
|
|
196
|
+
if (delay != null) {
|
|
197
|
+
await sleep(delay);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
54
201
|
function createAbortHandler(controller) {
|
|
55
202
|
return function () {
|
|
56
203
|
controller.abort();
|
|
@@ -110,89 +257,165 @@ class CustomAzureOpenAIClient extends AzureOpenAI {
|
|
|
110
257
|
}));
|
|
111
258
|
}
|
|
112
259
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
260
|
+
class LibreChatOpenAICompletions extends ChatOpenAICompletions {
|
|
261
|
+
includeReasoningContent;
|
|
262
|
+
includeReasoningDetails;
|
|
263
|
+
convertReasoningDetailsToContent;
|
|
116
264
|
constructor(fields) {
|
|
117
265
|
super(fields);
|
|
118
|
-
this.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
266
|
+
this.includeReasoningContent = fields?.includeReasoningContent;
|
|
267
|
+
this.includeReasoningDetails = fields?.includeReasoningDetails;
|
|
268
|
+
this.convertReasoningDetailsToContent =
|
|
269
|
+
fields?.convertReasoningDetailsToContent;
|
|
122
270
|
}
|
|
123
|
-
|
|
124
|
-
return
|
|
271
|
+
_getReasoningParams(options) {
|
|
272
|
+
return getReasoningParams(this.reasoning, options);
|
|
125
273
|
}
|
|
126
274
|
_getClientOptions(options) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
275
|
+
return getCustomOpenAIClientOptions(this, options);
|
|
276
|
+
}
|
|
277
|
+
async completionWithRetry(request, requestOptions) {
|
|
278
|
+
return completionWithFilteredOpenAIStream(request, requestOptions, super.completionWithRetry.bind(this));
|
|
279
|
+
}
|
|
280
|
+
_convertCompletionsDeltaToBaseMessageChunk(delta, rawResponse, defaultRole) {
|
|
281
|
+
return attachLibreChatDeltaFields(super._convertCompletionsDeltaToBaseMessageChunk(delta, rawResponse, defaultRole), delta);
|
|
282
|
+
}
|
|
283
|
+
_convertCompletionsMessageToBaseMessage(message, rawResponse) {
|
|
284
|
+
return attachLibreChatMessageFields(super._convertCompletionsMessageToBaseMessage(message, rawResponse), message);
|
|
285
|
+
}
|
|
286
|
+
async _generate(messages, options, runManager) {
|
|
287
|
+
if (this.includeReasoningContent !== true &&
|
|
288
|
+
this.includeReasoningDetails !== true) {
|
|
289
|
+
return super._generate(messages, options, runManager);
|
|
290
|
+
}
|
|
291
|
+
options.signal?.throwIfAborted();
|
|
292
|
+
const usageMetadata = {};
|
|
293
|
+
const params = this.invocationParams(options);
|
|
294
|
+
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model, {
|
|
295
|
+
includeReasoningContent: this.includeReasoningContent,
|
|
296
|
+
includeReasoningDetails: this.includeReasoningDetails,
|
|
297
|
+
convertReasoningDetailsToContent: this.convertReasoningDetailsToContent,
|
|
298
|
+
});
|
|
299
|
+
if (params.stream === true) {
|
|
300
|
+
const stream = this._streamResponseChunks(messages, options, runManager);
|
|
301
|
+
const finalChunks = new Map();
|
|
302
|
+
for await (const chunk of stream) {
|
|
303
|
+
chunk.message.response_metadata = {
|
|
304
|
+
...chunk.generationInfo,
|
|
305
|
+
...chunk.message.response_metadata,
|
|
306
|
+
};
|
|
307
|
+
const index = typeof chunk.generationInfo?.completion === 'number'
|
|
308
|
+
? chunk.generationInfo.completion
|
|
309
|
+
: 0;
|
|
310
|
+
const existingChunk = finalChunks.get(index);
|
|
311
|
+
if (existingChunk == null) {
|
|
312
|
+
finalChunks.set(index, chunk);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
finalChunks.set(index, existingChunk.concat(chunk));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const generations = Array.from(finalChunks.entries())
|
|
319
|
+
.sort(([aKey], [bKey]) => aKey - bKey)
|
|
320
|
+
.map(([, value]) => value);
|
|
321
|
+
const { functions, function_call } = this.invocationParams(options);
|
|
322
|
+
const promptTokenUsage = await this._getEstimatedTokenCountFromPrompt(messages, functions, function_call);
|
|
323
|
+
const completionTokenUsage = await this._getNumTokensFromGenerations(generations);
|
|
324
|
+
usageMetadata.input_tokens = promptTokenUsage;
|
|
325
|
+
usageMetadata.output_tokens = completionTokenUsage;
|
|
326
|
+
usageMetadata.total_tokens = promptTokenUsage + completionTokenUsage;
|
|
327
|
+
return {
|
|
328
|
+
generations,
|
|
329
|
+
llmOutput: {
|
|
330
|
+
estimatedTokenUsage: {
|
|
331
|
+
promptTokens: usageMetadata.input_tokens,
|
|
332
|
+
completionTokens: usageMetadata.output_tokens,
|
|
333
|
+
totalTokens: usageMetadata.total_tokens,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
130
336
|
};
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
337
|
+
}
|
|
338
|
+
const data = await this.completionWithRetry({
|
|
339
|
+
...params,
|
|
340
|
+
stream: false,
|
|
341
|
+
messages: messagesMapped,
|
|
342
|
+
}, {
|
|
343
|
+
signal: options.signal,
|
|
344
|
+
...options.options,
|
|
345
|
+
});
|
|
346
|
+
const { completion_tokens: completionTokens, prompt_tokens: promptTokens, total_tokens: totalTokens, prompt_tokens_details: promptTokensDetails, completion_tokens_details: completionTokensDetails, } = data.usage ?? {};
|
|
347
|
+
if (completionTokens != null) {
|
|
348
|
+
usageMetadata.output_tokens =
|
|
349
|
+
(usageMetadata.output_tokens ?? 0) + completionTokens;
|
|
350
|
+
}
|
|
351
|
+
if (promptTokens != null) {
|
|
352
|
+
usageMetadata.input_tokens =
|
|
353
|
+
(usageMetadata.input_tokens ?? 0) + promptTokens;
|
|
354
|
+
}
|
|
355
|
+
if (totalTokens != null) {
|
|
356
|
+
usageMetadata.total_tokens =
|
|
357
|
+
(usageMetadata.total_tokens ?? 0) + totalTokens;
|
|
358
|
+
}
|
|
359
|
+
if (promptTokensDetails?.audio_tokens != null ||
|
|
360
|
+
promptTokensDetails?.cached_tokens != null) {
|
|
361
|
+
usageMetadata.input_token_details = {
|
|
362
|
+
...(promptTokensDetails.audio_tokens != null && {
|
|
363
|
+
audio: promptTokensDetails.audio_tokens,
|
|
364
|
+
}),
|
|
365
|
+
...(promptTokensDetails.cached_tokens != null && {
|
|
366
|
+
cache_read: promptTokensDetails.cached_tokens,
|
|
367
|
+
}),
|
|
137
368
|
};
|
|
138
|
-
if (params.baseURL == null) {
|
|
139
|
-
delete params.baseURL;
|
|
140
|
-
}
|
|
141
|
-
this.client = new CustomOpenAIClient(params);
|
|
142
369
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
*/
|
|
153
|
-
getReasoningParams(options) {
|
|
154
|
-
// apply options in reverse order of importance -- newer options supersede older options
|
|
155
|
-
let reasoning;
|
|
156
|
-
if (this.reasoning !== undefined) {
|
|
157
|
-
reasoning = {
|
|
158
|
-
...reasoning,
|
|
159
|
-
...this.reasoning,
|
|
370
|
+
if (completionTokensDetails?.audio_tokens != null ||
|
|
371
|
+
completionTokensDetails?.reasoning_tokens != null) {
|
|
372
|
+
usageMetadata.output_token_details = {
|
|
373
|
+
...(completionTokensDetails.audio_tokens != null && {
|
|
374
|
+
audio: completionTokensDetails.audio_tokens,
|
|
375
|
+
}),
|
|
376
|
+
...(completionTokensDetails.reasoning_tokens != null && {
|
|
377
|
+
reasoning: completionTokensDetails.reasoning_tokens,
|
|
378
|
+
}),
|
|
160
379
|
};
|
|
161
380
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
381
|
+
const generations = [];
|
|
382
|
+
for (const part of data.choices) {
|
|
383
|
+
const generation = {
|
|
384
|
+
text: part.message.content ?? '',
|
|
385
|
+
message: this._convertCompletionsMessageToBaseMessage(part.message, data),
|
|
386
|
+
};
|
|
387
|
+
generation.generationInfo = {
|
|
388
|
+
finish_reason: part.finish_reason,
|
|
389
|
+
...(part.logprobs ? { logprobs: part.logprobs } : {}),
|
|
166
390
|
};
|
|
391
|
+
if (isAIMessage(generation.message)) {
|
|
392
|
+
generation.message.usage_metadata = usageMetadata;
|
|
393
|
+
}
|
|
394
|
+
generation.message = new AIMessage(Object.fromEntries(Object.entries(generation.message).filter(([key]) => !key.startsWith('lc_'))));
|
|
395
|
+
generations.push(generation);
|
|
167
396
|
}
|
|
168
|
-
return
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
397
|
+
return {
|
|
398
|
+
generations,
|
|
399
|
+
llmOutput: {
|
|
400
|
+
tokenUsage: {
|
|
401
|
+
promptTokens: usageMetadata.input_tokens,
|
|
402
|
+
completionTokens: usageMetadata.output_tokens,
|
|
403
|
+
totalTokens: usageMetadata.total_tokens,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
};
|
|
172
407
|
}
|
|
173
408
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
...this.invocationParams(options, { streaming: true }),
|
|
179
|
-
input: _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled),
|
|
180
|
-
stream: true,
|
|
181
|
-
}, options);
|
|
182
|
-
for await (const data of streamIterable) {
|
|
183
|
-
const chunk = _convertOpenAIResponsesDeltaToBaseMessageChunk(data);
|
|
184
|
-
if (chunk == null)
|
|
185
|
-
continue;
|
|
186
|
-
yield chunk;
|
|
187
|
-
if (this._lc_stream_delay != null) {
|
|
188
|
-
await sleep(this._lc_stream_delay);
|
|
189
|
-
}
|
|
190
|
-
await runManager?.handleLLMNewToken(chunk.text || '', undefined, undefined, undefined, undefined, { chunk });
|
|
409
|
+
if (this.includeReasoningContent !== true &&
|
|
410
|
+
this.includeReasoningDetails !== true) {
|
|
411
|
+
yield* super._streamResponseChunks(messages, options, runManager);
|
|
412
|
+
return;
|
|
191
413
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
414
|
+
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model, {
|
|
415
|
+
includeReasoningContent: this.includeReasoningContent,
|
|
416
|
+
includeReasoningDetails: this.includeReasoningDetails,
|
|
417
|
+
convertReasoningDetailsToContent: this.convertReasoningDetailsToContent,
|
|
418
|
+
});
|
|
196
419
|
const params = {
|
|
197
420
|
...this.invocationParams(options, {
|
|
198
421
|
streaming: true,
|
|
@@ -204,49 +427,40 @@ class ChatOpenAI extends ChatOpenAI$1 {
|
|
|
204
427
|
const streamIterable = await this.completionWithRetry(params, options);
|
|
205
428
|
let usage;
|
|
206
429
|
for await (const data of streamIterable) {
|
|
207
|
-
|
|
208
|
-
|
|
430
|
+
if (options.signal?.aborted === true) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const choices = data.choices;
|
|
434
|
+
const choice = choices?.[0];
|
|
435
|
+
if (data.usage != null) {
|
|
209
436
|
usage = data.usage;
|
|
210
437
|
}
|
|
211
|
-
if (
|
|
438
|
+
if (choice == null) {
|
|
212
439
|
continue;
|
|
213
440
|
}
|
|
214
441
|
const { delta } = choice;
|
|
215
|
-
if (
|
|
442
|
+
if (delta == null) {
|
|
216
443
|
continue;
|
|
217
444
|
}
|
|
218
|
-
const chunk = this.
|
|
219
|
-
if ('reasoning_content' in delta) {
|
|
220
|
-
chunk.additional_kwargs.reasoning_content = delta.reasoning_content;
|
|
221
|
-
}
|
|
222
|
-
else if ('reasoning' in delta) {
|
|
223
|
-
chunk.additional_kwargs.reasoning_content = delta.reasoning;
|
|
224
|
-
}
|
|
225
|
-
if ('provider_specific_fields' in delta) {
|
|
226
|
-
chunk.additional_kwargs.provider_specific_fields =
|
|
227
|
-
delta.provider_specific_fields;
|
|
228
|
-
}
|
|
445
|
+
const chunk = this._convertCompletionsDeltaToBaseMessageChunk(delta, data, defaultRole);
|
|
229
446
|
defaultRole = delta.role ?? defaultRole;
|
|
230
447
|
const newTokenIndices = {
|
|
231
448
|
prompt: options.promptIndex ?? 0,
|
|
232
|
-
completion: choice.index
|
|
449
|
+
completion: choice.index,
|
|
233
450
|
};
|
|
234
451
|
if (typeof chunk.content !== 'string') {
|
|
235
452
|
// eslint-disable-next-line no-console
|
|
236
453
|
console.log('[WARNING]: Received non-string content from OpenAI. This is currently not supported.');
|
|
237
454
|
continue;
|
|
238
455
|
}
|
|
239
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
240
456
|
const generationInfo = { ...newTokenIndices };
|
|
241
457
|
if (choice.finish_reason != null) {
|
|
242
458
|
generationInfo.finish_reason = choice.finish_reason;
|
|
243
|
-
// Only include system fingerprint in the last chunk for now
|
|
244
|
-
// to avoid concatenation issues
|
|
245
459
|
generationInfo.system_fingerprint = data.system_fingerprint;
|
|
246
460
|
generationInfo.model_name = data.model;
|
|
247
461
|
generationInfo.service_tier = data.service_tier;
|
|
248
462
|
}
|
|
249
|
-
if (this.logprobs
|
|
463
|
+
if (this.logprobs === true) {
|
|
250
464
|
generationInfo.logprobs = choice.logprobs;
|
|
251
465
|
}
|
|
252
466
|
const generationChunk = new ChatGenerationChunk({
|
|
@@ -255,10 +469,7 @@ class ChatOpenAI extends ChatOpenAI$1 {
|
|
|
255
469
|
generationInfo,
|
|
256
470
|
});
|
|
257
471
|
yield generationChunk;
|
|
258
|
-
|
|
259
|
-
await sleep(this._lc_stream_delay);
|
|
260
|
-
}
|
|
261
|
-
await runManager?.handleLLMNewToken(generationChunk.text || '', newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
472
|
+
await runManager?.handleLLMNewToken(generationChunk.text, newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
262
473
|
}
|
|
263
474
|
if (usage) {
|
|
264
475
|
const inputTokenDetails = {
|
|
@@ -280,9 +491,7 @@ class ChatOpenAI extends ChatOpenAI$1 {
|
|
|
280
491
|
const generationChunk = new ChatGenerationChunk({
|
|
281
492
|
message: new AIMessageChunk({
|
|
282
493
|
content: '',
|
|
283
|
-
response_metadata: {
|
|
284
|
-
usage: { ...usage },
|
|
285
|
-
},
|
|
494
|
+
response_metadata: { usage: { ...usage } },
|
|
286
495
|
usage_metadata: {
|
|
287
496
|
input_tokens: usage.prompt_tokens,
|
|
288
497
|
output_tokens: usage.completion_tokens,
|
|
@@ -298,54 +507,27 @@ class ChatOpenAI extends ChatOpenAI$1 {
|
|
|
298
507
|
text: '',
|
|
299
508
|
});
|
|
300
509
|
yield generationChunk;
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
510
|
+
await runManager?.handleLLMNewToken(generationChunk.text, {
|
|
511
|
+
prompt: 0,
|
|
512
|
+
completion: 0,
|
|
513
|
+
}, undefined, undefined, undefined, { chunk: generationChunk });
|
|
304
514
|
}
|
|
305
515
|
if (options.signal?.aborted === true) {
|
|
306
516
|
throw new Error('AbortError');
|
|
307
517
|
}
|
|
308
518
|
}
|
|
309
519
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
constructor(fields) {
|
|
314
|
-
super(fields);
|
|
315
|
-
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
316
|
-
}
|
|
317
|
-
get exposedClient() {
|
|
318
|
-
return this.client;
|
|
319
|
-
}
|
|
320
|
-
static lc_name() {
|
|
321
|
-
return 'LibreChatAzureOpenAI';
|
|
520
|
+
class LibreChatOpenAIResponses extends ChatOpenAIResponses {
|
|
521
|
+
_getReasoningParams(options) {
|
|
522
|
+
return getReasoningParams(this.reasoning, options);
|
|
322
523
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
* @internal
|
|
326
|
-
*/
|
|
327
|
-
getReasoningParams(options) {
|
|
328
|
-
if (!isReasoningModel(this.model)) {
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
// apply options in reverse order of importance -- newer options supersede older options
|
|
332
|
-
let reasoning;
|
|
333
|
-
if (this.reasoning !== undefined) {
|
|
334
|
-
reasoning = {
|
|
335
|
-
...reasoning,
|
|
336
|
-
...this.reasoning,
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
if (options?.reasoning !== undefined) {
|
|
340
|
-
reasoning = {
|
|
341
|
-
...reasoning,
|
|
342
|
-
...options.reasoning,
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
return reasoning;
|
|
524
|
+
_getClientOptions(options) {
|
|
525
|
+
return getCustomOpenAIClientOptions(this, options);
|
|
346
526
|
}
|
|
527
|
+
}
|
|
528
|
+
class LibreChatAzureOpenAICompletions extends AzureChatOpenAICompletions {
|
|
347
529
|
_getReasoningParams(options) {
|
|
348
|
-
return this.
|
|
530
|
+
return getGatedReasoningParams(this.model, this.reasoning, options);
|
|
349
531
|
}
|
|
350
532
|
_getClientOptions(options) {
|
|
351
533
|
if (!this.client) {
|
|
@@ -399,120 +581,22 @@ class AzureChatOpenAI extends AzureChatOpenAI$1 {
|
|
|
399
581
|
}
|
|
400
582
|
return requestOptions;
|
|
401
583
|
}
|
|
402
|
-
async
|
|
403
|
-
|
|
404
|
-
return yield* super._streamResponseChunks(messages, options, runManager);
|
|
405
|
-
}
|
|
406
|
-
const streamIterable = await this.responseApiWithRetry({
|
|
407
|
-
...this.invocationParams(options, { streaming: true }),
|
|
408
|
-
input: _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled),
|
|
409
|
-
stream: true,
|
|
410
|
-
}, options);
|
|
411
|
-
for await (const data of streamIterable) {
|
|
412
|
-
const chunk = _convertOpenAIResponsesDeltaToBaseMessageChunk(data);
|
|
413
|
-
if (chunk == null)
|
|
414
|
-
continue;
|
|
415
|
-
yield chunk;
|
|
416
|
-
if (this._lc_stream_delay != null) {
|
|
417
|
-
await sleep(this._lc_stream_delay);
|
|
418
|
-
}
|
|
419
|
-
await runManager?.handleLLMNewToken(chunk.text || '', undefined, undefined, undefined, undefined, { chunk });
|
|
420
|
-
}
|
|
421
|
-
return;
|
|
584
|
+
async completionWithRetry(request, requestOptions) {
|
|
585
|
+
return completionWithFilteredOpenAIStream(request, requestOptions, super.completionWithRetry.bind(this));
|
|
422
586
|
}
|
|
423
587
|
}
|
|
424
|
-
class
|
|
425
|
-
|
|
426
|
-
return this.
|
|
427
|
-
}
|
|
428
|
-
static lc_name() {
|
|
429
|
-
return 'LibreChatDeepSeek';
|
|
430
|
-
}
|
|
431
|
-
_convertMessages(messages) {
|
|
432
|
-
return _convertMessagesToOpenAIParams(messages, this.model, {
|
|
433
|
-
includeReasoningContent: true,
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
async _generate(messages, options, runManager) {
|
|
437
|
-
const params = this.invocationParams(options);
|
|
438
|
-
if (params.stream === true) {
|
|
439
|
-
return super._generate(messages, options ?? {}, runManager);
|
|
440
|
-
}
|
|
441
|
-
const messagesMapped = this._convertMessages(messages);
|
|
442
|
-
const data = await this.completionWithRetry({
|
|
443
|
-
...params,
|
|
444
|
-
stream: false,
|
|
445
|
-
messages: messagesMapped,
|
|
446
|
-
}, {
|
|
447
|
-
signal: options?.signal,
|
|
448
|
-
...options?.options,
|
|
449
|
-
});
|
|
450
|
-
const { completion_tokens, prompt_tokens, total_tokens } = data.usage ?? {};
|
|
451
|
-
const generations = [];
|
|
452
|
-
for (const part of data.choices ?? []) {
|
|
453
|
-
const text = part.message.content ?? '';
|
|
454
|
-
const generation = {
|
|
455
|
-
text: typeof text === 'string' ? text : '',
|
|
456
|
-
message: this._convertResponseToMessage(part, data),
|
|
457
|
-
};
|
|
458
|
-
generation.generationInfo = {
|
|
459
|
-
...(part.finish_reason != null
|
|
460
|
-
? { finish_reason: part.finish_reason }
|
|
461
|
-
: {}),
|
|
462
|
-
...(part.logprobs ? { logprobs: part.logprobs } : {}),
|
|
463
|
-
};
|
|
464
|
-
generations.push(generation);
|
|
465
|
-
}
|
|
466
|
-
return {
|
|
467
|
-
generations,
|
|
468
|
-
llmOutput: {
|
|
469
|
-
tokenUsage: {
|
|
470
|
-
completionTokens: completion_tokens,
|
|
471
|
-
promptTokens: prompt_tokens,
|
|
472
|
-
totalTokens: total_tokens,
|
|
473
|
-
},
|
|
474
|
-
},
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
_convertResponseToMessage(choice, data) {
|
|
478
|
-
const { message } = choice;
|
|
479
|
-
const rawToolCalls = message.tool_calls;
|
|
480
|
-
const toolCalls = rawToolCalls?.map((tc) => ({
|
|
481
|
-
id: tc.id,
|
|
482
|
-
name: tc.function.name,
|
|
483
|
-
args: JSON.parse(tc.function.arguments || '{}'),
|
|
484
|
-
type: 'tool_call',
|
|
485
|
-
}));
|
|
486
|
-
const additional_kwargs = {};
|
|
487
|
-
if (rawToolCalls) {
|
|
488
|
-
additional_kwargs.tool_calls = rawToolCalls;
|
|
489
|
-
}
|
|
490
|
-
if ('reasoning_content' in message &&
|
|
491
|
-
message.reasoning_content != null &&
|
|
492
|
-
message.reasoning_content !== '') {
|
|
493
|
-
additional_kwargs.reasoning_content = message.reasoning_content;
|
|
494
|
-
}
|
|
495
|
-
return new AIMessage({
|
|
496
|
-
content: message.content ?? '',
|
|
497
|
-
tool_calls: toolCalls,
|
|
498
|
-
additional_kwargs,
|
|
499
|
-
usage_metadata: data.usage
|
|
500
|
-
? {
|
|
501
|
-
input_tokens: data.usage.prompt_tokens,
|
|
502
|
-
output_tokens: data.usage.completion_tokens,
|
|
503
|
-
total_tokens: data.usage.total_tokens,
|
|
504
|
-
}
|
|
505
|
-
: undefined,
|
|
506
|
-
response_metadata: {
|
|
507
|
-
model_name: data.model,
|
|
508
|
-
system_fingerprint: data.system_fingerprint,
|
|
509
|
-
finish_reason: choice.finish_reason,
|
|
510
|
-
},
|
|
511
|
-
});
|
|
588
|
+
class LibreChatAzureOpenAIResponses extends AzureChatOpenAIResponses {
|
|
589
|
+
_getReasoningParams(options) {
|
|
590
|
+
return getGatedReasoningParams(this.model, this.reasoning, options);
|
|
512
591
|
}
|
|
513
592
|
_getClientOptions(options) {
|
|
514
593
|
if (!this.client) {
|
|
515
594
|
const openAIEndpointConfig = {
|
|
595
|
+
azureOpenAIApiDeploymentName: this.azureOpenAIApiDeploymentName,
|
|
596
|
+
azureOpenAIApiInstanceName: this.azureOpenAIApiInstanceName,
|
|
597
|
+
azureOpenAIApiKey: this.azureOpenAIApiKey,
|
|
598
|
+
azureOpenAIBasePath: this.azureOpenAIBasePath,
|
|
599
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
516
600
|
baseURL: this.clientConfig.baseURL,
|
|
517
601
|
};
|
|
518
602
|
const endpoint = getEndpoint(openAIEndpointConfig);
|
|
@@ -522,311 +606,227 @@ class ChatDeepSeek extends ChatDeepSeek$1 {
|
|
|
522
606
|
timeout: this.timeout,
|
|
523
607
|
maxRetries: 0,
|
|
524
608
|
};
|
|
609
|
+
if (!this.azureADTokenProvider) {
|
|
610
|
+
params.apiKey = openAIEndpointConfig.azureOpenAIApiKey;
|
|
611
|
+
}
|
|
525
612
|
if (params.baseURL == null) {
|
|
526
613
|
delete params.baseURL;
|
|
527
614
|
}
|
|
528
|
-
|
|
615
|
+
const defaultHeaders = normalizeHeaders(params.defaultHeaders);
|
|
616
|
+
params.defaultHeaders = {
|
|
617
|
+
...params.defaultHeaders,
|
|
618
|
+
'User-Agent': defaultHeaders['User-Agent'] != null
|
|
619
|
+
? `${defaultHeaders['User-Agent']}: librechat-azure-openai-v2`
|
|
620
|
+
: 'librechat-azure-openai-v2',
|
|
621
|
+
};
|
|
622
|
+
this.client = new CustomAzureOpenAIClient({
|
|
623
|
+
apiVersion: this.azureOpenAIApiVersion,
|
|
624
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
625
|
+
...params,
|
|
626
|
+
});
|
|
529
627
|
}
|
|
530
628
|
const requestOptions = {
|
|
531
629
|
...this.clientConfig,
|
|
532
630
|
...options,
|
|
533
631
|
};
|
|
632
|
+
if (this.azureOpenAIApiKey != null) {
|
|
633
|
+
requestOptions.headers = {
|
|
634
|
+
'api-key': this.azureOpenAIApiKey,
|
|
635
|
+
...requestOptions.headers,
|
|
636
|
+
};
|
|
637
|
+
requestOptions.query = {
|
|
638
|
+
'api-version': this.azureOpenAIApiVersion,
|
|
639
|
+
...requestOptions.query,
|
|
640
|
+
};
|
|
641
|
+
}
|
|
534
642
|
return requestOptions;
|
|
535
643
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
}
|
|
562
|
-
const chunk = this._convertOpenAIDeltaToBaseMessageChunk(delta, data, defaultRole);
|
|
563
|
-
if ('reasoning_content' in delta) {
|
|
564
|
-
chunk.additional_kwargs.reasoning_content = delta.reasoning_content;
|
|
565
|
-
}
|
|
566
|
-
defaultRole = delta.role ?? defaultRole;
|
|
567
|
-
const newTokenIndices = {
|
|
568
|
-
prompt: options.promptIndex ?? 0,
|
|
569
|
-
completion: choice.index ?? 0,
|
|
644
|
+
}
|
|
645
|
+
function withLibreChatOpenAIFields(fields) {
|
|
646
|
+
const nextFields = fields ?? {};
|
|
647
|
+
return {
|
|
648
|
+
...nextFields,
|
|
649
|
+
completions: nextFields.completions ?? new LibreChatOpenAICompletions(nextFields),
|
|
650
|
+
responses: nextFields.responses ?? new LibreChatOpenAIResponses(nextFields),
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
class ChatOpenAI extends ChatOpenAI$1 {
|
|
654
|
+
_lc_stream_delay;
|
|
655
|
+
constructor(fields) {
|
|
656
|
+
super(withLibreChatOpenAIFields(fields));
|
|
657
|
+
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
658
|
+
}
|
|
659
|
+
get exposedClient() {
|
|
660
|
+
return getExposedOpenAIClient(this.completions, this.responses, this._useResponsesApi(undefined));
|
|
661
|
+
}
|
|
662
|
+
static lc_name() {
|
|
663
|
+
return 'LibreChatOpenAI';
|
|
664
|
+
}
|
|
665
|
+
_getClientOptions(options) {
|
|
666
|
+
if (!this.client) {
|
|
667
|
+
const openAIEndpointConfig = {
|
|
668
|
+
baseURL: this.clientConfig.baseURL,
|
|
570
669
|
};
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
670
|
+
const endpoint = getEndpoint(openAIEndpointConfig);
|
|
671
|
+
const params = {
|
|
672
|
+
...this.clientConfig,
|
|
673
|
+
baseURL: endpoint,
|
|
674
|
+
timeout: this.timeout,
|
|
675
|
+
maxRetries: 0,
|
|
676
|
+
};
|
|
677
|
+
if (params.baseURL == null) {
|
|
678
|
+
delete params.baseURL;
|
|
575
679
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
680
|
+
this.client = new CustomOpenAIClient(params);
|
|
681
|
+
}
|
|
682
|
+
const requestOptions = {
|
|
683
|
+
...this.clientConfig,
|
|
684
|
+
...options,
|
|
685
|
+
};
|
|
686
|
+
return requestOptions;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Returns backwards compatible reasoning parameters from constructor params and call options
|
|
690
|
+
* @internal
|
|
691
|
+
*/
|
|
692
|
+
getReasoningParams(options) {
|
|
693
|
+
return getReasoningParams(this.reasoning, options);
|
|
694
|
+
}
|
|
695
|
+
_getReasoningParams(options) {
|
|
696
|
+
return this.getReasoningParams(options);
|
|
697
|
+
}
|
|
698
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
699
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
class AzureChatOpenAI extends AzureChatOpenAI$1 {
|
|
703
|
+
_lc_stream_delay;
|
|
704
|
+
constructor(fields) {
|
|
705
|
+
super(fields);
|
|
706
|
+
this.completions = new LibreChatAzureOpenAICompletions(fields);
|
|
707
|
+
this.responses = new LibreChatAzureOpenAIResponses(fields);
|
|
708
|
+
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
709
|
+
}
|
|
710
|
+
get exposedClient() {
|
|
711
|
+
return getExposedOpenAIClient(this.completions, this.responses, this._useResponsesApi(undefined));
|
|
712
|
+
}
|
|
713
|
+
static lc_name() {
|
|
714
|
+
return 'LibreChatAzureOpenAI';
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Returns backwards compatible reasoning parameters from constructor params and call options
|
|
718
|
+
* @internal
|
|
719
|
+
*/
|
|
720
|
+
getReasoningParams(options) {
|
|
721
|
+
return getGatedReasoningParams(this.model, this.reasoning, options);
|
|
722
|
+
}
|
|
723
|
+
_getReasoningParams(options) {
|
|
724
|
+
return this.getReasoningParams(options);
|
|
725
|
+
}
|
|
726
|
+
_getClientOptions(options) {
|
|
727
|
+
if (!this.client) {
|
|
728
|
+
const openAIEndpointConfig = {
|
|
729
|
+
azureOpenAIApiDeploymentName: this.azureOpenAIApiDeploymentName,
|
|
730
|
+
azureOpenAIApiInstanceName: this.azureOpenAIApiInstanceName,
|
|
731
|
+
azureOpenAIApiKey: this.azureOpenAIApiKey,
|
|
732
|
+
azureOpenAIBasePath: this.azureOpenAIBasePath,
|
|
733
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
734
|
+
baseURL: this.clientConfig.baseURL,
|
|
735
|
+
};
|
|
736
|
+
const endpoint = getEndpoint(openAIEndpointConfig);
|
|
737
|
+
const params = {
|
|
738
|
+
...this.clientConfig,
|
|
739
|
+
baseURL: endpoint,
|
|
740
|
+
timeout: this.timeout,
|
|
741
|
+
maxRetries: 0,
|
|
742
|
+
};
|
|
743
|
+
if (!this.azureADTokenProvider) {
|
|
744
|
+
params.apiKey = openAIEndpointConfig.azureOpenAIApiKey;
|
|
583
745
|
}
|
|
584
|
-
if (
|
|
585
|
-
|
|
746
|
+
if (params.baseURL == null) {
|
|
747
|
+
delete params.baseURL;
|
|
586
748
|
}
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
749
|
+
const defaultHeaders = normalizeHeaders(params.defaultHeaders);
|
|
750
|
+
params.defaultHeaders = {
|
|
751
|
+
...params.defaultHeaders,
|
|
752
|
+
'User-Agent': defaultHeaders['User-Agent'] != null
|
|
753
|
+
? `${defaultHeaders['User-Agent']}: librechat-azure-openai-v2`
|
|
754
|
+
: 'librechat-azure-openai-v2',
|
|
755
|
+
};
|
|
756
|
+
this.client = new CustomAzureOpenAIClient({
|
|
757
|
+
apiVersion: this.azureOpenAIApiVersion,
|
|
758
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
759
|
+
...params,
|
|
591
760
|
});
|
|
592
|
-
yield generationChunk;
|
|
593
|
-
await runManager?.handleLLMNewToken(generationChunk.text || '', newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
594
761
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
762
|
+
const requestOptions = {
|
|
763
|
+
...this.clientConfig,
|
|
764
|
+
...options,
|
|
765
|
+
};
|
|
766
|
+
if (this.azureOpenAIApiKey != null) {
|
|
767
|
+
requestOptions.headers = {
|
|
768
|
+
'api-key': this.azureOpenAIApiKey,
|
|
769
|
+
...requestOptions.headers,
|
|
603
770
|
};
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
}),
|
|
608
|
-
...(usage.completion_tokens_details?.reasoning_tokens != null && {
|
|
609
|
-
reasoning: usage.completion_tokens_details.reasoning_tokens,
|
|
610
|
-
}),
|
|
771
|
+
requestOptions.query = {
|
|
772
|
+
'api-version': this.azureOpenAIApiVersion,
|
|
773
|
+
...requestOptions.query,
|
|
611
774
|
};
|
|
612
|
-
const generationChunk = new ChatGenerationChunk({
|
|
613
|
-
message: new AIMessageChunk({
|
|
614
|
-
content: '',
|
|
615
|
-
response_metadata: {
|
|
616
|
-
usage: { ...usage },
|
|
617
|
-
},
|
|
618
|
-
usage_metadata: {
|
|
619
|
-
input_tokens: usage.prompt_tokens,
|
|
620
|
-
output_tokens: usage.completion_tokens,
|
|
621
|
-
total_tokens: usage.total_tokens,
|
|
622
|
-
...(Object.keys(inputTokenDetails).length > 0 && {
|
|
623
|
-
input_token_details: inputTokenDetails,
|
|
624
|
-
}),
|
|
625
|
-
...(Object.keys(outputTokenDetails).length > 0 && {
|
|
626
|
-
output_token_details: outputTokenDetails,
|
|
627
|
-
}),
|
|
628
|
-
},
|
|
629
|
-
}),
|
|
630
|
-
text: '',
|
|
631
|
-
});
|
|
632
|
-
yield generationChunk;
|
|
633
|
-
}
|
|
634
|
-
if (options.signal?.aborted === true) {
|
|
635
|
-
throw new Error('AbortError');
|
|
636
775
|
}
|
|
776
|
+
return requestOptions;
|
|
777
|
+
}
|
|
778
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
779
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
637
780
|
}
|
|
638
781
|
}
|
|
639
|
-
class
|
|
640
|
-
|
|
641
|
-
|
|
782
|
+
class ChatDeepSeek extends ChatDeepSeek$1 {
|
|
783
|
+
_lc_stream_delay;
|
|
784
|
+
constructor(fields) {
|
|
785
|
+
super(fields);
|
|
786
|
+
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
642
787
|
}
|
|
643
|
-
|
|
644
|
-
return
|
|
645
|
-
includeReasoningContent: true,
|
|
646
|
-
});
|
|
788
|
+
get exposedClient() {
|
|
789
|
+
return this.client;
|
|
647
790
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
...params,
|
|
656
|
-
stream: false,
|
|
657
|
-
messages: messagesMapped,
|
|
658
|
-
}, {
|
|
659
|
-
signal: options.signal,
|
|
660
|
-
...options.options,
|
|
661
|
-
});
|
|
662
|
-
const { completion_tokens, prompt_tokens, total_tokens } = data.usage ?? {};
|
|
663
|
-
const generations = [];
|
|
664
|
-
for (const part of data.choices ?? []) {
|
|
665
|
-
const text = part.message.content ?? '';
|
|
666
|
-
const generation = {
|
|
667
|
-
text: typeof text === 'string' ? text : '',
|
|
668
|
-
message: this._convertResponseToMessage(part, data),
|
|
791
|
+
static lc_name() {
|
|
792
|
+
return 'LibreChatDeepSeek';
|
|
793
|
+
}
|
|
794
|
+
_getClientOptions(options) {
|
|
795
|
+
if (!this.client) {
|
|
796
|
+
const openAIEndpointConfig = {
|
|
797
|
+
baseURL: this.clientConfig.baseURL,
|
|
669
798
|
};
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
...
|
|
799
|
+
const endpoint = getEndpoint(openAIEndpointConfig);
|
|
800
|
+
const params = {
|
|
801
|
+
...this.clientConfig,
|
|
802
|
+
baseURL: endpoint,
|
|
803
|
+
timeout: this.timeout,
|
|
804
|
+
maxRetries: 0,
|
|
673
805
|
};
|
|
674
|
-
|
|
806
|
+
if (params.baseURL == null) {
|
|
807
|
+
delete params.baseURL;
|
|
808
|
+
}
|
|
809
|
+
this.client = new CustomOpenAIClient(params);
|
|
675
810
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
tokenUsage: {
|
|
680
|
-
completionTokens: completion_tokens,
|
|
681
|
-
promptTokens: prompt_tokens,
|
|
682
|
-
totalTokens: total_tokens,
|
|
683
|
-
},
|
|
684
|
-
},
|
|
811
|
+
const requestOptions = {
|
|
812
|
+
...this.clientConfig,
|
|
813
|
+
...options,
|
|
685
814
|
};
|
|
686
|
-
|
|
687
|
-
_convertResponseToMessage(choice, data) {
|
|
688
|
-
const { message } = choice;
|
|
689
|
-
const rawToolCalls = message.tool_calls;
|
|
690
|
-
const toolCalls = rawToolCalls?.map((tc) => ({
|
|
691
|
-
id: tc.id,
|
|
692
|
-
name: tc.function.name,
|
|
693
|
-
args: JSON.parse(tc.function.arguments || '{}'),
|
|
694
|
-
type: 'tool_call',
|
|
695
|
-
}));
|
|
696
|
-
const additional_kwargs = {};
|
|
697
|
-
if (rawToolCalls) {
|
|
698
|
-
additional_kwargs.tool_calls = rawToolCalls;
|
|
699
|
-
}
|
|
700
|
-
if ('reasoning_content' in message &&
|
|
701
|
-
message.reasoning_content != null &&
|
|
702
|
-
message.reasoning_content !== '') {
|
|
703
|
-
additional_kwargs.reasoning_content = message.reasoning_content;
|
|
704
|
-
}
|
|
705
|
-
return new AIMessage({
|
|
706
|
-
content: message.content ?? '',
|
|
707
|
-
tool_calls: toolCalls,
|
|
708
|
-
additional_kwargs,
|
|
709
|
-
usage_metadata: data.usage
|
|
710
|
-
? {
|
|
711
|
-
input_tokens: data.usage.prompt_tokens,
|
|
712
|
-
output_tokens: data.usage.completion_tokens,
|
|
713
|
-
total_tokens: data.usage.total_tokens,
|
|
714
|
-
}
|
|
715
|
-
: undefined,
|
|
716
|
-
response_metadata: {
|
|
717
|
-
model_name: data.model,
|
|
718
|
-
system_fingerprint: data.system_fingerprint,
|
|
719
|
-
finish_reason: choice.finish_reason,
|
|
720
|
-
},
|
|
721
|
-
});
|
|
815
|
+
return requestOptions;
|
|
722
816
|
}
|
|
723
817
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
724
|
-
|
|
818
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
class ChatMoonshot extends ChatOpenAI {
|
|
822
|
+
constructor(fields) {
|
|
823
|
+
super({
|
|
824
|
+
...fields,
|
|
725
825
|
includeReasoningContent: true,
|
|
726
826
|
});
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}),
|
|
731
|
-
messages: messagesMapped,
|
|
732
|
-
stream: true,
|
|
733
|
-
};
|
|
734
|
-
let defaultRole;
|
|
735
|
-
const streamIterable = await this.completionWithRetry(params, options);
|
|
736
|
-
let usage;
|
|
737
|
-
for await (const data of streamIterable) {
|
|
738
|
-
const choice = data.choices[0];
|
|
739
|
-
if (data.usage) {
|
|
740
|
-
usage = data.usage;
|
|
741
|
-
}
|
|
742
|
-
if (!choice) {
|
|
743
|
-
continue;
|
|
744
|
-
}
|
|
745
|
-
const { delta } = choice;
|
|
746
|
-
if (!delta) {
|
|
747
|
-
continue;
|
|
748
|
-
}
|
|
749
|
-
const chunk = this._convertOpenAIDeltaToBaseMessageChunk(delta, data, defaultRole);
|
|
750
|
-
if ('reasoning_content' in delta) {
|
|
751
|
-
chunk.additional_kwargs.reasoning_content = delta.reasoning_content;
|
|
752
|
-
}
|
|
753
|
-
defaultRole = delta.role ?? defaultRole;
|
|
754
|
-
const newTokenIndices = {
|
|
755
|
-
prompt: options.promptIndex ?? 0,
|
|
756
|
-
completion: choice.index ?? 0,
|
|
757
|
-
};
|
|
758
|
-
if (typeof chunk.content !== 'string') {
|
|
759
|
-
// eslint-disable-next-line no-console
|
|
760
|
-
console.log('[WARNING]: Received non-string content from OpenAI. This is currently not supported.');
|
|
761
|
-
continue;
|
|
762
|
-
}
|
|
763
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
764
|
-
const generationInfo = { ...newTokenIndices };
|
|
765
|
-
if (choice.finish_reason != null) {
|
|
766
|
-
generationInfo.finish_reason = choice.finish_reason;
|
|
767
|
-
generationInfo.system_fingerprint = data.system_fingerprint;
|
|
768
|
-
generationInfo.model_name = data.model;
|
|
769
|
-
generationInfo.service_tier = data.service_tier;
|
|
770
|
-
}
|
|
771
|
-
if (this.logprobs == true) {
|
|
772
|
-
generationInfo.logprobs = choice.logprobs;
|
|
773
|
-
}
|
|
774
|
-
const generationChunk = new ChatGenerationChunk({
|
|
775
|
-
message: chunk,
|
|
776
|
-
text: chunk.content,
|
|
777
|
-
generationInfo,
|
|
778
|
-
});
|
|
779
|
-
yield generationChunk;
|
|
780
|
-
if (this._lc_stream_delay != null) {
|
|
781
|
-
await sleep(this._lc_stream_delay);
|
|
782
|
-
}
|
|
783
|
-
await runManager?.handleLLMNewToken(generationChunk.text || '', newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
784
|
-
}
|
|
785
|
-
if (usage) {
|
|
786
|
-
const inputTokenDetails = {
|
|
787
|
-
...(usage.prompt_tokens_details?.audio_tokens != null && {
|
|
788
|
-
audio: usage.prompt_tokens_details.audio_tokens,
|
|
789
|
-
}),
|
|
790
|
-
...(usage.prompt_tokens_details?.cached_tokens != null && {
|
|
791
|
-
cache_read: usage.prompt_tokens_details.cached_tokens,
|
|
792
|
-
}),
|
|
793
|
-
};
|
|
794
|
-
const outputTokenDetails = {
|
|
795
|
-
...(usage.completion_tokens_details?.audio_tokens != null && {
|
|
796
|
-
audio: usage.completion_tokens_details.audio_tokens,
|
|
797
|
-
}),
|
|
798
|
-
...(usage.completion_tokens_details?.reasoning_tokens != null && {
|
|
799
|
-
reasoning: usage.completion_tokens_details.reasoning_tokens,
|
|
800
|
-
}),
|
|
801
|
-
};
|
|
802
|
-
const generationChunk = new ChatGenerationChunk({
|
|
803
|
-
message: new AIMessageChunk({
|
|
804
|
-
content: '',
|
|
805
|
-
response_metadata: {
|
|
806
|
-
usage: { ...usage },
|
|
807
|
-
},
|
|
808
|
-
usage_metadata: {
|
|
809
|
-
input_tokens: usage.prompt_tokens,
|
|
810
|
-
output_tokens: usage.completion_tokens,
|
|
811
|
-
total_tokens: usage.total_tokens,
|
|
812
|
-
...(Object.keys(inputTokenDetails).length > 0 && {
|
|
813
|
-
input_token_details: inputTokenDetails,
|
|
814
|
-
}),
|
|
815
|
-
...(Object.keys(outputTokenDetails).length > 0 && {
|
|
816
|
-
output_token_details: outputTokenDetails,
|
|
817
|
-
}),
|
|
818
|
-
},
|
|
819
|
-
}),
|
|
820
|
-
text: '',
|
|
821
|
-
});
|
|
822
|
-
yield generationChunk;
|
|
823
|
-
if (this._lc_stream_delay != null) {
|
|
824
|
-
await sleep(this._lc_stream_delay);
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
if (options.signal?.aborted === true) {
|
|
828
|
-
throw new Error('AbortError');
|
|
829
|
-
}
|
|
827
|
+
}
|
|
828
|
+
static lc_name() {
|
|
829
|
+
return 'LibreChatMoonshot';
|
|
830
830
|
}
|
|
831
831
|
}
|
|
832
832
|
class ChatXAI extends ChatXAI$1 {
|
|
@@ -875,143 +875,7 @@ class ChatXAI extends ChatXAI$1 {
|
|
|
875
875
|
return requestOptions;
|
|
876
876
|
}
|
|
877
877
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
878
|
-
|
|
879
|
-
const params = {
|
|
880
|
-
...this.invocationParams(options, {
|
|
881
|
-
streaming: true,
|
|
882
|
-
}),
|
|
883
|
-
messages: messagesMapped,
|
|
884
|
-
stream: true,
|
|
885
|
-
};
|
|
886
|
-
let defaultRole;
|
|
887
|
-
const streamIterable = await this.completionWithRetry(params, options);
|
|
888
|
-
let usage;
|
|
889
|
-
for await (const data of streamIterable) {
|
|
890
|
-
const choice = data.choices[0];
|
|
891
|
-
if (data.usage) {
|
|
892
|
-
usage = data.usage;
|
|
893
|
-
}
|
|
894
|
-
if (!choice) {
|
|
895
|
-
continue;
|
|
896
|
-
}
|
|
897
|
-
const { delta } = choice;
|
|
898
|
-
if (!delta) {
|
|
899
|
-
continue;
|
|
900
|
-
}
|
|
901
|
-
const chunk = this._convertOpenAIDeltaToBaseMessageChunk(delta, data, defaultRole);
|
|
902
|
-
if (chunk.usage_metadata != null) {
|
|
903
|
-
chunk.usage_metadata = {
|
|
904
|
-
input_tokens: chunk.usage_metadata.input_tokens ?? 0,
|
|
905
|
-
output_tokens: chunk.usage_metadata.output_tokens ?? 0,
|
|
906
|
-
total_tokens: chunk.usage_metadata.total_tokens ?? 0,
|
|
907
|
-
};
|
|
908
|
-
}
|
|
909
|
-
if ('reasoning_content' in delta) {
|
|
910
|
-
chunk.additional_kwargs.reasoning_content = delta.reasoning_content;
|
|
911
|
-
}
|
|
912
|
-
defaultRole = delta.role ?? defaultRole;
|
|
913
|
-
const newTokenIndices = {
|
|
914
|
-
prompt: options.promptIndex ?? 0,
|
|
915
|
-
completion: choice.index ?? 0,
|
|
916
|
-
};
|
|
917
|
-
if (typeof chunk.content !== 'string') {
|
|
918
|
-
// eslint-disable-next-line no-console
|
|
919
|
-
console.log('[WARNING]: Received non-string content from OpenAI. This is currently not supported.');
|
|
920
|
-
continue;
|
|
921
|
-
}
|
|
922
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
923
|
-
const generationInfo = { ...newTokenIndices };
|
|
924
|
-
if (choice.finish_reason != null) {
|
|
925
|
-
generationInfo.finish_reason = choice.finish_reason;
|
|
926
|
-
// Only include system fingerprint in the last chunk for now
|
|
927
|
-
// to avoid concatenation issues
|
|
928
|
-
generationInfo.system_fingerprint = data.system_fingerprint;
|
|
929
|
-
generationInfo.model_name = data.model;
|
|
930
|
-
generationInfo.service_tier = data.service_tier;
|
|
931
|
-
}
|
|
932
|
-
if (this.logprobs == true) {
|
|
933
|
-
generationInfo.logprobs = choice.logprobs;
|
|
934
|
-
}
|
|
935
|
-
const generationChunk = new ChatGenerationChunk({
|
|
936
|
-
message: chunk,
|
|
937
|
-
text: chunk.content,
|
|
938
|
-
generationInfo,
|
|
939
|
-
});
|
|
940
|
-
yield generationChunk;
|
|
941
|
-
if (this._lc_stream_delay != null) {
|
|
942
|
-
await sleep(this._lc_stream_delay);
|
|
943
|
-
}
|
|
944
|
-
await runManager?.handleLLMNewToken(generationChunk.text || '', newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
945
|
-
}
|
|
946
|
-
if (usage) {
|
|
947
|
-
// Type assertion for xAI-specific usage structure
|
|
948
|
-
const xaiUsage = usage;
|
|
949
|
-
const inputTokenDetails = {
|
|
950
|
-
// Standard OpenAI fields
|
|
951
|
-
...(usage.prompt_tokens_details?.audio_tokens != null && {
|
|
952
|
-
audio: usage.prompt_tokens_details.audio_tokens,
|
|
953
|
-
}),
|
|
954
|
-
...(usage.prompt_tokens_details?.cached_tokens != null && {
|
|
955
|
-
cache_read: usage.prompt_tokens_details.cached_tokens,
|
|
956
|
-
}),
|
|
957
|
-
// Add xAI-specific prompt token details if they exist
|
|
958
|
-
...(xaiUsage.prompt_tokens_details?.text_tokens != null && {
|
|
959
|
-
text: xaiUsage.prompt_tokens_details.text_tokens,
|
|
960
|
-
}),
|
|
961
|
-
...(xaiUsage.prompt_tokens_details?.image_tokens != null && {
|
|
962
|
-
image: xaiUsage.prompt_tokens_details.image_tokens,
|
|
963
|
-
}),
|
|
964
|
-
};
|
|
965
|
-
const outputTokenDetails = {
|
|
966
|
-
// Standard OpenAI fields
|
|
967
|
-
...(usage.completion_tokens_details?.audio_tokens != null && {
|
|
968
|
-
audio: usage.completion_tokens_details.audio_tokens,
|
|
969
|
-
}),
|
|
970
|
-
...(usage.completion_tokens_details?.reasoning_tokens != null && {
|
|
971
|
-
reasoning: usage.completion_tokens_details.reasoning_tokens,
|
|
972
|
-
}),
|
|
973
|
-
// Add xAI-specific completion token details if they exist
|
|
974
|
-
...(xaiUsage.completion_tokens_details?.accepted_prediction_tokens !=
|
|
975
|
-
null && {
|
|
976
|
-
accepted_prediction: xaiUsage.completion_tokens_details.accepted_prediction_tokens,
|
|
977
|
-
}),
|
|
978
|
-
...(xaiUsage.completion_tokens_details?.rejected_prediction_tokens !=
|
|
979
|
-
null && {
|
|
980
|
-
rejected_prediction: xaiUsage.completion_tokens_details.rejected_prediction_tokens,
|
|
981
|
-
}),
|
|
982
|
-
};
|
|
983
|
-
const generationChunk = new ChatGenerationChunk({
|
|
984
|
-
message: new AIMessageChunk({
|
|
985
|
-
content: '',
|
|
986
|
-
response_metadata: {
|
|
987
|
-
usage: { ...usage },
|
|
988
|
-
// Include xAI-specific metadata if it exists
|
|
989
|
-
...(xaiUsage.num_sources_used != null && {
|
|
990
|
-
num_sources_used: xaiUsage.num_sources_used,
|
|
991
|
-
}),
|
|
992
|
-
},
|
|
993
|
-
usage_metadata: {
|
|
994
|
-
input_tokens: usage.prompt_tokens,
|
|
995
|
-
output_tokens: usage.completion_tokens,
|
|
996
|
-
total_tokens: usage.total_tokens,
|
|
997
|
-
...(Object.keys(inputTokenDetails).length > 0 && {
|
|
998
|
-
input_token_details: inputTokenDetails,
|
|
999
|
-
}),
|
|
1000
|
-
...(Object.keys(outputTokenDetails).length > 0 && {
|
|
1001
|
-
output_token_details: outputTokenDetails,
|
|
1002
|
-
}),
|
|
1003
|
-
},
|
|
1004
|
-
}),
|
|
1005
|
-
text: '',
|
|
1006
|
-
});
|
|
1007
|
-
yield generationChunk;
|
|
1008
|
-
if (this._lc_stream_delay != null) {
|
|
1009
|
-
await sleep(this._lc_stream_delay);
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
if (options.signal?.aborted === true) {
|
|
1013
|
-
throw new Error('AbortError');
|
|
1014
|
-
}
|
|
878
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
1015
879
|
}
|
|
1016
880
|
}
|
|
1017
881
|
|