@langchain/openai 0.5.13 → 0.5.15
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 +5 -2
- package/dist/azure/chat_models.js +5 -2
- package/dist/azure/embeddings.cjs +5 -8
- package/dist/azure/embeddings.d.ts +1 -1
- package/dist/azure/embeddings.js +5 -8
- package/dist/azure/llms.cjs +4 -2
- package/dist/azure/llms.js +4 -2
- package/dist/chat_models.cjs +139 -96
- package/dist/chat_models.d.ts +1 -1
- package/dist/chat_models.js +120 -87
- package/dist/embeddings.d.ts +7 -3
- package/dist/tools/dalle.d.ts +7 -2
- package/dist/types.d.ts +6 -3
- package/dist/utils/azure.cjs +1 -2
- package/dist/utils/errors.cjs +1 -2
- package/dist/utils/headers.cjs +39 -0
- package/dist/utils/headers.d.ts +8 -0
- package/dist/utils/headers.js +35 -0
- package/dist/utils/openai-format-fndef.cjs +1 -2
- package/dist/utils/openai.cjs +4 -4
- package/dist/utils/prompts.cjs +1 -2
- package/dist/utils/tools.cjs +1 -2
- package/package.json +6 -6
|
@@ -5,6 +5,7 @@ const openai_1 = require("openai");
|
|
|
5
5
|
const env_1 = require("@langchain/core/utils/env");
|
|
6
6
|
const chat_models_js_1 = require("../chat_models.cjs");
|
|
7
7
|
const azure_js_1 = require("../utils/azure.cjs");
|
|
8
|
+
const headers_js_1 = require("../utils/headers.cjs");
|
|
8
9
|
/**
|
|
9
10
|
* Azure OpenAI chat model integration.
|
|
10
11
|
*
|
|
@@ -558,10 +559,12 @@ class AzureChatOpenAI extends chat_models_js_1.ChatOpenAI {
|
|
|
558
559
|
if (env === "node" || env === "deno") {
|
|
559
560
|
env = `(${env}/${process.version}; ${process.platform}; ${process.arch})`;
|
|
560
561
|
}
|
|
561
|
-
const
|
|
562
|
+
const defaultHeaders = (0, headers_js_1.normalizeHeaders)(params.defaultHeaders);
|
|
562
563
|
params.defaultHeaders = {
|
|
563
564
|
...params.defaultHeaders,
|
|
564
|
-
"User-Agent":
|
|
565
|
+
"User-Agent": defaultHeaders["User-Agent"]
|
|
566
|
+
? `langchainjs-azure-openai/2.0.0 (${env})${defaultHeaders["User-Agent"]}`
|
|
567
|
+
: `langchainjs-azure-openai/2.0.0 (${env})`,
|
|
565
568
|
};
|
|
566
569
|
this.client = new openai_1.AzureOpenAI({
|
|
567
570
|
apiVersion: this.azureOpenAIApiVersion,
|
|
@@ -2,6 +2,7 @@ import { AzureOpenAI as AzureOpenAIClient } from "openai";
|
|
|
2
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
|
+
import { normalizeHeaders } from "../utils/headers.js";
|
|
5
6
|
/**
|
|
6
7
|
* Azure OpenAI chat model integration.
|
|
7
8
|
*
|
|
@@ -555,10 +556,12 @@ export class AzureChatOpenAI extends ChatOpenAI {
|
|
|
555
556
|
if (env === "node" || env === "deno") {
|
|
556
557
|
env = `(${env}/${process.version}; ${process.platform}; ${process.arch})`;
|
|
557
558
|
}
|
|
558
|
-
const
|
|
559
|
+
const defaultHeaders = normalizeHeaders(params.defaultHeaders);
|
|
559
560
|
params.defaultHeaders = {
|
|
560
561
|
...params.defaultHeaders,
|
|
561
|
-
"User-Agent":
|
|
562
|
+
"User-Agent": defaultHeaders["User-Agent"]
|
|
563
|
+
? `langchainjs-azure-openai/2.0.0 (${env})${defaultHeaders["User-Agent"]}`
|
|
564
|
+
: `langchainjs-azure-openai/2.0.0 (${env})`,
|
|
562
565
|
};
|
|
563
566
|
this.client = new AzureOpenAIClient({
|
|
564
567
|
apiVersion: this.azureOpenAIApiVersion,
|
|
@@ -6,6 +6,7 @@ const env_1 = require("@langchain/core/utils/env");
|
|
|
6
6
|
const embeddings_js_1 = require("../embeddings.cjs");
|
|
7
7
|
const azure_js_1 = require("../utils/azure.cjs");
|
|
8
8
|
const openai_js_1 = require("../utils/openai.cjs");
|
|
9
|
+
const headers_js_1 = require("../utils/headers.cjs");
|
|
9
10
|
class AzureOpenAIEmbeddings extends embeddings_js_1.OpenAIEmbeddings {
|
|
10
11
|
constructor(fields) {
|
|
11
12
|
super(fields);
|
|
@@ -90,10 +91,11 @@ class AzureOpenAIEmbeddings extends embeddings_js_1.OpenAIEmbeddings {
|
|
|
90
91
|
if (!params.baseURL) {
|
|
91
92
|
delete params.baseURL;
|
|
92
93
|
}
|
|
94
|
+
const defaultHeaders = (0, headers_js_1.normalizeHeaders)(params.defaultHeaders);
|
|
93
95
|
params.defaultHeaders = {
|
|
94
96
|
...params.defaultHeaders,
|
|
95
|
-
"User-Agent":
|
|
96
|
-
? `${
|
|
97
|
+
"User-Agent": defaultHeaders["User-Agent"]
|
|
98
|
+
? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
|
|
97
99
|
: `langchainjs-azure-openai-v2`,
|
|
98
100
|
};
|
|
99
101
|
this.client = new openai_1.AzureOpenAI({
|
|
@@ -116,12 +118,7 @@ class AzureOpenAIEmbeddings extends embeddings_js_1.OpenAIEmbeddings {
|
|
|
116
118
|
}
|
|
117
119
|
return this.caller.call(async () => {
|
|
118
120
|
try {
|
|
119
|
-
const res = await this.client.embeddings.create(request,
|
|
120
|
-
// This unknown cast is required because OpenAI types seem to be incorrect here
|
|
121
|
-
// without it, we can't pass arbitrary keys via the `query` field in the options,
|
|
122
|
-
// which means we can't specify the `api-version` as required by Azure OpenAI.
|
|
123
|
-
// See https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#rest-api-versioning
|
|
124
|
-
requestOptions);
|
|
121
|
+
const res = await this.client.embeddings.create(request, requestOptions);
|
|
125
122
|
return res;
|
|
126
123
|
}
|
|
127
124
|
catch (e) {
|
|
@@ -17,6 +17,6 @@ export declare class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
|
|
|
17
17
|
openAIApiVersion?: string;
|
|
18
18
|
});
|
|
19
19
|
protected embeddingWithRetry(request: OpenAIClient.EmbeddingCreateParams): Promise<OpenAIClient.Embeddings.CreateEmbeddingResponse & {
|
|
20
|
-
_request_id?: string | null
|
|
20
|
+
_request_id?: string | null;
|
|
21
21
|
}>;
|
|
22
22
|
}
|
package/dist/azure/embeddings.js
CHANGED
|
@@ -3,6 +3,7 @@ import { getEnvironmentVariable } from "@langchain/core/utils/env";
|
|
|
3
3
|
import { OpenAIEmbeddings } from "../embeddings.js";
|
|
4
4
|
import { getEndpoint } from "../utils/azure.js";
|
|
5
5
|
import { wrapOpenAIClientError } from "../utils/openai.js";
|
|
6
|
+
import { normalizeHeaders } from "../utils/headers.js";
|
|
6
7
|
export class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
|
|
7
8
|
constructor(fields) {
|
|
8
9
|
super(fields);
|
|
@@ -87,10 +88,11 @@ export class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
|
|
|
87
88
|
if (!params.baseURL) {
|
|
88
89
|
delete params.baseURL;
|
|
89
90
|
}
|
|
91
|
+
const defaultHeaders = normalizeHeaders(params.defaultHeaders);
|
|
90
92
|
params.defaultHeaders = {
|
|
91
93
|
...params.defaultHeaders,
|
|
92
|
-
"User-Agent":
|
|
93
|
-
? `${
|
|
94
|
+
"User-Agent": defaultHeaders["User-Agent"]
|
|
95
|
+
? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
|
|
94
96
|
: `langchainjs-azure-openai-v2`,
|
|
95
97
|
};
|
|
96
98
|
this.client = new AzureOpenAIClient({
|
|
@@ -113,12 +115,7 @@ export class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
|
|
|
113
115
|
}
|
|
114
116
|
return this.caller.call(async () => {
|
|
115
117
|
try {
|
|
116
|
-
const res = await this.client.embeddings.create(request,
|
|
117
|
-
// This unknown cast is required because OpenAI types seem to be incorrect here
|
|
118
|
-
// without it, we can't pass arbitrary keys via the `query` field in the options,
|
|
119
|
-
// which means we can't specify the `api-version` as required by Azure OpenAI.
|
|
120
|
-
// See https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#rest-api-versioning
|
|
121
|
-
requestOptions);
|
|
118
|
+
const res = await this.client.embeddings.create(request, requestOptions);
|
|
122
119
|
return res;
|
|
123
120
|
}
|
|
124
121
|
catch (e) {
|
package/dist/azure/llms.cjs
CHANGED
|
@@ -5,6 +5,7 @@ const openai_1 = require("openai");
|
|
|
5
5
|
const env_1 = require("@langchain/core/utils/env");
|
|
6
6
|
const llms_js_1 = require("../llms.cjs");
|
|
7
7
|
const azure_js_1 = require("../utils/azure.cjs");
|
|
8
|
+
const headers_js_1 = require("../utils/headers.cjs");
|
|
8
9
|
class AzureOpenAI extends llms_js_1.OpenAI {
|
|
9
10
|
get lc_aliases() {
|
|
10
11
|
return {
|
|
@@ -120,10 +121,11 @@ class AzureOpenAI extends llms_js_1.OpenAI {
|
|
|
120
121
|
if (!params.baseURL) {
|
|
121
122
|
delete params.baseURL;
|
|
122
123
|
}
|
|
124
|
+
const defaultHeaders = (0, headers_js_1.normalizeHeaders)(params.defaultHeaders);
|
|
123
125
|
params.defaultHeaders = {
|
|
124
126
|
...params.defaultHeaders,
|
|
125
|
-
"User-Agent":
|
|
126
|
-
? `${
|
|
127
|
+
"User-Agent": defaultHeaders["User-Agent"]
|
|
128
|
+
? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
|
|
127
129
|
: `langchainjs-azure-openai-v2`,
|
|
128
130
|
};
|
|
129
131
|
this.client = new openai_1.AzureOpenAI({
|
package/dist/azure/llms.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AzureOpenAI as AzureOpenAIClient } from "openai";
|
|
|
2
2
|
import { getEnvironmentVariable } from "@langchain/core/utils/env";
|
|
3
3
|
import { OpenAI } from "../llms.js";
|
|
4
4
|
import { getEndpoint } from "../utils/azure.js";
|
|
5
|
+
import { normalizeHeaders } from "../utils/headers.js";
|
|
5
6
|
export class AzureOpenAI extends OpenAI {
|
|
6
7
|
get lc_aliases() {
|
|
7
8
|
return {
|
|
@@ -117,10 +118,11 @@ export class AzureOpenAI extends OpenAI {
|
|
|
117
118
|
if (!params.baseURL) {
|
|
118
119
|
delete params.baseURL;
|
|
119
120
|
}
|
|
121
|
+
const defaultHeaders = normalizeHeaders(params.defaultHeaders);
|
|
120
122
|
params.defaultHeaders = {
|
|
121
123
|
...params.defaultHeaders,
|
|
122
|
-
"User-Agent":
|
|
123
|
-
? `${
|
|
124
|
+
"User-Agent": defaultHeaders["User-Agent"]
|
|
125
|
+
? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
|
|
124
126
|
: `langchainjs-azure-openai-v2`,
|
|
125
127
|
};
|
|
126
128
|
this.client = new AzureOpenAIClient({
|
package/dist/chat_models.cjs
CHANGED
|
@@ -15,15 +15,27 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.ChatOpenAI =
|
|
36
|
+
exports.ChatOpenAI = void 0;
|
|
37
|
+
exports.messageToOpenAIRole = messageToOpenAIRole;
|
|
38
|
+
exports._convertMessagesToOpenAIParams = _convertMessagesToOpenAIParams;
|
|
27
39
|
const z4 = __importStar(require("zod/v4/core"));
|
|
28
40
|
const openai_1 = require("openai");
|
|
29
41
|
const messages_1 = require("@langchain/core/messages");
|
|
@@ -74,7 +86,6 @@ function messageToOpenAIRole(message) {
|
|
|
74
86
|
throw new Error(`Unknown message type: ${type}`);
|
|
75
87
|
}
|
|
76
88
|
}
|
|
77
|
-
exports.messageToOpenAIRole = messageToOpenAIRole;
|
|
78
89
|
const completionsApiContentBlockConverter = {
|
|
79
90
|
providerName: "ChatOpenAI",
|
|
80
91
|
fromStandardTextBlock(block) {
|
|
@@ -163,7 +174,7 @@ const completionsApiContentBlockConverter = {
|
|
|
163
174
|
return {
|
|
164
175
|
type: "file",
|
|
165
176
|
file: {
|
|
166
|
-
file_data: block.url,
|
|
177
|
+
file_data: block.url, // formatted as base64 data URL
|
|
167
178
|
...(block.metadata?.filename || block.metadata?.name
|
|
168
179
|
? {
|
|
169
180
|
filename: (block.metadata?.filename ||
|
|
@@ -255,7 +266,6 @@ function _convertMessagesToOpenAIParams(messages, model) {
|
|
|
255
266
|
return completionParam;
|
|
256
267
|
});
|
|
257
268
|
}
|
|
258
|
-
exports._convertMessagesToOpenAIParams = _convertMessagesToOpenAIParams;
|
|
259
269
|
const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
|
|
260
270
|
function _convertReasoningSummaryToOpenAIResponsesParams(reasoning) {
|
|
261
271
|
// combine summary parts that have the the same index and then remove the indexes
|
|
@@ -277,12 +287,8 @@ function _convertReasoningSummaryToOpenAIResponsesParams(reasoning) {
|
|
|
277
287
|
};
|
|
278
288
|
}
|
|
279
289
|
function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const newMessages = lastAIMessageId && lastAIMessageId.startsWith("resp_") && !zdrEnabled
|
|
283
|
-
? messages.slice(messages.indexOf(lastAIMessage) + 1)
|
|
284
|
-
: messages;
|
|
285
|
-
return newMessages.flatMap((lcMsg) => {
|
|
290
|
+
return messages.flatMap((lcMsg) => {
|
|
291
|
+
const additional_kwargs = lcMsg.additional_kwargs;
|
|
286
292
|
let role = messageToOpenAIRole(lcMsg);
|
|
287
293
|
if (role === "system" && isReasoningModel(model))
|
|
288
294
|
role = "developer";
|
|
@@ -292,7 +298,7 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
|
|
|
292
298
|
if (role === "tool") {
|
|
293
299
|
const toolMessage = lcMsg;
|
|
294
300
|
// Handle computer call output
|
|
295
|
-
if (
|
|
301
|
+
if (additional_kwargs?.type === "computer_call_output") {
|
|
296
302
|
const output = (() => {
|
|
297
303
|
if (typeof toolMessage.content === "string") {
|
|
298
304
|
return {
|
|
@@ -343,25 +349,19 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
|
|
|
343
349
|
// otherwise, try to reconstruct the response from what we have
|
|
344
350
|
const input = [];
|
|
345
351
|
// reasoning items
|
|
346
|
-
if (
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
"type" in item &&
|
|
350
|
-
item.type === "reasoning";
|
|
351
|
-
if (isReasoningItem(lcMsg.additional_kwargs.reasoning)) {
|
|
352
|
-
const reasoningItem = _convertReasoningSummaryToOpenAIResponsesParams(lcMsg.additional_kwargs.reasoning);
|
|
353
|
-
input.push(reasoningItem);
|
|
354
|
-
}
|
|
352
|
+
if (additional_kwargs?.reasoning && !zdrEnabled) {
|
|
353
|
+
const reasoningItem = _convertReasoningSummaryToOpenAIResponsesParams(additional_kwargs.reasoning);
|
|
354
|
+
input.push(reasoningItem);
|
|
355
355
|
}
|
|
356
356
|
// ai content
|
|
357
357
|
let { content } = lcMsg;
|
|
358
|
-
if (
|
|
358
|
+
if (additional_kwargs?.refusal) {
|
|
359
359
|
if (typeof content === "string") {
|
|
360
360
|
content = [{ type: "output_text", text: content, annotations: [] }];
|
|
361
361
|
}
|
|
362
362
|
content = [
|
|
363
363
|
...content,
|
|
364
|
-
{ type: "refusal", refusal:
|
|
364
|
+
{ type: "refusal", refusal: additional_kwargs.refusal },
|
|
365
365
|
];
|
|
366
366
|
}
|
|
367
367
|
input.push({
|
|
@@ -385,10 +385,7 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
|
|
|
385
385
|
return [];
|
|
386
386
|
}),
|
|
387
387
|
});
|
|
388
|
-
|
|
389
|
-
const functionCallIds =
|
|
390
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
391
|
-
lcMsg.additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY];
|
|
388
|
+
const functionCallIds = additional_kwargs?.[_FUNCTION_CALL_IDS_MAP_KEY];
|
|
392
389
|
if ((0, messages_1.isAIMessage)(lcMsg) && !!lcMsg.tool_calls?.length) {
|
|
393
390
|
input.push(...lcMsg.tool_calls.map((toolCall) => ({
|
|
394
391
|
type: "function_call",
|
|
@@ -398,44 +395,64 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
|
|
|
398
395
|
...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
|
|
399
396
|
})));
|
|
400
397
|
}
|
|
401
|
-
else if (
|
|
402
|
-
input.push(...
|
|
398
|
+
else if (additional_kwargs?.tool_calls) {
|
|
399
|
+
input.push(...additional_kwargs.tool_calls.map((toolCall) => ({
|
|
403
400
|
type: "function_call",
|
|
404
401
|
name: toolCall.function.name,
|
|
405
402
|
call_id: toolCall.id,
|
|
406
|
-
...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
|
|
407
403
|
arguments: toolCall.function.arguments,
|
|
404
|
+
...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
|
|
408
405
|
})));
|
|
409
406
|
}
|
|
410
407
|
const toolOutputs = lcMsg.response_metadata.output?.length
|
|
411
408
|
? lcMsg.response_metadata.output
|
|
412
|
-
:
|
|
413
|
-
|
|
409
|
+
: additional_kwargs.tool_outputs;
|
|
410
|
+
const fallthroughCallTypes = [
|
|
411
|
+
"computer_call",
|
|
412
|
+
"mcp_call",
|
|
413
|
+
"code_interpreter_call",
|
|
414
|
+
"image_generation_call",
|
|
415
|
+
];
|
|
414
416
|
if (toolOutputs != null) {
|
|
415
417
|
const castToolOutputs = toolOutputs;
|
|
416
|
-
|
|
417
|
-
if (
|
|
418
|
-
input.push(...
|
|
418
|
+
const fallthroughCalls = castToolOutputs?.filter((item) => fallthroughCallTypes.includes(item.type));
|
|
419
|
+
if (fallthroughCalls.length > 0)
|
|
420
|
+
input.push(...fallthroughCalls);
|
|
419
421
|
}
|
|
420
422
|
return input;
|
|
421
423
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
424
|
+
if (role === "user" || role === "system" || role === "developer") {
|
|
425
|
+
if (typeof lcMsg.content === "string") {
|
|
426
|
+
return { type: "message", role, content: lcMsg.content };
|
|
427
|
+
}
|
|
428
|
+
const messages = [];
|
|
429
|
+
const content = lcMsg.content.flatMap((item) => {
|
|
430
|
+
if (item.type === "mcp_approval_response") {
|
|
431
|
+
messages.push({
|
|
432
|
+
type: "mcp_approval_response",
|
|
433
|
+
approval_request_id: item.approval_request_id,
|
|
434
|
+
approve: item.approve,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
425
437
|
if ((0, messages_1.isDataContentBlock)(item)) {
|
|
426
438
|
return (0, messages_1.convertToProviderContentBlock)(item, completionsApiContentBlockConverter);
|
|
427
439
|
}
|
|
428
440
|
if (item.type === "text") {
|
|
429
|
-
return {
|
|
441
|
+
return {
|
|
442
|
+
type: "input_text",
|
|
443
|
+
text: item.text,
|
|
444
|
+
};
|
|
430
445
|
}
|
|
431
446
|
if (item.type === "image_url") {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
: item.image_url
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
: item.image_url
|
|
438
|
-
|
|
447
|
+
return {
|
|
448
|
+
type: "input_image",
|
|
449
|
+
image_url: typeof item.image_url === "string"
|
|
450
|
+
? item.image_url
|
|
451
|
+
: item.image_url.url,
|
|
452
|
+
detail: typeof item.image_url === "string"
|
|
453
|
+
? "auto"
|
|
454
|
+
: item.image_url.detail,
|
|
455
|
+
};
|
|
439
456
|
}
|
|
440
457
|
if (item.type === "input_text" ||
|
|
441
458
|
item.type === "input_image" ||
|
|
@@ -444,8 +461,10 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
|
|
|
444
461
|
}
|
|
445
462
|
return [];
|
|
446
463
|
});
|
|
447
|
-
|
|
448
|
-
|
|
464
|
+
if (content.length > 0) {
|
|
465
|
+
messages.push({ type: "message", role, content });
|
|
466
|
+
}
|
|
467
|
+
return messages;
|
|
449
468
|
}
|
|
450
469
|
console.warn(`Unsupported role found when converting to OpenAI Responses API: ${role}`);
|
|
451
470
|
return [];
|
|
@@ -552,7 +571,7 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
|
|
|
552
571
|
index: chunk.content_index,
|
|
553
572
|
});
|
|
554
573
|
}
|
|
555
|
-
else if (chunk.type === "response.
|
|
574
|
+
else if (chunk.type === "response.output_text_annotation.added") {
|
|
556
575
|
content.push({
|
|
557
576
|
type: "text",
|
|
558
577
|
text: "",
|
|
@@ -578,9 +597,16 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
|
|
|
578
597
|
};
|
|
579
598
|
}
|
|
580
599
|
else if (chunk.type === "response.output_item.done" &&
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
600
|
+
[
|
|
601
|
+
"web_search_call",
|
|
602
|
+
"file_search_call",
|
|
603
|
+
"computer_call",
|
|
604
|
+
"code_interpreter_call",
|
|
605
|
+
"mcp_call",
|
|
606
|
+
"mcp_list_tools",
|
|
607
|
+
"mcp_approval_request",
|
|
608
|
+
"image_generation_call",
|
|
609
|
+
].includes(chunk.item.type)) {
|
|
584
610
|
additional_kwargs.tool_outputs = [chunk.item];
|
|
585
611
|
}
|
|
586
612
|
else if (chunk.type === "response.created") {
|
|
@@ -652,6 +678,11 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
|
|
|
652
678
|
],
|
|
653
679
|
};
|
|
654
680
|
}
|
|
681
|
+
else if (chunk.type === "response.image_generation_call.partial_image") {
|
|
682
|
+
// noop/fixme: retaining partial images in a message chunk means that _all_
|
|
683
|
+
// partial images get kept in history, so we don't do anything here.
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
655
686
|
else {
|
|
656
687
|
return null;
|
|
657
688
|
}
|
|
@@ -678,6 +709,29 @@ function isBuiltInToolChoice(tool_choice) {
|
|
|
678
709
|
"type" in tool_choice &&
|
|
679
710
|
tool_choice.type !== "function");
|
|
680
711
|
}
|
|
712
|
+
function _reduceChatOpenAIToolsForResponses(tools, fields) {
|
|
713
|
+
const reducedTools = [];
|
|
714
|
+
for (const tool of tools) {
|
|
715
|
+
if (isBuiltInTool(tool)) {
|
|
716
|
+
if (tool.type === "image_generation" && fields?.stream) {
|
|
717
|
+
// OpenAI sends a 400 error if partial_images is not set and we want to stream.
|
|
718
|
+
// We also set it to 1 since we don't support partial images yet.
|
|
719
|
+
tool.partial_images = 1;
|
|
720
|
+
}
|
|
721
|
+
reducedTools.push(tool);
|
|
722
|
+
}
|
|
723
|
+
else if ((0, base_1.isOpenAITool)(tool)) {
|
|
724
|
+
reducedTools.push({
|
|
725
|
+
type: "function",
|
|
726
|
+
name: tool.function.name,
|
|
727
|
+
parameters: tool.function.parameters,
|
|
728
|
+
description: tool.function.description,
|
|
729
|
+
strict: fields?.strict ?? null,
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return reducedTools;
|
|
734
|
+
}
|
|
681
735
|
function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
|
|
682
736
|
if ((0, base_1.isOpenAITool)(tool)) {
|
|
683
737
|
if (fields?.strict !== undefined) {
|
|
@@ -1671,25 +1725,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1671
1725
|
truncation: options?.truncation,
|
|
1672
1726
|
include: options?.include,
|
|
1673
1727
|
tools: options?.tools?.length
|
|
1674
|
-
? options.tools
|
|
1675
|
-
.
|
|
1676
|
-
|
|
1677
|
-
return tool;
|
|
1678
|
-
}
|
|
1679
|
-
else if ((0, base_1.isOpenAITool)(tool)) {
|
|
1680
|
-
return {
|
|
1681
|
-
type: "function",
|
|
1682
|
-
name: tool.function.name,
|
|
1683
|
-
parameters: tool.function.parameters,
|
|
1684
|
-
description: tool.function.description,
|
|
1685
|
-
strict,
|
|
1686
|
-
};
|
|
1687
|
-
}
|
|
1688
|
-
else {
|
|
1689
|
-
return null;
|
|
1690
|
-
}
|
|
1728
|
+
? _reduceChatOpenAIToolsForResponses(options.tools, {
|
|
1729
|
+
stream: this.streaming,
|
|
1730
|
+
strict,
|
|
1691
1731
|
})
|
|
1692
|
-
.filter((tool) => tool !== null)
|
|
1693
1732
|
: undefined,
|
|
1694
1733
|
tool_choice: isBuiltInToolChoice(options?.tool_choice)
|
|
1695
1734
|
? options?.tool_choice
|
|
@@ -1932,17 +1971,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1932
1971
|
}
|
|
1933
1972
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
1934
1973
|
if (this._useResponseApi(options)) {
|
|
1935
|
-
const lastAIMessage = messages.filter((m) => (0, messages_1.isAIMessage)(m)).pop();
|
|
1936
|
-
const lastAIMessageId = lastAIMessage?.response_metadata?.id;
|
|
1937
1974
|
const streamIterable = await this.responseApiWithRetry({
|
|
1938
1975
|
...this.invocationParams(options, { streaming: true }),
|
|
1939
1976
|
input: _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled),
|
|
1940
1977
|
stream: true,
|
|
1941
|
-
...(lastAIMessageId &&
|
|
1942
|
-
lastAIMessageId.startsWith("resp_") &&
|
|
1943
|
-
!this.zdrEnabled
|
|
1944
|
-
? { previous_response_id: lastAIMessageId }
|
|
1945
|
-
: {}),
|
|
1946
1978
|
}, options);
|
|
1947
1979
|
for await (const data of streamIterable) {
|
|
1948
1980
|
const chunk = _convertOpenAIResponsesDeltaToBaseMessageChunk(data);
|
|
@@ -2076,17 +2108,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2076
2108
|
},
|
|
2077
2109
|
};
|
|
2078
2110
|
}
|
|
2079
|
-
const lastAIMessage = messages.filter((m) => (0, messages_1.isAIMessage)(m)).pop();
|
|
2080
|
-
const lastAIMessageId = lastAIMessage?.response_metadata?.id;
|
|
2081
2111
|
const input = _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled);
|
|
2082
2112
|
const data = await this.responseApiWithRetry({
|
|
2083
2113
|
input,
|
|
2084
2114
|
...invocationParams,
|
|
2085
|
-
...(lastAIMessageId &&
|
|
2086
|
-
lastAIMessageId.startsWith("resp_") &&
|
|
2087
|
-
!this.zdrEnabled
|
|
2088
|
-
? { previous_response_id: lastAIMessageId }
|
|
2089
|
-
: {}),
|
|
2090
2115
|
}, { signal: options?.signal, ...options?.options });
|
|
2091
2116
|
return {
|
|
2092
2117
|
generations: [
|
|
@@ -2396,7 +2421,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2396
2421
|
const requestOptions = this._getClientOptions(options);
|
|
2397
2422
|
return this.caller.call(async () => {
|
|
2398
2423
|
try {
|
|
2399
|
-
const res = await this.client.
|
|
2424
|
+
const res = await this.client.chat.completions.parse(request, requestOptions);
|
|
2400
2425
|
return res;
|
|
2401
2426
|
}
|
|
2402
2427
|
catch (e) {
|
|
@@ -2483,15 +2508,21 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2483
2508
|
console.warn(`[WARNING]: JSON Schema is not supported for model "${this.model}". Falling back to tool calling.`);
|
|
2484
2509
|
}
|
|
2485
2510
|
if (method === "jsonMode") {
|
|
2486
|
-
|
|
2487
|
-
response_format: { type: "json_object" },
|
|
2488
|
-
});
|
|
2511
|
+
let outputFormatSchema;
|
|
2489
2512
|
if ((0, types_1.isInteropZodSchema)(schema)) {
|
|
2490
2513
|
outputParser = output_parsers_1.StructuredOutputParser.fromZodSchema(schema);
|
|
2514
|
+
outputFormatSchema = (0, json_schema_1.toJsonSchema)(schema);
|
|
2491
2515
|
}
|
|
2492
2516
|
else {
|
|
2493
2517
|
outputParser = new output_parsers_1.JsonOutputParser();
|
|
2494
2518
|
}
|
|
2519
|
+
llm = this.withConfig({
|
|
2520
|
+
response_format: { type: "json_object" },
|
|
2521
|
+
ls_structured_output_format: {
|
|
2522
|
+
kwargs: { method: "jsonMode" },
|
|
2523
|
+
schema: outputFormatSchema,
|
|
2524
|
+
},
|
|
2525
|
+
});
|
|
2495
2526
|
}
|
|
2496
2527
|
else if (method === "jsonSchema") {
|
|
2497
2528
|
llm = this.withConfig({
|
|
@@ -2504,6 +2535,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2504
2535
|
strict: config?.strict,
|
|
2505
2536
|
},
|
|
2506
2537
|
},
|
|
2538
|
+
ls_structured_output_format: {
|
|
2539
|
+
kwargs: { method: "jsonSchema" },
|
|
2540
|
+
schema: (0, json_schema_1.toJsonSchema)(schema),
|
|
2541
|
+
},
|
|
2507
2542
|
});
|
|
2508
2543
|
if ((0, types_1.isInteropZodSchema)(schema)) {
|
|
2509
2544
|
const altParser = output_parsers_1.StructuredOutputParser.fromZodSchema(schema);
|
|
@@ -2540,6 +2575,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2540
2575
|
name: functionName,
|
|
2541
2576
|
},
|
|
2542
2577
|
},
|
|
2578
|
+
ls_structured_output_format: {
|
|
2579
|
+
kwargs: { method: "functionCalling" },
|
|
2580
|
+
schema: asJsonSchema,
|
|
2581
|
+
},
|
|
2543
2582
|
// Do not pass `strict` argument to OpenAI if `config.strict` is undefined
|
|
2544
2583
|
...(config?.strict !== undefined ? { strict: config.strict } : {}),
|
|
2545
2584
|
});
|
|
@@ -2578,6 +2617,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2578
2617
|
name: functionName,
|
|
2579
2618
|
},
|
|
2580
2619
|
},
|
|
2620
|
+
ls_structured_output_format: {
|
|
2621
|
+
kwargs: { method: "functionCalling" },
|
|
2622
|
+
schema: (0, json_schema_1.toJsonSchema)(schema),
|
|
2623
|
+
},
|
|
2581
2624
|
// Do not pass `strict` argument to OpenAI if `config.strict` is undefined
|
|
2582
2625
|
...(config?.strict !== undefined ? { strict: config.strict } : {}),
|
|
2583
2626
|
});
|
|
@@ -2639,8 +2682,8 @@ function interopZodResponseFormat(zodSchema, name, props) {
|
|
|
2639
2682
|
name,
|
|
2640
2683
|
strict: true,
|
|
2641
2684
|
schema: z4.toJSONSchema(zodSchema, {
|
|
2642
|
-
cycles: "ref",
|
|
2643
|
-
reused: "ref",
|
|
2685
|
+
cycles: "ref", // equivalent to nameStrategy: 'duplicate-ref'
|
|
2686
|
+
reused: "ref", // equivalent to $refStrategy: 'extract-to-root'
|
|
2644
2687
|
override(ctx) {
|
|
2645
2688
|
ctx.jsonSchema.title = name; // equivalent to `name` property
|
|
2646
2689
|
// TODO: implement `nullableStrategy` patch-fix (zod doesn't support openApi3 json schema target)
|
package/dist/chat_models.d.ts
CHANGED
|
@@ -841,7 +841,7 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
|
|
|
841
841
|
* @param {OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming} request
|
|
842
842
|
* @param {OpenAICoreRequestOptions | undefined} options
|
|
843
843
|
*/
|
|
844
|
-
betaParsedCompletionWithRetry(request: OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming, options?: OpenAICoreRequestOptions): Promise<ReturnType<OpenAIClient["
|
|
844
|
+
betaParsedCompletionWithRetry(request: OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming, options?: OpenAICoreRequestOptions): Promise<ReturnType<OpenAIClient["chat"]["completions"]["parse"]>>;
|
|
845
845
|
protected _getClientOptions(options: OpenAICoreRequestOptions | undefined): OpenAICoreRequestOptions;
|
|
846
846
|
_llmType(): string;
|
|
847
847
|
/** @ignore */
|