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