@langchain/openai 0.2.5 → 0.2.7

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/types.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { OpenAI as OpenAIClient } from "openai";
2
+ import type { ResponseFormatText, ResponseFormatJSONObject, ResponseFormatJSONSchema } from "openai/resources/shared";
2
3
  import { TiktokenModel } from "js-tiktoken/lite";
3
4
  import type { BaseLanguageModelCallOptions } from "@langchain/core/language_models/base";
5
+ import type { z } from "zod";
4
6
  export type { TiktokenModel };
5
7
  export declare interface OpenAIBaseInput {
6
8
  /** Sampling temperature to use */
@@ -121,6 +123,11 @@ export interface OpenAIChatInput extends OpenAIBaseInput {
121
123
  * Currently in experimental beta.
122
124
  */
123
125
  __includeRawResponse?: boolean;
126
+ /**
127
+ * Whether the model supports the `strict` argument when passing in tools.
128
+ * If `undefined` the `strict` argument will not be passed to OpenAI.
129
+ */
130
+ supportsStrictToolCalling?: boolean;
124
131
  }
125
132
  export declare interface AzureOpenAIInput {
126
133
  /**
@@ -174,3 +181,13 @@ export declare interface AzureOpenAIInput {
174
181
  */
175
182
  azureADTokenProvider?: () => Promise<string>;
176
183
  }
184
+ type ChatOpenAIResponseFormatJSONSchema = Omit<ResponseFormatJSONSchema, "json_schema"> & {
185
+ json_schema: Omit<ResponseFormatJSONSchema["json_schema"], "schema"> & {
186
+ /**
187
+ * The schema for the response format, described as a JSON Schema object
188
+ * or a Zod object.
189
+ */
190
+ schema: Record<string, any> | z.ZodObject<any, any, any, any>;
191
+ };
192
+ };
193
+ export type ChatOpenAIResponseFormat = ResponseFormatText | ResponseFormatJSONObject | ChatOpenAIResponseFormatJSONSchema;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._convertToOpenAITool = void 0;
4
+ const function_calling_1 = require("@langchain/core/utils/function_calling");
5
+ const zod_1 = require("openai/helpers/zod");
6
+ /**
7
+ * Formats a tool in either OpenAI format, or LangChain structured tool format
8
+ * into an OpenAI tool format. If the tool is already in OpenAI format, return without
9
+ * any changes. If it is in LangChain structured tool format, convert it to OpenAI tool format
10
+ * using OpenAI's `zodFunction` util, falling back to `convertToOpenAIFunction` if the parameters
11
+ * returned from the `zodFunction` util are not defined.
12
+ *
13
+ * @param {BindToolsInput} tool The tool to convert to an OpenAI tool.
14
+ * @param {Object} [fields] Additional fields to add to the OpenAI tool.
15
+ * @returns {ToolDefinition} The inputted tool in OpenAI tool format.
16
+ */
17
+ function _convertToOpenAITool(
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ tool, fields) {
20
+ let toolDef;
21
+ if ((0, function_calling_1.isLangChainTool)(tool)) {
22
+ const oaiToolDef = (0, zod_1.zodFunction)({
23
+ name: tool.name,
24
+ parameters: tool.schema,
25
+ description: tool.description,
26
+ });
27
+ if (!oaiToolDef.function.parameters) {
28
+ // Fallback to the `convertToOpenAIFunction` util if the parameters are not defined.
29
+ toolDef = {
30
+ type: "function",
31
+ function: (0, function_calling_1.convertToOpenAIFunction)(tool, fields),
32
+ };
33
+ }
34
+ else {
35
+ toolDef = {
36
+ type: oaiToolDef.type,
37
+ function: {
38
+ name: oaiToolDef.function.name,
39
+ description: oaiToolDef.function.description,
40
+ parameters: oaiToolDef.function.parameters,
41
+ ...(fields?.strict !== undefined ? { strict: fields.strict } : {}),
42
+ },
43
+ };
44
+ }
45
+ }
46
+ else {
47
+ toolDef = tool;
48
+ }
49
+ if (fields?.strict !== undefined) {
50
+ toolDef.function.strict = fields.strict;
51
+ }
52
+ return toolDef;
53
+ }
54
+ exports._convertToOpenAITool = _convertToOpenAITool;
@@ -0,0 +1,20 @@
1
+ import { ToolDefinition } from "@langchain/core/language_models/base";
2
+ import { BindToolsInput } from "@langchain/core/language_models/chat_models";
3
+ /**
4
+ * Formats a tool in either OpenAI format, or LangChain structured tool format
5
+ * into an OpenAI tool format. If the tool is already in OpenAI format, return without
6
+ * any changes. If it is in LangChain structured tool format, convert it to OpenAI tool format
7
+ * using OpenAI's `zodFunction` util, falling back to `convertToOpenAIFunction` if the parameters
8
+ * returned from the `zodFunction` util are not defined.
9
+ *
10
+ * @param {BindToolsInput} tool The tool to convert to an OpenAI tool.
11
+ * @param {Object} [fields] Additional fields to add to the OpenAI tool.
12
+ * @returns {ToolDefinition} The inputted tool in OpenAI tool format.
13
+ */
14
+ export declare function _convertToOpenAITool(tool: BindToolsInput, fields?: {
15
+ /**
16
+ * If `true`, model output is guaranteed to exactly match the JSON Schema
17
+ * provided in the function definition.
18
+ */
19
+ strict?: boolean;
20
+ }): ToolDefinition;
@@ -0,0 +1,50 @@
1
+ import { convertToOpenAIFunction, isLangChainTool, } from "@langchain/core/utils/function_calling";
2
+ import { zodFunction } from "openai/helpers/zod";
3
+ /**
4
+ * Formats a tool in either OpenAI format, or LangChain structured tool format
5
+ * into an OpenAI tool format. If the tool is already in OpenAI format, return without
6
+ * any changes. If it is in LangChain structured tool format, convert it to OpenAI tool format
7
+ * using OpenAI's `zodFunction` util, falling back to `convertToOpenAIFunction` if the parameters
8
+ * returned from the `zodFunction` util are not defined.
9
+ *
10
+ * @param {BindToolsInput} tool The tool to convert to an OpenAI tool.
11
+ * @param {Object} [fields] Additional fields to add to the OpenAI tool.
12
+ * @returns {ToolDefinition} The inputted tool in OpenAI tool format.
13
+ */
14
+ export function _convertToOpenAITool(
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ tool, fields) {
17
+ let toolDef;
18
+ if (isLangChainTool(tool)) {
19
+ const oaiToolDef = zodFunction({
20
+ name: tool.name,
21
+ parameters: tool.schema,
22
+ description: tool.description,
23
+ });
24
+ if (!oaiToolDef.function.parameters) {
25
+ // Fallback to the `convertToOpenAIFunction` util if the parameters are not defined.
26
+ toolDef = {
27
+ type: "function",
28
+ function: convertToOpenAIFunction(tool, fields),
29
+ };
30
+ }
31
+ else {
32
+ toolDef = {
33
+ type: oaiToolDef.type,
34
+ function: {
35
+ name: oaiToolDef.function.name,
36
+ description: oaiToolDef.function.description,
37
+ parameters: oaiToolDef.function.parameters,
38
+ ...(fields?.strict !== undefined ? { strict: fields.strict } : {}),
39
+ },
40
+ };
41
+ }
42
+ }
43
+ else {
44
+ toolDef = tool;
45
+ }
46
+ if (fields?.strict !== undefined) {
47
+ toolDef.function.strict = fields.strict;
48
+ }
49
+ return toolDef;
50
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/openai",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "OpenAI integrations for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {
@@ -15,7 +15,7 @@
15
15
  "homepage": "https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain-openai/",
16
16
  "scripts": {
17
17
  "build": "yarn turbo:command build:internal --filter=@langchain/openai",
18
- "build:internal": "yarn lc-build:v2 --create-entrypoints --pre --tree-shaking",
18
+ "build:internal": "yarn lc_build_v2 --create-entrypoints --pre --tree-shaking",
19
19
  "lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js src/",
20
20
  "lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
21
21
  "lint": "yarn lint:eslint && yarn lint:dpdm",
@@ -35,16 +35,16 @@
35
35
  "author": "LangChain",
36
36
  "license": "MIT",
37
37
  "dependencies": {
38
- "@langchain/core": ">=0.2.16 <0.3.0",
38
+ "@langchain/core": ">=0.2.26 <0.3.0",
39
39
  "js-tiktoken": "^1.0.12",
40
- "openai": "^4.49.1",
40
+ "openai": "^4.55.0",
41
41
  "zod": "^3.22.4",
42
42
  "zod-to-json-schema": "^3.22.3"
43
43
  },
44
44
  "devDependencies": {
45
- "@azure/identity": "^4.2.0",
45
+ "@azure/identity": "^4.2.1",
46
46
  "@jest/globals": "^29.5.0",
47
- "@langchain/scripts": "~0.0.14",
47
+ "@langchain/scripts": "^0.0.21",
48
48
  "@langchain/standard-tests": "0.0.0",
49
49
  "@swc/core": "^1.3.90",
50
50
  "@swc/jest": "^0.2.29",
@@ -59,7 +59,7 @@
59
59
  "jest": "^29.5.0",
60
60
  "jest-environment-node": "^29.6.4",
61
61
  "prettier": "^2.8.3",
62
- "release-it": "^15.10.1",
62
+ "release-it": "^17.6.0",
63
63
  "rimraf": "^5.0.1",
64
64
  "ts-jest": "^29.1.0",
65
65
  "typescript": "~5.1.6"
@@ -1 +0,0 @@
1
- export {};
@@ -1,57 +0,0 @@
1
- import { test, expect } from "@jest/globals";
2
- import { DallEAPIWrapper } from "../dalle.js";
3
- test.skip("Dalle can generate images", async () => {
4
- const dalle = new DallEAPIWrapper();
5
- const res = await dalle.invoke("A painting of a cat");
6
- expect(res).toBeDefined();
7
- expect(res).toContain("https://");
8
- });
9
- test.skip("Dalle can generate images with base 64 response format", async () => {
10
- const dalle = new DallEAPIWrapper({
11
- responseFormat: "b64_json",
12
- });
13
- const res = await dalle.invoke("A painting of a cat");
14
- expect(res).toBeDefined();
15
- expect(res).not.toContain("https://");
16
- });
17
- test.skip("Dalle returns multiple image URLs if n > 1", async () => {
18
- const dalle = new DallEAPIWrapper({
19
- n: 2,
20
- });
21
- const res = await dalle.invoke("A painting of a cat");
22
- expect(res).toBeDefined();
23
- expect(res).toBeInstanceOf(Array);
24
- if (!Array.isArray(res))
25
- return;
26
- expect(res).toHaveLength(2);
27
- // The types for each should be `image_url` with an `image_url` field containing the URL
28
- expect(res[0].type).toBe("image_url");
29
- expect(res[1].type).toBe("image_url");
30
- expect(res[0]).toHaveProperty("image_url");
31
- expect(res[1]).toHaveProperty("image_url");
32
- expect(res[0].image_url.startsWith("https://")).toBe(true);
33
- expect(res[1].image_url.startsWith("https://")).toBe(true);
34
- });
35
- test.skip("Dalle returns multiple base64 image strings if n > 1", async () => {
36
- const dalle = new DallEAPIWrapper({
37
- n: 2,
38
- dallEResponseFormat: "b64_json",
39
- });
40
- const res = await dalle.invoke("A painting of a cat");
41
- expect(res).toBeDefined();
42
- expect(res).toBeInstanceOf(Array);
43
- if (!Array.isArray(res))
44
- return;
45
- expect(res).toHaveLength(2);
46
- // The types for each should be `b64_json` with an `b64_json` field containing the URL
47
- expect(res[0].type).toBe("image_url");
48
- expect(res[1].type).toBe("image_url");
49
- expect(res[0]).toHaveProperty("image_url");
50
- expect(res[1]).toHaveProperty("image_url");
51
- expect(res[0].image_url).toHaveProperty("url");
52
- expect(res[1].image_url).toHaveProperty("url");
53
- expect(res[0].image_url.url).toBeDefined();
54
- expect(res[1].image_url.url).toBeDefined();
55
- expect(res[0].image_url.url).not.toBe("");
56
- expect(res[1].image_url.url).not.toBe("");
57
- });