@langchain/openai 0.4.3 → 0.4.5-rc.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/dist/azure/chat_models.cjs +6 -3
- package/dist/azure/chat_models.js +7 -4
- package/dist/chat_models.cjs +454 -4
- package/dist/chat_models.d.ts +46 -5
- package/dist/chat_models.js +454 -4
- package/dist/types.d.ts +7 -1
- package/package.json +2 -2
|
@@ -554,11 +554,14 @@ class AzureChatOpenAI extends chat_models_js_1.ChatOpenAI {
|
|
|
554
554
|
if (!params.baseURL) {
|
|
555
555
|
delete params.baseURL;
|
|
556
556
|
}
|
|
557
|
+
let env = (0, env_1.getEnv)();
|
|
558
|
+
if (env === "node" || env === "deno") {
|
|
559
|
+
env = `(${env}/${process.version}; ${process.platform}; ${process.arch})`;
|
|
560
|
+
}
|
|
561
|
+
const specifiedUserAgent = params.defaultHeaders?.["User-Agent"];
|
|
557
562
|
params.defaultHeaders = {
|
|
558
563
|
...params.defaultHeaders,
|
|
559
|
-
"User-Agent":
|
|
560
|
-
? `${params.defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
|
|
561
|
-
: `langchainjs-azure-openai-v2`,
|
|
564
|
+
"User-Agent": `langchainjs-azure-openai/2.0.0 (${env})${specifiedUserAgent ? ` ${specifiedUserAgent}` : ""}`,
|
|
562
565
|
};
|
|
563
566
|
this.client = new openai_1.AzureOpenAI({
|
|
564
567
|
apiVersion: this.azureOpenAIApiVersion,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AzureOpenAI as AzureOpenAIClient } from "openai";
|
|
2
|
-
import { getEnvironmentVariable } from "@langchain/core/utils/env";
|
|
2
|
+
import { getEnv, getEnvironmentVariable } from "@langchain/core/utils/env";
|
|
3
3
|
import { ChatOpenAI, } from "../chat_models.js";
|
|
4
4
|
import { getEndpoint } from "../utils/azure.js";
|
|
5
5
|
/**
|
|
@@ -551,11 +551,14 @@ export class AzureChatOpenAI extends ChatOpenAI {
|
|
|
551
551
|
if (!params.baseURL) {
|
|
552
552
|
delete params.baseURL;
|
|
553
553
|
}
|
|
554
|
+
let env = getEnv();
|
|
555
|
+
if (env === "node" || env === "deno") {
|
|
556
|
+
env = `(${env}/${process.version}; ${process.platform}; ${process.arch})`;
|
|
557
|
+
}
|
|
558
|
+
const specifiedUserAgent = params.defaultHeaders?.["User-Agent"];
|
|
554
559
|
params.defaultHeaders = {
|
|
555
560
|
...params.defaultHeaders,
|
|
556
|
-
"User-Agent":
|
|
557
|
-
? `${params.defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
|
|
558
|
-
: `langchainjs-azure-openai-v2`,
|
|
561
|
+
"User-Agent": `langchainjs-azure-openai/2.0.0 (${env})${specifiedUserAgent ? ` ${specifiedUserAgent}` : ""}`,
|
|
559
562
|
};
|
|
560
563
|
this.client = new AzureOpenAIClient({
|
|
561
564
|
apiVersion: this.azureOpenAIApiVersion,
|
package/dist/chat_models.cjs
CHANGED
|
@@ -55,7 +55,7 @@ function _convertMessagesToOpenAIParams(messages, model) {
|
|
|
55
55
|
// TODO: Function messages do not support array content, fix cast
|
|
56
56
|
return messages.flatMap((message) => {
|
|
57
57
|
let role = messageToOpenAIRole(message);
|
|
58
|
-
if (role === "system" && model
|
|
58
|
+
if (role === "system" && isReasoningModel(model)) {
|
|
59
59
|
role = "developer";
|
|
60
60
|
}
|
|
61
61
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -97,6 +97,283 @@ function _convertMessagesToOpenAIParams(messages, model) {
|
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
exports._convertMessagesToOpenAIParams = _convertMessagesToOpenAIParams;
|
|
100
|
+
const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
|
|
101
|
+
function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
102
|
+
return messages.flatMap((lcMsg) => {
|
|
103
|
+
let role = messageToOpenAIRole(lcMsg);
|
|
104
|
+
if (role === "system" && isReasoningModel(model))
|
|
105
|
+
role = "developer";
|
|
106
|
+
if (role === "function") {
|
|
107
|
+
throw new Error("Function messages are not supported in Responses API");
|
|
108
|
+
}
|
|
109
|
+
if (role === "tool") {
|
|
110
|
+
const toolMessage = lcMsg;
|
|
111
|
+
return {
|
|
112
|
+
type: "function_call_output",
|
|
113
|
+
call_id: toolMessage.tool_call_id,
|
|
114
|
+
id: toolMessage.id,
|
|
115
|
+
output: typeof toolMessage.content !== "string"
|
|
116
|
+
? JSON.stringify(toolMessage.content)
|
|
117
|
+
: toolMessage.content,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (role === "assistant") {
|
|
121
|
+
const functionCallIds =
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
123
|
+
lcMsg.additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY];
|
|
124
|
+
if ((0, messages_1.isAIMessage)(lcMsg) && !!lcMsg.tool_calls?.length) {
|
|
125
|
+
return lcMsg.tool_calls.map((toolCall) => ({
|
|
126
|
+
type: "function_call",
|
|
127
|
+
name: toolCall.name,
|
|
128
|
+
arguments: JSON.stringify(toolCall.args),
|
|
129
|
+
call_id: toolCall.id,
|
|
130
|
+
id: functionCallIds[toolCall.id],
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
if (lcMsg.additional_kwargs.tool_calls != null) {
|
|
134
|
+
return lcMsg.additional_kwargs.tool_calls.map((toolCall) => ({
|
|
135
|
+
type: "function_call",
|
|
136
|
+
name: toolCall.function.name,
|
|
137
|
+
call_id: toolCall.id,
|
|
138
|
+
id: functionCallIds[toolCall.id],
|
|
139
|
+
arguments: toolCall.function.arguments,
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
let { content } = lcMsg;
|
|
143
|
+
if (lcMsg.additional_kwargs.refusal != null) {
|
|
144
|
+
if (typeof content === "string") {
|
|
145
|
+
content = [{ type: "output_text", text: content, annotations: [] }];
|
|
146
|
+
}
|
|
147
|
+
content = [
|
|
148
|
+
...content,
|
|
149
|
+
{ type: "refusal", refusal: lcMsg.additional_kwargs.refusal },
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
type: "message",
|
|
154
|
+
role: "assistant",
|
|
155
|
+
content: typeof content === "string"
|
|
156
|
+
? content
|
|
157
|
+
: content.flatMap((item) => {
|
|
158
|
+
if (item.type === "text") {
|
|
159
|
+
return {
|
|
160
|
+
type: "output_text",
|
|
161
|
+
text: item.text,
|
|
162
|
+
// @ts-expect-error TODO: add types for `annotations`
|
|
163
|
+
annotations: item.annotations ?? [],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (item.type === "output_text" || item.type === "refusal") {
|
|
167
|
+
return item;
|
|
168
|
+
}
|
|
169
|
+
return [];
|
|
170
|
+
}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (role === "user") {
|
|
174
|
+
return {
|
|
175
|
+
type: "message",
|
|
176
|
+
role: "user",
|
|
177
|
+
content: typeof lcMsg.content === "string"
|
|
178
|
+
? lcMsg.content
|
|
179
|
+
: lcMsg.content.flatMap((item) => {
|
|
180
|
+
if (item.type === "text") {
|
|
181
|
+
return { type: "input_text", text: item.text };
|
|
182
|
+
}
|
|
183
|
+
if (item.type === "image_url") {
|
|
184
|
+
const image_url = typeof item.image_url === "string"
|
|
185
|
+
? item.image_url
|
|
186
|
+
: item.image_url.url;
|
|
187
|
+
const detail = typeof item.image_url === "string"
|
|
188
|
+
? "auto"
|
|
189
|
+
: item.image_url.detail;
|
|
190
|
+
return { type: "input_image", image_url, detail };
|
|
191
|
+
}
|
|
192
|
+
if (item.type === "input_text" ||
|
|
193
|
+
item.type === "input_image" ||
|
|
194
|
+
item.type === "input_file") {
|
|
195
|
+
return item;
|
|
196
|
+
}
|
|
197
|
+
return [];
|
|
198
|
+
}),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
return [];
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function _convertOpenAIResponsesMessageToBaseMessage(response) {
|
|
205
|
+
if (response.error) {
|
|
206
|
+
// TODO: add support for `addLangChainErrorFields`
|
|
207
|
+
const error = new Error(response.error.message);
|
|
208
|
+
error.name = response.error.code;
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
const content = [];
|
|
212
|
+
const tool_calls = [];
|
|
213
|
+
const invalid_tool_calls = [];
|
|
214
|
+
const response_metadata = {
|
|
215
|
+
model: response.model,
|
|
216
|
+
created_at: response.created_at,
|
|
217
|
+
id: response.id,
|
|
218
|
+
incomplete_details: response.incomplete_details,
|
|
219
|
+
metadata: response.metadata,
|
|
220
|
+
object: response.object,
|
|
221
|
+
status: response.status,
|
|
222
|
+
user: response.user,
|
|
223
|
+
// for compatibility with chat completion calls.
|
|
224
|
+
model_name: response.model,
|
|
225
|
+
};
|
|
226
|
+
const additional_kwargs = {};
|
|
227
|
+
for (const item of response.output) {
|
|
228
|
+
if (item.type === "message") {
|
|
229
|
+
// TODO: how to handle refusals?
|
|
230
|
+
content.push(...item.content.map((part) => {
|
|
231
|
+
if (part.type === "output_text") {
|
|
232
|
+
return {
|
|
233
|
+
type: "text",
|
|
234
|
+
text: part.text,
|
|
235
|
+
annotations: part.annotations,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return part;
|
|
239
|
+
}));
|
|
240
|
+
}
|
|
241
|
+
else if (item.type === "function_call") {
|
|
242
|
+
const fnAdapter = {
|
|
243
|
+
function: { name: item.name, arguments: item.arguments },
|
|
244
|
+
id: item.call_id,
|
|
245
|
+
};
|
|
246
|
+
try {
|
|
247
|
+
tool_calls.push((0, openai_tools_1.parseToolCall)(fnAdapter, { returnId: true }));
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
let errMessage;
|
|
251
|
+
if (typeof e === "object" &&
|
|
252
|
+
e != null &&
|
|
253
|
+
"message" in e &&
|
|
254
|
+
typeof e.message === "string") {
|
|
255
|
+
errMessage = e.message;
|
|
256
|
+
}
|
|
257
|
+
invalid_tool_calls.push((0, openai_tools_1.makeInvalidToolCall)(fnAdapter, errMessage));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if (item.type === "reasoning") {
|
|
261
|
+
additional_kwargs.reasoning = item;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
additional_kwargs.tool_outputs ??= [];
|
|
265
|
+
additional_kwargs.tool_outputs.push(item);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return new messages_1.AIMessage({
|
|
269
|
+
id: response.id,
|
|
270
|
+
content,
|
|
271
|
+
tool_calls,
|
|
272
|
+
invalid_tool_calls,
|
|
273
|
+
usage_metadata: response.usage,
|
|
274
|
+
additional_kwargs,
|
|
275
|
+
response_metadata,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
|
|
279
|
+
const content = [];
|
|
280
|
+
let generationInfo = {};
|
|
281
|
+
let usage_metadata;
|
|
282
|
+
const tool_call_chunks = [];
|
|
283
|
+
const response_metadata = {};
|
|
284
|
+
const additional_kwargs = {};
|
|
285
|
+
let id;
|
|
286
|
+
if (chunk.type === "response.output_text.delta") {
|
|
287
|
+
content.push({
|
|
288
|
+
type: "text",
|
|
289
|
+
text: chunk.delta,
|
|
290
|
+
index: chunk.content_index,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
else if (chunk.type === "response.output_text.annotation.added") {
|
|
294
|
+
content.push({
|
|
295
|
+
type: "text",
|
|
296
|
+
text: "",
|
|
297
|
+
annotations: [chunk.annotation],
|
|
298
|
+
index: chunk.content_index,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
else if (chunk.type === "response.output_item.added" &&
|
|
302
|
+
chunk.item.type === "message") {
|
|
303
|
+
id = chunk.item.id;
|
|
304
|
+
}
|
|
305
|
+
else if (chunk.type === "response.output_item.added" &&
|
|
306
|
+
chunk.item.type === "function_call") {
|
|
307
|
+
tool_call_chunks.push({
|
|
308
|
+
type: "tool_call_chunk",
|
|
309
|
+
name: chunk.item.name,
|
|
310
|
+
args: chunk.item.arguments,
|
|
311
|
+
id: chunk.item.id,
|
|
312
|
+
index: chunk.output_index,
|
|
313
|
+
});
|
|
314
|
+
additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY] = {
|
|
315
|
+
[chunk.item.call_id]: chunk.item.id,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
else if (chunk.type === "response.output_item.done" &&
|
|
319
|
+
(chunk.item.type === "web_search_call" ||
|
|
320
|
+
chunk.item.type === "file_search_call")) {
|
|
321
|
+
additional_kwargs.tool_outputs = [chunk.item];
|
|
322
|
+
}
|
|
323
|
+
else if (chunk.type === "response.created") {
|
|
324
|
+
response_metadata.id = chunk.response.id;
|
|
325
|
+
response_metadata.model_name = chunk.response.model;
|
|
326
|
+
response_metadata.model = chunk.response.model;
|
|
327
|
+
}
|
|
328
|
+
else if (chunk.type === "response.completed") {
|
|
329
|
+
usage_metadata = chunk.response.usage;
|
|
330
|
+
}
|
|
331
|
+
else if (chunk.type === "response.function_call_arguments.delta") {
|
|
332
|
+
tool_call_chunks.push({
|
|
333
|
+
type: "tool_call_chunk",
|
|
334
|
+
args: chunk.delta,
|
|
335
|
+
index: chunk.output_index,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
else if (chunk.type === "response.web_search_call.completed" ||
|
|
339
|
+
chunk.type === "response.file_search_call.completed") {
|
|
340
|
+
generationInfo = {
|
|
341
|
+
tool_outputs: {
|
|
342
|
+
id: chunk.item_id,
|
|
343
|
+
type: chunk.type.replace("response.", "").replace(".completed", ""),
|
|
344
|
+
status: "completed",
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
else if (chunk.type === "response.refusal.done") {
|
|
349
|
+
additional_kwargs.refusal = chunk.refusal;
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
return new outputs_1.ChatGenerationChunk({
|
|
355
|
+
// Legacy reasons, `onLLMNewToken` should pulls this out
|
|
356
|
+
text: content.map((part) => part.text).join(""),
|
|
357
|
+
message: new messages_1.AIMessageChunk({
|
|
358
|
+
id,
|
|
359
|
+
content,
|
|
360
|
+
tool_call_chunks,
|
|
361
|
+
usage_metadata,
|
|
362
|
+
additional_kwargs,
|
|
363
|
+
response_metadata,
|
|
364
|
+
}),
|
|
365
|
+
generationInfo,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
function isBuiltInTool(tool) {
|
|
369
|
+
return "type" in tool && tool.type !== "function";
|
|
370
|
+
}
|
|
371
|
+
function isBuiltInToolChoice(tool_choice) {
|
|
372
|
+
return (tool_choice != null &&
|
|
373
|
+
typeof tool_choice === "object" &&
|
|
374
|
+
"type" in tool_choice &&
|
|
375
|
+
tool_choice.type !== "function");
|
|
376
|
+
}
|
|
100
377
|
function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
|
|
101
378
|
if ((0, base_1.isOpenAITool)(tool)) {
|
|
102
379
|
if (fields?.strict !== undefined) {
|
|
@@ -112,6 +389,9 @@ function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
|
|
|
112
389
|
}
|
|
113
390
|
return (0, tools_js_1._convertToOpenAITool)(tool, fields);
|
|
114
391
|
}
|
|
392
|
+
function isReasoningModel(model) {
|
|
393
|
+
return model?.startsWith("o1") || model?.startsWith("o3");
|
|
394
|
+
}
|
|
115
395
|
/**
|
|
116
396
|
* OpenAI chat model integration.
|
|
117
397
|
*
|
|
@@ -901,6 +1181,12 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
901
1181
|
writable: true,
|
|
902
1182
|
value: void 0
|
|
903
1183
|
});
|
|
1184
|
+
Object.defineProperty(this, "useResponsesApi", {
|
|
1185
|
+
enumerable: true,
|
|
1186
|
+
configurable: true,
|
|
1187
|
+
writable: true,
|
|
1188
|
+
value: false
|
|
1189
|
+
});
|
|
904
1190
|
this.openAIApiKey =
|
|
905
1191
|
fields?.apiKey ??
|
|
906
1192
|
fields?.openAIApiKey ??
|
|
@@ -918,7 +1204,6 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
918
1204
|
this.topP = fields?.topP ?? this.topP;
|
|
919
1205
|
this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;
|
|
920
1206
|
this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;
|
|
921
|
-
this.maxTokens = fields?.maxTokens;
|
|
922
1207
|
this.logprobs = fields?.logprobs;
|
|
923
1208
|
this.topLogprobs = fields?.topLogprobs;
|
|
924
1209
|
this.n = fields?.n ?? this.n;
|
|
@@ -930,6 +1215,8 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
930
1215
|
this.audio = fields?.audio;
|
|
931
1216
|
this.modalities = fields?.modalities;
|
|
932
1217
|
this.reasoningEffort = fields?.reasoningEffort;
|
|
1218
|
+
this.maxTokens = fields?.maxCompletionTokens ?? fields?.maxTokens;
|
|
1219
|
+
this.useResponsesApi = fields?.useResponsesApi ?? this.useResponsesApi;
|
|
933
1220
|
if (this.model === "o1") {
|
|
934
1221
|
this.disableStreaming = true;
|
|
935
1222
|
}
|
|
@@ -967,7 +1254,9 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
967
1254
|
strict = this.supportsStrictToolCalling;
|
|
968
1255
|
}
|
|
969
1256
|
return this.bind({
|
|
970
|
-
tools: tools.map((tool) =>
|
|
1257
|
+
tools: tools.map((tool) => isBuiltInTool(tool)
|
|
1258
|
+
? tool
|
|
1259
|
+
: _convertChatOpenAIToolTypeToOpenAITool(tool, { strict })),
|
|
971
1260
|
...kwargs,
|
|
972
1261
|
});
|
|
973
1262
|
}
|
|
@@ -993,6 +1282,80 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
993
1282
|
else if (this.supportsStrictToolCalling !== undefined) {
|
|
994
1283
|
strict = this.supportsStrictToolCalling;
|
|
995
1284
|
}
|
|
1285
|
+
if (this._useResponseApi(options)) {
|
|
1286
|
+
const params = {
|
|
1287
|
+
model: this.model,
|
|
1288
|
+
temperature: this.temperature,
|
|
1289
|
+
top_p: this.topP,
|
|
1290
|
+
user: this.user,
|
|
1291
|
+
// if include_usage is set or streamUsage then stream must be set to true.
|
|
1292
|
+
stream: this.streaming,
|
|
1293
|
+
previous_response_id: options?.previous_response_id,
|
|
1294
|
+
truncation: options?.truncation,
|
|
1295
|
+
include: options?.include,
|
|
1296
|
+
tools: options?.tools?.length
|
|
1297
|
+
? options.tools
|
|
1298
|
+
.map((tool) => {
|
|
1299
|
+
if (isBuiltInTool(tool)) {
|
|
1300
|
+
return tool;
|
|
1301
|
+
}
|
|
1302
|
+
else if ((0, base_1.isOpenAITool)(tool)) {
|
|
1303
|
+
return {
|
|
1304
|
+
type: "function",
|
|
1305
|
+
name: tool.function.name,
|
|
1306
|
+
parameters: tool.function.parameters,
|
|
1307
|
+
description: tool.function.description,
|
|
1308
|
+
strict,
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
else {
|
|
1312
|
+
return null;
|
|
1313
|
+
}
|
|
1314
|
+
})
|
|
1315
|
+
.filter((tool) => tool !== null)
|
|
1316
|
+
: undefined,
|
|
1317
|
+
tool_choice: isBuiltInToolChoice(options?.tool_choice)
|
|
1318
|
+
? options?.tool_choice
|
|
1319
|
+
: (() => {
|
|
1320
|
+
const formatted = (0, openai_js_1.formatToOpenAIToolChoice)(options?.tool_choice);
|
|
1321
|
+
if (typeof formatted === "object" && "type" in formatted) {
|
|
1322
|
+
return { type: "function", name: formatted.function.name };
|
|
1323
|
+
}
|
|
1324
|
+
else {
|
|
1325
|
+
return undefined;
|
|
1326
|
+
}
|
|
1327
|
+
})(),
|
|
1328
|
+
text: (() => {
|
|
1329
|
+
if (options?.text)
|
|
1330
|
+
return options.text;
|
|
1331
|
+
const format = this.createResponseFormat(options?.response_format);
|
|
1332
|
+
if (format?.type === "json_schema") {
|
|
1333
|
+
if (format.json_schema.schema != null) {
|
|
1334
|
+
return {
|
|
1335
|
+
format: {
|
|
1336
|
+
type: "json_schema",
|
|
1337
|
+
schema: format.json_schema.schema,
|
|
1338
|
+
description: format.json_schema.description,
|
|
1339
|
+
name: format.json_schema.name,
|
|
1340
|
+
strict: format.json_schema.strict,
|
|
1341
|
+
},
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
return undefined;
|
|
1345
|
+
}
|
|
1346
|
+
return { format };
|
|
1347
|
+
})(),
|
|
1348
|
+
parallel_tool_calls: options?.parallel_tool_calls,
|
|
1349
|
+
max_output_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,
|
|
1350
|
+
...this.modelKwargs,
|
|
1351
|
+
};
|
|
1352
|
+
const reasoningEffort = options?.reasoning_effort ?? this.reasoningEffort;
|
|
1353
|
+
if (reasoningEffort !== undefined) {
|
|
1354
|
+
params.reasoning = { effort: reasoningEffort };
|
|
1355
|
+
}
|
|
1356
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1357
|
+
return params;
|
|
1358
|
+
}
|
|
996
1359
|
let streamOptionsConfig = {};
|
|
997
1360
|
if (options?.stream_options !== undefined) {
|
|
998
1361
|
streamOptionsConfig = { stream_options: options.stream_options };
|
|
@@ -1006,7 +1369,6 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1006
1369
|
top_p: this.topP,
|
|
1007
1370
|
frequency_penalty: this.frequencyPenalty,
|
|
1008
1371
|
presence_penalty: this.presencePenalty,
|
|
1009
|
-
max_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,
|
|
1010
1372
|
logprobs: this.logprobs,
|
|
1011
1373
|
top_logprobs: this.topLogprobs,
|
|
1012
1374
|
n: this.n,
|
|
@@ -1040,6 +1402,14 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1040
1402
|
if (reasoningEffort !== undefined) {
|
|
1041
1403
|
params.reasoning_effort = reasoningEffort;
|
|
1042
1404
|
}
|
|
1405
|
+
if (isReasoningModel(params.model)) {
|
|
1406
|
+
params.max_completion_tokens =
|
|
1407
|
+
this.maxTokens === -1 ? undefined : this.maxTokens;
|
|
1408
|
+
}
|
|
1409
|
+
else {
|
|
1410
|
+
params.max_tokens = this.maxTokens === -1 ? undefined : this.maxTokens;
|
|
1411
|
+
}
|
|
1412
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1043
1413
|
return params;
|
|
1044
1414
|
}
|
|
1045
1415
|
_convertOpenAIChatCompletionMessageToBaseMessage(message, rawResponse) {
|
|
@@ -1183,6 +1553,20 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1183
1553
|
};
|
|
1184
1554
|
}
|
|
1185
1555
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
1556
|
+
if (this._useResponseApi(options)) {
|
|
1557
|
+
const streamIterable = await this.responseApiWithRetry({
|
|
1558
|
+
...this.invocationParams(options, { streaming: true }),
|
|
1559
|
+
input: _convertMessagesToOpenAIResponsesParams(messages, this.model),
|
|
1560
|
+
stream: true,
|
|
1561
|
+
}, options);
|
|
1562
|
+
for await (const data of streamIterable) {
|
|
1563
|
+
const chunk = _convertOpenAIResponsesDeltaToBaseMessageChunk(data);
|
|
1564
|
+
if (chunk == null)
|
|
1565
|
+
continue;
|
|
1566
|
+
yield chunk;
|
|
1567
|
+
}
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1186
1570
|
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model);
|
|
1187
1571
|
const params = {
|
|
1188
1572
|
...this.invocationParams(options, {
|
|
@@ -1287,7 +1671,60 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1287
1671
|
return this._identifyingParams();
|
|
1288
1672
|
}
|
|
1289
1673
|
/** @ignore */
|
|
1674
|
+
async _responseApiGenerate(messages, options, runManager) {
|
|
1675
|
+
const invocationParams = this.invocationParams(options);
|
|
1676
|
+
if (invocationParams.stream) {
|
|
1677
|
+
const stream = this._streamResponseChunks(messages, options, runManager);
|
|
1678
|
+
let finalChunk;
|
|
1679
|
+
for await (const chunk of stream) {
|
|
1680
|
+
chunk.message.response_metadata = {
|
|
1681
|
+
...chunk.generationInfo,
|
|
1682
|
+
...chunk.message.response_metadata,
|
|
1683
|
+
};
|
|
1684
|
+
finalChunk = finalChunk?.concat(chunk) ?? chunk;
|
|
1685
|
+
}
|
|
1686
|
+
return {
|
|
1687
|
+
generations: finalChunk ? [finalChunk] : [],
|
|
1688
|
+
llmOutput: {
|
|
1689
|
+
estimatedTokenUsage: finalChunk?.message
|
|
1690
|
+
?.usage_metadata,
|
|
1691
|
+
},
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
const input = _convertMessagesToOpenAIResponsesParams(messages, this.model);
|
|
1695
|
+
const data = await this.responseApiWithRetry({ input, ...invocationParams }, { signal: options?.signal, ...options?.options });
|
|
1696
|
+
return {
|
|
1697
|
+
generations: [
|
|
1698
|
+
{
|
|
1699
|
+
text: data.output_text,
|
|
1700
|
+
message: _convertOpenAIResponsesMessageToBaseMessage(data),
|
|
1701
|
+
},
|
|
1702
|
+
],
|
|
1703
|
+
llmOutput: {
|
|
1704
|
+
id: data.id,
|
|
1705
|
+
estimatedTokenUsage: data.usage
|
|
1706
|
+
? {
|
|
1707
|
+
promptTokens: data.usage.input_tokens,
|
|
1708
|
+
completionTokens: data.usage.output_tokens,
|
|
1709
|
+
totalTokens: data.usage.total_tokens,
|
|
1710
|
+
}
|
|
1711
|
+
: undefined,
|
|
1712
|
+
},
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
_useResponseApi(options) {
|
|
1716
|
+
const usesBuiltInTools = options?.tools?.some(isBuiltInTool);
|
|
1717
|
+
const hasResponsesOnlyKwargs = options?.previous_response_id != null ||
|
|
1718
|
+
options?.text != null ||
|
|
1719
|
+
options?.truncation != null ||
|
|
1720
|
+
options?.include != null;
|
|
1721
|
+
return this.useResponsesApi || usesBuiltInTools || hasResponsesOnlyKwargs;
|
|
1722
|
+
}
|
|
1723
|
+
/** @ignore */
|
|
1290
1724
|
async _generate(messages, options, runManager) {
|
|
1725
|
+
if (this._useResponseApi(options)) {
|
|
1726
|
+
return this._responseApiGenerate(messages, options, runManager);
|
|
1727
|
+
}
|
|
1291
1728
|
const usageMetadata = {};
|
|
1292
1729
|
const params = this.invocationParams(options);
|
|
1293
1730
|
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model);
|
|
@@ -1525,6 +1962,19 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1525
1962
|
}
|
|
1526
1963
|
});
|
|
1527
1964
|
}
|
|
1965
|
+
async responseApiWithRetry(request, options) {
|
|
1966
|
+
return this.caller.call(async () => {
|
|
1967
|
+
const requestOptions = this._getClientOptions(options);
|
|
1968
|
+
try {
|
|
1969
|
+
const res = await this.client.responses.create(request, requestOptions);
|
|
1970
|
+
return res;
|
|
1971
|
+
}
|
|
1972
|
+
catch (e) {
|
|
1973
|
+
const error = (0, openai_js_1.wrapOpenAIClientError)(e);
|
|
1974
|
+
throw error;
|
|
1975
|
+
}
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1528
1978
|
/**
|
|
1529
1979
|
* Call the beta chat completions parse endpoint. This should only be called if
|
|
1530
1980
|
* response_format is set to "json_object".
|
package/dist/chat_models.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type ClientOptions, OpenAI as OpenAIClient } from "openai";
|
|
|
2
2
|
import { CallbackManagerForLLMRun } from "@langchain/core/callbacks/manager";
|
|
3
3
|
import { AIMessageChunk, type BaseMessage, ChatMessageChunk, FunctionMessageChunk, HumanMessageChunk, SystemMessageChunk, ToolMessageChunk } from "@langchain/core/messages";
|
|
4
4
|
import { ChatGenerationChunk, type ChatResult } from "@langchain/core/outputs";
|
|
5
|
-
import { BaseChatModel, BindToolsInput, LangSmithParams, type BaseChatModelParams } from "@langchain/core/language_models/chat_models";
|
|
5
|
+
import { BaseChatModel, type BindToolsInput, type LangSmithParams, type BaseChatModelParams } from "@langchain/core/language_models/chat_models";
|
|
6
6
|
import { type BaseFunctionCallOptions, type BaseLanguageModelInput, type StructuredOutputMethodOptions } from "@langchain/core/language_models/base";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { Runnable } from "@langchain/core/runnables";
|
|
@@ -21,7 +21,21 @@ type OpenAIRoleEnum = "system" | "developer" | "assistant" | "user" | "function"
|
|
|
21
21
|
type OpenAICompletionParam = OpenAIClient.Chat.Completions.ChatCompletionMessageParam;
|
|
22
22
|
export declare function messageToOpenAIRole(message: BaseMessage): OpenAIRoleEnum;
|
|
23
23
|
export declare function _convertMessagesToOpenAIParams(messages: BaseMessage[], model?: string): OpenAICompletionParam[];
|
|
24
|
-
type
|
|
24
|
+
type ExcludeController<T> = T extends {
|
|
25
|
+
controller: unknown;
|
|
26
|
+
} ? never : T;
|
|
27
|
+
type ExcludeNonController<T> = T extends {
|
|
28
|
+
controller: unknown;
|
|
29
|
+
} ? T : never;
|
|
30
|
+
type ResponsesCreate = OpenAIClient.Responses["create"];
|
|
31
|
+
type ResponsesCreateParams = Parameters<OpenAIClient.Responses["create"]>[0];
|
|
32
|
+
type ResponsesTool = Exclude<ResponsesCreateParams["tools"], undefined>[number];
|
|
33
|
+
type ResponsesToolChoice = Exclude<ResponsesCreateParams["tool_choice"], undefined>;
|
|
34
|
+
type ResponsesCreateInvoke = ExcludeController<Awaited<ReturnType<ResponsesCreate>>>;
|
|
35
|
+
type ResponsesCreateStream = ExcludeNonController<Awaited<ReturnType<ResponsesCreate>>>;
|
|
36
|
+
type ResponseInvocationParams = Omit<ResponsesCreateParams, "input">;
|
|
37
|
+
type ChatCompletionInvocationParams = Omit<OpenAIClient.Chat.ChatCompletionCreateParams, "messages">;
|
|
38
|
+
type ChatOpenAIToolType = BindToolsInput | OpenAIClient.ChatCompletionTool | ResponsesTool;
|
|
25
39
|
export interface ChatOpenAIStructuredOutputMethodOptions<IncludeRaw extends boolean> extends StructuredOutputMethodOptions<IncludeRaw> {
|
|
26
40
|
/**
|
|
27
41
|
* strict: If `true` and `method` = "function_calling", model output is
|
|
@@ -41,7 +55,7 @@ export interface ChatOpenAIStructuredOutputMethodOptions<IncludeRaw extends bool
|
|
|
41
55
|
}
|
|
42
56
|
export interface ChatOpenAICallOptions extends OpenAICallOptions, BaseFunctionCallOptions {
|
|
43
57
|
tools?: ChatOpenAIToolType[];
|
|
44
|
-
tool_choice?: OpenAIToolChoice;
|
|
58
|
+
tool_choice?: OpenAIToolChoice | ResponsesToolChoice;
|
|
45
59
|
promptIndex?: number;
|
|
46
60
|
response_format?: ChatOpenAIResponseFormat;
|
|
47
61
|
seed?: number;
|
|
@@ -105,9 +119,28 @@ export interface ChatOpenAICallOptions extends OpenAICallOptions, BaseFunctionCa
|
|
|
105
119
|
* Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
|
|
106
120
|
*/
|
|
107
121
|
reasoning_effort?: OpenAIClient.Chat.ChatCompletionReasoningEffort;
|
|
122
|
+
/**
|
|
123
|
+
* Configuration options for a text response from the model. Can be plain text or
|
|
124
|
+
* structured JSON data.
|
|
125
|
+
*/
|
|
126
|
+
text?: ResponsesCreateParams["text"];
|
|
127
|
+
/**
|
|
128
|
+
* The truncation strategy to use for the model response.
|
|
129
|
+
*/
|
|
130
|
+
truncation?: ResponsesCreateParams["truncation"];
|
|
131
|
+
/**
|
|
132
|
+
* Specify additional output data to include in the model response.
|
|
133
|
+
*/
|
|
134
|
+
include?: ResponsesCreateParams["include"];
|
|
135
|
+
/**
|
|
136
|
+
* The unique ID of the previous response to the model. Use this to create
|
|
137
|
+
* multi-turn conversations.
|
|
138
|
+
*/
|
|
139
|
+
previous_response_id?: ResponsesCreateParams["previous_response_id"];
|
|
108
140
|
}
|
|
109
141
|
export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, BaseChatModelParams {
|
|
110
142
|
configuration?: ClientOptions;
|
|
143
|
+
useResponsesApi?: boolean;
|
|
111
144
|
}
|
|
112
145
|
/**
|
|
113
146
|
* OpenAI chat model integration.
|
|
@@ -689,6 +722,7 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
|
|
|
689
722
|
audio?: OpenAIClient.Chat.ChatCompletionAudioParam;
|
|
690
723
|
modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;
|
|
691
724
|
reasoningEffort?: OpenAIClient.Chat.ChatCompletionReasoningEffort;
|
|
725
|
+
useResponsesApi: boolean;
|
|
692
726
|
constructor(fields?: ChatOpenAIFields);
|
|
693
727
|
getLsParams(options: this["ParsedCallOptions"]): LangSmithParams;
|
|
694
728
|
bindTools(tools: ChatOpenAIToolType[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions>;
|
|
@@ -696,9 +730,9 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
|
|
|
696
730
|
/**
|
|
697
731
|
* Get the parameters used to invoke the model
|
|
698
732
|
*/
|
|
699
|
-
invocationParams(options?: this["ParsedCallOptions"], extra?: {
|
|
733
|
+
invocationParams<Type extends "responses" | "completion" = "completion">(options?: this["ParsedCallOptions"], extra?: {
|
|
700
734
|
streaming?: boolean;
|
|
701
|
-
}):
|
|
735
|
+
}): Type extends "responses" ? ResponseInvocationParams : ChatCompletionInvocationParams;
|
|
702
736
|
protected _convertOpenAIChatCompletionMessageToBaseMessage(message: OpenAIClient.Chat.Completions.ChatCompletionMessage, rawResponse: OpenAIClient.Chat.Completions.ChatCompletion): BaseMessage;
|
|
703
737
|
protected _convertOpenAIDeltaToBaseMessageChunk(delta: Record<string, any>, rawResponse: OpenAIClient.Chat.Completions.ChatCompletionChunk, defaultRole?: OpenAIRoleEnum): AIMessageChunk | HumanMessageChunk | SystemMessageChunk | FunctionMessageChunk | ToolMessageChunk | ChatMessageChunk;
|
|
704
738
|
/** @ignore */
|
|
@@ -714,6 +748,9 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
|
|
|
714
748
|
model_name: string;
|
|
715
749
|
} & ClientOptions;
|
|
716
750
|
/** @ignore */
|
|
751
|
+
_responseApiGenerate(messages: BaseMessage[], options: this["ParsedCallOptions"], runManager?: CallbackManagerForLLMRun): Promise<ChatResult>;
|
|
752
|
+
protected _useResponseApi(options: this["ParsedCallOptions"] | undefined): boolean;
|
|
753
|
+
/** @ignore */
|
|
717
754
|
_generate(messages: BaseMessage[], options: this["ParsedCallOptions"], runManager?: CallbackManagerForLLMRun): Promise<ChatResult>;
|
|
718
755
|
/**
|
|
719
756
|
* Estimate the number of tokens a prompt will use.
|
|
@@ -736,6 +773,10 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
|
|
|
736
773
|
*/
|
|
737
774
|
completionWithRetry(request: OpenAIClient.Chat.ChatCompletionCreateParamsStreaming, options?: OpenAICoreRequestOptions): Promise<AsyncIterable<OpenAIClient.Chat.Completions.ChatCompletionChunk>>;
|
|
738
775
|
completionWithRetry(request: OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming, options?: OpenAICoreRequestOptions): Promise<OpenAIClient.Chat.Completions.ChatCompletion>;
|
|
776
|
+
protected responseApiWithRetry(request: ResponsesCreateParams & {
|
|
777
|
+
stream: true;
|
|
778
|
+
}, options?: OpenAICoreRequestOptions): Promise<ResponsesCreateStream>;
|
|
779
|
+
protected responseApiWithRetry(request: ResponsesCreateParams, options?: OpenAICoreRequestOptions): Promise<ResponsesCreateInvoke>;
|
|
739
780
|
/**
|
|
740
781
|
* Call the beta chat completions parse endpoint. This should only be called if
|
|
741
782
|
* response_format is set to "json_object".
|
package/dist/chat_models.js
CHANGED
|
@@ -51,7 +51,7 @@ export function _convertMessagesToOpenAIParams(messages, model) {
|
|
|
51
51
|
// TODO: Function messages do not support array content, fix cast
|
|
52
52
|
return messages.flatMap((message) => {
|
|
53
53
|
let role = messageToOpenAIRole(message);
|
|
54
|
-
if (role === "system" && model
|
|
54
|
+
if (role === "system" && isReasoningModel(model)) {
|
|
55
55
|
role = "developer";
|
|
56
56
|
}
|
|
57
57
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -92,6 +92,283 @@ export function _convertMessagesToOpenAIParams(messages, model) {
|
|
|
92
92
|
return completionParam;
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
+
const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
|
|
96
|
+
function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
97
|
+
return messages.flatMap((lcMsg) => {
|
|
98
|
+
let role = messageToOpenAIRole(lcMsg);
|
|
99
|
+
if (role === "system" && isReasoningModel(model))
|
|
100
|
+
role = "developer";
|
|
101
|
+
if (role === "function") {
|
|
102
|
+
throw new Error("Function messages are not supported in Responses API");
|
|
103
|
+
}
|
|
104
|
+
if (role === "tool") {
|
|
105
|
+
const toolMessage = lcMsg;
|
|
106
|
+
return {
|
|
107
|
+
type: "function_call_output",
|
|
108
|
+
call_id: toolMessage.tool_call_id,
|
|
109
|
+
id: toolMessage.id,
|
|
110
|
+
output: typeof toolMessage.content !== "string"
|
|
111
|
+
? JSON.stringify(toolMessage.content)
|
|
112
|
+
: toolMessage.content,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (role === "assistant") {
|
|
116
|
+
const functionCallIds =
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
118
|
+
lcMsg.additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY];
|
|
119
|
+
if (isAIMessage(lcMsg) && !!lcMsg.tool_calls?.length) {
|
|
120
|
+
return lcMsg.tool_calls.map((toolCall) => ({
|
|
121
|
+
type: "function_call",
|
|
122
|
+
name: toolCall.name,
|
|
123
|
+
arguments: JSON.stringify(toolCall.args),
|
|
124
|
+
call_id: toolCall.id,
|
|
125
|
+
id: functionCallIds[toolCall.id],
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
if (lcMsg.additional_kwargs.tool_calls != null) {
|
|
129
|
+
return lcMsg.additional_kwargs.tool_calls.map((toolCall) => ({
|
|
130
|
+
type: "function_call",
|
|
131
|
+
name: toolCall.function.name,
|
|
132
|
+
call_id: toolCall.id,
|
|
133
|
+
id: functionCallIds[toolCall.id],
|
|
134
|
+
arguments: toolCall.function.arguments,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
let { content } = lcMsg;
|
|
138
|
+
if (lcMsg.additional_kwargs.refusal != null) {
|
|
139
|
+
if (typeof content === "string") {
|
|
140
|
+
content = [{ type: "output_text", text: content, annotations: [] }];
|
|
141
|
+
}
|
|
142
|
+
content = [
|
|
143
|
+
...content,
|
|
144
|
+
{ type: "refusal", refusal: lcMsg.additional_kwargs.refusal },
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
type: "message",
|
|
149
|
+
role: "assistant",
|
|
150
|
+
content: typeof content === "string"
|
|
151
|
+
? content
|
|
152
|
+
: content.flatMap((item) => {
|
|
153
|
+
if (item.type === "text") {
|
|
154
|
+
return {
|
|
155
|
+
type: "output_text",
|
|
156
|
+
text: item.text,
|
|
157
|
+
// @ts-expect-error TODO: add types for `annotations`
|
|
158
|
+
annotations: item.annotations ?? [],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (item.type === "output_text" || item.type === "refusal") {
|
|
162
|
+
return item;
|
|
163
|
+
}
|
|
164
|
+
return [];
|
|
165
|
+
}),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (role === "user") {
|
|
169
|
+
return {
|
|
170
|
+
type: "message",
|
|
171
|
+
role: "user",
|
|
172
|
+
content: typeof lcMsg.content === "string"
|
|
173
|
+
? lcMsg.content
|
|
174
|
+
: lcMsg.content.flatMap((item) => {
|
|
175
|
+
if (item.type === "text") {
|
|
176
|
+
return { type: "input_text", text: item.text };
|
|
177
|
+
}
|
|
178
|
+
if (item.type === "image_url") {
|
|
179
|
+
const image_url = typeof item.image_url === "string"
|
|
180
|
+
? item.image_url
|
|
181
|
+
: item.image_url.url;
|
|
182
|
+
const detail = typeof item.image_url === "string"
|
|
183
|
+
? "auto"
|
|
184
|
+
: item.image_url.detail;
|
|
185
|
+
return { type: "input_image", image_url, detail };
|
|
186
|
+
}
|
|
187
|
+
if (item.type === "input_text" ||
|
|
188
|
+
item.type === "input_image" ||
|
|
189
|
+
item.type === "input_file") {
|
|
190
|
+
return item;
|
|
191
|
+
}
|
|
192
|
+
return [];
|
|
193
|
+
}),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return [];
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function _convertOpenAIResponsesMessageToBaseMessage(response) {
|
|
200
|
+
if (response.error) {
|
|
201
|
+
// TODO: add support for `addLangChainErrorFields`
|
|
202
|
+
const error = new Error(response.error.message);
|
|
203
|
+
error.name = response.error.code;
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
const content = [];
|
|
207
|
+
const tool_calls = [];
|
|
208
|
+
const invalid_tool_calls = [];
|
|
209
|
+
const response_metadata = {
|
|
210
|
+
model: response.model,
|
|
211
|
+
created_at: response.created_at,
|
|
212
|
+
id: response.id,
|
|
213
|
+
incomplete_details: response.incomplete_details,
|
|
214
|
+
metadata: response.metadata,
|
|
215
|
+
object: response.object,
|
|
216
|
+
status: response.status,
|
|
217
|
+
user: response.user,
|
|
218
|
+
// for compatibility with chat completion calls.
|
|
219
|
+
model_name: response.model,
|
|
220
|
+
};
|
|
221
|
+
const additional_kwargs = {};
|
|
222
|
+
for (const item of response.output) {
|
|
223
|
+
if (item.type === "message") {
|
|
224
|
+
// TODO: how to handle refusals?
|
|
225
|
+
content.push(...item.content.map((part) => {
|
|
226
|
+
if (part.type === "output_text") {
|
|
227
|
+
return {
|
|
228
|
+
type: "text",
|
|
229
|
+
text: part.text,
|
|
230
|
+
annotations: part.annotations,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
return part;
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
else if (item.type === "function_call") {
|
|
237
|
+
const fnAdapter = {
|
|
238
|
+
function: { name: item.name, arguments: item.arguments },
|
|
239
|
+
id: item.call_id,
|
|
240
|
+
};
|
|
241
|
+
try {
|
|
242
|
+
tool_calls.push(parseToolCall(fnAdapter, { returnId: true }));
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
let errMessage;
|
|
246
|
+
if (typeof e === "object" &&
|
|
247
|
+
e != null &&
|
|
248
|
+
"message" in e &&
|
|
249
|
+
typeof e.message === "string") {
|
|
250
|
+
errMessage = e.message;
|
|
251
|
+
}
|
|
252
|
+
invalid_tool_calls.push(makeInvalidToolCall(fnAdapter, errMessage));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else if (item.type === "reasoning") {
|
|
256
|
+
additional_kwargs.reasoning = item;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
additional_kwargs.tool_outputs ??= [];
|
|
260
|
+
additional_kwargs.tool_outputs.push(item);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return new AIMessage({
|
|
264
|
+
id: response.id,
|
|
265
|
+
content,
|
|
266
|
+
tool_calls,
|
|
267
|
+
invalid_tool_calls,
|
|
268
|
+
usage_metadata: response.usage,
|
|
269
|
+
additional_kwargs,
|
|
270
|
+
response_metadata,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
|
|
274
|
+
const content = [];
|
|
275
|
+
let generationInfo = {};
|
|
276
|
+
let usage_metadata;
|
|
277
|
+
const tool_call_chunks = [];
|
|
278
|
+
const response_metadata = {};
|
|
279
|
+
const additional_kwargs = {};
|
|
280
|
+
let id;
|
|
281
|
+
if (chunk.type === "response.output_text.delta") {
|
|
282
|
+
content.push({
|
|
283
|
+
type: "text",
|
|
284
|
+
text: chunk.delta,
|
|
285
|
+
index: chunk.content_index,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
else if (chunk.type === "response.output_text.annotation.added") {
|
|
289
|
+
content.push({
|
|
290
|
+
type: "text",
|
|
291
|
+
text: "",
|
|
292
|
+
annotations: [chunk.annotation],
|
|
293
|
+
index: chunk.content_index,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
else if (chunk.type === "response.output_item.added" &&
|
|
297
|
+
chunk.item.type === "message") {
|
|
298
|
+
id = chunk.item.id;
|
|
299
|
+
}
|
|
300
|
+
else if (chunk.type === "response.output_item.added" &&
|
|
301
|
+
chunk.item.type === "function_call") {
|
|
302
|
+
tool_call_chunks.push({
|
|
303
|
+
type: "tool_call_chunk",
|
|
304
|
+
name: chunk.item.name,
|
|
305
|
+
args: chunk.item.arguments,
|
|
306
|
+
id: chunk.item.id,
|
|
307
|
+
index: chunk.output_index,
|
|
308
|
+
});
|
|
309
|
+
additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY] = {
|
|
310
|
+
[chunk.item.call_id]: chunk.item.id,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
else if (chunk.type === "response.output_item.done" &&
|
|
314
|
+
(chunk.item.type === "web_search_call" ||
|
|
315
|
+
chunk.item.type === "file_search_call")) {
|
|
316
|
+
additional_kwargs.tool_outputs = [chunk.item];
|
|
317
|
+
}
|
|
318
|
+
else if (chunk.type === "response.created") {
|
|
319
|
+
response_metadata.id = chunk.response.id;
|
|
320
|
+
response_metadata.model_name = chunk.response.model;
|
|
321
|
+
response_metadata.model = chunk.response.model;
|
|
322
|
+
}
|
|
323
|
+
else if (chunk.type === "response.completed") {
|
|
324
|
+
usage_metadata = chunk.response.usage;
|
|
325
|
+
}
|
|
326
|
+
else if (chunk.type === "response.function_call_arguments.delta") {
|
|
327
|
+
tool_call_chunks.push({
|
|
328
|
+
type: "tool_call_chunk",
|
|
329
|
+
args: chunk.delta,
|
|
330
|
+
index: chunk.output_index,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
else if (chunk.type === "response.web_search_call.completed" ||
|
|
334
|
+
chunk.type === "response.file_search_call.completed") {
|
|
335
|
+
generationInfo = {
|
|
336
|
+
tool_outputs: {
|
|
337
|
+
id: chunk.item_id,
|
|
338
|
+
type: chunk.type.replace("response.", "").replace(".completed", ""),
|
|
339
|
+
status: "completed",
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
else if (chunk.type === "response.refusal.done") {
|
|
344
|
+
additional_kwargs.refusal = chunk.refusal;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
return new ChatGenerationChunk({
|
|
350
|
+
// Legacy reasons, `onLLMNewToken` should pulls this out
|
|
351
|
+
text: content.map((part) => part.text).join(""),
|
|
352
|
+
message: new AIMessageChunk({
|
|
353
|
+
id,
|
|
354
|
+
content,
|
|
355
|
+
tool_call_chunks,
|
|
356
|
+
usage_metadata,
|
|
357
|
+
additional_kwargs,
|
|
358
|
+
response_metadata,
|
|
359
|
+
}),
|
|
360
|
+
generationInfo,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function isBuiltInTool(tool) {
|
|
364
|
+
return "type" in tool && tool.type !== "function";
|
|
365
|
+
}
|
|
366
|
+
function isBuiltInToolChoice(tool_choice) {
|
|
367
|
+
return (tool_choice != null &&
|
|
368
|
+
typeof tool_choice === "object" &&
|
|
369
|
+
"type" in tool_choice &&
|
|
370
|
+
tool_choice.type !== "function");
|
|
371
|
+
}
|
|
95
372
|
function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
|
|
96
373
|
if (isOpenAITool(tool)) {
|
|
97
374
|
if (fields?.strict !== undefined) {
|
|
@@ -107,6 +384,9 @@ function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
|
|
|
107
384
|
}
|
|
108
385
|
return _convertToOpenAITool(tool, fields);
|
|
109
386
|
}
|
|
387
|
+
function isReasoningModel(model) {
|
|
388
|
+
return model?.startsWith("o1") || model?.startsWith("o3");
|
|
389
|
+
}
|
|
110
390
|
/**
|
|
111
391
|
* OpenAI chat model integration.
|
|
112
392
|
*
|
|
@@ -896,6 +1176,12 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
896
1176
|
writable: true,
|
|
897
1177
|
value: void 0
|
|
898
1178
|
});
|
|
1179
|
+
Object.defineProperty(this, "useResponsesApi", {
|
|
1180
|
+
enumerable: true,
|
|
1181
|
+
configurable: true,
|
|
1182
|
+
writable: true,
|
|
1183
|
+
value: false
|
|
1184
|
+
});
|
|
899
1185
|
this.openAIApiKey =
|
|
900
1186
|
fields?.apiKey ??
|
|
901
1187
|
fields?.openAIApiKey ??
|
|
@@ -913,7 +1199,6 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
913
1199
|
this.topP = fields?.topP ?? this.topP;
|
|
914
1200
|
this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;
|
|
915
1201
|
this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;
|
|
916
|
-
this.maxTokens = fields?.maxTokens;
|
|
917
1202
|
this.logprobs = fields?.logprobs;
|
|
918
1203
|
this.topLogprobs = fields?.topLogprobs;
|
|
919
1204
|
this.n = fields?.n ?? this.n;
|
|
@@ -925,6 +1210,8 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
925
1210
|
this.audio = fields?.audio;
|
|
926
1211
|
this.modalities = fields?.modalities;
|
|
927
1212
|
this.reasoningEffort = fields?.reasoningEffort;
|
|
1213
|
+
this.maxTokens = fields?.maxCompletionTokens ?? fields?.maxTokens;
|
|
1214
|
+
this.useResponsesApi = fields?.useResponsesApi ?? this.useResponsesApi;
|
|
928
1215
|
if (this.model === "o1") {
|
|
929
1216
|
this.disableStreaming = true;
|
|
930
1217
|
}
|
|
@@ -962,7 +1249,9 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
962
1249
|
strict = this.supportsStrictToolCalling;
|
|
963
1250
|
}
|
|
964
1251
|
return this.bind({
|
|
965
|
-
tools: tools.map((tool) =>
|
|
1252
|
+
tools: tools.map((tool) => isBuiltInTool(tool)
|
|
1253
|
+
? tool
|
|
1254
|
+
: _convertChatOpenAIToolTypeToOpenAITool(tool, { strict })),
|
|
966
1255
|
...kwargs,
|
|
967
1256
|
});
|
|
968
1257
|
}
|
|
@@ -988,6 +1277,80 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
988
1277
|
else if (this.supportsStrictToolCalling !== undefined) {
|
|
989
1278
|
strict = this.supportsStrictToolCalling;
|
|
990
1279
|
}
|
|
1280
|
+
if (this._useResponseApi(options)) {
|
|
1281
|
+
const params = {
|
|
1282
|
+
model: this.model,
|
|
1283
|
+
temperature: this.temperature,
|
|
1284
|
+
top_p: this.topP,
|
|
1285
|
+
user: this.user,
|
|
1286
|
+
// if include_usage is set or streamUsage then stream must be set to true.
|
|
1287
|
+
stream: this.streaming,
|
|
1288
|
+
previous_response_id: options?.previous_response_id,
|
|
1289
|
+
truncation: options?.truncation,
|
|
1290
|
+
include: options?.include,
|
|
1291
|
+
tools: options?.tools?.length
|
|
1292
|
+
? options.tools
|
|
1293
|
+
.map((tool) => {
|
|
1294
|
+
if (isBuiltInTool(tool)) {
|
|
1295
|
+
return tool;
|
|
1296
|
+
}
|
|
1297
|
+
else if (isOpenAITool(tool)) {
|
|
1298
|
+
return {
|
|
1299
|
+
type: "function",
|
|
1300
|
+
name: tool.function.name,
|
|
1301
|
+
parameters: tool.function.parameters,
|
|
1302
|
+
description: tool.function.description,
|
|
1303
|
+
strict,
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1306
|
+
else {
|
|
1307
|
+
return null;
|
|
1308
|
+
}
|
|
1309
|
+
})
|
|
1310
|
+
.filter((tool) => tool !== null)
|
|
1311
|
+
: undefined,
|
|
1312
|
+
tool_choice: isBuiltInToolChoice(options?.tool_choice)
|
|
1313
|
+
? options?.tool_choice
|
|
1314
|
+
: (() => {
|
|
1315
|
+
const formatted = formatToOpenAIToolChoice(options?.tool_choice);
|
|
1316
|
+
if (typeof formatted === "object" && "type" in formatted) {
|
|
1317
|
+
return { type: "function", name: formatted.function.name };
|
|
1318
|
+
}
|
|
1319
|
+
else {
|
|
1320
|
+
return undefined;
|
|
1321
|
+
}
|
|
1322
|
+
})(),
|
|
1323
|
+
text: (() => {
|
|
1324
|
+
if (options?.text)
|
|
1325
|
+
return options.text;
|
|
1326
|
+
const format = this.createResponseFormat(options?.response_format);
|
|
1327
|
+
if (format?.type === "json_schema") {
|
|
1328
|
+
if (format.json_schema.schema != null) {
|
|
1329
|
+
return {
|
|
1330
|
+
format: {
|
|
1331
|
+
type: "json_schema",
|
|
1332
|
+
schema: format.json_schema.schema,
|
|
1333
|
+
description: format.json_schema.description,
|
|
1334
|
+
name: format.json_schema.name,
|
|
1335
|
+
strict: format.json_schema.strict,
|
|
1336
|
+
},
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
return undefined;
|
|
1340
|
+
}
|
|
1341
|
+
return { format };
|
|
1342
|
+
})(),
|
|
1343
|
+
parallel_tool_calls: options?.parallel_tool_calls,
|
|
1344
|
+
max_output_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,
|
|
1345
|
+
...this.modelKwargs,
|
|
1346
|
+
};
|
|
1347
|
+
const reasoningEffort = options?.reasoning_effort ?? this.reasoningEffort;
|
|
1348
|
+
if (reasoningEffort !== undefined) {
|
|
1349
|
+
params.reasoning = { effort: reasoningEffort };
|
|
1350
|
+
}
|
|
1351
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1352
|
+
return params;
|
|
1353
|
+
}
|
|
991
1354
|
let streamOptionsConfig = {};
|
|
992
1355
|
if (options?.stream_options !== undefined) {
|
|
993
1356
|
streamOptionsConfig = { stream_options: options.stream_options };
|
|
@@ -1001,7 +1364,6 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1001
1364
|
top_p: this.topP,
|
|
1002
1365
|
frequency_penalty: this.frequencyPenalty,
|
|
1003
1366
|
presence_penalty: this.presencePenalty,
|
|
1004
|
-
max_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,
|
|
1005
1367
|
logprobs: this.logprobs,
|
|
1006
1368
|
top_logprobs: this.topLogprobs,
|
|
1007
1369
|
n: this.n,
|
|
@@ -1035,6 +1397,14 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1035
1397
|
if (reasoningEffort !== undefined) {
|
|
1036
1398
|
params.reasoning_effort = reasoningEffort;
|
|
1037
1399
|
}
|
|
1400
|
+
if (isReasoningModel(params.model)) {
|
|
1401
|
+
params.max_completion_tokens =
|
|
1402
|
+
this.maxTokens === -1 ? undefined : this.maxTokens;
|
|
1403
|
+
}
|
|
1404
|
+
else {
|
|
1405
|
+
params.max_tokens = this.maxTokens === -1 ? undefined : this.maxTokens;
|
|
1406
|
+
}
|
|
1407
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1038
1408
|
return params;
|
|
1039
1409
|
}
|
|
1040
1410
|
_convertOpenAIChatCompletionMessageToBaseMessage(message, rawResponse) {
|
|
@@ -1178,6 +1548,20 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1178
1548
|
};
|
|
1179
1549
|
}
|
|
1180
1550
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
1551
|
+
if (this._useResponseApi(options)) {
|
|
1552
|
+
const streamIterable = await this.responseApiWithRetry({
|
|
1553
|
+
...this.invocationParams(options, { streaming: true }),
|
|
1554
|
+
input: _convertMessagesToOpenAIResponsesParams(messages, this.model),
|
|
1555
|
+
stream: true,
|
|
1556
|
+
}, options);
|
|
1557
|
+
for await (const data of streamIterable) {
|
|
1558
|
+
const chunk = _convertOpenAIResponsesDeltaToBaseMessageChunk(data);
|
|
1559
|
+
if (chunk == null)
|
|
1560
|
+
continue;
|
|
1561
|
+
yield chunk;
|
|
1562
|
+
}
|
|
1563
|
+
return;
|
|
1564
|
+
}
|
|
1181
1565
|
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model);
|
|
1182
1566
|
const params = {
|
|
1183
1567
|
...this.invocationParams(options, {
|
|
@@ -1282,7 +1666,60 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1282
1666
|
return this._identifyingParams();
|
|
1283
1667
|
}
|
|
1284
1668
|
/** @ignore */
|
|
1669
|
+
async _responseApiGenerate(messages, options, runManager) {
|
|
1670
|
+
const invocationParams = this.invocationParams(options);
|
|
1671
|
+
if (invocationParams.stream) {
|
|
1672
|
+
const stream = this._streamResponseChunks(messages, options, runManager);
|
|
1673
|
+
let finalChunk;
|
|
1674
|
+
for await (const chunk of stream) {
|
|
1675
|
+
chunk.message.response_metadata = {
|
|
1676
|
+
...chunk.generationInfo,
|
|
1677
|
+
...chunk.message.response_metadata,
|
|
1678
|
+
};
|
|
1679
|
+
finalChunk = finalChunk?.concat(chunk) ?? chunk;
|
|
1680
|
+
}
|
|
1681
|
+
return {
|
|
1682
|
+
generations: finalChunk ? [finalChunk] : [],
|
|
1683
|
+
llmOutput: {
|
|
1684
|
+
estimatedTokenUsage: finalChunk?.message
|
|
1685
|
+
?.usage_metadata,
|
|
1686
|
+
},
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
const input = _convertMessagesToOpenAIResponsesParams(messages, this.model);
|
|
1690
|
+
const data = await this.responseApiWithRetry({ input, ...invocationParams }, { signal: options?.signal, ...options?.options });
|
|
1691
|
+
return {
|
|
1692
|
+
generations: [
|
|
1693
|
+
{
|
|
1694
|
+
text: data.output_text,
|
|
1695
|
+
message: _convertOpenAIResponsesMessageToBaseMessage(data),
|
|
1696
|
+
},
|
|
1697
|
+
],
|
|
1698
|
+
llmOutput: {
|
|
1699
|
+
id: data.id,
|
|
1700
|
+
estimatedTokenUsage: data.usage
|
|
1701
|
+
? {
|
|
1702
|
+
promptTokens: data.usage.input_tokens,
|
|
1703
|
+
completionTokens: data.usage.output_tokens,
|
|
1704
|
+
totalTokens: data.usage.total_tokens,
|
|
1705
|
+
}
|
|
1706
|
+
: undefined,
|
|
1707
|
+
},
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
_useResponseApi(options) {
|
|
1711
|
+
const usesBuiltInTools = options?.tools?.some(isBuiltInTool);
|
|
1712
|
+
const hasResponsesOnlyKwargs = options?.previous_response_id != null ||
|
|
1713
|
+
options?.text != null ||
|
|
1714
|
+
options?.truncation != null ||
|
|
1715
|
+
options?.include != null;
|
|
1716
|
+
return this.useResponsesApi || usesBuiltInTools || hasResponsesOnlyKwargs;
|
|
1717
|
+
}
|
|
1718
|
+
/** @ignore */
|
|
1285
1719
|
async _generate(messages, options, runManager) {
|
|
1720
|
+
if (this._useResponseApi(options)) {
|
|
1721
|
+
return this._responseApiGenerate(messages, options, runManager);
|
|
1722
|
+
}
|
|
1286
1723
|
const usageMetadata = {};
|
|
1287
1724
|
const params = this.invocationParams(options);
|
|
1288
1725
|
const messagesMapped = _convertMessagesToOpenAIParams(messages, this.model);
|
|
@@ -1520,6 +1957,19 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1520
1957
|
}
|
|
1521
1958
|
});
|
|
1522
1959
|
}
|
|
1960
|
+
async responseApiWithRetry(request, options) {
|
|
1961
|
+
return this.caller.call(async () => {
|
|
1962
|
+
const requestOptions = this._getClientOptions(options);
|
|
1963
|
+
try {
|
|
1964
|
+
const res = await this.client.responses.create(request, requestOptions);
|
|
1965
|
+
return res;
|
|
1966
|
+
}
|
|
1967
|
+
catch (e) {
|
|
1968
|
+
const error = wrapOpenAIClientError(e);
|
|
1969
|
+
throw error;
|
|
1970
|
+
}
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1523
1973
|
/**
|
|
1524
1974
|
* Call the beta chat completions parse endpoint. This should only be called if
|
|
1525
1975
|
* response_format is set to "json_object".
|
package/dist/types.d.ts
CHANGED
|
@@ -12,6 +12,12 @@ export declare interface OpenAIBaseInput {
|
|
|
12
12
|
* tokens as possible given the prompt and the model's maximum context size.
|
|
13
13
|
*/
|
|
14
14
|
maxTokens?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Maximum number of tokens to generate in the completion. -1 returns as many
|
|
17
|
+
* tokens as possible given the prompt and the model's maximum context size.
|
|
18
|
+
* Alias for `maxTokens` for reasoning models.
|
|
19
|
+
*/
|
|
20
|
+
maxCompletionTokens?: number;
|
|
15
21
|
/** Total probability mass of tokens to consider at each step */
|
|
16
22
|
topP: number;
|
|
17
23
|
/** Penalizes repeated tokens according to frequency */
|
|
@@ -140,7 +146,7 @@ export interface OpenAIChatInput extends OpenAIBaseInput {
|
|
|
140
146
|
* Constrains effort on reasoning for reasoning models. Currently supported values are low, medium, and high.
|
|
141
147
|
* Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
|
|
142
148
|
*/
|
|
143
|
-
reasoningEffort?: OpenAIClient.ChatCompletionReasoningEffort;
|
|
149
|
+
reasoningEffort?: OpenAIClient.Chat.ChatCompletionReasoningEffort;
|
|
144
150
|
}
|
|
145
151
|
export declare interface AzureOpenAIInput {
|
|
146
152
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/openai",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5-rc.0",
|
|
4
4
|
"description": "OpenAI integrations for LangChain.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"js-tiktoken": "^1.0.12",
|
|
39
|
-
"openai": "^4.
|
|
39
|
+
"openai": "^4.87.3",
|
|
40
40
|
"zod": "^3.22.4",
|
|
41
41
|
"zod-to-json-schema": "^3.22.3"
|
|
42
42
|
},
|