@langchain/openai 0.6.11 → 0.6.12
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 +8 -5
- package/dist/chat_models.js +8 -5
- package/dist/embeddings.cjs +13 -0
- package/dist/embeddings.d.ts +8 -3
- package/dist/embeddings.js +13 -0
- package/dist/utils/output.cjs +30 -0
- package/dist/utils/output.d.ts +9 -0
- package/dist/utils/output.js +27 -0
- package/package.json +1 -1
package/dist/chat_models.cjs
CHANGED
|
@@ -18,6 +18,7 @@ const azure_js_1 = require("./utils/azure.cjs");
|
|
|
18
18
|
const openai_js_1 = require("./utils/openai.cjs");
|
|
19
19
|
const openai_format_fndef_js_1 = require("./utils/openai-format-fndef.cjs");
|
|
20
20
|
const tools_js_1 = require("./utils/tools.cjs");
|
|
21
|
+
const output_js_1 = require("./utils/output.cjs");
|
|
21
22
|
const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
|
|
22
23
|
function isReasoningModel(model) {
|
|
23
24
|
if (!model)
|
|
@@ -608,14 +609,14 @@ class BaseChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
608
609
|
? { effort: fields.reasoningEffort }
|
|
609
610
|
: undefined;
|
|
610
611
|
this.maxTokens = fields?.maxCompletionTokens ?? fields?.maxTokens;
|
|
611
|
-
this.disableStreaming = fields?.disableStreaming
|
|
612
|
+
this.disableStreaming = fields?.disableStreaming === true;
|
|
613
|
+
this.streaming = fields?.streaming === true;
|
|
612
614
|
this.promptCacheKey = fields?.promptCacheKey ?? this.promptCacheKey;
|
|
613
615
|
this.verbosity = fields?.verbosity ?? this.verbosity;
|
|
614
|
-
this.streaming = fields?.streaming ?? false;
|
|
615
616
|
// disable streaming in BaseChatModel if explicitly disabled
|
|
616
617
|
if (this.streaming === false)
|
|
617
618
|
this.disableStreaming = true;
|
|
618
|
-
if (this.disableStreaming)
|
|
619
|
+
if (this.disableStreaming === true)
|
|
619
620
|
this.streaming = false;
|
|
620
621
|
this.streamUsage = fields?.streamUsage ?? this.streamUsage;
|
|
621
622
|
if (this.disableStreaming)
|
|
@@ -1374,7 +1375,8 @@ class ChatOpenAIResponses extends BaseChatOpenAI {
|
|
|
1374
1375
|
response_metadata[key] = value;
|
|
1375
1376
|
}
|
|
1376
1377
|
}
|
|
1377
|
-
else if (chunk.type === "response.function_call_arguments.delta"
|
|
1378
|
+
else if (chunk.type === "response.function_call_arguments.delta" ||
|
|
1379
|
+
chunk.type === "response.custom_tool_call_input.delta") {
|
|
1378
1380
|
tool_call_chunks.push({
|
|
1379
1381
|
type: "tool_call_chunk",
|
|
1380
1382
|
args: chunk.delta,
|
|
@@ -2062,8 +2064,9 @@ class ChatOpenAICompletions extends BaseChatOpenAI {
|
|
|
2062
2064
|
if (message.audio) {
|
|
2063
2065
|
additional_kwargs.audio = message.audio;
|
|
2064
2066
|
}
|
|
2067
|
+
const content = (0, output_js_1.handleMultiModalOutput)(message.content || "", rawResponse.choices?.[0]?.message);
|
|
2065
2068
|
return new messages_1.AIMessage({
|
|
2066
|
-
content
|
|
2069
|
+
content,
|
|
2067
2070
|
tool_calls: toolCalls,
|
|
2068
2071
|
invalid_tool_calls: invalidToolCalls,
|
|
2069
2072
|
additional_kwargs,
|
package/dist/chat_models.js
CHANGED
|
@@ -13,6 +13,7 @@ import { getEndpoint } from "./utils/azure.js";
|
|
|
13
13
|
import { formatToOpenAIToolChoice, interopZodResponseFormat, wrapOpenAIClientError, } from "./utils/openai.js";
|
|
14
14
|
import { formatFunctionDefinitions, } from "./utils/openai-format-fndef.js";
|
|
15
15
|
import { _convertToOpenAITool, convertCompletionsCustomTool, convertResponsesCustomTool, isBuiltInTool, isBuiltInToolChoice, isCustomTool, isCustomToolCall, isOpenAICustomTool, parseCustomToolCall, } from "./utils/tools.js";
|
|
16
|
+
import { handleMultiModalOutput } from "./utils/output.js";
|
|
16
17
|
const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
|
|
17
18
|
function isReasoningModel(model) {
|
|
18
19
|
if (!model)
|
|
@@ -603,14 +604,14 @@ export class BaseChatOpenAI extends BaseChatModel {
|
|
|
603
604
|
? { effort: fields.reasoningEffort }
|
|
604
605
|
: undefined;
|
|
605
606
|
this.maxTokens = fields?.maxCompletionTokens ?? fields?.maxTokens;
|
|
606
|
-
this.disableStreaming = fields?.disableStreaming
|
|
607
|
+
this.disableStreaming = fields?.disableStreaming === true;
|
|
608
|
+
this.streaming = fields?.streaming === true;
|
|
607
609
|
this.promptCacheKey = fields?.promptCacheKey ?? this.promptCacheKey;
|
|
608
610
|
this.verbosity = fields?.verbosity ?? this.verbosity;
|
|
609
|
-
this.streaming = fields?.streaming ?? false;
|
|
610
611
|
// disable streaming in BaseChatModel if explicitly disabled
|
|
611
612
|
if (this.streaming === false)
|
|
612
613
|
this.disableStreaming = true;
|
|
613
|
-
if (this.disableStreaming)
|
|
614
|
+
if (this.disableStreaming === true)
|
|
614
615
|
this.streaming = false;
|
|
615
616
|
this.streamUsage = fields?.streamUsage ?? this.streamUsage;
|
|
616
617
|
if (this.disableStreaming)
|
|
@@ -1368,7 +1369,8 @@ export class ChatOpenAIResponses extends BaseChatOpenAI {
|
|
|
1368
1369
|
response_metadata[key] = value;
|
|
1369
1370
|
}
|
|
1370
1371
|
}
|
|
1371
|
-
else if (chunk.type === "response.function_call_arguments.delta"
|
|
1372
|
+
else if (chunk.type === "response.function_call_arguments.delta" ||
|
|
1373
|
+
chunk.type === "response.custom_tool_call_input.delta") {
|
|
1372
1374
|
tool_call_chunks.push({
|
|
1373
1375
|
type: "tool_call_chunk",
|
|
1374
1376
|
args: chunk.delta,
|
|
@@ -2055,8 +2057,9 @@ export class ChatOpenAICompletions extends BaseChatOpenAI {
|
|
|
2055
2057
|
if (message.audio) {
|
|
2056
2058
|
additional_kwargs.audio = message.audio;
|
|
2057
2059
|
}
|
|
2060
|
+
const content = handleMultiModalOutput(message.content || "", rawResponse.choices?.[0]?.message);
|
|
2058
2061
|
return new AIMessage({
|
|
2059
|
-
content
|
|
2062
|
+
content,
|
|
2060
2063
|
tool_calls: toolCalls,
|
|
2061
2064
|
invalid_tool_calls: invalidToolCalls,
|
|
2062
2065
|
additional_kwargs,
|
package/dist/embeddings.cjs
CHANGED
|
@@ -75,6 +75,12 @@ class OpenAIEmbeddings extends embeddings_1.Embeddings {
|
|
|
75
75
|
writable: true,
|
|
76
76
|
value: void 0
|
|
77
77
|
});
|
|
78
|
+
Object.defineProperty(this, "encodingFormat", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: void 0
|
|
83
|
+
});
|
|
78
84
|
Object.defineProperty(this, "client", {
|
|
79
85
|
enumerable: true,
|
|
80
86
|
configurable: true,
|
|
@@ -101,6 +107,7 @@ class OpenAIEmbeddings extends embeddings_1.Embeddings {
|
|
|
101
107
|
fieldsWithDefaults?.stripNewLines ?? this.stripNewLines;
|
|
102
108
|
this.timeout = fieldsWithDefaults?.timeout;
|
|
103
109
|
this.dimensions = fieldsWithDefaults?.dimensions;
|
|
110
|
+
this.encodingFormat = fieldsWithDefaults?.encodingFormat;
|
|
104
111
|
this.clientConfig = {
|
|
105
112
|
apiKey,
|
|
106
113
|
organization: this.organization,
|
|
@@ -125,6 +132,9 @@ class OpenAIEmbeddings extends embeddings_1.Embeddings {
|
|
|
125
132
|
if (this.dimensions) {
|
|
126
133
|
params.dimensions = this.dimensions;
|
|
127
134
|
}
|
|
135
|
+
if (this.encodingFormat) {
|
|
136
|
+
params.encoding_format = this.encodingFormat;
|
|
137
|
+
}
|
|
128
138
|
return this.embeddingWithRetry(params);
|
|
129
139
|
});
|
|
130
140
|
const batchResponses = await Promise.all(batchRequests);
|
|
@@ -152,6 +162,9 @@ class OpenAIEmbeddings extends embeddings_1.Embeddings {
|
|
|
152
162
|
if (this.dimensions) {
|
|
153
163
|
params.dimensions = this.dimensions;
|
|
154
164
|
}
|
|
165
|
+
if (this.encodingFormat) {
|
|
166
|
+
params.encoding_format = this.encodingFormat;
|
|
167
|
+
}
|
|
155
168
|
const { data } = await this.embeddingWithRetry(params);
|
|
156
169
|
return data[0].embedding;
|
|
157
170
|
}
|
package/dist/embeddings.d.ts
CHANGED
|
@@ -37,6 +37,10 @@ export interface OpenAIEmbeddingsParams extends EmbeddingsParams {
|
|
|
37
37
|
* See: https://github.com/openai/openai-python/issues/418#issuecomment-1525939500
|
|
38
38
|
*/
|
|
39
39
|
stripNewLines?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* The format to return the embeddings in. Can be either 'float' or 'base64'.
|
|
42
|
+
*/
|
|
43
|
+
encodingFormat?: "float" | "base64";
|
|
40
44
|
}
|
|
41
45
|
/**
|
|
42
46
|
* Class for generating embeddings using the OpenAI API.
|
|
@@ -54,7 +58,7 @@ export interface OpenAIEmbeddingsParams extends EmbeddingsParams {
|
|
|
54
58
|
*
|
|
55
59
|
* ```
|
|
56
60
|
*/
|
|
57
|
-
export declare class OpenAIEmbeddings extends Embeddings implements Partial<OpenAIEmbeddingsParams> {
|
|
61
|
+
export declare class OpenAIEmbeddings<TOutput = number[]> extends Embeddings<TOutput> implements Partial<OpenAIEmbeddingsParams> {
|
|
58
62
|
model: string;
|
|
59
63
|
/** @deprecated Use "model" instead */
|
|
60
64
|
modelName: string;
|
|
@@ -67,6 +71,7 @@ export declare class OpenAIEmbeddings extends Embeddings implements Partial<Open
|
|
|
67
71
|
dimensions?: number;
|
|
68
72
|
timeout?: number;
|
|
69
73
|
organization?: string;
|
|
74
|
+
encodingFormat?: "float" | "base64";
|
|
70
75
|
protected client: OpenAIClient;
|
|
71
76
|
protected clientConfig: ClientOptions;
|
|
72
77
|
constructor(fields?: Partial<OpenAIEmbeddingsParams> & {
|
|
@@ -87,14 +92,14 @@ export declare class OpenAIEmbeddings extends Embeddings implements Partial<Open
|
|
|
87
92
|
* @param texts Array of documents to generate embeddings for.
|
|
88
93
|
* @returns Promise that resolves to a 2D array of embeddings for each document.
|
|
89
94
|
*/
|
|
90
|
-
embedDocuments(texts: string[]): Promise<
|
|
95
|
+
embedDocuments(texts: string[]): Promise<TOutput[]>;
|
|
91
96
|
/**
|
|
92
97
|
* Method to generate an embedding for a single document. Calls the
|
|
93
98
|
* embeddingWithRetry method with the document as the input.
|
|
94
99
|
* @param text Document to generate an embedding for.
|
|
95
100
|
* @returns Promise that resolves to an embedding for the document.
|
|
96
101
|
*/
|
|
97
|
-
embedQuery(text: string): Promise<
|
|
102
|
+
embedQuery(text: string): Promise<TOutput>;
|
|
98
103
|
/**
|
|
99
104
|
* Private method to make a request to the OpenAI API to generate
|
|
100
105
|
* embeddings. Handles the retry logic and returns the response from the
|
package/dist/embeddings.js
CHANGED
|
@@ -72,6 +72,12 @@ export class OpenAIEmbeddings extends Embeddings {
|
|
|
72
72
|
writable: true,
|
|
73
73
|
value: void 0
|
|
74
74
|
});
|
|
75
|
+
Object.defineProperty(this, "encodingFormat", {
|
|
76
|
+
enumerable: true,
|
|
77
|
+
configurable: true,
|
|
78
|
+
writable: true,
|
|
79
|
+
value: void 0
|
|
80
|
+
});
|
|
75
81
|
Object.defineProperty(this, "client", {
|
|
76
82
|
enumerable: true,
|
|
77
83
|
configurable: true,
|
|
@@ -98,6 +104,7 @@ export class OpenAIEmbeddings extends Embeddings {
|
|
|
98
104
|
fieldsWithDefaults?.stripNewLines ?? this.stripNewLines;
|
|
99
105
|
this.timeout = fieldsWithDefaults?.timeout;
|
|
100
106
|
this.dimensions = fieldsWithDefaults?.dimensions;
|
|
107
|
+
this.encodingFormat = fieldsWithDefaults?.encodingFormat;
|
|
101
108
|
this.clientConfig = {
|
|
102
109
|
apiKey,
|
|
103
110
|
organization: this.organization,
|
|
@@ -122,6 +129,9 @@ export class OpenAIEmbeddings extends Embeddings {
|
|
|
122
129
|
if (this.dimensions) {
|
|
123
130
|
params.dimensions = this.dimensions;
|
|
124
131
|
}
|
|
132
|
+
if (this.encodingFormat) {
|
|
133
|
+
params.encoding_format = this.encodingFormat;
|
|
134
|
+
}
|
|
125
135
|
return this.embeddingWithRetry(params);
|
|
126
136
|
});
|
|
127
137
|
const batchResponses = await Promise.all(batchRequests);
|
|
@@ -149,6 +159,9 @@ export class OpenAIEmbeddings extends Embeddings {
|
|
|
149
159
|
if (this.dimensions) {
|
|
150
160
|
params.dimensions = this.dimensions;
|
|
151
161
|
}
|
|
162
|
+
if (this.encodingFormat) {
|
|
163
|
+
params.encoding_format = this.encodingFormat;
|
|
164
|
+
}
|
|
152
165
|
const { data } = await this.embeddingWithRetry(params);
|
|
153
166
|
return data[0].embedding;
|
|
154
167
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleMultiModalOutput = handleMultiModalOutput;
|
|
4
|
+
/**
|
|
5
|
+
* Handle multi modal response content.
|
|
6
|
+
*
|
|
7
|
+
* @param content The content of the message.
|
|
8
|
+
* @param messages The messages of the response.
|
|
9
|
+
* @returns The new content of the message.
|
|
10
|
+
*/
|
|
11
|
+
function handleMultiModalOutput(content, messages) {
|
|
12
|
+
/**
|
|
13
|
+
* Handle OpenRouter image responses
|
|
14
|
+
* @see https://openrouter.ai/docs/features/multimodal/image-generation#api-usage
|
|
15
|
+
*/
|
|
16
|
+
if (messages &&
|
|
17
|
+
typeof messages === "object" &&
|
|
18
|
+
"images" in messages &&
|
|
19
|
+
Array.isArray(messages.images)) {
|
|
20
|
+
const images = messages.images
|
|
21
|
+
.filter((image) => typeof image?.image_url?.url === "string")
|
|
22
|
+
.map((image) => ({
|
|
23
|
+
type: "image",
|
|
24
|
+
url: image.image_url.url,
|
|
25
|
+
source_type: "url",
|
|
26
|
+
}));
|
|
27
|
+
return [{ type: "text", text: content, source_type: "text" }, ...images];
|
|
28
|
+
}
|
|
29
|
+
return content;
|
|
30
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { StandardImageBlock, StandardTextBlock } from "@langchain/core/messages";
|
|
2
|
+
/**
|
|
3
|
+
* Handle multi modal response content.
|
|
4
|
+
*
|
|
5
|
+
* @param content The content of the message.
|
|
6
|
+
* @param messages The messages of the response.
|
|
7
|
+
* @returns The new content of the message.
|
|
8
|
+
*/
|
|
9
|
+
export declare function handleMultiModalOutput(content: string, messages: unknown): (StandardImageBlock | StandardTextBlock)[] | string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handle multi modal response content.
|
|
3
|
+
*
|
|
4
|
+
* @param content The content of the message.
|
|
5
|
+
* @param messages The messages of the response.
|
|
6
|
+
* @returns The new content of the message.
|
|
7
|
+
*/
|
|
8
|
+
export function handleMultiModalOutput(content, messages) {
|
|
9
|
+
/**
|
|
10
|
+
* Handle OpenRouter image responses
|
|
11
|
+
* @see https://openrouter.ai/docs/features/multimodal/image-generation#api-usage
|
|
12
|
+
*/
|
|
13
|
+
if (messages &&
|
|
14
|
+
typeof messages === "object" &&
|
|
15
|
+
"images" in messages &&
|
|
16
|
+
Array.isArray(messages.images)) {
|
|
17
|
+
const images = messages.images
|
|
18
|
+
.filter((image) => typeof image?.image_url?.url === "string")
|
|
19
|
+
.map((image) => ({
|
|
20
|
+
type: "image",
|
|
21
|
+
url: image.image_url.url,
|
|
22
|
+
source_type: "url",
|
|
23
|
+
}));
|
|
24
|
+
return [{ type: "text", text: content, source_type: "text" }, ...images];
|
|
25
|
+
}
|
|
26
|
+
return content;
|
|
27
|
+
}
|