@langchain/openai 0.3.10 → 0.3.11
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 +116 -2
- package/dist/chat_models.d.ts +97 -1
- package/dist/chat_models.js +116 -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,6 +1189,12 @@ 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
|
};
|
|
1086
1200
|
return params;
|
|
@@ -1116,7 +1230,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
|
|
|
1116
1230
|
const streamIterable = await this.completionWithRetry(params, options);
|
|
1117
1231
|
let usage;
|
|
1118
1232
|
for await (const data of streamIterable) {
|
|
1119
|
-
const choice = data?.choices[0];
|
|
1233
|
+
const choice = data?.choices?.[0];
|
|
1120
1234
|
if (data.usage) {
|
|
1121
1235
|
usage = data.usage;
|
|
1122
1236
|
}
|
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,25 @@ 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;
|
|
78
98
|
}
|
|
79
99
|
export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, Partial<AzureOpenAIInput>, BaseChatModelParams {
|
|
80
100
|
configuration?: ClientOptions & LegacyOpenAIInput;
|
|
@@ -540,6 +560,80 @@ export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, Partial<Azur
|
|
|
540
560
|
* </details>
|
|
541
561
|
*
|
|
542
562
|
* <br />
|
|
563
|
+
*
|
|
564
|
+
* <details>
|
|
565
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
566
|
+
*
|
|
567
|
+
* ```typescript
|
|
568
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
569
|
+
*
|
|
570
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
571
|
+
* model: "gpt-4o-audio-preview",
|
|
572
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
573
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
574
|
+
* audio: {
|
|
575
|
+
* voice: "alloy",
|
|
576
|
+
* format: "wav",
|
|
577
|
+
* },
|
|
578
|
+
* });
|
|
579
|
+
*
|
|
580
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
581
|
+
* const castMessageContent = audioOutputResult.content[0] as Record<string, any>;
|
|
582
|
+
*
|
|
583
|
+
* console.log({
|
|
584
|
+
* ...castMessageContent,
|
|
585
|
+
* data: castMessageContent.data.slice(0, 100) // Sliced for brevity
|
|
586
|
+
* })
|
|
587
|
+
* ```
|
|
588
|
+
*
|
|
589
|
+
* ```txt
|
|
590
|
+
* {
|
|
591
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
592
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
593
|
+
* expires_at: 1729201448,
|
|
594
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
595
|
+
* }
|
|
596
|
+
* ```
|
|
597
|
+
* </details>
|
|
598
|
+
*
|
|
599
|
+
* <br />
|
|
600
|
+
*
|
|
601
|
+
* <details>
|
|
602
|
+
* <summary><strong>Audio Outputs</strong></summary>
|
|
603
|
+
*
|
|
604
|
+
* ```typescript
|
|
605
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
606
|
+
*
|
|
607
|
+
* const modelWithAudioOutput = new ChatOpenAI({
|
|
608
|
+
* model: "gpt-4o-audio-preview",
|
|
609
|
+
* // You may also pass these fields to `.bind` as a call argument.
|
|
610
|
+
* modalities: ["text", "audio"], // Specifies that the model should output audio.
|
|
611
|
+
* audio: {
|
|
612
|
+
* voice: "alloy",
|
|
613
|
+
* format: "wav",
|
|
614
|
+
* },
|
|
615
|
+
* });
|
|
616
|
+
*
|
|
617
|
+
* const audioOutputResult = await modelWithAudioOutput.invoke("Tell me a joke about cats.");
|
|
618
|
+
* const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;
|
|
619
|
+
*
|
|
620
|
+
* console.log({
|
|
621
|
+
* ...castAudioContent,
|
|
622
|
+
* data: castAudioContent.data.slice(0, 100) // Sliced for brevity
|
|
623
|
+
* })
|
|
624
|
+
* ```
|
|
625
|
+
*
|
|
626
|
+
* ```txt
|
|
627
|
+
* {
|
|
628
|
+
* id: 'audio_67117718c6008190a3afad3e3054b9b6',
|
|
629
|
+
* data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',
|
|
630
|
+
* expires_at: 1729201448,
|
|
631
|
+
* transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'
|
|
632
|
+
* }
|
|
633
|
+
* ```
|
|
634
|
+
* </details>
|
|
635
|
+
*
|
|
636
|
+
* <br />
|
|
543
637
|
*/
|
|
544
638
|
export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions> extends BaseChatModel<CallOptions, AIMessageChunk> implements OpenAIChatInput, AzureOpenAIInput {
|
|
545
639
|
static lc_name(): string;
|
|
@@ -585,6 +679,8 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
|
|
|
585
679
|
* If `undefined` the `strict` argument will not be passed to OpenAI.
|
|
586
680
|
*/
|
|
587
681
|
supportsStrictToolCalling?: boolean;
|
|
682
|
+
audio?: OpenAIClient.Chat.ChatCompletionAudioParam;
|
|
683
|
+
modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;
|
|
588
684
|
constructor(fields?: ChatOpenAIFields,
|
|
589
685
|
/** @deprecated */
|
|
590
686
|
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,6 +1184,12 @@ 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
|
};
|
|
1081
1195
|
return params;
|
|
@@ -1111,7 +1225,7 @@ export class ChatOpenAI extends BaseChatModel {
|
|
|
1111
1225
|
const streamIterable = await this.completionWithRetry(params, options);
|
|
1112
1226
|
let usage;
|
|
1113
1227
|
for await (const data of streamIterable) {
|
|
1114
|
-
const choice = data?.choices[0];
|
|
1228
|
+
const choice = data?.choices?.[0];
|
|
1115
1229
|
if (data.usage) {
|
|
1116
1230
|
usage = data.usage;
|
|
1117
1231
|
}
|
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.11",
|
|
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.68.0",
|
|
40
40
|
"zod": "^3.22.4",
|
|
41
41
|
"zod-to-json-schema": "^3.22.3"
|
|
42
42
|
},
|