@langchain/openai 0.4.5-rc.0 → 0.4.6
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/chat_models.cjs +51 -11
- package/dist/chat_models.js +52 -12
- package/package.json +1 -1
package/dist/chat_models.cjs
CHANGED
|
@@ -108,6 +108,27 @@ function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
|
108
108
|
}
|
|
109
109
|
if (role === "tool") {
|
|
110
110
|
const toolMessage = lcMsg;
|
|
111
|
+
// Handle computer call output
|
|
112
|
+
if (toolMessage.additional_kwargs?.type === "computer_call_output") {
|
|
113
|
+
const output = (() => {
|
|
114
|
+
if (typeof toolMessage.content === "string") {
|
|
115
|
+
return {
|
|
116
|
+
type: "computer_screenshot",
|
|
117
|
+
image_url: toolMessage.content,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (Array.isArray(toolMessage.content)) {
|
|
121
|
+
return toolMessage.content.find((i) => i.type === "computer_screenshot");
|
|
122
|
+
}
|
|
123
|
+
return toolMessage.content;
|
|
124
|
+
})();
|
|
125
|
+
return {
|
|
126
|
+
type: "computer_call_output",
|
|
127
|
+
output,
|
|
128
|
+
call_id: toolMessage.tool_call_id,
|
|
129
|
+
id: toolMessage.id,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
111
132
|
return {
|
|
112
133
|
type: "function_call_output",
|
|
113
134
|
call_id: toolMessage.tool_call_id,
|
|
@@ -127,7 +148,8 @@ function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
|
127
148
|
name: toolCall.name,
|
|
128
149
|
arguments: JSON.stringify(toolCall.args),
|
|
129
150
|
call_id: toolCall.id,
|
|
130
|
-
|
|
151
|
+
// @ts-expect-error Might come from a non-Responses API message
|
|
152
|
+
id: functionCallIds?.[toolCall.id],
|
|
131
153
|
}));
|
|
132
154
|
}
|
|
133
155
|
if (lcMsg.additional_kwargs.tool_calls != null) {
|
|
@@ -135,7 +157,8 @@ function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
|
135
157
|
type: "function_call",
|
|
136
158
|
name: toolCall.function.name,
|
|
137
159
|
call_id: toolCall.id,
|
|
138
|
-
|
|
160
|
+
// @ts-expect-error Might come from a non-Responses API message
|
|
161
|
+
id: functionCallIds?.[toolCall.id],
|
|
139
162
|
arguments: toolCall.function.arguments,
|
|
140
163
|
}));
|
|
141
164
|
}
|
|
@@ -229,6 +252,9 @@ function _convertOpenAIResponsesMessageToBaseMessage(response) {
|
|
|
229
252
|
// TODO: how to handle refusals?
|
|
230
253
|
content.push(...item.content.map((part) => {
|
|
231
254
|
if (part.type === "output_text") {
|
|
255
|
+
if ("parsed" in part && part.parsed != null) {
|
|
256
|
+
additional_kwargs.parsed = part.parsed;
|
|
257
|
+
}
|
|
232
258
|
return {
|
|
233
259
|
type: "text",
|
|
234
260
|
text: part.text,
|
|
@@ -256,6 +282,8 @@ function _convertOpenAIResponsesMessageToBaseMessage(response) {
|
|
|
256
282
|
}
|
|
257
283
|
invalid_tool_calls.push((0, openai_tools_1.makeInvalidToolCall)(fnAdapter, errMessage));
|
|
258
284
|
}
|
|
285
|
+
additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY] ??= {};
|
|
286
|
+
additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY][item.call_id] = item.id;
|
|
259
287
|
}
|
|
260
288
|
else if (item.type === "reasoning") {
|
|
261
289
|
additional_kwargs.reasoning = item;
|
|
@@ -326,7 +354,15 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
|
|
|
326
354
|
response_metadata.model = chunk.response.model;
|
|
327
355
|
}
|
|
328
356
|
else if (chunk.type === "response.completed") {
|
|
357
|
+
const msg = _convertOpenAIResponsesMessageToBaseMessage(chunk.response);
|
|
329
358
|
usage_metadata = chunk.response.usage;
|
|
359
|
+
if (chunk.response.text?.format?.type === "json_schema") {
|
|
360
|
+
additional_kwargs.parsed ??= JSON.parse(msg.text);
|
|
361
|
+
}
|
|
362
|
+
for (const [key, value] of Object.entries(chunk.response)) {
|
|
363
|
+
if (key !== "id")
|
|
364
|
+
response_metadata[key] = value;
|
|
365
|
+
}
|
|
330
366
|
}
|
|
331
367
|
else if (chunk.type === "response.function_call_arguments.delta") {
|
|
332
368
|
tool_call_chunks.push({
|
|
@@ -1966,8 +2002,11 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1966
2002
|
return this.caller.call(async () => {
|
|
1967
2003
|
const requestOptions = this._getClientOptions(options);
|
|
1968
2004
|
try {
|
|
1969
|
-
|
|
1970
|
-
|
|
2005
|
+
// use parse if dealing with json_schema
|
|
2006
|
+
if (request.text?.format?.type === "json_schema" && !request.stream) {
|
|
2007
|
+
return await this.client.responses.parse(request, requestOptions);
|
|
2008
|
+
}
|
|
2009
|
+
return await this.client.responses.create(request, requestOptions);
|
|
1971
2010
|
}
|
|
1972
2011
|
catch (e) {
|
|
1973
2012
|
const error = (0, openai_js_1.wrapOpenAIClientError)(e);
|
|
@@ -2097,7 +2136,13 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2097
2136
|
},
|
|
2098
2137
|
});
|
|
2099
2138
|
if (isZodSchema(schema)) {
|
|
2100
|
-
|
|
2139
|
+
const altParser = output_parsers_1.StructuredOutputParser.fromZodSchema(schema);
|
|
2140
|
+
outputParser = runnables_1.RunnableLambda.from((aiMessage) => {
|
|
2141
|
+
if ("parsed" in aiMessage.additional_kwargs) {
|
|
2142
|
+
return aiMessage.additional_kwargs.parsed;
|
|
2143
|
+
}
|
|
2144
|
+
return altParser;
|
|
2145
|
+
});
|
|
2101
2146
|
}
|
|
2102
2147
|
else {
|
|
2103
2148
|
outputParser = new output_parsers_1.JsonOutputParser();
|
|
@@ -2185,12 +2230,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
2185
2230
|
const parsedWithFallback = parserAssign.withFallbacks({
|
|
2186
2231
|
fallbacks: [parserNone],
|
|
2187
2232
|
});
|
|
2188
|
-
return runnables_1.RunnableSequence.from([
|
|
2189
|
-
{
|
|
2190
|
-
raw: llm,
|
|
2191
|
-
},
|
|
2192
|
-
parsedWithFallback,
|
|
2193
|
-
]);
|
|
2233
|
+
return runnables_1.RunnableSequence.from([{ raw: llm }, parsedWithFallback]);
|
|
2194
2234
|
}
|
|
2195
2235
|
}
|
|
2196
2236
|
exports.ChatOpenAI = ChatOpenAI;
|
package/dist/chat_models.js
CHANGED
|
@@ -4,7 +4,7 @@ import { ChatGenerationChunk, } from "@langchain/core/outputs";
|
|
|
4
4
|
import { getEnvironmentVariable } from "@langchain/core/utils/env";
|
|
5
5
|
import { BaseChatModel, } from "@langchain/core/language_models/chat_models";
|
|
6
6
|
import { isOpenAITool, } from "@langchain/core/language_models/base";
|
|
7
|
-
import { RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnables";
|
|
7
|
+
import { RunnableLambda, RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnables";
|
|
8
8
|
import { JsonOutputParser, StructuredOutputParser, } from "@langchain/core/output_parsers";
|
|
9
9
|
import { JsonOutputKeyToolsParser, convertLangChainToolCallToOpenAI, makeInvalidToolCall, parseToolCall, } from "@langchain/core/output_parsers/openai_tools";
|
|
10
10
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
@@ -103,6 +103,27 @@ function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
|
103
103
|
}
|
|
104
104
|
if (role === "tool") {
|
|
105
105
|
const toolMessage = lcMsg;
|
|
106
|
+
// Handle computer call output
|
|
107
|
+
if (toolMessage.additional_kwargs?.type === "computer_call_output") {
|
|
108
|
+
const output = (() => {
|
|
109
|
+
if (typeof toolMessage.content === "string") {
|
|
110
|
+
return {
|
|
111
|
+
type: "computer_screenshot",
|
|
112
|
+
image_url: toolMessage.content,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(toolMessage.content)) {
|
|
116
|
+
return toolMessage.content.find((i) => i.type === "computer_screenshot");
|
|
117
|
+
}
|
|
118
|
+
return toolMessage.content;
|
|
119
|
+
})();
|
|
120
|
+
return {
|
|
121
|
+
type: "computer_call_output",
|
|
122
|
+
output,
|
|
123
|
+
call_id: toolMessage.tool_call_id,
|
|
124
|
+
id: toolMessage.id,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
106
127
|
return {
|
|
107
128
|
type: "function_call_output",
|
|
108
129
|
call_id: toolMessage.tool_call_id,
|
|
@@ -122,7 +143,8 @@ function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
|
122
143
|
name: toolCall.name,
|
|
123
144
|
arguments: JSON.stringify(toolCall.args),
|
|
124
145
|
call_id: toolCall.id,
|
|
125
|
-
|
|
146
|
+
// @ts-expect-error Might come from a non-Responses API message
|
|
147
|
+
id: functionCallIds?.[toolCall.id],
|
|
126
148
|
}));
|
|
127
149
|
}
|
|
128
150
|
if (lcMsg.additional_kwargs.tool_calls != null) {
|
|
@@ -130,7 +152,8 @@ function _convertMessagesToOpenAIResponsesParams(messages, model) {
|
|
|
130
152
|
type: "function_call",
|
|
131
153
|
name: toolCall.function.name,
|
|
132
154
|
call_id: toolCall.id,
|
|
133
|
-
|
|
155
|
+
// @ts-expect-error Might come from a non-Responses API message
|
|
156
|
+
id: functionCallIds?.[toolCall.id],
|
|
134
157
|
arguments: toolCall.function.arguments,
|
|
135
158
|
}));
|
|
136
159
|
}
|
|
@@ -224,6 +247,9 @@ function _convertOpenAIResponsesMessageToBaseMessage(response) {
|
|
|
224
247
|
// TODO: how to handle refusals?
|
|
225
248
|
content.push(...item.content.map((part) => {
|
|
226
249
|
if (part.type === "output_text") {
|
|
250
|
+
if ("parsed" in part && part.parsed != null) {
|
|
251
|
+
additional_kwargs.parsed = part.parsed;
|
|
252
|
+
}
|
|
227
253
|
return {
|
|
228
254
|
type: "text",
|
|
229
255
|
text: part.text,
|
|
@@ -251,6 +277,8 @@ function _convertOpenAIResponsesMessageToBaseMessage(response) {
|
|
|
251
277
|
}
|
|
252
278
|
invalid_tool_calls.push(makeInvalidToolCall(fnAdapter, errMessage));
|
|
253
279
|
}
|
|
280
|
+
additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY] ??= {};
|
|
281
|
+
additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY][item.call_id] = item.id;
|
|
254
282
|
}
|
|
255
283
|
else if (item.type === "reasoning") {
|
|
256
284
|
additional_kwargs.reasoning = item;
|
|
@@ -321,7 +349,15 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
|
|
|
321
349
|
response_metadata.model = chunk.response.model;
|
|
322
350
|
}
|
|
323
351
|
else if (chunk.type === "response.completed") {
|
|
352
|
+
const msg = _convertOpenAIResponsesMessageToBaseMessage(chunk.response);
|
|
324
353
|
usage_metadata = chunk.response.usage;
|
|
354
|
+
if (chunk.response.text?.format?.type === "json_schema") {
|
|
355
|
+
additional_kwargs.parsed ??= JSON.parse(msg.text);
|
|
356
|
+
}
|
|
357
|
+
for (const [key, value] of Object.entries(chunk.response)) {
|
|
358
|
+
if (key !== "id")
|
|
359
|
+
response_metadata[key] = value;
|
|
360
|
+
}
|
|
325
361
|
}
|
|
326
362
|
else if (chunk.type === "response.function_call_arguments.delta") {
|
|
327
363
|
tool_call_chunks.push({
|
|
@@ -1961,8 +1997,11 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1961
1997
|
return this.caller.call(async () => {
|
|
1962
1998
|
const requestOptions = this._getClientOptions(options);
|
|
1963
1999
|
try {
|
|
1964
|
-
|
|
1965
|
-
|
|
2000
|
+
// use parse if dealing with json_schema
|
|
2001
|
+
if (request.text?.format?.type === "json_schema" && !request.stream) {
|
|
2002
|
+
return await this.client.responses.parse(request, requestOptions);
|
|
2003
|
+
}
|
|
2004
|
+
return await this.client.responses.create(request, requestOptions);
|
|
1966
2005
|
}
|
|
1967
2006
|
catch (e) {
|
|
1968
2007
|
const error = wrapOpenAIClientError(e);
|
|
@@ -2092,7 +2131,13 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
2092
2131
|
},
|
|
2093
2132
|
});
|
|
2094
2133
|
if (isZodSchema(schema)) {
|
|
2095
|
-
|
|
2134
|
+
const altParser = StructuredOutputParser.fromZodSchema(schema);
|
|
2135
|
+
outputParser = RunnableLambda.from((aiMessage) => {
|
|
2136
|
+
if ("parsed" in aiMessage.additional_kwargs) {
|
|
2137
|
+
return aiMessage.additional_kwargs.parsed;
|
|
2138
|
+
}
|
|
2139
|
+
return altParser;
|
|
2140
|
+
});
|
|
2096
2141
|
}
|
|
2097
2142
|
else {
|
|
2098
2143
|
outputParser = new JsonOutputParser();
|
|
@@ -2180,12 +2225,7 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
2180
2225
|
const parsedWithFallback = parserAssign.withFallbacks({
|
|
2181
2226
|
fallbacks: [parserNone],
|
|
2182
2227
|
});
|
|
2183
|
-
return RunnableSequence.from([
|
|
2184
|
-
{
|
|
2185
|
-
raw: llm,
|
|
2186
|
-
},
|
|
2187
|
-
parsedWithFallback,
|
|
2188
|
-
]);
|
|
2228
|
+
return RunnableSequence.from([{ raw: llm }, parsedWithFallback]);
|
|
2189
2229
|
}
|
|
2190
2230
|
}
|
|
2191
2231
|
function isZodSchema(
|