@langchain/openai 0.0.15 → 0.0.17

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.
@@ -718,18 +718,24 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
718
718
  },
719
719
  });
720
720
  }
721
- /**
722
- * Model wrapper that returns outputs formatted to match the given schema.
723
- *
724
- * @template {z.ZodObject<any, any, any, any>} RunOutput The output type for the Runnable, expected to be a Zod schema object for structured output validation.
725
- *
726
- * @param {z.ZodEffects<RunOutput>} schema The schema for the structured output. Either as a Zod schema or a valid JSON schema object.
727
- * @param {string} name The name of the function to call.
728
- * @param {"functionCalling" | "jsonMode"} method The method to use for getting the structured output. Defaults to "functionCalling".
729
- * @param {boolean | undefined} includeRaw Whether to include the raw output in the result. Defaults to false.
730
- * @returns {Runnable<RunInput, RunOutput> | Runnable<RunInput, { raw: BaseMessage; parsed: RunOutput }>} A new runnable that calls the LLM with structured output.
731
- */
732
- withStructuredOutput({ schema, name, method = "functionCalling", includeRaw = false, }) {
721
+ withStructuredOutput(outputSchema, config) {
722
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
723
+ let schema;
724
+ let name;
725
+ let method;
726
+ let includeRaw;
727
+ if (isStructuredOutputMethodParams(outputSchema)) {
728
+ schema = outputSchema.schema;
729
+ name = outputSchema.name;
730
+ method = outputSchema.method;
731
+ includeRaw = outputSchema.includeRaw;
732
+ }
733
+ else {
734
+ schema = outputSchema;
735
+ name = config?.name;
736
+ method = config?.method;
737
+ includeRaw = config?.includeRaw;
738
+ }
733
739
  let llm;
734
740
  let outputParser;
735
741
  if (method === "jsonMode") {
@@ -739,6 +745,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
739
745
  outputParser = new output_parsers_1.JsonOutputParser();
740
746
  }
741
747
  else {
748
+ const functionName = name ?? "extract";
742
749
  // Is function calling
743
750
  if (isZodSchema(schema)) {
744
751
  const asZodSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(schema);
@@ -753,11 +760,16 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
753
760
  },
754
761
  },
755
762
  ],
756
- tool_choice: "auto",
763
+ tool_choice: {
764
+ type: "function",
765
+ function: {
766
+ name: functionName,
767
+ },
768
+ },
757
769
  });
758
770
  outputParser = new openai_tools_1.JsonOutputKeyToolsParser({
759
771
  returnSingle: true,
760
- keyName: name,
772
+ keyName: functionName,
761
773
  });
762
774
  }
763
775
  else {
@@ -772,11 +784,16 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
772
784
  },
773
785
  },
774
786
  ],
775
- tool_choice: "auto",
787
+ tool_choice: {
788
+ type: "function",
789
+ function: {
790
+ name,
791
+ },
792
+ },
776
793
  });
777
794
  outputParser = new openai_tools_1.JsonOutputKeyToolsParser({
778
795
  returnSingle: true,
779
- keyName: name,
796
+ keyName: functionName,
780
797
  });
781
798
  }
782
799
  }
@@ -806,3 +823,11 @@ function isZodSchema(input) {
806
823
  // Check for a characteristic method of Zod schemas
807
824
  return typeof input?.parse === "function";
808
825
  }
826
+ function isStructuredOutputMethodParams(x
827
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
828
+ ) {
829
+ return (x !== undefined &&
830
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
831
+ typeof x.schema ===
832
+ "object");
833
+ }
@@ -4,7 +4,7 @@ import { type BaseMessage } from "@langchain/core/messages";
4
4
  import { ChatGenerationChunk, type ChatResult } from "@langchain/core/outputs";
5
5
  import { type StructuredToolInterface } from "@langchain/core/tools";
6
6
  import { BaseChatModel, type BaseChatModelParams } from "@langchain/core/language_models/chat_models";
7
- import type { BaseFunctionCallOptions, BaseLanguageModelInput } from "@langchain/core/language_models/base";
7
+ import type { BaseFunctionCallOptions, BaseLanguageModelInput, StructuredOutputMethodOptions, StructuredOutputMethodParams } from "@langchain/core/language_models/base";
8
8
  import { z } from "zod";
