@langchain/openai 0.4.0-rc.0 → 0.4.1

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.
@@ -1,26 +1,98 @@
1
1
  import { AzureOpenAI as AzureOpenAIClient } from "openai";
2
+ import { getEnvironmentVariable } from "@langchain/core/utils/env";
2
3
  import { OpenAI } from "../llms.js";
3
4
  import { getEndpoint } from "../utils/azure.js";
4
5
  export class AzureOpenAI extends OpenAI {
5
6
  get lc_aliases() {
6
7
  return {
8
+ ...super.lc_aliases,
7
9
  openAIApiKey: "openai_api_key",
8
10
  openAIApiVersion: "openai_api_version",
9
11
  openAIBasePath: "openai_api_base",
12
+ deploymentName: "deployment_name",
13
+ azureOpenAIEndpoint: "azure_endpoint",
14
+ azureOpenAIApiVersion: "openai_api_version",
15
+ azureOpenAIBasePath: "openai_api_base",
16
+ azureOpenAIApiDeploymentName: "deployment_name",
17
+ };
18
+ }
19
+ get lc_secrets() {
20
+ return {
21
+ ...super.lc_secrets,
22
+ azureOpenAIApiKey: "AZURE_OPENAI_API_KEY",
10
23
  };
11
24
  }
12
25
  constructor(fields) {
13
- const newFields = fields ? { ...fields } : fields;
14
- if (newFields) {
15
- // don't rewrite the fields if they are already set
16
- newFields.azureOpenAIApiDeploymentName =
17
- newFields.azureOpenAIApiDeploymentName ?? newFields.deploymentName;
18
- newFields.azureOpenAIApiKey =
19
- newFields.azureOpenAIApiKey ?? newFields.openAIApiKey;
20
- newFields.azureOpenAIApiVersion =
21
- newFields.azureOpenAIApiVersion ?? newFields.openAIApiVersion;
26
+ super(fields);
27
+ Object.defineProperty(this, "azureOpenAIApiVersion", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: void 0
32
+ });
33
+ Object.defineProperty(this, "azureOpenAIApiKey", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: void 0
38
+ });
39
+ Object.defineProperty(this, "azureADTokenProvider", {
40
+ enumerable: true,
41
+ configurable: true,
42
+ writable: true,
43
+ value: void 0
44
+ });
45
+ Object.defineProperty(this, "azureOpenAIApiInstanceName", {
46
+ enumerable: true,
47
+ configurable: true,
48
+ writable: true,
49
+ value: void 0
50
+ });
51
+ Object.defineProperty(this, "azureOpenAIApiDeploymentName", {
52
+ enumerable: true,
53
+ configurable: true,
54
+ writable: true,
55
+ value: void 0
56
+ });
57
+ Object.defineProperty(this, "azureOpenAIBasePath", {
58
+ enumerable: true,
59
+ configurable: true,
60
+ writable: true,
61
+ value: void 0
62
+ });
63
+ Object.defineProperty(this, "azureOpenAIEndpoint", {
64
+ enumerable: true,
65
+ configurable: true,
66
+ writable: true,
67
+ value: void 0
68
+ });
69
+ this.azureOpenAIApiDeploymentName =
70
+ (fields?.azureOpenAIApiCompletionsDeploymentName ||
71
+ fields?.azureOpenAIApiDeploymentName) ??
72
+ (getEnvironmentVariable("AZURE_OPENAI_API_COMPLETIONS_DEPLOYMENT_NAME") ||
73
+ getEnvironmentVariable("AZURE_OPENAI_API_DEPLOYMENT_NAME"));
74
+ this.azureOpenAIApiKey =
75
+ fields?.azureOpenAIApiKey ??
76
+ fields?.openAIApiKey ??
77
+ fields?.apiKey ??
78
+ getEnvironmentVariable("AZURE_OPENAI_API_KEY");
79
+ this.azureOpenAIApiInstanceName =
80
+ fields?.azureOpenAIApiInstanceName ??
81
+ getEnvironmentVariable("AZURE_OPENAI_API_INSTANCE_NAME");
82
+ this.azureOpenAIApiVersion =
83
+ fields?.azureOpenAIApiVersion ??
84
+ fields?.openAIApiVersion ??
85
+ getEnvironmentVariable("AZURE_OPENAI_API_VERSION");
86
+ this.azureOpenAIBasePath =
87
+ fields?.azureOpenAIBasePath ??
88
+ getEnvironmentVariable("AZURE_OPENAI_BASE_PATH");
89
+ this.azureOpenAIEndpoint =
90
+ fields?.azureOpenAIEndpoint ??
91
+ getEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
92
+ this.azureADTokenProvider = fields?.azureADTokenProvider;
93
+ if (!this.azureOpenAIApiKey && !this.apiKey && !this.azureADTokenProvider) {
94
+ throw new Error("Azure OpenAI API key or Token Provider not found");
22
95
  }
23
- super(newFields);
24
96
  }
