@librechat/agents 3.1.74 → 3.1.75-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/README.md +66 -0
- package/dist/cjs/agents/AgentContext.cjs +84 -37
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +13 -3
- package/dist/cjs/graphs/Graph.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 +25 -15
- 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 +468 -647
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +1 -448
- 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 +83 -3
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +39 -4
- 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 +7 -6
- 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/tools/ToolNode.cjs +5 -1
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +85 -38
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +13 -3
- package/dist/esm/graphs/Graph.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 +25 -15
- 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 +469 -648
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +4 -449
- 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 +4 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +39 -4
- 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 +7 -6
- 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/tools/ToolNode.mjs +5 -1
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +14 -4
- package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +46 -0
- package/dist/types/index.d.ts +1 -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/langchain.d.ts +27 -0
- package/dist/types/types/graph.d.ts +26 -38
- package/dist/types/types/llm.d.ts +3 -3
- package/dist/types/types/run.d.ts +2 -0
- package/dist/types/types/stream.d.ts +1 -1
- package/package.json +80 -17
- package/src/agents/AgentContext.ts +123 -44
- package/src/agents/__tests__/AgentContext.anthropic.live.test.ts +116 -0
- package/src/agents/__tests__/AgentContext.bedrock.live.test.ts +149 -0
- package/src/agents/__tests__/AgentContext.test.ts +155 -2
- package/src/agents/__tests__/promptCacheLiveHelpers.ts +165 -0
- package/src/graphs/Graph.ts +24 -4
- package/src/graphs/__tests__/composition.smoke.test.ts +188 -0
- package/src/index.ts +3 -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 +43 -20
- package/src/llm/anthropic/utils/message_outputs.ts +119 -101
- package/src/llm/anthropic/utils/server-tool-inputs.test.ts +77 -0
- 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 +662 -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 +736 -837
- package/src/llm/openai/utils/index.ts +84 -64
- 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 +106 -4
- package/src/messages/cache.ts +57 -5
- package/src/messages/core.ts +16 -9
- package/src/messages/format.ts +9 -6
- package/src/messages/langchain.ts +39 -0
- package/src/messages/prune.ts +12 -8
- package/src/scripts/caching.ts +2 -3
- package/src/specs/anthropic.simple.test.ts +61 -0
- package/src/specs/summarization.test.ts +58 -61
- package/src/tools/ToolNode.ts +5 -1
- package/src/types/graph.ts +35 -88
- package/src/types/llm.ts +3 -3
- package/src/types/run.ts +2 -0
- package/src/types/stream.ts +1 -1
- package/src/utils/llmConfig.ts +1 -6
|
@@ -53,6 +53,116 @@ 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 attachLibreChatDeltaFields(chunk, delta) {
|
|
99
|
+
if (!messages.AIMessageChunk.isInstance(chunk)) {
|
|
100
|
+
return chunk;
|
|
101
|
+
}
|
|
102
|
+
const libreChatDelta = delta;
|
|
103
|
+
if (libreChatDelta.reasoning != null &&
|
|
104
|
+
chunk.additional_kwargs.reasoning_content == null) {
|
|
105
|
+
chunk.additional_kwargs.reasoning_content = libreChatDelta.reasoning;
|
|
106
|
+
}
|
|
107
|
+
if (libreChatDelta.reasoning_details != null) {
|
|
108
|
+
chunk.additional_kwargs.reasoning_details =
|
|
109
|
+
libreChatDelta.reasoning_details;
|
|
110
|
+
}
|
|
111
|
+
if (libreChatDelta.provider_specific_fields != null) {
|
|
112
|
+
chunk.additional_kwargs.provider_specific_fields =
|
|
113
|
+
libreChatDelta.provider_specific_fields;
|
|
114
|
+
}
|
|
115
|
+
return chunk;
|
|
116
|
+
}
|
|
117
|
+
function attachLibreChatMessageFields(message, rawMessage) {
|
|
118
|
+
if (!messages.isAIMessage(message)) {
|
|
119
|
+
return message;
|
|
120
|
+
}
|
|
121
|
+
if (rawMessage.reasoning != null &&
|
|
122
|
+
message.additional_kwargs.reasoning_content == null) {
|
|
123
|
+
message.additional_kwargs.reasoning_content = rawMessage.reasoning;
|
|
124
|
+
}
|
|
125
|
+
if (rawMessage.reasoning_details != null) {
|
|
126
|
+
message.additional_kwargs.reasoning_details = rawMessage.reasoning_details;
|
|
127
|
+
}
|
|
128
|
+
if (rawMessage.provider_specific_fields != null) {
|
|
129
|
+
message.additional_kwargs.provider_specific_fields =
|
|
130
|
+
rawMessage.provider_specific_fields;
|
|
131
|
+
}
|
|
132
|
+
return message;
|
|
133
|
+
}
|
|
134
|
+
function getCustomOpenAIClientOptions(owner, options) {
|
|
135
|
+
if (!owner.client) {
|
|
136
|
+
const openAIEndpointConfig = {
|
|
137
|
+
baseURL: owner.clientConfig.baseURL,
|
|
138
|
+
};
|
|
139
|
+
const endpoint = openai.getEndpoint(openAIEndpointConfig);
|
|
140
|
+
const params = {
|
|
141
|
+
...owner.clientConfig,
|
|
142
|
+
baseURL: endpoint,
|
|
143
|
+
timeout: owner.timeout,
|
|
144
|
+
maxRetries: 0,
|
|
145
|
+
};
|
|
146
|
+
if (params.baseURL == null) {
|
|
147
|
+
delete params.baseURL;
|
|
148
|
+
}
|
|
149
|
+
params.defaultHeaders = openai.getHeadersWithUserAgent(params.defaultHeaders);
|
|
150
|
+
owner.client = new CustomOpenAIClient(params);
|
|
151
|
+
}
|
|
152
|
+
const requestOptions = {
|
|
153
|
+
...owner.clientConfig,
|
|
154
|
+
...options,
|
|
155
|
+
};
|
|
156
|
+
return requestOptions;
|
|
157
|
+
}
|
|
158
|
+
async function* delayStreamChunks(chunks, delay) {
|
|
159
|
+
for await (const chunk of chunks) {
|
|
160
|
+
yield chunk;
|
|
161
|
+
if (delay != null) {
|
|
162
|
+
await run.sleep(delay);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
56
166
|
function createAbortHandler(controller) {
|
|
57
167
|
return function () {
|
|
58
168
|
controller.abort();
|
|
@@ -112,89 +222,162 @@ class CustomAzureOpenAIClient extends openai$1.AzureOpenAI {
|
|
|
112
222
|
}));
|
|
113
223
|
}
|
|
114
224
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
225
|
+
class LibreChatOpenAICompletions extends openai.ChatOpenAICompletions {
|
|
226
|
+
includeReasoningContent;
|
|
227
|
+
includeReasoningDetails;
|
|
228
|
+
convertReasoningDetailsToContent;
|
|
118
229
|
constructor(fields) {
|
|
119
230
|
super(fields);
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
231
|
+
this.includeReasoningContent = fields?.includeReasoningContent;
|
|
232
|
+
this.includeReasoningDetails = fields?.includeReasoningDetails;
|
|
233
|
+
this.convertReasoningDetailsToContent =
|
|
234
|
+
fields?.convertReasoningDetailsToContent;
|
|
124
235
|
}
|
|
125
|
-
|
|
126
|
-
return
|
|
236
|
+
_getReasoningParams(options) {
|
|
237
|
+
return getReasoningParams(this.reasoning, options);
|
|
127
238
|
}
|
|
128
239
|
_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;
|
|
240
|
+
return getCustomOpenAIClientOptions(this, options);
|
|
150
241
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (this.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
242
|
+
_convertCompletionsDeltaToBaseMessageChunk(delta, rawResponse, defaultRole) {
|
|
243
|
+
return attachLibreChatDeltaFields(super._convertCompletionsDeltaToBaseMessageChunk(delta, rawResponse, defaultRole), delta);
|
|
244
|
+
}
|
|
245
|
+
_convertCompletionsMessageToBaseMessage(message, rawResponse) {
|
|
246
|
+
return attachLibreChatMessageFields(super._convertCompletionsMessageToBaseMessage(message, rawResponse), message);
|
|
247
|
+
}
|
|
248
|
+
async _generate(messages$1, options, runManager) {
|
|
249
|
+
if (this.includeReasoningContent !== true &&
|
|
250
|
+
this.includeReasoningDetails !== true) {
|
|
251
|
+
return super._generate(messages$1, options, runManager);
|
|
252
|
+
}
|
|
253
|
+
options.signal?.throwIfAborted();
|
|
254
|
+
const usageMetadata = {};
|
|
255
|
+
const params = this.invocationParams(options);
|
|
256
|
+
const messagesMapped = index._convertMessagesToOpenAIParams(messages$1, this.model, {
|
|
257
|
+
includeReasoningContent: this.includeReasoningContent,
|
|
258
|
+
includeReasoningDetails: this.includeReasoningDetails,
|
|
259
|
+
convertReasoningDetailsToContent: this.convertReasoningDetailsToContent,
|
|
260
|
+
});
|
|
261
|
+
if (params.stream === true) {
|
|
262
|
+
const stream = this._streamResponseChunks(messages$1, options, runManager);
|
|
263
|
+
const finalChunks = new Map();
|
|
264
|
+
for await (const chunk of stream) {
|
|
265
|
+
chunk.message.response_metadata = {
|
|
266
|
+
...chunk.generationInfo,
|
|
267
|
+
...chunk.message.response_metadata,
|
|
268
|
+
};
|
|
269
|
+
const index = typeof chunk.generationInfo?.completion === 'number'
|
|
270
|
+
? chunk.generationInfo.completion
|
|
271
|
+
: 0;
|
|
272
|
+
const existingChunk = finalChunks.get(index);
|
|
273
|
+
if (existingChunk == null) {
|
|
274
|
+
finalChunks.set(index, chunk);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
finalChunks.set(index, existingChunk.concat(chunk));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const generations = Array.from(finalChunks.entries())
|
|
281
|
+
.sort(([aKey], [bKey]) => aKey - bKey)
|
|
282
|
+
.map(([, value]) => value);
|
|
283
|
+
const { functions, function_call } = this.invocationParams(options);
|
|
284
|
+
const promptTokenUsage = await this._getEstimatedTokenCountFromPrompt(messages$1, functions, function_call);
|
|
285
|
+
const completionTokenUsage = await this._getNumTokensFromGenerations(generations);
|
|
286
|
+
usageMetadata.input_tokens = promptTokenUsage;
|
|
287
|
+
usageMetadata.output_tokens = completionTokenUsage;
|
|
288
|
+
usageMetadata.total_tokens = promptTokenUsage + completionTokenUsage;
|
|
289
|
+
return {
|
|
290
|
+
generations,
|
|
291
|
+
llmOutput: {
|
|
292
|
+
estimatedTokenUsage: {
|
|
293
|
+
promptTokens: usageMetadata.input_tokens,
|
|
294
|
+
completionTokens: usageMetadata.output_tokens,
|
|
295
|
+
totalTokens: usageMetadata.total_tokens,
|
|
296
|
+
},
|
|
297
|
+
},
|
|
162
298
|
};
|
|
163
299
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
300
|
+
const data = await this.completionWithRetry({
|
|
301
|
+
...params,
|
|
302
|
+
stream: false,
|
|
303
|
+
messages: messagesMapped,
|
|
304
|
+
}, {
|
|
305
|
+
signal: options.signal,
|
|
306
|
+
...options.options,
|
|
307
|
+
});
|
|
308
|
+
const { completion_tokens: completionTokens, prompt_tokens: promptTokens, total_tokens: totalTokens, prompt_tokens_details: promptTokensDetails, completion_tokens_details: completionTokensDetails, } = data.usage ?? {};
|
|
309
|
+
if (completionTokens != null) {
|
|
310
|
+
usageMetadata.output_tokens =
|
|
311
|
+
(usageMetadata.output_tokens ?? 0) + completionTokens;
|
|
312
|
+
}
|
|
313
|
+
if (promptTokens != null) {
|
|
314
|
+
usageMetadata.input_tokens =
|
|
315
|
+
(usageMetadata.input_tokens ?? 0) + promptTokens;
|
|
316
|
+
}
|
|
317
|
+
if (totalTokens != null) {
|
|
318
|
+
usageMetadata.total_tokens =
|
|
319
|
+
(usageMetadata.total_tokens ?? 0) + totalTokens;
|
|
320
|
+
}
|
|
321
|
+
if (promptTokensDetails?.audio_tokens != null ||
|
|
322
|
+
promptTokensDetails?.cached_tokens != null) {
|
|
323
|
+
usageMetadata.input_token_details = {
|
|
324
|
+
...(promptTokensDetails.audio_tokens != null && {
|
|
325
|
+
audio: promptTokensDetails.audio_tokens,
|
|
326
|
+
}),
|
|
327
|
+
...(promptTokensDetails.cached_tokens != null && {
|
|
328
|
+
cache_read: promptTokensDetails.cached_tokens,
|
|
329
|
+
}),
|
|
168
330
|
};
|
|
169
331
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
332
|
+
if (completionTokensDetails?.audio_tokens != null ||
|
|
333
|
+
completionTokensDetails?.reasoning_tokens != null) {
|
|
334
|
+
usageMetadata.output_token_details = {
|
|
335
|
+
...(completionTokensDetails.audio_tokens != null && {
|
|
336
|
+
audio: completionTokensDetails.audio_tokens,
|
|
337
|
+
}),
|
|
338
|
+
...(completionTokensDetails.reasoning_tokens != null && {
|
|
339
|
+
reasoning: completionTokensDetails.reasoning_tokens,
|
|
340
|
+
}),
|
|
341
|
+
};
|
|
178
342
|
}
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (
|
|
190
|
-
|
|
343
|
+
const generations = [];
|
|
344
|
+
for (const part of data.choices) {
|
|
345
|
+
const generation = {
|
|
346
|
+
text: part.message.content ?? '',
|
|
347
|
+
message: this._convertCompletionsMessageToBaseMessage(part.message, data),
|
|
348
|
+
};
|
|
349
|
+
generation.generationInfo = {
|
|
350
|
+
finish_reason: part.finish_reason,
|
|
351
|
+
...(part.logprobs ? { logprobs: part.logprobs } : {}),
|
|
352
|
+
};
|
|
353
|
+
if (messages.isAIMessage(generation.message)) {
|
|
354
|
+
generation.message.usage_metadata = usageMetadata;
|
|
191
355
|
}
|
|
192
|
-
|
|
356
|
+
generation.message = new messages.AIMessage(Object.fromEntries(Object.entries(generation.message).filter(([key]) => !key.startsWith('lc_'))));
|
|
357
|
+
generations.push(generation);
|
|
193
358
|
}
|
|
194
|
-
return
|
|
359
|
+
return {
|
|
360
|
+
generations,
|
|
361
|
+
llmOutput: {
|
|
362
|
+
tokenUsage: {
|
|
363
|
+
promptTokens: usageMetadata.input_tokens,
|
|
364
|
+
completionTokens: usageMetadata.output_tokens,
|
|
365
|
+
totalTokens: usageMetadata.total_tokens,
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
};
|
|
195
369
|
}
|
|
196
|
-
async *
|
|
197
|
-
|
|
370
|
+
async *_streamResponseChunks(messages$1, options, runManager) {
|
|
371
|
+
if (this.includeReasoningContent !== true &&
|
|
372
|
+
this.includeReasoningDetails !== true) {
|
|
373
|
+
yield* super._streamResponseChunks(messages$1, options, runManager);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const messagesMapped = index._convertMessagesToOpenAIParams(messages$1, this.model, {
|
|
377
|
+
includeReasoningContent: this.includeReasoningContent,
|
|
378
|
+
includeReasoningDetails: this.includeReasoningDetails,
|
|
379
|
+
convertReasoningDetailsToContent: this.convertReasoningDetailsToContent,
|
|
380
|
+
});
|
|
198
381
|
const params = {
|
|
199
382
|
...this.invocationParams(options, {
|
|
200
383
|
streaming: true,
|
|
@@ -206,49 +389,40 @@ class ChatOpenAI extends openai.ChatOpenAI {
|
|
|
206
389
|
const streamIterable = await this.completionWithRetry(params, options);
|
|
207
390
|
let usage;
|
|
208
391
|
for await (const data of streamIterable) {
|
|
209
|
-
|
|
210
|
-
|
|
392
|
+
if (options.signal?.aborted === true) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
const choices = data.choices;
|
|
396
|
+
const choice = choices?.[0];
|
|
397
|
+
if (data.usage != null) {
|
|
211
398
|
usage = data.usage;
|
|
212
399
|
}
|
|
213
|
-
if (
|
|
400
|
+
if (choice == null) {
|
|
214
401
|
continue;
|
|
215
402
|
}
|
|
216
403
|
const { delta } = choice;
|
|
217
|
-
if (
|
|
404
|
+
if (delta == null) {
|
|
218
405
|
continue;
|
|
219
406
|
}
|
|
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
|
-
}
|
|
407
|
+
const chunk = this._convertCompletionsDeltaToBaseMessageChunk(delta, data, defaultRole);
|
|
231
408
|
defaultRole = delta.role ?? defaultRole;
|
|
232
409
|
const newTokenIndices = {
|
|
233
410
|
prompt: options.promptIndex ?? 0,
|
|
234
|
-
completion: choice.index
|
|
411
|
+
completion: choice.index,
|
|
235
412
|
};
|
|
236
413
|
if (typeof chunk.content !== 'string') {
|
|
237
414
|
// eslint-disable-next-line no-console
|
|
238
415
|
console.log('[WARNING]: Received non-string content from OpenAI. This is currently not supported.');
|
|
239
416
|
continue;
|
|
240
417
|
}
|
|
241
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
242
418
|
const generationInfo = { ...newTokenIndices };
|
|
243
419
|
if (choice.finish_reason != null) {
|
|
244
420
|
generationInfo.finish_reason = choice.finish_reason;
|
|
245
|
-
// Only include system fingerprint in the last chunk for now
|
|
246
|
-
// to avoid concatenation issues
|
|
247
421
|
generationInfo.system_fingerprint = data.system_fingerprint;
|
|
248
422
|
generationInfo.model_name = data.model;
|
|
249
423
|
generationInfo.service_tier = data.service_tier;
|
|
250
424
|
}
|
|
251
|
-
if (this.logprobs
|
|
425
|
+
if (this.logprobs === true) {
|
|
252
426
|
generationInfo.logprobs = choice.logprobs;
|
|
253
427
|
}
|
|
254
428
|
const generationChunk = new outputs.ChatGenerationChunk({
|
|
@@ -257,10 +431,7 @@ class ChatOpenAI extends openai.ChatOpenAI {
|
|
|
257
431
|
generationInfo,
|
|
258
432
|
});
|
|
259
433
|
yield generationChunk;
|
|
260
|
-
|
|
261
|
-
await run.sleep(this._lc_stream_delay);
|
|
262
|
-
}
|
|
263
|
-
await runManager?.handleLLMNewToken(generationChunk.text || '', newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
434
|
+
await runManager?.handleLLMNewToken(generationChunk.text, newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
264
435
|
}
|
|
265
436
|
if (usage) {
|
|
266
437
|
const inputTokenDetails = {
|
|
@@ -282,9 +453,7 @@ class ChatOpenAI extends openai.ChatOpenAI {
|
|
|
282
453
|
const generationChunk = new outputs.ChatGenerationChunk({
|
|
283
454
|
message: new messages.AIMessageChunk({
|
|
284
455
|
content: '',
|
|
285
|
-
response_metadata: {
|
|
286
|
-
usage: { ...usage },
|
|
287
|
-
},
|
|
456
|
+
response_metadata: { usage: { ...usage } },
|
|
288
457
|
usage_metadata: {
|
|
289
458
|
input_tokens: usage.prompt_tokens,
|
|
290
459
|
output_tokens: usage.completion_tokens,
|
|
@@ -300,54 +469,84 @@ class ChatOpenAI extends openai.ChatOpenAI {
|
|
|
300
469
|
text: '',
|
|
301
470
|
});
|
|
302
471
|
yield generationChunk;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
472
|
+
await runManager?.handleLLMNewToken(generationChunk.text, {
|
|
473
|
+
prompt: 0,
|
|
474
|
+
completion: 0,
|
|
475
|
+
}, undefined, undefined, undefined, { chunk: generationChunk });
|
|
306
476
|
}
|
|
307
477
|
if (options.signal?.aborted === true) {
|
|
308
478
|
throw new Error('AbortError');
|
|
309
479
|
}
|
|
310
480
|
}
|
|
311
481
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
constructor(fields) {
|
|
316
|
-
super(fields);
|
|
317
|
-
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
482
|
+
class LibreChatOpenAIResponses extends openai.ChatOpenAIResponses {
|
|
483
|
+
_getReasoningParams(options) {
|
|
484
|
+
return getReasoningParams(this.reasoning, options);
|
|
318
485
|
}
|
|
319
|
-
|
|
320
|
-
return this
|
|
486
|
+
_getClientOptions(options) {
|
|
487
|
+
return getCustomOpenAIClientOptions(this, options);
|
|
321
488
|
}
|
|
322
|
-
|
|
323
|
-
|
|
489
|
+
}
|
|
490
|
+
class LibreChatAzureOpenAICompletions extends openai.AzureChatOpenAICompletions {
|
|
491
|
+
_getReasoningParams(options) {
|
|
492
|
+
return getGatedReasoningParams(this.model, this.reasoning, options);
|
|
324
493
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
...
|
|
338
|
-
|
|
494
|
+
_getClientOptions(options) {
|
|
495
|
+
if (!this.client) {
|
|
496
|
+
const openAIEndpointConfig = {
|
|
497
|
+
azureOpenAIApiDeploymentName: this.azureOpenAIApiDeploymentName,
|
|
498
|
+
azureOpenAIApiInstanceName: this.azureOpenAIApiInstanceName,
|
|
499
|
+
azureOpenAIApiKey: this.azureOpenAIApiKey,
|
|
500
|
+
azureOpenAIBasePath: this.azureOpenAIBasePath,
|
|
501
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
502
|
+
baseURL: this.clientConfig.baseURL,
|
|
503
|
+
};
|
|
504
|
+
const endpoint = openai.getEndpoint(openAIEndpointConfig);
|
|
505
|
+
const params = {
|
|
506
|
+
...this.clientConfig,
|
|
507
|
+
baseURL: endpoint,
|
|
508
|
+
timeout: this.timeout,
|
|
509
|
+
maxRetries: 0,
|
|
510
|
+
};
|
|
511
|
+
if (!this.azureADTokenProvider) {
|
|
512
|
+
params.apiKey = openAIEndpointConfig.azureOpenAIApiKey;
|
|
513
|
+
}
|
|
514
|
+
if (params.baseURL == null) {
|
|
515
|
+
delete params.baseURL;
|
|
516
|
+
}
|
|
517
|
+
const defaultHeaders = normalizeHeaders(params.defaultHeaders);
|
|
518
|
+
params.defaultHeaders = {
|
|
519
|
+
...params.defaultHeaders,
|
|
520
|
+
'User-Agent': defaultHeaders['User-Agent'] != null
|
|
521
|
+
? `${defaultHeaders['User-Agent']}: librechat-azure-openai-v2`
|
|
522
|
+
: 'librechat-azure-openai-v2',
|
|
339
523
|
};
|
|
524
|
+
this.client = new CustomAzureOpenAIClient({
|
|
525
|
+
apiVersion: this.azureOpenAIApiVersion,
|
|
526
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
527
|
+
...params,
|
|
528
|
+
});
|
|
340
529
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
530
|
+
const requestOptions = {
|
|
531
|
+
...this.clientConfig,
|
|
532
|
+
...options,
|
|
533
|
+
};
|
|
534
|
+
if (this.azureOpenAIApiKey != null) {
|
|
535
|
+
requestOptions.headers = {
|
|
536
|
+
'api-key': this.azureOpenAIApiKey,
|
|
537
|
+
...requestOptions.headers,
|
|
538
|
+
};
|
|
539
|
+
requestOptions.query = {
|
|
540
|
+
'api-version': this.azureOpenAIApiVersion,
|
|
541
|
+
...requestOptions.query,
|
|
345
542
|
};
|
|
346
543
|
}
|
|
347
|
-
return
|
|
544
|
+
return requestOptions;
|
|
348
545
|
}
|
|
546
|
+
}
|
|
547
|
+
class LibreChatAzureOpenAIResponses extends openai.AzureChatOpenAIResponses {
|
|
349
548
|
_getReasoningParams(options) {
|
|
350
|
-
return this.
|
|
549
|
+
return getGatedReasoningParams(this.model, this.reasoning, options);
|
|
351
550
|
}
|
|
352
551
|
_getClientOptions(options) {
|
|
353
552
|
if (!this.client) {
|
|
@@ -401,116 +600,26 @@ class AzureChatOpenAI extends openai.AzureChatOpenAI {
|
|
|
401
600
|
}
|
|
402
601
|
return requestOptions;
|
|
403
602
|
}
|
|
404
|
-
async *_streamResponseChunks(messages, options, runManager) {
|
|
405
|
-
if (!this._useResponseApi(options)) {
|
|
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;
|
|
424
|
-
}
|
|
425
603
|
}
|
|
426
|
-
|
|
604
|
+
function withLibreChatOpenAIFields(fields) {
|
|
605
|
+
const nextFields = fields ?? {};
|
|
606
|
+
return {
|
|
607
|
+
...nextFields,
|
|
608
|
+
completions: nextFields.completions ?? new LibreChatOpenAICompletions(nextFields),
|
|
609
|
+
responses: nextFields.responses ?? new LibreChatOpenAIResponses(nextFields),
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
class ChatOpenAI extends openai.ChatOpenAI {
|
|
613
|
+
_lc_stream_delay;
|
|
614
|
+
constructor(fields) {
|
|
615
|
+
super(withLibreChatOpenAIFields(fields));
|
|
616
|
+
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
617
|
+
}
|
|
427
618
|
get exposedClient() {
|
|
428
|
-
return this.
|
|
619
|
+
return getExposedOpenAIClient(this.completions, this.responses, this._useResponsesApi(undefined));
|
|
429
620
|
}
|
|
430
621
|
static lc_name() {
|
|
431
|
-
return '
|
|
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
|
-
});
|
|
622
|
+
return 'LibreChatOpenAI';
|
|
514
623
|
}
|
|
515
624
|
_getClientOptions(options) {
|
|
516
625
|
if (!this.client) {
|
|
@@ -535,300 +644,148 @@ class ChatDeepSeek extends deepseek.ChatDeepSeek {
|
|
|
535
644
|
};
|
|
536
645
|
return requestOptions;
|
|
537
646
|
}
|
|
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
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
647
|
+
/**
|
|
648
|
+
* Returns backwards compatible reasoning parameters from constructor params and call options
|
|
649
|
+
* @internal
|
|
650
|
+
*/
|
|
651
|
+
getReasoningParams(options) {
|
|
652
|
+
return getReasoningParams(this.reasoning, options);
|
|
653
|
+
}
|
|
654
|
+
_getReasoningParams(options) {
|
|
655
|
+
return this.getReasoningParams(options);
|
|
656
|
+
}
|
|
657
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
658
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
class AzureChatOpenAI extends openai.AzureChatOpenAI {
|
|
662
|
+
_lc_stream_delay;
|
|
663
|
+
constructor(fields) {
|
|
664
|
+
super(fields);
|
|
665
|
+
this.completions = new LibreChatAzureOpenAICompletions(fields);
|
|
666
|
+
this.responses = new LibreChatAzureOpenAIResponses(fields);
|
|
667
|
+
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
668
|
+
}
|
|
669
|
+
get exposedClient() {
|
|
670
|
+
return getExposedOpenAIClient(this.completions, this.responses, this._useResponsesApi(undefined));
|
|
671
|
+
}
|
|
672
|
+
static lc_name() {
|
|
673
|
+
return 'LibreChatAzureOpenAI';
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Returns backwards compatible reasoning parameters from constructor params and call options
|
|
677
|
+
* @internal
|
|
678
|
+
*/
|
|
679
|
+
getReasoningParams(options) {
|
|
680
|
+
return getGatedReasoningParams(this.model, this.reasoning, options);
|
|
681
|
+
}
|
|
682
|
+
_getReasoningParams(options) {
|
|
683
|
+
return this.getReasoningParams(options);
|
|
684
|
+
}
|
|
685
|
+
_getClientOptions(options) {
|
|
686
|
+
if (!this.client) {
|
|
687
|
+
const openAIEndpointConfig = {
|
|
688
|
+
azureOpenAIApiDeploymentName: this.azureOpenAIApiDeploymentName,
|
|
689
|
+
azureOpenAIApiInstanceName: this.azureOpenAIApiInstanceName,
|
|
690
|
+
azureOpenAIApiKey: this.azureOpenAIApiKey,
|
|
691
|
+
azureOpenAIBasePath: this.azureOpenAIBasePath,
|
|
692
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
693
|
+
baseURL: this.clientConfig.baseURL,
|
|
572
694
|
};
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
if (
|
|
581
|
-
|
|
582
|
-
generationInfo.system_fingerprint = data.system_fingerprint;
|
|
583
|
-
generationInfo.model_name = data.model;
|
|
584
|
-
generationInfo.service_tier = data.service_tier;
|
|
695
|
+
const endpoint = openai.getEndpoint(openAIEndpointConfig);
|
|
696
|
+
const params = {
|
|
697
|
+
...this.clientConfig,
|
|
698
|
+
baseURL: endpoint,
|
|
699
|
+
timeout: this.timeout,
|
|
700
|
+
maxRetries: 0,
|
|
701
|
+
};
|
|
702
|
+
if (!this.azureADTokenProvider) {
|
|
703
|
+
params.apiKey = openAIEndpointConfig.azureOpenAIApiKey;
|
|
585
704
|
}
|
|
586
|
-
if (
|
|
587
|
-
|
|
705
|
+
if (params.baseURL == null) {
|
|
706
|
+
delete params.baseURL;
|
|
588
707
|
}
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
708
|
+
const defaultHeaders = normalizeHeaders(params.defaultHeaders);
|
|
709
|
+
params.defaultHeaders = {
|
|
710
|
+
...params.defaultHeaders,
|
|
711
|
+
'User-Agent': defaultHeaders['User-Agent'] != null
|
|
712
|
+
? `${defaultHeaders['User-Agent']}: librechat-azure-openai-v2`
|
|
713
|
+
: 'librechat-azure-openai-v2',
|
|
714
|
+
};
|
|
715
|
+
this.client = new CustomAzureOpenAIClient({
|
|
716
|
+
apiVersion: this.azureOpenAIApiVersion,
|
|
717
|
+
azureADTokenProvider: this.azureADTokenProvider,
|
|
718
|
+
...params,
|
|
593
719
|
});
|
|
594
|
-
yield generationChunk;
|
|
595
|
-
await runManager?.handleLLMNewToken(generationChunk.text || '', newTokenIndices, undefined, undefined, undefined, { chunk: generationChunk });
|
|
596
720
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
721
|
+
const requestOptions = {
|
|
722
|
+
...this.clientConfig,
|
|
723
|
+
...options,
|
|
724
|
+
};
|
|
725
|
+
if (this.azureOpenAIApiKey != null) {
|
|
726
|
+
requestOptions.headers = {
|
|
727
|
+
'api-key': this.azureOpenAIApiKey,
|
|
728
|
+
...requestOptions.headers,
|
|
605
729
|
};
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
}),
|
|
610
|
-
...(usage.completion_tokens_details?.reasoning_tokens != null && {
|
|
611
|
-
reasoning: usage.completion_tokens_details.reasoning_tokens,
|
|
612
|
-
}),
|
|
730
|
+
requestOptions.query = {
|
|
731
|
+
'api-version': this.azureOpenAIApiVersion,
|
|
732
|
+
...requestOptions.query,
|
|
613
733
|
};
|
|
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
734
|
}
|
|
735
|
+
return requestOptions;
|
|
736
|
+
}
|
|
737
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
738
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
639
739
|
}
|
|
640
740
|
}
|
|
641
|
-
class
|
|
642
|
-
|
|
643
|
-
|
|
741
|
+
class ChatDeepSeek extends deepseek.ChatDeepSeek {
|
|
742
|
+
_lc_stream_delay;
|
|
743
|
+
constructor(fields) {
|
|
744
|
+
super(fields);
|
|
745
|
+
this._lc_stream_delay = fields?._lc_stream_delay;
|
|
644
746
|
}
|
|
645
|
-
|
|
646
|
-
return
|
|
647
|
-
includeReasoningContent: true,
|
|
648
|
-
});
|
|
747
|
+
get exposedClient() {
|
|
748
|
+
return this.client;
|
|
649
749
|
}
|
|
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),
|
|
750
|
+
static lc_name() {
|
|
751
|
+
return 'LibreChatDeepSeek';
|
|
752
|
+
}
|
|
753
|
+
_getClientOptions(options) {
|
|
754
|
+
if (!this.client) {
|
|
755
|
+
const openAIEndpointConfig = {
|
|
756
|
+
baseURL: this.clientConfig.baseURL,
|
|
671
757
|
};
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
...
|
|
758
|
+
const endpoint = openai.getEndpoint(openAIEndpointConfig);
|
|
759
|
+
const params = {
|
|
760
|
+
...this.clientConfig,
|
|
761
|
+
baseURL: endpoint,
|
|
762
|
+
timeout: this.timeout,
|
|
763
|
+
maxRetries: 0,
|
|
675
764
|
};
|
|
676
|
-
|
|
765
|
+
if (params.baseURL == null) {
|
|
766
|
+
delete params.baseURL;
|
|
767
|
+
}
|
|
768
|
+
this.client = new CustomOpenAIClient(params);
|
|
677
769
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
tokenUsage: {
|
|
682
|
-
completionTokens: completion_tokens,
|
|
683
|
-
promptTokens: prompt_tokens,
|
|
684
|
-
totalTokens: total_tokens,
|
|
685
|
-
},
|
|
686
|
-
},
|
|
770
|
+
const requestOptions = {
|
|
771
|
+
...this.clientConfig,
|
|
772
|
+
...options,
|
|
687
773
|
};
|
|
774
|
+
return requestOptions;
|
|
688
775
|
}
|
|
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
|
-
});
|
|
776
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
777
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
724
778
|
}
|
|
725
|
-
|
|
726
|
-
|
|
779
|
+
}
|
|
780
|
+
class ChatMoonshot extends ChatOpenAI {
|
|
781
|
+
constructor(fields) {
|
|
782
|
+
super({
|
|
783
|
+
...fields,
|
|
727
784
|
includeReasoningContent: true,
|
|
728
785
|
});
|
|
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
|
-
}
|
|
786
|
+
}
|
|
787
|
+
static lc_name() {
|
|
788
|
+
return 'LibreChatMoonshot';
|
|
832
789
|
}
|
|
833
790
|
}
|
|
834
791
|
class ChatXAI extends xai.ChatXAI {
|
|
@@ -876,144 +833,8 @@ class ChatXAI extends xai.ChatXAI {
|
|
|
876
833
|
};
|
|
877
834
|
return requestOptions;
|
|
878
835
|
}
|
|
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
|
-
}
|
|
836
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
837
|
+
yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
|
|
1017
838
|
}
|
|
1018
839
|
}
|
|
1019
840
|
|