9
9
  import { Runnable } from "@langchain/core/runnables";
10
10
  import type { AzureOpenAIInput, OpenAICallOptions, OpenAIChatInput, OpenAICoreRequestOptions, LegacyOpenAIInput } from "./types.js";
@@ -142,19 +142,9 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
142
142
  _llmType(): string;
143
143
  /** @ignore */
144
144
  _combineLLMOutput(...llmOutputs: OpenAILLMOutput[]): OpenAILLMOutput;
145
- withStructuredOutput<RunInput = BaseLanguageModelInput, RunOutput extends z.ZodObject<any, any, any, any> = z.ZodObject<any, any, any, any>>({ schema, name, method, includeRaw, }: {
146
- schema: z.ZodEffects<RunOutput> | Record<string, any>;
147
- name: string;
148
- method?: "functionCalling" | "jsonMode";
149
- includeRaw: true;
150
- }): Runnable<RunInput, {
145
+ withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: StructuredOutputMethodParams<RunOutput, false> | z.ZodType<RunOutput> | Record<string, any>, config?: StructuredOutputMethodOptions<false>): Runnable<BaseLanguageModelInput, RunOutput>;
146
+ withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: StructuredOutputMethodParams<RunOutput, true> | z.ZodType<RunOutput> | Record<string, any>, config?: StructuredOutputMethodOptions<true>): Runnable<BaseLanguageModelInput, {
151
147
  raw: BaseMessage;
152
148
  parsed: RunOutput;
153
149
  }>;
154
- withStructuredOutput<RunInput = BaseLanguageModelInput, RunOutput extends z.ZodObject<any, any, any, any> = z.ZodObject<any, any, any, any>>({ schema, name, method, includeRaw, }: {
155
- schema: z.ZodEffects<RunOutput> | Record<string, any>;
156
- name: string;
157
- method?: "functionCalling" | "jsonMode";
158
- includeRaw?: false;
159
- }): Runnable<RunInput, RunOutput>;
160
150
  }
@@ -714,18 +714,24 @@ export class ChatOpenAI extends BaseChatModel {
714
714
  },
715
715
  });
716
716
  }
717
- /**
718
- * Model wrapper that returns outputs formatted to match the given schema.
719
- *
720
- * @template {z.ZodObject<any, any, any, any>} RunOutput The output type for the Runnable, expected to be a Zod schema object for structured output validation.
721
- *
722
- * @param {z.ZodEffects<RunOutput>} schema The schema for the structured output. Either as a Zod schema or a valid JSON schema object.
723
- * @param {string} name The name of the function to call.
724
- * @param {"functionCalling" | "jsonMode"} method The method to use for getting the structured output. Defaults to "functionCalling".
725
- * @param {boolean | undefined} includeRaw Whether to include the raw output in the result. Defaults to false.
726
- * @returns {Runnable<RunInput, RunOutput> | Runnable<RunInput, { raw: BaseMessage; parsed: RunOutput }>} A new runnable that calls the LLM with structured output.
727
- */
728
- withStructuredOutput({ schema, name, method = "functionCalling", includeRaw = false, }) {
717
+ withStructuredOutput(outputSchema, config) {
718
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
719
+ let schema;
720
+ let name;
721
+ let method;
722
+ let includeRaw;
723
+ if (isStructuredOutputMethodParams(outputSchema)) {
724
+ schema = outputSchema.schema;
725
+ name = outputSchema.name;
726
+ method = outputSchema.method;
727
+ includeRaw = outputSchema.includeRaw;
728
+ }
729
+ else {
730
+ schema = outputSchema;
731
+ name = config?.name;
732
+ method = config?.method;
733
+ includeRaw = config?.includeRaw;
734
+ }
729
735
  let llm;
730
736
  let outputParser;
731
737
  if (method === "jsonMode") {
@@ -735,6 +741,7 @@ export class ChatOpenAI extends BaseChatModel {
735
741
  outputParser = new JsonOutputParser();
736
742
  }
737
743
  else {
744
+ const functionName = name ?? "extract";
738
745
  // Is function calling
739
746
  if (isZodSchema(schema)) {
740
747
  const asZodSchema = zodToJsonSchema(schema);
@@ -749,11 +756,16 @@ export class ChatOpenAI extends BaseChatModel {
749
756
  },
750
757
  },
751
758
  ],
752
- tool_choice: "auto",
759
+ tool_choice: {
760
+ type: "function",
761
+ function: {
762
+ name: functionName,
763
+ },
764
+ },
753
765
  });
754
766
  outputParser = new JsonOutputKeyToolsParser({
755
767
  returnSingle: true,
756
- keyName: name,
768
+ keyName: functionName,
757
769
  });
758
770
  }