25
97
  _getClientOptions(options) {
26
98
  if (!this.client) {
@@ -247,6 +247,8 @@ function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
247
247
  /**
248
248
  * OpenAI chat model integration.
249
249
  *
250
+ * To use with Azure, import the `AzureChatOpenAI` class.
251
+ *
250
252
  * Setup:
251
253
  * Install `@langchain/openai` and set an environment variable named `OPENAI_API_KEY`.
252
254
  *
@@ -496,7 +498,7 @@ function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
496
498
  * const Joke = z.object({
497
499
  * setup: z.string().describe("The setup of the joke"),
498
500
  * punchline: z.string().describe("The punchline to the joke"),
499
- * rating: z.number().optional().describe("How funny the joke is, from 1 to 10")
501
+ * rating: z.number().nullable().describe("How funny the joke is, from 1 to 10")
500
502
  * }).describe('Joke to tell user.');
501
503
  *
502
504
  * const structuredLlm = llm.withStructuredOutput(Joke, {
@@ -802,7 +804,6 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
802
804
  return {
803
805
  openAIApiKey: "OPENAI_API_KEY",
804
806
  apiKey: "OPENAI_API_KEY",
805
- azureOpenAIApiKey: "AZURE_OPENAI_API_KEY",
806
807
  organization: "OPENAI_ORGANIZATION",
807
808
  };
808
809
  }
@@ -811,15 +812,9 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
811
812
  modelName: "model",
812
813
  openAIApiKey: "openai_api_key",
813
814
  apiKey: "openai_api_key",
814
- azureOpenAIApiVersion: "azure_openai_api_version",
815
- azureOpenAIApiKey: "azure_openai_api_key",
816
- azureOpenAIApiInstanceName: "azure_openai_api_instance_name",
817
- azureOpenAIApiDeploymentName: "azure_openai_api_deployment_name",
818
815
  };
819
816
  }
820
- constructor(fields,
821
- /** @deprecated */
822
- configuration) {
817
+ constructor(fields) {
823
818
  super(fields ?? {});
824
819
  Object.defineProperty(this, "lc_serializable", {
825
820
  enumerable: true,
@@ -831,25 +826,25 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
831
826
  enumerable: true,
832
827
  configurable: true,
833
828
  writable: true,
834
- value: 1
829
+ value: void 0
835
830
  });
836
831
  Object.defineProperty(this, "topP", {
837
832
  enumerable: true,
838
833
  configurable: true,
839
834
  writable: true,
840
- value: 1
835
+ value: void 0
841
836
  });
842
837
  Object.defineProperty(this, "frequencyPenalty", {
843
838
  enumerable: true,
844
839
  configurable: true,
845
840
  writable: true,
846
- value: 0
841
+ value: void 0
847
842
  });
848
843
  Object.defineProperty(this, "presencePenalty", {
849
844
  enumerable: true,
850
845
  configurable: true,
851
846
  writable: true,
852
- value: 0
847
+ value: void 0
853
848
  });
854
849
  Object.defineProperty(this, "n", {
855
850
  enumerable: true,
@@ -863,11 +858,12 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
863
858
  writable: true,
864
859
  value: void 0
865
860
  });
861
+ /** @deprecated Use "model" instead */
866
862
  Object.defineProperty(this, "modelName", {
867
863
  enumerable: true,
868
864
  configurable: true,
869
865
  writable: true,
870
- value: "gpt-3.5-turbo"
866
+ value: void 0
871
867
  });
872
868
  Object.defineProperty(this, "model", {
873
869
  enumerable: true,
@@ -947,48 +943,6 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
947
943
  writable: true,
948
944
  value: void 0
949
945
  });
950
- Object.defineProperty(this, "azureOpenAIApiVersion", {
951
- enumerable: true,
952
- configurable: true,
953
- writable: true,
954
- value: void 0
955
- });
956
- Object.defineProperty(this, "azureOpenAIApiKey", {
957
- enumerable: true,
958
- configurable: true,
959
- writable: true,
960
- value: void 0
961
- });
962
- Object.defineProperty(this, "azureADTokenProvider", {
963
- enumerable: true,
964
- configurable: true,
965
- writable: true,
966
- value: void 0
967
- });
968
- Object.defineProperty(this, "azureOpenAIApiInstanceName", {
969
- enumerable: true,
970
- configurable: true,
971
- writable: true,
972
- value: void 0
973
- });
974
- Object.defineProperty(this, "azureOpenAIApiDeploymentName", {
975
- enumerable: true,
976
- configurable: true,
977
- writable: true,
978
- value: void 0
979
- });
980
- Object.defineProperty(this, "azureOpenAIBasePath", {
981
- enumerable: true,
982
- configurable: true,
983
- writable: true,
984
- value: void 0
985
- });
986
- Object.defineProperty(this, "azureOpenAIEndpoint", {
987
- enumerable: true,
988
- configurable: true,
989
- writable: true,
990
- value: void 0
991
- });
992
946
  Object.defineProperty(this, "organization", {
993
947
  enumerable: true,
994
948
  configurable: true,
@@ -1047,21 +1001,11 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1047
1001
  fields?.configuration?.apiKey ??
1048
1002
  (0, env_1.getEnvironmentVariable)("OPENAI_API_KEY");
1049
1003
  this.apiKey = this.openAIApiKey;
1050
- this.azureOpenAIApiKey = fields?.azureOpenAIApiKey;
1051
- this.azureADTokenProvider = fields?.azureADTokenProvider ?? undefined;
1052
- if (!this.azureOpenAIApiKey && !this.apiKey && !this.azureADTokenProvider) {
1053
- throw new Error("OpenAI or Azure OpenAI API key or Token Provider not found");
1054
- }
1055
- this.azureOpenAIApiInstanceName = fields?.azureOpenAIApiInstanceName;
1056
- this.azureOpenAIApiDeploymentName = fields?.azureOpenAIApiDeploymentName;
1057
- this.azureOpenAIApiVersion = fields?.azureOpenAIApiVersion;
1058
- this.azureOpenAIBasePath = fields?.azureOpenAIBasePath;
1059
- this.azureOpenAIEndpoint = fields?.azureOpenAIEndpoint;
1060
1004
  this.organization =
1061
1005
  fields?.configuration?.organization ??
1062
1006
  (0, env_1.getEnvironmentVariable)("OPENAI_ORGANIZATION");
1063
- this.modelName = fields?.model ?? fields?.modelName ?? this.model;
1064
- this.model = this.modelName;
1007
+ this.model = fields?.model ?? fields?.modelName ?? this.model;
1008
+ this.modelName = this.model;
1065
1009
  this.modelKwargs = fields?.modelKwargs ?? {};
1066
1010
  this.timeout = fields?.timeout;
1067
1011
  this.temperature = fields?.temperature ?? this.temperature;
@@ -1080,29 +1024,6 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1080
1024
  this.audio = fields?.audio;
1081
1025
  this.modalities = fields?.modalities;
1082
1026
  this.reasoningEffort = fields?.reasoningEffort;
1083
- if (this.azureOpenAIApiKey || this.azureADTokenProvider) {
1084
- if (!this.azureOpenAIApiInstanceName &&
1085
- !this.azureOpenAIBasePath &&
1086
- !this.azureOpenAIEndpoint) {
1087
- throw new Error("Azure OpenAI API instance name not found");
1088
- }
1089
- if (!this.azureOpenAIApiDeploymentName && this.azureOpenAIBasePath) {
1090
- const parts = this.azureOpenAIBasePath.split("/openai/deployments/");
1091
- if (parts.length === 2) {
1092
- const [, deployment] = parts;
1093
- this.azureOpenAIApiDeploymentName = deployment;
1094
- }
1095
- }
1096
- if (!this.azureOpenAIApiDeploymentName) {
1097
- throw new Error("Azure OpenAI API deployment name not found");
1098
- }
1099
- if (!this.azureOpenAIApiVersion) {
1100
- throw new Error("Azure OpenAI API version not found");
1101
- }
1102
- this.apiKey = this.apiKey ?? "";
1103
- // Streaming usage is not supported by Azure deployments, so default to false
1104
- this.streamUsage = false;
1105
- }
1106
1027
  if (this.model === "o1") {
1107
1028
  this.disableStreaming = true;
1108
1029
  }
@@ -1111,13 +1032,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1111
1032
  this.clientConfig = {
1112
1033
  apiKey: this.apiKey,
1113
1034
  organization: this.organization,
1114
- baseURL: configuration?.basePath ?? fields?.configuration?.basePath,
1115
1035
  dangerouslyAllowBrowser: true,
1116
- defaultHeaders: configuration?.baseOptions?.headers ??
1117
- fields?.configuration?.baseOptions?.headers,
1118
- defaultQuery: configuration?.baseOptions?.params ??
1119
- fields?.configuration?.baseOptions?.params,
1120
- ...configuration,
1121
1036
  ...fields?.configuration,
1122
1037
  };
1123
1038
  // If `supportsStrictToolCalling` is explicitly set, use that value.
@@ -1596,12 +1511,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1596
1511
  _getClientOptions(options) {
1597
1512
  if (!this.client) {
1598
1513
  const openAIEndpointConfig = {
1599
- azureOpenAIApiDeploymentName: this.azureOpenAIApiDeploymentName,
1600
- azureOpenAIApiInstanceName: this.azureOpenAIApiInstanceName,
1601
- azureOpenAIApiKey: this.azureOpenAIApiKey,
1602
- azureOpenAIBasePath: this.azureOpenAIBasePath,
1603
1514
  baseURL: this.clientConfig.baseURL,
1604
- azureOpenAIEndpoint: this.azureOpenAIEndpoint,
1605
1515
  };
1606
1516
  const endpoint = (0, azure_js_1.getEndpoint)(openAIEndpointConfig);
1607
1517
  const params = {
@@ -1619,16 +1529,6 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1619
1529
  ...this.clientConfig,
1620
1530
  ...options,
1621
1531
  };
1622
- if (this.azureOpenAIApiKey) {
1623
- requestOptions.headers = {
1624
- "api-key": this.azureOpenAIApiKey,
1625
- ...requestOptions.headers,
1626
- };
1627
- requestOptions.query = {
1628
- "api-version": this.azureOpenAIApiVersion,
1629
- ...requestOptions.query,
1630
- };
1631
- }
1632
1532
  return requestOptions;
1633
1533
  }
1634
1534
  _llmType() {
@@ -1675,6 +1575,16 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1675
1575
  if (config?.strict !== undefined && method === "jsonMode") {
1676
1576
  throw new Error("Argument `strict` is only supported for `method` = 'function_calling'");
1677
1577
  }
1578
+ if (!this.model.startsWith("gpt-3") &&
1579
+ !this.model.startsWith("gpt-4-") &&
1580
+ this.model !== "gpt-4") {
1581
+ if (method === undefined) {
1582
+ method = "jsonSchema";
1583
+ }
1584
+ }
1585
+ else if (method === "jsonSchema") {
1586
+ console.warn(`[WARNING]: JSON Schema is not supported for model "${this.model}". Falling back to tool calling.`);
1587
+ }
1678
1588
  if (method === "jsonMode") {
1679
1589
  llm = this.bind({
1680
1590
  response_format: { type: "json_object" },
@@ -6,9 +6,9 @@ import { BaseChatModel, BindToolsInput, LangSmithParams, type BaseChatModelParam
6
6
  import { type BaseFunctionCallOptions, type BaseLanguageModelInput, type StructuredOutputMethodOptions } from "@langchain/core/language_models/base";
7
7
  import { z } from "zod";
8
8
  import { Runnable } from "@langchain/core/runnables";
9
- import type { AzureOpenAIInput, OpenAICallOptions, OpenAIChatInput, OpenAICoreRequestOptions, LegacyOpenAIInput, ChatOpenAIResponseFormat } from "./types.js";
9
+ import type { OpenAICallOptions, OpenAIChatInput, OpenAICoreRequestOptions, ChatOpenAIResponseFormat } from "./types.js";
10
10
  import { OpenAIToolChoice } from "./utils/openai.js";
11
- export type { AzureOpenAIInput, OpenAICallOptions, OpenAIChatInput };
11
+ export type { OpenAICallOptions, OpenAIChatInput };
12
12
  interface TokenUsage {
13
13
  completionTokens?: number;
14
14
  promptTokens?: number;
@@ -106,12 +106,14 @@ export interface ChatOpenAICallOptions extends OpenAICallOptions, BaseFunctionCa
106
106
  */
107
107
  reasoning_effort?: OpenAIClient.Chat.ChatCompletionReasoningEffort;
108
108
  }
109
- export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, Partial<AzureOpenAIInput>, BaseChatModelParams {
110
- configuration?: ClientOptions & LegacyOpenAIInput;
109
+ export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, BaseChatModelParams {
110
+ configuration?: ClientOptions;
111
111
  }
112
112
  /**
113
113
  * OpenAI chat model integration.
114
114
  *
115
+ * To use with Azure, import the `AzureChatOpenAI` class.
116
+ *
115
117
  * Setup:
116
118
  * Install `@langchain/openai` and set an environment variable named `OPENAI_API_KEY`.
117
119
  *
@@ -361,7 +363,7 @@ export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, Partial<Azur
361
363
  * const Joke = z.object({
362
364
  * setup: z.string().describe("The setup of the joke"),
363
365
  * punchline: z.string().describe("The punchline to the joke"),
364
- * rating: z.number().optional().describe("How funny the joke is, from 1 to 10")
366
+ * rating: z.number().nullable().describe("How funny the joke is, from 1 to 10")
365
367
  * }).describe('Joke to tell user.');
366
368
  *
367
369
  * const structuredLlm = llm.withStructuredOutput(Joke, {
@@ -645,7 +647,7 @@ export interface ChatOpenAIFields extends Partial<OpenAIChatInput>, Partial<Azur
645
647
  *
646
648
  * <br />
647
649
  */
648
- export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions> extends BaseChatModel<CallOptions, AIMessageChunk> implements OpenAIChatInput, AzureOpenAIInput {
650
+ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions> extends BaseChatModel<CallOptions, AIMessageChunk> implements Partial<OpenAIChatInput> {
649
651
  static lc_name(): string;
650
652
  get callKeys(): string[];
651
653
  lc_serializable: boolean;
@@ -653,12 +655,13 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
653
655
  [key: string]: string;
654
656
  } | undefined;
655
657
  get lc_aliases(): Record<string, string>;
656
- temperature: number;
657
- topP: number;
658
- frequencyPenalty: number;
659
- presencePenalty: number;
658
+ temperature?: number;
659
+ topP?: number;
660
+ frequencyPenalty?: number;
661
+ presencePenalty?: number;
660
662
  n: number;
661
663
  logitBias?: Record<string, number>;
664
+ /** @deprecated Use "model" instead */
662
665
  modelName: string;
663
666
  model: string;
664
667
  modelKwargs?: OpenAIChatInput["modelKwargs"];
@@ -673,13 +676,6 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
673
676
  topLogprobs?: number;
674
677
  openAIApiKey?: string;
675
678
  apiKey?: string;
676
- azureOpenAIApiVersion?: string;
677
- azureOpenAIApiKey?: string;
678
- azureADTokenProvider?: () => Promise<string>;
679
- azureOpenAIApiInstanceName?: string;
680
- azureOpenAIApiDeploymentName?: string;
681
- azureOpenAIBasePath?: string;
682
- azureOpenAIEndpoint?: string;
683
679
  organization?: string;
684
680
  __includeRawResponse?: boolean;
685
681
  protected client: OpenAIClient;
@@ -692,9 +688,7 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
692
688
  audio?: OpenAIClient.Chat.ChatCompletionAudioParam;
693
689
  modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;
694
690
  reasoningEffort?: OpenAIClient.Chat.ChatCompletionReasoningEffort;
695
- constructor(fields?: ChatOpenAIFields,
696
- /** @deprecated */
697
- configuration?: ClientOptions & LegacyOpenAIInput);
691
+ constructor(fields?: ChatOpenAIFields);
698
692
  getLsParams(options: this["ParsedCallOptions"]): LangSmithParams;
699
693
  bindTools(tools: ChatOpenAIToolType[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions>;
700
694
  private createResponseFormat;
@@ -755,4 +749,8 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
755
749
  raw: BaseMessage;
756
750
  parsed: RunOutput;
757
751
  }>;
752
+ withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: z.ZodType<RunOutput> | Record<string, any>, config?: ChatOpenAIStructuredOutputMethodOptions<boolean>): Runnable<BaseLanguageModelInput, RunOutput> | Runnable<BaseLanguageModelInput, {
753
+ raw: BaseMessage;
754
+ parsed: RunOutput;
755
+ }>;
758
756
  }