@langchain/openai 0.3.10 → 0.3.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 +119 -2
- package/dist/chat_models.d.ts +102 -1
- package/dist/chat_models.js +119 -2
- package/dist/types.d.ts +19 -0
- package/package.json +2 -2
package/dist/chat_models.cjs
CHANGED
|
@@ -78,6 +78,9 @@ function openAIResponseToChatMessage(message, rawResponse, includeRawResponse) {
|
|
|
78
78
|
system_fingerprint: rawResponse.system_fingerprint,
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
|
+
if (message.audio) {
|
|
82
|
+
additional_kwargs.audio = message.audio;
|
|
83
|
+
}
|
|
81
84
|
return new messages_1.AIMessage({
|
|
82
85
|
content: message.content || "",
|
|
83
86
|
tool_calls: toolCalls,
|
|
@@ -113,6 +116,12 @@ delta, rawResponse, defaultRole, includeRawResponse) {
|
|
|
113
116
|
if (includeRawResponse) {
|
|
114
117
|
additional_kwargs.__raw_response = rawResponse;
|
|
115
118
|
}
|
|
119
|
+
if (delta.audio) {
|
|
120
|
+
additional_kwargs.audio = {
|
|
121
|
+
...delta.audio,
|
|
122
|
+
index: rawResponse.choices[0].index,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
116
125
|
const response_metadata = { usage: { ...rawResponse.usage } };
|
|
117
126
|
if (role === "user") {
|
|
118
127
|
return new messages_1.HumanMessageChunk({ content, response_metadata });
|
|
@@ -164,7 +173,7 @@ delta, rawResponse, defaultRole, includeRawResponse) {
|
|
|
164
173
|
// Used in LangSmith, export is important here
|
|
165
174
|
function _convertMessagesToOpenAIParams(messages) {
|
|
166
175
|
// TODO: Function messages do not support array content, fix cast
|
|
167
|
-
return messages.
|
|
176
|
+
return messages.flatMap((message) => {
|
|
168
177
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
169
178
|
const completionParam = {
|
|
170
179
|
role: messageToOpenAIRole(message),
|
|
@@ -189,6 +198,17 @@ function _convertMessagesToOpenAIParams(messages) {
|
|
|
189
198
|
completionParam.tool_call_id = message.tool_call_id;
|
|
190
199
|
}
|
|
191
200
|
}
|
|
201
|
+
if (message.additional_kwargs.audio &&
|
|
202
|
+
typeof message.additional_kwargs.audio === "object" &&
|
|
203
|
+
"id" in message.additional_kwargs.audio) {
|
|
204
|
+
const audioMessage = {
|
|
205
|
+
role: "assistant",
|
|
206
|
+
audio: {
|
|
207
|
+
id: message.additional_kwargs.audio.id,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
return [completionParam, audioMessage];
|
|
211
|
+
}
|
|
192
212
|
return completionParam;
|
|
193
213
|
});
|
|
194
214
|
}
|
|
@@ -669,6 +689,80 @@ function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
|
|
|
669
689
|
* </details>
|
|
670
690
|
*
|
|
671
691
|
* <br />
|
|
692
|
+
*
|
|
693
|
+
* <details>
|
|
694
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
695
|
+
*
|
|
696
|
+
* ```typescript
|
|
697
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
698
|
+
*
|
|
699
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
700
|
+
* model: "gpt-4o-audio-preview",
|
|
701
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
702
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
703
|
+
* audio: {
|
|
704
|
+
* voice: "alloy",
|
|
705
|
+
* format: "wav",
|
|
706
|
+
* },
|
|
707
|
+
* });
|
|
708
|
+
*
|
|
709
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
710
|
+
* const castMessageContent = audioOutputResult.content[0] as Record<string, any>;
|
|
711
|
+
*
|
|
712
|
+
* console.log({
|
|
713
|
+
* ...castMessageContent,
|
|
714
|
+
* data: castMessageContent.data.slice(0, 100) // Sliced for brevity
|
|
715
|
+
* })
|
|
716
|
+
* ```
|
|
717
|
+
*
|
|
718
|
+
* ```txt
|
|
719
|
+
* {
|
|
720
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
721
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
722
|
+
* expires_at: 1729201448,
|
|
723
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
724
|
+
* }
|
|
725
|
+
* ```
|
|
726
|
+
* </details>
|
|
727
|
+
*
|
|
728
|
+
* <br />
|
|
729
|
+
*
|
|
730
|
+
* <details>
|
|
731
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
732
|
+
*
|
|
733
|
+
* ```typescript
|
|
734
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
735
|
+
*
|
|
736
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
737
|
+
* model: "gpt-4o-audio-preview",
|
|
738
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
739
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
740
|
+
* audio: {
|
|
741
|
+
* voice: "alloy",
|
|
742
|
+
* format: "wav",
|
|
743
|
+
* },
|
|
744
|
+
* });
|
|
745
|
+
*
|
|
746
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
747
|
+
* const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;
|
|
748
|
+
*
|
|
749
|
+
* console.log({
|
|
750
|
+
* ...castAudioContent,
|
|
751
|
+
* data: castAudioContent.data.slice(0, 100) // Sliced for brevity
|
|
752
|
+
* })
|
|
753
|
+
* ```
|
|
754
|
+
*
|
|
755
|
+
* ```txt
|
|
756
|
+
* {
|
|
757
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
758
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
759
|
+
* expires_at: 1729201448,
|
|
760
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
761
|
+
* }
|
|
762
|
+
* ```
|
|
763
|
+
* </details>
|
|
764
|
+
*
|
|
765
|
+
* <br />
|
|
672
766
|
*/
|
|
673
767
|
class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
674
768
|
static lc_name() {
|
|
@@ -912,6 +1006,18 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
912
1006
|
writable: true,
|
|
913
1007
|
value: void 0
|
|
914
1008
|
});
|
|
1009
|
+
Object.defineProperty(this, "audio", {
|
|
1010
|
+
enumerable: true,
|
|
1011
|
+
configurable: true,
|
|
1012
|
+
writable: true,
|
|
1013
|
+
value: void 0
|
|
1014
|
+
});
|
|
1015
|
+
Object.defineProperty(this, "modalities", {
|
|
1016
|
+
enumerable: true,
|
|
1017
|
+
configurable: true,
|
|
1018
|
+
writable: true,
|
|
1019
|
+
value: void 0
|
|
1020
|
+
});
|
|
915
1021
|
this.openAIApiKey =
|
|
916
1022
|
fields?.apiKey ??
|
|
917
1023
|
fields?.openAIApiKey ??
|
|
@@ -960,6 +1066,8 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
960
1066
|
this.stopSequences = this?.stop;
|
|
961
1067
|
this.user = fields?.user;
|
|
962
1068
|
this.__includeRawResponse = fields?.__includeRawResponse;
|
|
1069
|
+
this.audio = fields?.audio;
|
|
1070
|
+
this.modalities = fields?.modalities;
|
|
963
1071
|
if (this.azureOpenAIApiKey || this.azureADTokenProvider) {
|
|
964
1072
|
if (!this.azureOpenAIApiInstanceName &&
|
|
965
1073
|
!this.azureOpenAIBasePath &&
|
|
@@ -1081,8 +1189,17 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1081
1189
|
seed: options?.seed,
|
|
1082
1190
|
...streamOptionsConfig,
|
|
1083
1191
|
parallel_tool_calls: options?.parallel_tool_calls,
|
|
1192
|
+
...(this.audio || options?.audio
|
|
1193
|
+
? { audio: this.audio || options?.audio }
|
|
1194
|
+
: {}),
|
|
1195
|
+
...(this.modalities || options?.modalities
|
|
1196
|
+
? { modalities: this.modalities || options?.modalities }
|
|
1197
|
+
: {}),
|
|
1084
1198
|
...this.modelKwargs,
|
|
1085
1199
|
};
|
|
1200
|
+
if (options?.prediction !== undefined) {
|
|
1201
|
+
params.prediction = options.prediction;
|
|
1202
|
+
}
|
|
1086
1203
|
return params;
|
|
1087
1204
|
}
|
|
1088
1205
|
/** @ignore */
|
|
@@ -1116,7 +1233,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1116
1233
|
const streamIterable = await this.completionWithRetry(params, options);
|
|
1117
1234
|
let usage;
|
|
1118
1235
|
for await (const data of streamIterable) {
|
|
1119
|
-
const choice = data?.choices[0];
|
|
1236
|
+
const choice = data?.choices?.[0];
|
|
1120
1237
|
if (data.usage) {
|
|
1121
1238
|
usage = data.usage;
|
|
1122
1239
|
}
|
package/dist/chat_models.d.ts
CHANGED
|
@@ -18,8 +18,9 @@ interface OpenAILLMOutput {
|
|
|
18
18
|
tokenUsage: TokenUsage;
|
|
19
19
|
}
|
|
20
20
|
type OpenAIRoleEnum = "system" | "assistant" | "user" | "function" | "tool";
|
|
21
|
+
type OpenAICompletionParam = OpenAIClient.Chat.Completions.ChatCompletionMessageParam;
|
|
21
22
|
export declare function messageToOpenAIRole(message: BaseMessage): OpenAIRoleEnum;
|
|
22
|
-
export declare function _convertMessagesToOpenAIParams(messages: BaseMessage[]):
|
|
23
|
+
export declare function _convertMessagesToOpenAIParams(messages: BaseMessage[]): OpenAICompletionParam[];
|
|
23
24
|
type ChatOpenAIToolType = BindToolsInput | OpenAIClient.ChatCompletionTool;
|
|
24
25
|
export interface ChatOpenAIStructuredOutputMethodOptions<IncludeRaw extends boolean> extends StructuredOutputMethodOptions<IncludeRaw> {
|
|
25
26
|
/**
|
|
@@ -75,6 +76,30 @@ export interface ChatOpenAICallOptions extends OpenAICallOptions, BaseFunctionCa
|
|
|
75
76
|
* @version 0.2.6
|
|
76
77
|
*/
|
|
77
78
|
strict?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Output types that you would like the model to generate for this request. Most
|
|
81
|
+
* models are capable of generating text, which is the default:
|
|
82
|
+
*
|
|
83
|
+
* `["text"]`
|
|
84
|
+
*
|
|
85
|
+
* The `gpt-4o-audio-preview` model can also be used to
|
|
86
|
+
* [generate audio](https://platform.openai.com/docs/guides/audio). To request that
|
|
87
|
+
* this model generate both text and audio responses, you can use:
|
|
88
|
+
*
|
|
89
|
+
* `["text", "audio"]`
|
|
90
|
+
*/
|
|
91
|
+
modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;
|
|
92
|
+
/**
|
|
93
|
+
* Parameters for audio output. Required when audio output is requested with
|
|
94
|
+
* `modalities: ["audio"]`.
|
|
95
|
+
* [Learn more](https://platform.openai.com/docs/guides/audio).
|
|
96
|
+
*/
|
|
97
|
+
audio?: OpenAIClient.Chat.ChatCompletionAudioParam;
|
|
98
|
+
/**
|
|
99
|
+
* Static predicted output content, such as the content of a text file that is being regenerated.
|
|
100
|
+
* [Learn more](https://platform.openai.com/docs/guides/latency-optimization#use-predicted-outputs).
|
|
101
|
+
*/
|
|
102
|
+
prediction?: OpenAIClient.ChatCompletionPredictionContent;
|
|
78
103
|
}
|
|
79
104
|
export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, Partial<AzureOpenAIInput>, BaseChatModelParams {
|
|
80
105
|
configuration?: ClientOptions & LegacyOpenAIInput;
|
|
@@ -540,6 +565,80 @@ export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, Partial<Azur
|
|
|
540
565
|
* </details>
|
|
541
566
|
*
|
|
542
567
|
* <br />
|
|
568
|
+
*
|
|
569
|
+
* <details>
|
|
570
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
571
|
+
*
|
|
572
|
+
* ```typescript
|
|
573
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
574
|
+
*
|
|
575
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
576
|
+
* model: "gpt-4o-audio-preview",
|
|
577
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
578
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
579
|
+
* audio: {
|
|
580
|
+
* voice: "alloy",
|
|
581
|
+
* format: "wav",
|
|
582
|
+
* },
|
|
583
|
+
* });
|
|
584
|
+
*
|
|
585
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
586
|
+
* const castMessageContent = audioOutputResult.content[0] as Record<string, any>;
|
|
587
|
+
*
|
|
588
|
+
* console.log({
|
|
589
|
+
* ...castMessageContent,
|
|
590
|
+
* data: castMessageContent.data.slice(0, 100) // Sliced for brevity
|
|
591
|
+
* })
|
|
592
|
+
* ```
|
|
593
|
+
*
|
|
594
|
+
* ```txt
|
|
595
|
+
* {
|
|
596
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
597
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
598
|
+
* expires_at: 1729201448,
|
|
599
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
600
|
+
* }
|
|
601
|
+
* ```
|
|
602
|
+
* </details>
|
|
603
|
+
*
|
|
604
|
+
* <br />
|
|
605
|
+
*
|
|
606
|
+
* <details>
|
|
607
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
608
|
+
*
|
|
609
|
+
* ```typescript
|
|
610
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
611
|
+
*
|
|
612
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
613
|
+
* model: "gpt-4o-audio-preview",
|
|
614
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
615
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
616
|
+
* audio: {
|
|
617
|
+
* voice: "alloy",
|
|
618
|
+
* format: "wav",
|
|
619
|
+
* },
|
|
620
|
+
* });
|
|
621
|
+
*
|
|
622
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
623
|
+
* const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;
|
|
624
|
+
*
|
|
625
|
+
* console.log({
|
|
626
|
+
* ...castAudioContent,
|
|
627
|
+
* data: castAudioContent.data.slice(0, 100) // Sliced for brevity
|
|
628
|
+
* })
|
|
629
|
+
* ```
|
|
630
|
+
*
|
|
631
|
+
* ```txt
|
|
632
|
+
* {
|
|
633
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
634
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
635
|
+
* expires_at: 1729201448,
|
|
636
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
637
|
+
* }
|
|
638
|
+
* ```
|
|
639
|
+
* </details>
|
|
640
|
+
*
|
|
641
|
+
* <br />
|
|
543
642
|
*/
|
|
544
643
|
export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions> extends BaseChatModel<CallOptions, AIMessageChunk> implements OpenAIChatInput, AzureOpenAIInput {
|
|
545
644
|
static lc_name(): string;
|
|
@@ -585,6 +684,8 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
|
|
|
585
684
|
* If `undefined` the `strict` argument will not be passed to OpenAI.
|
|
586
685
|
*/
|
|
587
686
|
supportsStrictToolCalling?: boolean;
|
|
687
|
+
audio?: OpenAIClient.Chat.ChatCompletionAudioParam;
|
|
688
|
+
modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;
|
|
588
689
|
constructor(fields?: ChatOpenAIFields,
|
|
589
690
|
/** @deprecated */
|
|
590
691
|
configuration?: ClientOptions & LegacyOpenAIInput);
|
package/dist/chat_models.js
CHANGED
|
@@ -74,6 +74,9 @@ function openAIResponseToChatMessage(message, rawResponse, includeRawResponse) {
|
|
|
74
74
|
system_fingerprint: rawResponse.system_fingerprint,
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
+
if (message.audio) {
|
|
78
|
+
additional_kwargs.audio = message.audio;
|
|
79
|
+
}
|
|
77
80
|
return new AIMessage({
|
|
78
81
|
content: message.content || "",
|
|
79
82
|
tool_calls: toolCalls,
|
|
@@ -109,6 +112,12 @@ delta, rawResponse, defaultRole, includeRawResponse) {
|
|
|
109
112
|
if (includeRawResponse) {
|
|
110
113
|
additional_kwargs.__raw_response = rawResponse;
|
|
111
114
|
}
|
|
115
|
+
if (delta.audio) {
|
|
116
|
+
additional_kwargs.audio = {
|
|
117
|
+
...delta.audio,
|
|
118
|
+
index: rawResponse.choices[0].index,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
112
121
|
const response_metadata = { usage: { ...rawResponse.usage } };
|
|
113
122
|
if (role === "user") {
|
|
114
123
|
return new HumanMessageChunk({ content, response_metadata });
|
|
@@ -160,7 +169,7 @@ delta, rawResponse, defaultRole, includeRawResponse) {
|
|
|
160
169
|
// Used in LangSmith, export is important here
|
|
161
170
|
export function _convertMessagesToOpenAIParams(messages) {
|
|
162
171
|
// TODO: Function messages do not support array content, fix cast
|
|
163
|
-
return messages.
|
|
172
|
+
return messages.flatMap((message) => {
|
|
164
173
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
165
174
|
const completionParam = {
|
|
166
175
|
role: messageToOpenAIRole(message),
|
|
@@ -185,6 +194,17 @@ export function _convertMessagesToOpenAIParams(messages) {
|
|
|
185
194
|
completionParam.tool_call_id = message.tool_call_id;
|
|
186
195
|
}
|
|
187
196
|
}
|
|
197
|
+
if (message.additional_kwargs.audio &&
|
|
198
|
+
typeof message.additional_kwargs.audio === "object" &&
|
|
199
|
+
"id" in message.additional_kwargs.audio) {
|
|
200
|
+
const audioMessage = {
|
|
201
|
+
role: "assistant",
|
|
202
|
+
audio: {
|
|
203
|
+
id: message.additional_kwargs.audio.id,
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
return [completionParam, audioMessage];
|
|
207
|
+
}
|
|
188
208
|
return completionParam;
|
|
189
209
|
});
|
|
190
210
|
}
|
|
@@ -664,6 +684,80 @@ function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
|
|
|
664
684
|
* </details>
|
|
665
685
|
*
|
|
666
686
|
* <br />
|
|
687
|
+
*
|
|
688
|
+
* <details>
|
|
689
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
690
|
+
*
|
|
691
|
+
* ```typescript
|
|
692
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
693
|
+
*
|
|
694
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
695
|
+
* model: "gpt-4o-audio-preview",
|
|
696
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
697
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
698
|
+
* audio: {
|
|
699
|
+
* voice: "alloy",
|
|
700
|
+
* format: "wav",
|
|
701
|
+
* },
|
|
702
|
+
* });
|
|
703
|
+
*
|
|
704
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
705
|
+
* const castMessageContent = audioOutputResult.content[0] as Record<string, any>;
|
|
706
|
+
*
|
|
707
|
+
* console.log({
|
|
708
|
+
* ...castMessageContent,
|
|
709
|
+
* data: castMessageContent.data.slice(0, 100) // Sliced for brevity
|
|
710
|
+
* })
|
|
711
|
+
* ```
|
|
712
|
+
*
|
|
713
|
+
* ```txt
|
|
714
|
+
* {
|
|
715
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
716
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
717
|
+
* expires_at: 1729201448,
|
|
718
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
719
|
+
* }
|
|
720
|
+
* ```
|
|
721
|
+
* </details>
|
|
722
|
+
*
|
|
723
|
+
* <br />
|
|
724
|
+
*
|
|
725
|
+
* <details>
|
|
726
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
727
|
+
*
|
|
728
|
+
* ```typescript
|
|
729
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
730
|
+
*
|
|
731
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
732
|
+
* model: "gpt-4o-audio-preview",
|
|
733
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
734
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
735
|
+
* audio: {
|
|
736
|
+
* voice: "alloy",
|
|
737
|
+
* format: "wav",
|
|
738
|
+
* },
|
|
739
|
+
* });
|
|
740
|
+
*
|
|
741
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
742
|
+
* const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;
|
|
743
|
+
*
|
|
744
|
+
* console.log({
|
|
745
|
+
* ...castAudioContent,
|
|
746
|
+
* data: castAudioContent.data.slice(0, 100) // Sliced for brevity
|
|
747
|
+
* })
|
|
748
|
+
* ```
|
|
749
|
+
*
|
|
750
|
+
* ```txt
|
|
751
|
+
* {
|
|
752
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
753
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
754
|
+
* expires_at: 1729201448,
|
|
755
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
756
|
+
* }
|
|
757
|
+
* ```
|
|
758
|
+
* </details>
|
|
759
|
+
*
|
|
760
|
+
* <br />
|
|
667
761
|
*/
|
|
668
762
|
export class ChatOpenAI extends BaseChatModel {
|
|
669
763
|
static lc_name() {
|
|
@@ -907,6 +1001,18 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
907
1001
|
writable: true,
|
|
908
1002
|
value: void 0
|
|
909
1003
|
});
|
|
1004
|
+
Object.defineProperty(this, "audio", {
|
|
1005
|
+
enumerable: true,
|
|
1006
|
+
configurable: true,
|
|
1007
|
+
writable: true,
|
|
1008
|
+
value: void 0
|
|
1009
|
+
});
|
|
1010
|
+
Object.defineProperty(this, "modalities", {
|
|
1011
|
+
enumerable: true,
|
|
1012
|
+
configurable: true,
|
|
1013
|
+
writable: true,
|
|
1014
|
+
value: void 0
|
|
1015
|
+
});
|
|
910
1016
|
this.openAIApiKey =
|
|
911
1017
|
fields?.apiKey ??
|
|
912
1018
|
fields?.openAIApiKey ??
|
|
@@ -955,6 +1061,8 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
955
1061
|
this.stopSequences = this?.stop;
|
|
956
1062
|
this.user = fields?.user;
|
|
957
1063
|
this.__includeRawResponse = fields?.__includeRawResponse;
|
|
1064
|
+
this.audio = fields?.audio;
|
|
1065
|
+
this.modalities = fields?.modalities;
|
|
958
1066
|
if (this.azureOpenAIApiKey || this.azureADTokenProvider) {
|
|
959
1067
|
if (!this.azureOpenAIApiInstanceName &&
|
|
960
1068
|
!this.azureOpenAIBasePath &&
|
|
@@ -1076,8 +1184,17 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1076
1184
|
seed: options?.seed,
|
|
1077
1185
|
...streamOptionsConfig,
|
|
1078
1186
|
parallel_tool_calls: options?.parallel_tool_calls,
|
|
1187
|
+
...(this.audio || options?.audio
|
|
1188
|
+
? { audio: this.audio || options?.audio }
|
|
1189
|
+
: {}),
|
|
1190
|
+
...(this.modalities || options?.modalities
|
|
1191
|
+
? { modalities: this.modalities || options?.modalities }
|
|
1192
|
+
: {}),
|
|
1079
1193
|
...this.modelKwargs,
|
|
1080
1194
|
};
|
|
1195
|
+
if (options?.prediction !== undefined) {
|
|
1196
|
+
params.prediction = options.prediction;
|
|
1197
|
+
}
|
|
1081
1198
|
return params;
|
|
1082
1199
|
}
|
|
1083
1200
|
/** @ignore */
|
|
@@ -1111,7 +1228,7 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1111
1228
|
const streamIterable = await this.completionWithRetry(params, options);
|
|
1112
1229
|
let usage;
|
|
1113
1230
|
for await (const data of streamIterable) {
|
|
1114
|
-
const choice = data?.choices[0];
|
|
1231
|
+
const choice = data?.choices?.[0];
|
|
1115
1232
|
if (data.usage) {
|
|
1116
1233
|
usage = data.usage;
|
|
1117
1234
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -128,6 +128,25 @@ export interface OpenAIChatInput extends OpenAIBaseInput {
|
|
|
128
128
|
* If `undefined` the `strict` argument will not be passed to OpenAI.
|
|
129
129
|
*/
|
|
130
130
|
supportsStrictToolCalling?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Output types that you would like the model to generate for this request. Most
|
|
133
|
+
* models are capable of generating text, which is the default:
|
|
134
|
+
*
|
|
135
|
+
* `["text"]`
|
|
136
|
+
*
|
|
137
|
+
* The `gpt-4o-audio-preview` model can also be used to
|
|
138
|
+
* [generate audio](https://platform.openai.com/docs/guides/audio). To request that
|
|
139
|
+
* this model generate both text and audio responses, you can use:
|
|
140
|
+
*
|
|
141
|
+
* `["text", "audio"]`
|
|
142
|
+
*/
|
|
143
|
+
modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;
|
|
144
|
+
/**
|
|
145
|
+
* Parameters for audio output. Required when audio output is requested with
|
|
146
|
+
* `modalities: ["audio"]`.
|
|
147
|
+
* [Learn more](https://platform.openai.com/docs/guides/audio).
|
|
148
|
+
*/
|
|
149
|
+
audio?: OpenAIClient.Chat.ChatCompletionAudioParam;
|
|
131
150
|
}
|
|
132
151
|
export declare interface AzureOpenAIInput {
|
|
133
152
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/openai",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
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.71.0",
|
|
40
40
|
"zod": "^3.22.4",
|
|
41
41
|
"zod-to-json-schema": "^3.22.3"
|
|
42
42
|
},
|