759
771
  else {
@@ -768,11 +780,16 @@ export class ChatOpenAI extends BaseChatModel {
768
780
  },
769
781
  },
770
782
  ],
771
- tool_choice: "auto",
783
+ tool_choice: {
784
+ type: "function",
785
+ function: {
786
+ name,
787
+ },
788
+ },
772
789
  });
773
790
  outputParser = new JsonOutputKeyToolsParser({
774
791
  returnSingle: true,
775
- keyName: name,
792
+ keyName: functionName,
776
793
  });
777
794
  }
778
795
  }
@@ -801,3 +818,11 @@ function isZodSchema(input) {
801
818
  // Check for a characteristic method of Zod schemas
802
819
  return typeof input?.parse === "function";
803
820
  }
821
+ function isStructuredOutputMethodParams(x
822
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
823
+ ) {
824
+ return (x !== undefined &&
825
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
826
+ typeof x.schema ===
827
+ "object");
828
+ }
@@ -641,8 +641,7 @@ describe("ChatOpenAI withStructuredOutput", () => {
641
641
  number1: z.number(),
642
642
  number2: z.number(),
643
643
  });
644
- const modelWithStructuredOutput = model.withStructuredOutput({
645
- schema: calculatorSchema,
644
+ const modelWithStructuredOutput = model.withStructuredOutput(calculatorSchema, {
646
645
  name: "calculator",
647
646
  });
648
647
  const prompt = ChatPromptTemplate.fromMessages([
@@ -668,8 +667,7 @@ describe("ChatOpenAI withStructuredOutput", () => {
668
667
  number1: z.number(),
669
668
  number2: z.number(),
670
669
  });
671
- const modelWithStructuredOutput = model.withStructuredOutput({
672
- schema: calculatorSchema,
670
+ const modelWithStructuredOutput = model.withStructuredOutput(calculatorSchema, {
673
671
  name: "calculator",
674
672
  method: "jsonMode",
675
673
  });
@@ -728,8 +726,7 @@ describe("ChatOpenAI withStructuredOutput", () => {
728
726
  number1: z.number(),
729
727
  number2: z.number(),
730
728
  });
731
- const modelWithStructuredOutput = model.withStructuredOutput({
732
- schema: zodToJsonSchema(calculatorSchema),
729
+ const modelWithStructuredOutput = model.withStructuredOutput(zodToJsonSchema(calculatorSchema), {
733
730
  name: "calculator",
734
731
  method: "jsonMode",
735
732
  });
@@ -761,8 +758,7 @@ describe("ChatOpenAI withStructuredOutput", () => {
761
758
  number1: z.number(),
762
759
  number2: z.number(),
763
760
  });
764
- const modelWithStructuredOutput = model.withStructuredOutput({
765
- schema: calculatorSchema,
761
+ const modelWithStructuredOutput = model.withStructuredOutput(calculatorSchema, {
766
762
  name: "calculator",
767
763
  includeRaw: true,
768
764
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/openai",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "OpenAI integrations for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {
@@ -39,7 +39,7 @@
39
39
  "author": "LangChain",
40
40
  "license": "MIT",
41
41
  "dependencies": {
42
- "@langchain/core": "~0.1.39",
42
+ "@langchain/core": "~0.1.41",
43
43
  "js-tiktoken": "^1.0.7",
44
44
  "openai": "^4.26.0",
45
45
  "zod": "^3.22.4",