@langchain/openai 1.0.0-alpha.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/LICENSE +6 -6
- package/dist/azure/chat_models/common.cjs +130 -0
- package/dist/azure/chat_models/common.cjs.map +1 -0
- package/dist/azure/chat_models/common.d.cts +16 -0
- package/dist/azure/chat_models/common.d.cts.map +1 -0
- package/dist/azure/chat_models/common.d.ts +16 -0
- package/dist/azure/chat_models/common.d.ts.map +1 -0
- package/dist/azure/chat_models/common.js +124 -0
- package/dist/azure/chat_models/common.js.map +1 -0
- package/dist/azure/chat_models/completions.cjs +50 -0
- package/dist/azure/chat_models/completions.cjs.map +1 -0
- package/dist/azure/chat_models/completions.d.cts +29 -0
- package/dist/azure/chat_models/completions.d.cts.map +1 -0
- package/dist/azure/chat_models/completions.d.ts +29 -0
- package/dist/azure/chat_models/completions.d.ts.map +1 -0
- package/dist/azure/chat_models/completions.js +50 -0
- package/dist/azure/chat_models/completions.js.map +1 -0
- package/dist/azure/{chat_models.cjs → chat_models/index.cjs} +14 -214
- package/dist/azure/chat_models/index.cjs.map +1 -0
- package/dist/azure/{chat_models.d.ts → chat_models/index.d.cts} +6 -11
- package/dist/azure/chat_models/index.d.cts.map +1 -0
- package/dist/azure/{chat_models.d.cts → chat_models/index.d.ts} +6 -11
- package/dist/azure/chat_models/index.d.ts.map +1 -0
- package/dist/azure/{chat_models.js → chat_models/index.js} +6 -205
- package/dist/azure/chat_models/index.js.map +1 -0
- package/dist/azure/chat_models/responses.cjs +50 -0
- package/dist/azure/chat_models/responses.cjs.map +1 -0
- package/dist/azure/chat_models/responses.d.cts +29 -0
- package/dist/azure/chat_models/responses.d.cts.map +1 -0
- package/dist/azure/chat_models/responses.d.ts +29 -0
- package/dist/azure/chat_models/responses.d.ts.map +1 -0
- package/dist/azure/chat_models/responses.js +50 -0
- package/dist/azure/chat_models/responses.js.map +1 -0
- package/dist/chat_models/base.cjs +533 -0
- package/dist/chat_models/base.cjs.map +1 -0
- package/dist/chat_models/base.d.cts +272 -0
- package/dist/chat_models/base.d.cts.map +1 -0
- package/dist/chat_models/base.d.ts +272 -0
- package/dist/chat_models/base.d.ts.map +1 -0
- package/dist/chat_models/base.js +532 -0
- package/dist/chat_models/base.js.map +1 -0
- package/dist/chat_models/completions.cjs +328 -0
- package/dist/chat_models/completions.cjs.map +1 -0
- package/dist/chat_models/completions.d.cts +33 -0
- package/dist/chat_models/completions.d.cts.map +1 -0
- package/dist/chat_models/completions.d.ts +33 -0
- package/dist/chat_models/completions.d.ts.map +1 -0
- package/dist/chat_models/completions.js +327 -0
- package/dist/chat_models/completions.js.map +1 -0
- package/dist/chat_models/index.cjs +608 -0
- package/dist/chat_models/index.cjs.map +1 -0
- package/dist/chat_models/index.d.cts +593 -0
- package/dist/chat_models/index.d.cts.map +1 -0
- package/dist/chat_models/index.d.ts +593 -0
- package/dist/chat_models/index.d.ts.map +1 -0
- package/dist/chat_models/index.js +608 -0
- package/dist/chat_models/index.js.map +1 -0
- package/dist/chat_models/responses.cjs +550 -0
- package/dist/chat_models/responses.cjs.map +1 -0
- package/dist/chat_models/responses.d.cts +77 -0
- package/dist/chat_models/responses.d.cts.map +1 -0
- package/dist/chat_models/responses.d.ts +77 -0
- package/dist/chat_models/responses.d.ts.map +1 -0
- package/dist/chat_models/responses.js +549 -0
- package/dist/chat_models/responses.js.map +1 -0
- package/dist/index.cjs +14 -7
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +8 -3
- package/dist/langchain-core/dist/callbacks/base.d.ts +1 -0
- package/dist/langchain-core/dist/callbacks/manager.d.ts +2 -0
- package/dist/langchain-core/dist/language_models/base.d.ts +5 -0
- package/dist/langchain-core/dist/language_models/chat_models.d.cts +13 -0
- package/dist/langchain-core/dist/language_models/chat_models.d.cts.map +1 -0
- package/dist/langchain-core/dist/language_models/chat_models.d.ts +20 -0
- package/dist/langchain-core/dist/language_models/chat_models.d.ts.map +1 -0
- package/dist/langchain-core/dist/runnables/base.d.ts +7 -0
- package/dist/langchain-core/dist/runnables/graph.d.ts +1 -0
- package/dist/langchain-core/dist/runnables/types.d.ts +2 -0
- package/dist/langchain-core/dist/tools/types.d.ts +5 -0
- package/dist/langchain-core/dist/tracers/base.d.ts +2 -0
- package/dist/langchain-core/dist/tracers/event_stream.d.ts +1 -0
- package/dist/langchain-core/dist/tracers/log_stream.d.ts +3 -0
- package/dist/langchain-core/dist/utils/types/index.d.ts +1 -0
- package/dist/langchain-core/dist/utils/types/zod.d.ts +1 -0
- package/dist/llms.cjs +1 -1
- package/dist/llms.d.cts +1 -1
- package/dist/llms.js +1 -1
- package/dist/utils/message_inputs.cjs +1 -1
- package/dist/utils/message_inputs.js +1 -1
- package/dist/utils/misc.cjs +4 -1
- package/dist/utils/misc.cjs.map +1 -1
- package/dist/utils/misc.d.cts.map +1 -1
- package/dist/utils/misc.d.ts.map +1 -1
- package/dist/utils/misc.js +4 -1
- package/dist/utils/misc.js.map +1 -1
- package/package.json +11 -10
- package/dist/azure/chat_models.cjs.map +0 -1
- package/dist/azure/chat_models.d.cts.map +0 -1
- package/dist/azure/chat_models.d.ts.map +0 -1
- package/dist/azure/chat_models.js.map +0 -1
- package/dist/chat_models.cjs +0 -1965
- package/dist/chat_models.cjs.map +0 -1
- package/dist/chat_models.d.cts +0 -931
- package/dist/chat_models.d.cts.map +0 -1
- package/dist/chat_models.d.ts +0 -931
- package/dist/chat_models.d.ts.map +0 -1
- package/dist/chat_models.js +0 -1961
- package/dist/chat_models.js.map +0 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { isReasoningModel } from "../utils/misc.js";
|
|
2
|
+
import { formatToOpenAIToolChoice } from "../utils/tools.js";
|
|
3
|
+
import { handleMultiModalOutput } from "../utils/output.js";
|
|
4
|
+
import { BaseChatOpenAI } from "./base.js";
|
|
5
|
+
import { wrapOpenAIClientError } from "../utils/client.js";
|
|
6
|
+
import { _convertMessagesToOpenAIParams } from "../utils/message_inputs.js";
|
|
7
|
+
import { makeInvalidToolCall, parseToolCall } from "@langchain/core/output_parsers/openai_tools";
|
|
8
|
+
import { AIMessage, AIMessageChunk, ChatMessage, ChatMessageChunk, FunctionMessageChunk, HumanMessageChunk, SystemMessageChunk, ToolMessageChunk, isAIMessage } from "@langchain/core/messages";
|
|
9
|
+
import { ChatGenerationChunk } from "@langchain/core/outputs";
|
|
10
|
+
|
|
11
|
+
//#region src/chat_models/completions.ts
|
|
12
|
+
/**
|
|
13
|
+
* OpenAI Completions API implementation.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
var ChatOpenAICompletions = class extends BaseChatOpenAI {
|
|
17
|
+
/** @internal */
|
|
18
|
+
invocationParams(options, extra) {
|
|
19
|
+
let strict;
|
|
20
|
+
if (options?.strict !== void 0) strict = options.strict;
|
|
21
|
+
else if (this.supportsStrictToolCalling !== void 0) strict = this.supportsStrictToolCalling;
|
|
22
|
+
let streamOptionsConfig = {};
|
|
23
|
+
if (options?.stream_options !== void 0) streamOptionsConfig = { stream_options: options.stream_options };
|
|
24
|
+
else if (this.streamUsage && (this.streaming || extra?.streaming)) streamOptionsConfig = { stream_options: { include_usage: true } };
|
|
25
|
+
const params = {
|
|
26
|
+
model: this.model,
|
|
27
|
+
temperature: this.temperature,
|
|
28
|
+
top_p: this.topP,
|
|
29
|
+
frequency_penalty: this.frequencyPenalty,
|
|
30
|
+
presence_penalty: this.presencePenalty,
|
|
31
|
+
logprobs: this.logprobs,
|
|
32
|
+
top_logprobs: this.topLogprobs,
|
|
33
|
+
n: this.n,
|
|
34
|
+
logit_bias: this.logitBias,
|
|
35
|
+
stop: options?.stop ?? this.stopSequences,
|
|
36
|
+
user: this.user,
|
|
37
|
+
stream: this.streaming,
|
|
38
|
+
functions: options?.functions,
|
|
39
|
+
function_call: options?.function_call,
|
|
40
|
+
tools: options?.tools?.length ? options.tools.map((tool) => this._convertChatOpenAIToolToCompletionsTool(tool, { strict })) : void 0,
|
|
41
|
+
tool_choice: formatToOpenAIToolChoice(options?.tool_choice),
|
|
42
|
+
response_format: this._getResponseFormat(options?.response_format),
|
|
43
|
+
seed: options?.seed,
|
|
44
|
+
...streamOptionsConfig,
|
|
45
|
+
parallel_tool_calls: options?.parallel_tool_calls,
|
|
46
|
+
...this.audio || options?.audio ? { audio: this.audio || options?.audio } : {},
|
|
47
|
+
...this.modalities || options?.modalities ? { modalities: this.modalities || options?.modalities } : {},
|
|
48
|
+
...this.modelKwargs,
|
|
49
|
+
prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,
|
|
50
|
+
verbosity: options?.verbosity ?? this.verbosity
|
|
51
|
+
};
|
|
52
|
+
if (options?.prediction !== void 0) params.prediction = options.prediction;
|
|
53
|
+
if (this.service_tier !== void 0) params.service_tier = this.service_tier;
|
|
54
|
+
if (options?.service_tier !== void 0) params.service_tier = options.service_tier;
|
|
55
|
+
const reasoning = this._getReasoningParams(options);
|
|
56
|
+
if (reasoning !== void 0 && reasoning.effort !== void 0) params.reasoning_effort = reasoning.effort;
|
|
57
|
+
if (isReasoningModel(params.model)) params.max_completion_tokens = this.maxTokens === -1 ? void 0 : this.maxTokens;
|
|
58
|
+
else params.max_tokens = this.maxTokens === -1 ? void 0 : this.maxTokens;
|
|
59
|
+
return params;
|
|
60
|
+
}
|
|
61
|
+
async _generate(messages, options, runManager) {
|
|
62
|
+
const usageMetadata = {};
|
|
63
|
+
const params = this.invocationParams(options);
|
|
64
|
+
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model);
|
|
65
|
+
if (params.stream) {
|
|
66
|
+
const stream = this._streamResponseChunks(messages, options, runManager);
|
|
67
|
+
const finalChunks = {};
|
|
68
|
+
for await (const chunk of stream) {
|
|
69
|
+
chunk.message.response_metadata = {
|
|
70
|
+
...chunk.generationInfo,
|
|
71
|
+
...chunk.message.response_metadata
|
|
72
|
+
};
|
|
73
|
+
const index = chunk.generationInfo?.completion ?? 0;
|
|
74
|
+
if (finalChunks[index] === void 0) finalChunks[index] = chunk;
|
|
75
|
+
else finalChunks[index] = finalChunks[index].concat(chunk);
|
|
76
|
+
}
|
|
77
|
+
const generations = Object.entries(finalChunks).sort(([aKey], [bKey]) => parseInt(aKey, 10) - parseInt(bKey, 10)).map(([_, value]) => value);
|
|
78
|
+
const { functions, function_call } = this.invocationParams(options);
|
|
79
|
+
const promptTokenUsage = await this._getEstimatedTokenCountFromPrompt(messages, functions, function_call);
|
|
80
|
+
const completionTokenUsage = await this._getNumTokensFromGenerations(generations);
|
|
81
|
+
usageMetadata.input_tokens = promptTokenUsage;
|
|
82
|
+
usageMetadata.output_tokens = completionTokenUsage;
|
|
83
|
+
usageMetadata.total_tokens = promptTokenUsage + completionTokenUsage;
|
|
84
|
+
return {
|
|
85
|
+
generations,
|
|
86
|
+
llmOutput: { estimatedTokenUsage: {
|
|
87
|
+
promptTokens: usageMetadata.input_tokens,
|
|
88
|
+
completionTokens: usageMetadata.output_tokens,
|
|
89
|
+
totalTokens: usageMetadata.total_tokens
|
|
90
|
+
} }
|
|
91
|
+
};
|
|
92
|
+
} else {
|
|
93
|
+
const data = await this.completionWithRetry({
|
|
94
|
+
...params,
|
|
95
|
+
stream: false,
|
|
96
|
+
messages: messagesMapped
|
|
97
|
+
}, {
|
|
98
|
+
signal: options?.signal,
|
|
99
|
+
...options?.options
|
|
100
|
+
});
|
|
101
|
+
const { completion_tokens: completionTokens, prompt_tokens: promptTokens, total_tokens: totalTokens, prompt_tokens_details: promptTokensDetails, completion_tokens_details: completionTokensDetails } = data?.usage ?? {};
|
|
102
|
+
if (completionTokens) usageMetadata.output_tokens = (usageMetadata.output_tokens ?? 0) + completionTokens;
|
|
103
|
+
if (promptTokens) usageMetadata.input_tokens = (usageMetadata.input_tokens ?? 0) + promptTokens;
|
|
104
|
+
if (totalTokens) usageMetadata.total_tokens = (usageMetadata.total_tokens ?? 0) + totalTokens;
|
|
105
|
+
if (promptTokensDetails?.audio_tokens !== null || promptTokensDetails?.cached_tokens !== null) usageMetadata.input_token_details = {
|
|
106
|
+
...promptTokensDetails?.audio_tokens !== null && { audio: promptTokensDetails?.audio_tokens },
|
|
107
|
+
...promptTokensDetails?.cached_tokens !== null && { cache_read: promptTokensDetails?.cached_tokens }
|
|
108
|
+
};
|
|
109
|
+
if (completionTokensDetails?.audio_tokens !== null || completionTokensDetails?.reasoning_tokens !== null) usageMetadata.output_token_details = {
|
|
110
|
+
...completionTokensDetails?.audio_tokens !== null && { audio: completionTokensDetails?.audio_tokens },
|
|
111
|
+
...completionTokensDetails?.reasoning_tokens !== null && { reasoning: completionTokensDetails?.reasoning_tokens }
|
|
112
|
+
};
|
|
113
|
+
const generations = [];
|
|
114
|
+
for (const part of data?.choices ?? []) {
|
|
115
|
+
const text = part.message?.content ?? "";
|
|
116
|
+
const generation = {
|
|
117
|
+
text,
|
|
118
|
+
message: this._convertCompletionsMessageToBaseMessage(part.message ?? { role: "assistant" }, data)
|
|
119
|
+
};
|
|
120
|
+
generation.generationInfo = {
|
|
121
|
+
...part.finish_reason ? { finish_reason: part.finish_reason } : {},
|
|
122
|
+
...part.logprobs ? { logprobs: part.logprobs } : {}
|
|
123
|
+
};
|
|
124
|
+
if (isAIMessage(generation.message)) generation.message.usage_metadata = usageMetadata;
|
|
125
|
+
generation.message = new AIMessage(Object.fromEntries(Object.entries(generation.message).filter(([key]) => !key.startsWith("lc_"))));
|
|
126
|
+
generations.push(generation);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
generations,
|
|
130
|
+
llmOutput: { tokenUsage: {
|
|
131
|
+
promptTokens: usageMetadata.input_tokens,
|
|
132
|
+
completionTokens: usageMetadata.output_tokens,
|
|
133
|
+
totalTokens: usageMetadata.total_tokens
|
|
134
|
+
} }
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
139
|
+
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model);
|
|
140
|
+
const params = {
|
|
141
|
+
...this.invocationParams(options, { streaming: true }),
|
|
142
|
+
messages: messagesMapped,
|
|
143
|
+
stream: true
|
|
144
|
+
};
|
|
145
|
+
let defaultRole;
|
|
146
|
+
const streamIterable = await this.completionWithRetry(params, options);
|
|
147
|
+
let usage;
|
|
148
|
+
for await (const data of streamIterable) {
|
|
149
|
+
const choice = data?.choices?.[0];
|
|
150
|
+
if (data.usage) usage = data.usage;
|
|
151
|
+
if (!choice) continue;
|
|
152
|
+
const { delta } = choice;
|
|
153
|
+
if (!delta) continue;
|
|
154
|
+
const chunk = this._convertCompletionsDeltaToBaseMessageChunk(delta, data, defaultRole);
|
|
155
|
+
defaultRole = delta.role ?? defaultRole;
|
|
156
|
+
const newTokenIndices = {
|
|
157
|
+
prompt: options.promptIndex ?? 0,
|
|
158
|
+
completion: choice.index ?? 0
|
|
159
|
+
};
|
|
160
|
+
if (typeof chunk.content !== "string") {
|
|
161
|
+
console.log("[WARNING]: Received non-string content from OpenAI. This is currently not supported.");
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const generationInfo = { ...newTokenIndices };
|
|
165
|
+
if (choice.finish_reason != null) {
|
|
166
|
+
generationInfo.finish_reason = choice.finish_reason;
|
|
167
|
+
generationInfo.system_fingerprint = data.system_fingerprint;
|
|
168
|
+
generationInfo.model_name = data.model;
|
|
169
|
+
generationInfo.service_tier = data.service_tier;
|
|
170
|
+
}
|
|
171
|
+
if (this.logprobs) generationInfo.logprobs = choice.logprobs;
|
|
172
|
+
const generationChunk = new ChatGenerationChunk({
|
|
173
|
+
message: chunk,
|
|
174
|
+
text: chunk.content,
|
|
175
|
+
generationInfo
|
|
176
|
+
});
|
|
177
|
+
yield generationChunk;
|
|
178
|
+
await runManager?.handleLLMNewToken(generationChunk.text ?? "", newTokenIndices, void 0, void 0, void 0, { chunk: generationChunk });
|
|
179
|
+
}
|
|
180
|
+
if (usage) {
|
|
181
|
+
const inputTokenDetails = {
|
|
182
|
+
...usage.prompt_tokens_details?.audio_tokens !== null && { audio: usage.prompt_tokens_details?.audio_tokens },
|
|
183
|
+
...usage.prompt_tokens_details?.cached_tokens !== null && { cache_read: usage.prompt_tokens_details?.cached_tokens }
|
|
184
|
+
};
|
|
185
|
+
const outputTokenDetails = {
|
|
186
|
+
...usage.completion_tokens_details?.audio_tokens !== null && { audio: usage.completion_tokens_details?.audio_tokens },
|
|
187
|
+
...usage.completion_tokens_details?.reasoning_tokens !== null && { reasoning: usage.completion_tokens_details?.reasoning_tokens }
|
|
188
|
+
};
|
|
189
|
+
const generationChunk = new ChatGenerationChunk({
|
|
190
|
+
message: new AIMessageChunk({
|
|
191
|
+
content: "",
|
|
192
|
+
response_metadata: { usage: { ...usage } },
|
|
193
|
+
usage_metadata: {
|
|
194
|
+
input_tokens: usage.prompt_tokens,
|
|
195
|
+
output_tokens: usage.completion_tokens,
|
|
196
|
+
total_tokens: usage.total_tokens,
|
|
197
|
+
...Object.keys(inputTokenDetails).length > 0 && { input_token_details: inputTokenDetails },
|
|
198
|
+
...Object.keys(outputTokenDetails).length > 0 && { output_token_details: outputTokenDetails }
|
|
199
|
+
}
|
|
200
|
+
}),
|
|
201
|
+
text: ""
|
|
202
|
+
});
|
|
203
|
+
yield generationChunk;
|
|
204
|
+
}
|
|
205
|
+
if (options.signal?.aborted) throw new Error("AbortError");
|
|
206
|
+
}
|
|
207
|
+
async completionWithRetry(request, requestOptions) {
|
|
208
|
+
const clientOptions = this._getClientOptions(requestOptions);
|
|
209
|
+
const isParseableFormat = request.response_format && request.response_format.type === "json_schema";
|
|
210
|
+
return this.caller.call(async () => {
|
|
211
|
+
try {
|
|
212
|
+
if (isParseableFormat && !request.stream) return await this.client.chat.completions.parse(request, clientOptions);
|
|
213
|
+
else return await this.client.chat.completions.create(request, clientOptions);
|
|
214
|
+
} catch (e) {
|
|
215
|
+
const error = wrapOpenAIClientError(e);
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/** @internal */
|
|
221
|
+
_convertCompletionsMessageToBaseMessage(message, rawResponse) {
|
|
222
|
+
const rawToolCalls = message.tool_calls;
|
|
223
|
+
switch (message.role) {
|
|
224
|
+
case "assistant": {
|
|
225
|
+
const toolCalls = [];
|
|
226
|
+
const invalidToolCalls = [];
|
|
227
|
+
for (const rawToolCall of rawToolCalls ?? []) try {
|
|
228
|
+
toolCalls.push(parseToolCall(rawToolCall, { returnId: true }));
|
|
229
|
+
} catch (e) {
|
|
230
|
+
invalidToolCalls.push(makeInvalidToolCall(rawToolCall, e.message));
|
|
231
|
+
}
|
|
232
|
+
const additional_kwargs = {
|
|
233
|
+
function_call: message.function_call,
|
|
234
|
+
tool_calls: rawToolCalls
|
|
235
|
+
};
|
|
236
|
+
if (this.__includeRawResponse !== void 0) additional_kwargs.__raw_response = rawResponse;
|
|
237
|
+
const response_metadata = {
|
|
238
|
+
model_provider: "openai",
|
|
239
|
+
model_name: rawResponse.model,
|
|
240
|
+
...rawResponse.system_fingerprint ? {
|
|
241
|
+
usage: { ...rawResponse.usage },
|
|
242
|
+
system_fingerprint: rawResponse.system_fingerprint
|
|
243
|
+
} : {}
|
|
244
|
+
};
|
|
245
|
+
if (message.audio) additional_kwargs.audio = message.audio;
|
|
246
|
+
const content = handleMultiModalOutput(message.content || "", rawResponse.choices?.[0]?.message);
|
|
247
|
+
return new AIMessage({
|
|
248
|
+
content,
|
|
249
|
+
tool_calls: toolCalls,
|
|
250
|
+
invalid_tool_calls: invalidToolCalls,
|
|
251
|
+
additional_kwargs,
|
|
252
|
+
response_metadata,
|
|
253
|
+
id: rawResponse.id
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
default: return new ChatMessage(message.content || "", message.role ?? "unknown");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/** @internal */
|
|
260
|
+
_convertCompletionsDeltaToBaseMessageChunk(delta, rawResponse, defaultRole) {
|
|
261
|
+
const role = delta.role ?? defaultRole;
|
|
262
|
+
const content = delta.content ?? "";
|
|
263
|
+
let additional_kwargs;
|
|
264
|
+
if (delta.function_call) additional_kwargs = { function_call: delta.function_call };
|
|
265
|
+
else if (delta.tool_calls) additional_kwargs = { tool_calls: delta.tool_calls };
|
|
266
|
+
else additional_kwargs = {};
|
|
267
|
+
if (this.__includeRawResponse) additional_kwargs.__raw_response = rawResponse;
|
|
268
|
+
if (delta.audio) additional_kwargs.audio = {
|
|
269
|
+
...delta.audio,
|
|
270
|
+
index: rawResponse.choices[0].index
|
|
271
|
+
};
|
|
272
|
+
const response_metadata = {
|
|
273
|
+
model_provider: "openai",
|
|
274
|
+
usage: { ...rawResponse.usage }
|
|
275
|
+
};
|
|
276
|
+
if (role === "user") return new HumanMessageChunk({
|
|
277
|
+
content,
|
|
278
|
+
response_metadata
|
|
279
|
+
});
|
|
280
|
+
else if (role === "assistant") {
|
|
281
|
+
const toolCallChunks = [];
|
|
282
|
+
if (Array.isArray(delta.tool_calls)) for (const rawToolCall of delta.tool_calls) toolCallChunks.push({
|
|
283
|
+
name: rawToolCall.function?.name,
|
|
284
|
+
args: rawToolCall.function?.arguments,
|
|
285
|
+
id: rawToolCall.id,
|
|
286
|
+
index: rawToolCall.index,
|
|
287
|
+
type: "tool_call_chunk"
|
|
288
|
+
});
|
|
289
|
+
return new AIMessageChunk({
|
|
290
|
+
content,
|
|
291
|
+
tool_call_chunks: toolCallChunks,
|
|
292
|
+
additional_kwargs,
|
|
293
|
+
id: rawResponse.id,
|
|
294
|
+
response_metadata
|
|
295
|
+
});
|
|
296
|
+
} else if (role === "system") return new SystemMessageChunk({
|
|
297
|
+
content,
|
|
298
|
+
response_metadata
|
|
299
|
+
});
|
|
300
|
+
else if (role === "developer") return new SystemMessageChunk({
|
|
301
|
+
content,
|
|
302
|
+
response_metadata,
|
|
303
|
+
additional_kwargs: { __openai_role__: "developer" }
|
|
304
|
+
});
|
|
305
|
+
else if (role === "function") return new FunctionMessageChunk({
|
|
306
|
+
content,
|
|
307
|
+
additional_kwargs,
|
|
308
|
+
name: delta.name,
|
|
309
|
+
response_metadata
|
|
310
|
+
});
|
|
311
|
+
else if (role === "tool") return new ToolMessageChunk({
|
|
312
|
+
content,
|
|
313
|
+
additional_kwargs,
|
|
314
|
+
tool_call_id: delta.tool_call_id,
|
|
315
|
+
response_metadata
|
|
316
|
+
});
|
|
317
|
+
else return new ChatMessageChunk({
|
|
318
|
+
content,
|
|
319
|
+
role,
|
|
320
|
+
response_metadata
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
//#endregion
|
|
326
|
+
export { ChatOpenAICompletions };
|
|
327
|
+
//# sourceMappingURL=completions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completions.js","names":["options?: this[\"ParsedCallOptions\"]","extra?: { streaming?: boolean }","strict: boolean | undefined","params: Partial<ChatCompletionsInvocationParams>","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","messagesMapped: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[]","finalChunks: Record<number, ChatGenerationChunk>","generations: ChatGeneration[]","generation: ChatGeneration","defaultRole: OpenAIClient.Chat.ChatCompletionRole | undefined","usage: OpenAIClient.Completions.CompletionUsage | undefined","generationInfo: Record<string, any>","request: OpenAIClient.Chat.ChatCompletionCreateParams","requestOptions?: OpenAIClient.RequestOptions","message: OpenAIClient.Chat.Completions.ChatCompletionMessage","rawResponse: OpenAIClient.Chat.Completions.ChatCompletion","rawToolCalls: OpenAIToolCall[] | undefined","e: any","additional_kwargs: Record<string, unknown>","response_metadata: Record<string, unknown> | undefined","delta: Record<string, any>","rawResponse: OpenAIClient.Chat.Completions.ChatCompletionChunk","defaultRole?: OpenAIClient.Chat.ChatCompletionRole","toolCallChunks: ToolCallChunk[]"],"sources":["../../src/chat_models/completions.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n AIMessage,\n AIMessageChunk,\n type BaseMessage,\n ChatMessage,\n ChatMessageChunk,\n FunctionMessageChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n ToolMessageChunk,\n OpenAIToolCall,\n isAIMessage,\n type UsageMetadata,\n type BaseMessageFields,\n} from \"@langchain/core/messages\";\nimport {\n ChatGenerationChunk,\n type ChatGeneration,\n type ChatResult,\n} from \"@langchain/core/outputs\";\nimport { NewTokenIndices } from \"@langchain/core/callbacks/base\";\nimport {\n makeInvalidToolCall,\n parseToolCall,\n} from \"@langchain/core/output_parsers/openai_tools\";\nimport type { ToolCallChunk } from \"@langchain/core/messages/tool\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport {\n OpenAIToolChoice,\n formatToOpenAIToolChoice,\n _convertToOpenAITool,\n} from \"../utils/tools.js\";\nimport {\n handleMultiModalOutput,\n _convertOpenAIResponsesUsageToLangChainUsage,\n} from \"../utils/output.js\";\nimport { _convertMessagesToOpenAIParams } from \"../utils/message_inputs.js\";\nimport { _convertToResponsesMessageFromV1 } from \"../utils/standard.js\";\nimport { isReasoningModel } from \"../utils/misc.js\";\nimport { BaseChatOpenAICallOptions } from \"./base.js\";\nimport { BaseChatOpenAI } from \"./base.js\";\n\nexport interface ChatOpenAICompletionsCallOptions\n extends BaseChatOpenAICallOptions {}\n\ntype ChatCompletionsInvocationParams = Omit<\n OpenAIClient.Chat.Completions.ChatCompletionCreateParams,\n \"messages\"\n>;\n\n/**\n * OpenAI Completions API implementation.\n * @internal\n */\nexport class ChatOpenAICompletions<\n CallOptions extends ChatOpenAICompletionsCallOptions = ChatOpenAICompletionsCallOptions\n> extends BaseChatOpenAI<CallOptions> {\n /** @internal */\n override invocationParams(\n options?: this[\"ParsedCallOptions\"],\n extra?: { streaming?: boolean }\n ): ChatCompletionsInvocationParams {\n let strict: boolean | undefined;\n if (options?.strict !== undefined) {\n strict = options.strict;\n } else if (this.supportsStrictToolCalling !== undefined) {\n strict = this.supportsStrictToolCalling;\n }\n\n let streamOptionsConfig = {};\n if (options?.stream_options !== undefined) {\n streamOptionsConfig = { stream_options: options.stream_options };\n } else if (this.streamUsage && (this.streaming || extra?.streaming)) {\n streamOptionsConfig = { stream_options: { include_usage: true } };\n }\n\n const params: Partial<ChatCompletionsInvocationParams> = {\n model: this.model,\n temperature: this.temperature,\n top_p: this.topP,\n frequency_penalty: this.frequencyPenalty,\n presence_penalty: this.presencePenalty,\n logprobs: this.logprobs,\n top_logprobs: this.topLogprobs,\n n: this.n,\n logit_bias: this.logitBias,\n stop: options?.stop ?? this.stopSequences,\n user: this.user,\n // if include_usage is set or streamUsage then stream must be set to true.\n stream: this.streaming,\n functions: options?.functions,\n function_call: options?.function_call,\n tools: options?.tools?.length\n ? options.tools.map((tool) =>\n this._convertChatOpenAIToolToCompletionsTool(tool, { strict })\n )\n : undefined,\n tool_choice: formatToOpenAIToolChoice(\n options?.tool_choice as OpenAIToolChoice\n ),\n response_format: this._getResponseFormat(options?.response_format),\n seed: options?.seed,\n ...streamOptionsConfig,\n parallel_tool_calls: options?.parallel_tool_calls,\n ...(this.audio || options?.audio\n ? { audio: this.audio || options?.audio }\n : {}),\n ...(this.modalities || options?.modalities\n ? { modalities: this.modalities || options?.modalities }\n : {}),\n ...this.modelKwargs,\n prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,\n verbosity: options?.verbosity ?? this.verbosity,\n };\n if (options?.prediction !== undefined) {\n params.prediction = options.prediction;\n }\n if (this.service_tier !== undefined) {\n params.service_tier = this.service_tier;\n }\n if (options?.service_tier !== undefined) {\n params.service_tier = options.service_tier;\n }\n const reasoning = this._getReasoningParams(options);\n if (reasoning !== undefined && reasoning.effort !== undefined) {\n params.reasoning_effort = reasoning.effort;\n }\n if (isReasoningModel(params.model)) {\n params.max_completion_tokens =\n this.maxTokens === -1 ? undefined : this.maxTokens;\n } else {\n params.max_tokens = this.maxTokens === -1 ? undefined : this.maxTokens;\n }\n\n return params as ChatCompletionsInvocationParams;\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const usageMetadata = {} as UsageMetadata;\n const params = this.invocationParams(options);\n const messagesMapped: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[] =\n _convertMessagesToOpenAIParams(messages, this.model);\n\n if (params.stream) {\n const stream = this._streamResponseChunks(messages, options, runManager);\n const finalChunks: Record<number, ChatGenerationChunk> = {};\n for await (const chunk of stream) {\n chunk.message.response_metadata = {\n ...chunk.generationInfo,\n ...chunk.message.response_metadata,\n };\n const index =\n (chunk.generationInfo as NewTokenIndices)?.completion ?? 0;\n if (finalChunks[index] === undefined) {\n finalChunks[index] = chunk;\n } else {\n finalChunks[index] = finalChunks[index].concat(chunk);\n }\n }\n const generations = Object.entries(finalChunks)\n .sort(([aKey], [bKey]) => parseInt(aKey, 10) - parseInt(bKey, 10))\n .map(([_, value]) => value);\n\n const { functions, function_call } = this.invocationParams(options);\n\n // OpenAI does not support token usage report under stream mode,\n // fallback to estimation.\n\n const promptTokenUsage = await this._getEstimatedTokenCountFromPrompt(\n messages,\n functions,\n function_call\n );\n const completionTokenUsage = await this._getNumTokensFromGenerations(\n generations\n );\n\n usageMetadata.input_tokens = promptTokenUsage;\n usageMetadata.output_tokens = completionTokenUsage;\n usageMetadata.total_tokens = promptTokenUsage + completionTokenUsage;\n return {\n generations,\n llmOutput: {\n estimatedTokenUsage: {\n promptTokens: usageMetadata.input_tokens,\n completionTokens: usageMetadata.output_tokens,\n totalTokens: usageMetadata.total_tokens,\n },\n },\n };\n } else {\n const data = await this.completionWithRetry(\n {\n ...params,\n stream: false,\n messages: messagesMapped,\n },\n {\n signal: options?.signal,\n ...options?.options,\n }\n );\n\n const {\n completion_tokens: completionTokens,\n prompt_tokens: promptTokens,\n total_tokens: totalTokens,\n prompt_tokens_details: promptTokensDetails,\n completion_tokens_details: completionTokensDetails,\n } = data?.usage ?? {};\n\n if (completionTokens) {\n usageMetadata.output_tokens =\n (usageMetadata.output_tokens ?? 0) + completionTokens;\n }\n\n if (promptTokens) {\n usageMetadata.input_tokens =\n (usageMetadata.input_tokens ?? 0) + promptTokens;\n }\n\n if (totalTokens) {\n usageMetadata.total_tokens =\n (usageMetadata.total_tokens ?? 0) + totalTokens;\n }\n\n if (\n promptTokensDetails?.audio_tokens !== null ||\n promptTokensDetails?.cached_tokens !== null\n ) {\n usageMetadata.input_token_details = {\n ...(promptTokensDetails?.audio_tokens !== null && {\n audio: promptTokensDetails?.audio_tokens,\n }),\n ...(promptTokensDetails?.cached_tokens !== null && {\n cache_read: promptTokensDetails?.cached_tokens,\n }),\n };\n }\n\n if (\n completionTokensDetails?.audio_tokens !== null ||\n completionTokensDetails?.reasoning_tokens !== null\n ) {\n usageMetadata.output_token_details = {\n ...(completionTokensDetails?.audio_tokens !== null && {\n audio: completionTokensDetails?.audio_tokens,\n }),\n ...(completionTokensDetails?.reasoning_tokens !== null && {\n reasoning: completionTokensDetails?.reasoning_tokens,\n }),\n };\n }\n\n const generations: ChatGeneration[] = [];\n for (const part of data?.choices ?? []) {\n const text = part.message?.content ?? \"\";\n const generation: ChatGeneration = {\n text,\n message: this._convertCompletionsMessageToBaseMessage(\n part.message ?? { role: \"assistant\" },\n data\n ),\n };\n generation.generationInfo = {\n ...(part.finish_reason ? { finish_reason: part.finish_reason } : {}),\n ...(part.logprobs ? { logprobs: part.logprobs } : {}),\n };\n if (isAIMessage(generation.message)) {\n generation.message.usage_metadata = usageMetadata;\n }\n // Fields are not serialized unless passed to the constructor\n // Doing this ensures all fields on the message are serialized\n generation.message = new AIMessage(\n Object.fromEntries(\n Object.entries(generation.message).filter(\n ([key]) => !key.startsWith(\"lc_\")\n )\n ) as BaseMessageFields\n );\n generations.push(generation);\n }\n return {\n generations,\n llmOutput: {\n tokenUsage: {\n promptTokens: usageMetadata.input_tokens,\n completionTokens: usageMetadata.output_tokens,\n totalTokens: usageMetadata.total_tokens,\n },\n },\n };\n }\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const messagesMapped: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[] =\n _convertMessagesToOpenAIParams(messages, this.model);\n\n const params = {\n ...this.invocationParams(options, {\n streaming: true,\n }),\n messages: messagesMapped,\n stream: true as const,\n };\n let defaultRole: OpenAIClient.Chat.ChatCompletionRole | undefined;\n\n const streamIterable = await this.completionWithRetry(params, options);\n let usage: OpenAIClient.Completions.CompletionUsage | undefined;\n for await (const data of streamIterable) {\n const choice = data?.choices?.[0];\n if (data.usage) {\n usage = data.usage;\n }\n if (!choice) {\n continue;\n }\n\n const { delta } = choice;\n if (!delta) {\n continue;\n }\n const chunk = this._convertCompletionsDeltaToBaseMessageChunk(\n delta,\n data,\n defaultRole\n );\n defaultRole = delta.role ?? defaultRole;\n const newTokenIndices = {\n prompt: options.promptIndex ?? 0,\n completion: choice.index ?? 0,\n };\n if (typeof chunk.content !== \"string\") {\n console.log(\n \"[WARNING]: Received non-string content from OpenAI. This is currently not supported.\"\n );\n continue;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const generationInfo: Record<string, any> = { ...newTokenIndices };\n if (choice.finish_reason != null) {\n generationInfo.finish_reason = choice.finish_reason;\n // Only include system fingerprint in the last chunk for now\n // to avoid concatenation issues\n generationInfo.system_fingerprint = data.system_fingerprint;\n generationInfo.model_name = data.model;\n generationInfo.service_tier = data.service_tier;\n }\n if (this.logprobs) {\n generationInfo.logprobs = choice.logprobs;\n }\n const generationChunk = new ChatGenerationChunk({\n message: chunk,\n text: chunk.content,\n generationInfo,\n });\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n generationChunk.text ?? \"\",\n newTokenIndices,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n }\n if (usage) {\n const inputTokenDetails = {\n ...(usage.prompt_tokens_details?.audio_tokens !== null && {\n audio: usage.prompt_tokens_details?.audio_tokens,\n }),\n ...(usage.prompt_tokens_details?.cached_tokens !== null && {\n cache_read: usage.prompt_tokens_details?.cached_tokens,\n }),\n };\n const outputTokenDetails = {\n ...(usage.completion_tokens_details?.audio_tokens !== null && {\n audio: usage.completion_tokens_details?.audio_tokens,\n }),\n ...(usage.completion_tokens_details?.reasoning_tokens !== null && {\n reasoning: usage.completion_tokens_details?.reasoning_tokens,\n }),\n };\n const generationChunk = new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n response_metadata: {\n usage: { ...usage },\n },\n usage_metadata: {\n input_tokens: usage.prompt_tokens,\n output_tokens: usage.completion_tokens,\n total_tokens: usage.total_tokens,\n ...(Object.keys(inputTokenDetails).length > 0 && {\n input_token_details: inputTokenDetails,\n }),\n ...(Object.keys(outputTokenDetails).length > 0 && {\n output_token_details: outputTokenDetails,\n }),\n },\n }),\n text: \"\",\n });\n yield generationChunk;\n }\n if (options.signal?.aborted) {\n throw new Error(\"AbortError\");\n }\n }\n\n async completionWithRetry(\n request: OpenAIClient.Chat.ChatCompletionCreateParamsStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<AsyncIterable<OpenAIClient.Chat.Completions.ChatCompletionChunk>>;\n\n async completionWithRetry(\n request: OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<OpenAIClient.Chat.Completions.ChatCompletion>;\n\n async completionWithRetry(\n request: OpenAIClient.Chat.ChatCompletionCreateParams,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<\n | AsyncIterable<OpenAIClient.Chat.Completions.ChatCompletionChunk>\n | OpenAIClient.Chat.Completions.ChatCompletion\n > {\n const clientOptions = this._getClientOptions(requestOptions);\n const isParseableFormat =\n request.response_format && request.response_format.type === \"json_schema\";\n return this.caller.call(async () => {\n try {\n if (isParseableFormat && !request.stream) {\n return await this.client.chat.completions.parse(\n request,\n clientOptions\n );\n } else {\n return await this.client.chat.completions.create(\n request,\n clientOptions\n );\n }\n } catch (e) {\n const error = wrapOpenAIClientError(e);\n throw error;\n }\n });\n }\n\n /** @internal */\n protected _convertCompletionsMessageToBaseMessage(\n message: OpenAIClient.Chat.Completions.ChatCompletionMessage,\n rawResponse: OpenAIClient.Chat.Completions.ChatCompletion\n ): BaseMessage {\n const rawToolCalls: OpenAIToolCall[] | undefined = message.tool_calls as\n | OpenAIToolCall[]\n | undefined;\n switch (message.role) {\n case \"assistant\": {\n const toolCalls = [];\n const invalidToolCalls = [];\n for (const rawToolCall of rawToolCalls ?? []) {\n try {\n toolCalls.push(parseToolCall(rawToolCall, { returnId: true }));\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n invalidToolCalls.push(makeInvalidToolCall(rawToolCall, e.message));\n }\n }\n const additional_kwargs: Record<string, unknown> = {\n function_call: message.function_call,\n tool_calls: rawToolCalls,\n };\n if (this.__includeRawResponse !== undefined) {\n additional_kwargs.__raw_response = rawResponse;\n }\n const response_metadata: Record<string, unknown> | undefined = {\n model_provider: \"openai\",\n model_name: rawResponse.model,\n ...(rawResponse.system_fingerprint\n ? {\n usage: { ...rawResponse.usage },\n system_fingerprint: rawResponse.system_fingerprint,\n }\n : {}),\n };\n\n if (message.audio) {\n additional_kwargs.audio = message.audio;\n }\n\n const content = handleMultiModalOutput(\n message.content || \"\",\n rawResponse.choices?.[0]?.message\n );\n return new AIMessage({\n content,\n tool_calls: toolCalls,\n invalid_tool_calls: invalidToolCalls,\n additional_kwargs,\n response_metadata,\n id: rawResponse.id,\n });\n }\n default:\n return new ChatMessage(\n message.content || \"\",\n message.role ?? \"unknown\"\n );\n }\n }\n\n /** @internal */\n protected _convertCompletionsDeltaToBaseMessageChunk(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delta: Record<string, any>,\n rawResponse: OpenAIClient.Chat.Completions.ChatCompletionChunk,\n defaultRole?: OpenAIClient.Chat.ChatCompletionRole\n ) {\n const role = delta.role ?? defaultRole;\n const content = delta.content ?? \"\";\n let additional_kwargs: Record<string, unknown>;\n if (delta.function_call) {\n additional_kwargs = {\n function_call: delta.function_call,\n };\n } else if (delta.tool_calls) {\n additional_kwargs = {\n tool_calls: delta.tool_calls,\n };\n } else {\n additional_kwargs = {};\n }\n if (this.__includeRawResponse) {\n additional_kwargs.__raw_response = rawResponse;\n }\n\n if (delta.audio) {\n additional_kwargs.audio = {\n ...delta.audio,\n index: rawResponse.choices[0].index,\n };\n }\n\n const response_metadata = {\n model_provider: \"openai\",\n usage: { ...rawResponse.usage },\n };\n if (role === \"user\") {\n return new HumanMessageChunk({ content, response_metadata });\n } else if (role === \"assistant\") {\n const toolCallChunks: ToolCallChunk[] = [];\n if (Array.isArray(delta.tool_calls)) {\n for (const rawToolCall of delta.tool_calls) {\n toolCallChunks.push({\n name: rawToolCall.function?.name,\n args: rawToolCall.function?.arguments,\n id: rawToolCall.id,\n index: rawToolCall.index,\n type: \"tool_call_chunk\",\n });\n }\n }\n return new AIMessageChunk({\n content,\n tool_call_chunks: toolCallChunks,\n additional_kwargs,\n id: rawResponse.id,\n response_metadata,\n });\n } else if (role === \"system\") {\n return new SystemMessageChunk({ content, response_metadata });\n } else if (role === \"developer\") {\n return new SystemMessageChunk({\n content,\n response_metadata,\n additional_kwargs: {\n __openai_role__: \"developer\",\n },\n });\n } else if (role === \"function\") {\n return new FunctionMessageChunk({\n content,\n additional_kwargs,\n name: delta.name,\n response_metadata,\n });\n } else if (role === \"tool\") {\n return new ToolMessageChunk({\n content,\n additional_kwargs,\n tool_call_id: delta.tool_call_id,\n response_metadata,\n });\n } else {\n return new ChatMessageChunk({ content, role, response_metadata });\n }\n }\n}\n"],"mappings":"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"}
|