@langchain/openai 0.0.32 → 0.0.34

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,232 +0,0 @@
1
- import { z } from "zod";
2
- import { zodToJsonSchema } from "zod-to-json-schema";
3
- import { ChatPromptTemplate } from "@langchain/core/prompts";
4
- import { ChatOpenAI } from "../chat_models.js";
5
- test("withStructuredOutput zod schema function calling", async () => {
6
- const model = new ChatOpenAI({
7
- temperature: 0,
8
- modelName: "gpt-4-turbo-preview",
9
- });
10
- const calculatorSchema = z.object({
11
- operation: z.enum(["add", "subtract", "multiply", "divide"]),
12
- number1: z.number(),
13
- number2: z.number(),
14
- });
15
- const modelWithStructuredOutput = model.withStructuredOutput(calculatorSchema, {
16
- name: "calculator",
17
- });
18
- const prompt = ChatPromptTemplate.fromMessages([
19
- "system",
20
- "You are VERY bad at math and must always use a calculator.",
21
- "human",
22
- "Please help me!! What is 2 + 2?",
23
- ]);
24
- const chain = prompt.pipe(modelWithStructuredOutput);
25
- const result = await chain.invoke({});
26
- console.log(result);
27
- expect("operation" in result).toBe(true);
28
- expect("number1" in result).toBe(true);
29
- expect("number2" in result).toBe(true);
30
- });
31
- test("withStructuredOutput zod schema JSON mode", async () => {
32
- const model = new ChatOpenAI({
33
- temperature: 0,
34
- modelName: "gpt-4-turbo-preview",
35
- });
36
- const calculatorSchema = z.object({
37
- operation: z.enum(["add", "subtract", "multiply", "divide"]),
38
- number1: z.number(),
39
- number2: z.number(),
40
- });
41
- const modelWithStructuredOutput = model.withStructuredOutput(calculatorSchema, {
42
- name: "calculator",
43
- method: "jsonMode",
44
- });
45
- const prompt = ChatPromptTemplate.fromMessages([
46
- "system",
47
- `You are VERY bad at math and must always use a calculator.
48
- Respond with a JSON object containing three keys:
49
- 'operation': the type of operation to execute, either 'add', 'subtract', 'multiply' or 'divide',
50
- 'number1': the first number to operate on,
51
- 'number2': the second number to operate on.
52
- `,
53
- "human",
54
- "Please help me!! What is 2 + 2?",
55
- ]);
56
- const chain = prompt.pipe(modelWithStructuredOutput);
57
- const result = await chain.invoke({});
58
- console.log(result);
59
- expect("operation" in result).toBe(true);
60
- expect("number1" in result).toBe(true);
61
- expect("number2" in result).toBe(true);
62
- });
63
- test("withStructuredOutput JSON schema function calling", async () => {
64
- const model = new ChatOpenAI({
65
- temperature: 0,
66
- modelName: "gpt-4-turbo-preview",
67
- });
68
- const calculatorSchema = z.object({
69
- operation: z.enum(["add", "subtract", "multiply", "divide"]),
70
- number1: z.number(),
71
- number2: z.number(),
72
- });
73
- const modelWithStructuredOutput = model.withStructuredOutput({
74
- schema: zodToJsonSchema(calculatorSchema),
75
- name: "calculator",
76
- });
77
- const prompt = ChatPromptTemplate.fromMessages([
78
- "system",
79
- `You are VERY bad at math and must always use a calculator.`,
80
- "human",
81
- "Please help me!! What is 2 + 2?",
82
- ]);
83
- const chain = prompt.pipe(modelWithStructuredOutput);
84
- const result = await chain.invoke({});
85
- console.log(result);
86
- expect("operation" in result).toBe(true);
87
- expect("number1" in result).toBe(true);
88
- expect("number2" in result).toBe(true);
89
- });
90
- test("withStructuredOutput OpenAI function definition function calling", async () => {
91
- const model = new ChatOpenAI({
92
- temperature: 0,
93
- modelName: "gpt-4-turbo-preview",
94
- });
95
- const calculatorSchema = z.object({
96
- operation: z.enum(["add", "subtract", "multiply", "divide"]),
97
- number1: z.number(),
98
- number2: z.number(),
99
- });
100
- const modelWithStructuredOutput = model.withStructuredOutput({
101
- name: "calculator",
102
- parameters: zodToJsonSchema(calculatorSchema),
103
- });
104
- const prompt = ChatPromptTemplate.fromMessages([
105
- "system",
106
- `You are VERY bad at math and must always use a calculator.`,
107
- "human",
108
- "Please help me!! What is 2 + 2?",
109
- ]);
110
- const chain = prompt.pipe(modelWithStructuredOutput);
111
- const result = await chain.invoke({});
112
- console.log(result);
113
- expect("operation" in result).toBe(true);
114
- expect("number1" in result).toBe(true);
115
- expect("number2" in result).toBe(true);
116
- });
117
- test("withStructuredOutput JSON schema JSON mode", async () => {
118
- const model = new ChatOpenAI({
119
- temperature: 0,
120
- modelName: "gpt-4-turbo-preview",
121
- });
122
- const calculatorSchema = z.object({
123
- operation: z.enum(["add", "subtract", "multiply", "divide"]),
124
- number1: z.number(),
125
- number2: z.number(),
126
- });
127
- const modelWithStructuredOutput = model.withStructuredOutput(zodToJsonSchema(calculatorSchema), {
128
- name: "calculator",
129
- method: "jsonMode",
130
- });
131
- const prompt = ChatPromptTemplate.fromMessages([
132
- "system",
133
- `You are VERY bad at math and must always use a calculator.
134
- Respond with a JSON object containing three keys:
135
- 'operation': the type of operation to execute, either 'add', 'subtract', 'multiply' or 'divide',
136
- 'number1': the first number to operate on,
137
- 'number2': the second number to operate on.
138
- `,
139
- "human",
140
- "Please help me!! What is 2 + 2?",
141
- ]);
142
- const chain = prompt.pipe(modelWithStructuredOutput);
143
- const result = await chain.invoke({});
144
- console.log(result);
145
- expect("operation" in result).toBe(true);
146
- expect("number1" in result).toBe(true);
147
- expect("number2" in result).toBe(true);
148
- });
149
- test("withStructuredOutput JSON schema", async () => {
150
- const model = new ChatOpenAI({
151
- temperature: 0,
152
- modelName: "gpt-4-turbo-preview",
153
- });
154
- const jsonSchema = {
155
- title: "calculator",
156
- description: "A simple calculator",
157
- type: "object",
158
- properties: {
159
- operation: {
160
- type: "string",
161
- enum: ["add", "subtract", "multiply", "divide"],
162
- },
163
- number1: { type: "number" },
164
- number2: { type: "number" },
165
- },
166
- };
167
- const modelWithStructuredOutput = model.withStructuredOutput(jsonSchema);
168
- const prompt = ChatPromptTemplate.fromMessages([
169
- "system",
170
- `You are VERY bad at math and must always use a calculator.
171
- Respond with a JSON object containing three keys:
172
- 'operation': the type of operation to execute, either 'add', 'subtract', 'multiply' or 'divide',
173
- 'number1': the first number to operate on,
174
- 'number2': the second number to operate on.
175
- `,
176
- "human",
177
- "Please help me!! What is 2 + 2?",
178
- ]);
179
- const chain = prompt.pipe(modelWithStructuredOutput);
180
- const result = await chain.invoke({});
181
- console.log(result);
182
- expect("operation" in result).toBe(true);
183
- expect("number1" in result).toBe(true);
184
- expect("number2" in result).toBe(true);
185
- });
186
- test("withStructuredOutput includeRaw true", async () => {
187
- const model = new ChatOpenAI({
188
- temperature: 0,
189
- modelName: "gpt-4-turbo-preview",
190
- });
191
- const calculatorSchema = z.object({
192
- operation: z.enum(["add", "subtract", "multiply", "divide"]),
193
- number1: z.number(),
194
- number2: z.number(),
195
- });
196
- const modelWithStructuredOutput = model.withStructuredOutput(calculatorSchema, {
197
- name: "calculator",
198
- includeRaw: true,
199
- });
200
- const prompt = ChatPromptTemplate.fromMessages([
201
- "system",
202
- "You are VERY bad at math and must always use a calculator.",
203
- "human",
204
- "Please help me!! What is 2 + 2?",
205
- ]);
206
- const chain = prompt.pipe(modelWithStructuredOutput);
207
- const result = await chain.invoke({});
208
- console.log(result);
209
- expect("parsed" in result).toBe(true);
210
- // Need to make TS happy :)
211
- if (!("parsed" in result)) {
212
- throw new Error("parsed not in result");
213
- }
214
- const { parsed } = result;
215
- expect("operation" in parsed).toBe(true);
216
- expect("number1" in parsed).toBe(true);
217
- expect("number2" in parsed).toBe(true);
218
- expect("raw" in result).toBe(true);
219
- // Need to make TS happy :)
220
- if (!("raw" in result)) {
221
- throw new Error("raw not in result");
222
- }
223
- const { raw } = result;
224
- expect(raw.additional_kwargs.tool_calls?.length).toBeGreaterThan(0);
225
- expect(raw.additional_kwargs.tool_calls?.[0].function.name).toBe("calculator");
226
- expect("operation" in
227
- JSON.parse(raw.additional_kwargs.tool_calls?.[0].function.arguments ?? "")).toBe(true);
228
- expect("number1" in
229
- JSON.parse(raw.additional_kwargs.tool_calls?.[0].function.arguments ?? "")).toBe(true);
230
- expect("number2" in
231
- JSON.parse(raw.additional_kwargs.tool_calls?.[0].function.arguments ?? "")).toBe(true);
232
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,84 +0,0 @@
1
- import { test, expect } from "@jest/globals";
2
- import { OpenAIEmbeddings } from "../embeddings.js";
3
- test("Test OpenAIEmbeddings.embedQuery", async () => {
4
- const embeddings = new OpenAIEmbeddings();
5
- const res = await embeddings.embedQuery("Hello world");
6
- expect(typeof res[0]).toBe("number");
7
- });
8
- test("Test OpenAIEmbeddings.embedDocuments", async () => {
9
- const embeddings = new OpenAIEmbeddings();
10
- const res = await embeddings.embedDocuments(["Hello world", "Bye bye"]);
11
- expect(res).toHaveLength(2);
12
- expect(typeof res[0][0]).toBe("number");
13
- expect(typeof res[1][0]).toBe("number");
14
- });
15
- test("Test OpenAIEmbeddings concurrency", async () => {
16
- const embeddings = new OpenAIEmbeddings({
17
- batchSize: 1,
18
- maxConcurrency: 2,
19
- });
20
- const res = await embeddings.embedDocuments([
21
- "Hello world",
22
- "Bye bye",
23
- "Hello world",
24
- "Bye bye",
25
- "Hello world",
26
- "Bye bye",
27
- ]);
28
- expect(res).toHaveLength(6);
29
- expect(res.find((embedding) => typeof embedding[0] !== "number")).toBe(undefined);
30
- });
31
- test("Test timeout error thrown from SDK", async () => {
32
- await expect(async () => {
33
- const model = new OpenAIEmbeddings({
34
- timeout: 1,
35
- maxRetries: 0,
36
- });
37
- await model.embedDocuments([
38
- "Hello world",
39
- "Bye bye",
40
- "Hello world",
41
- "Bye bye",
42
- "Hello world",
43
- "Bye bye",
44
- ]);
45
- }).rejects.toThrow();
46
- });
47
- test("Test OpenAI embeddings with an invalid org throws", async () => {
48
- await expect(async () => {
49
- const model = new OpenAIEmbeddings({
50
- configuration: {
51
- organization: "NOT_REAL",
52
- },
53
- });
54
- await model.embedDocuments([
55
- "Hello world",
56
- "Bye bye",
57
- "Hello world",
58
- "Bye bye",
59
- "Hello world",
60
- "Bye bye",
61
- ]);
62
- }).rejects.toThrow();
63
- });
64
- test("Test OpenAIEmbeddings.embedQuery with v3 and dimensions", async () => {
65
- const embeddings = new OpenAIEmbeddings({
66
- modelName: "text-embedding-3-small",
67
- dimensions: 127,
68
- });
69
- const res = await embeddings.embedQuery("Hello world");
70
- expect(typeof res[0]).toBe("number");
71
- expect(res.length).toBe(127);
72
- });
73
- test("Test OpenAIEmbeddings.embedDocuments with v3 and dimensions", async () => {
74
- const embeddings = new OpenAIEmbeddings({
75
- modelName: "text-embedding-3-small",
76
- dimensions: 127,
77
- });
78
- const res = await embeddings.embedDocuments(["Hello world", "Bye bye"]);
79
- expect(res).toHaveLength(2);
80
- expect(typeof res[0][0]).toBe("number");
81
- expect(typeof res[1][0]).toBe("number");
82
- expect(res[0].length).toBe(127);
83
- expect(res[1].length).toBe(127);
84
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,115 +0,0 @@
1
- import { expect, test } from "@jest/globals";
2
- import { CallbackManager } from "@langchain/core/callbacks/manager";
3
- import { OpenAIChat } from "../legacy.js";
4
- test("Test OpenAI", async () => {
5
- const model = new OpenAIChat({ modelName: "gpt-3.5-turbo", maxTokens: 10 });
6
- const res = await model.invoke("Print hello world");
7
- console.log({ res });
8
- });
9
- test("Test OpenAI with prefix messages", async () => {
10
- const model = new OpenAIChat({
11
- prefixMessages: [
12
- { role: "user", content: "My name is John" },
13
- { role: "assistant", content: "Hi there" },
14
- ],
15
- maxTokens: 10,
16
- });
17
- const res = await model.invoke("What is my name");
18
- console.log({ res });
19
- });
20
- test("Test OpenAI in streaming mode", async () => {
21
- let nrNewTokens = 0;
22
- let streamedCompletion = "";
23
- const model = new OpenAIChat({
24
- maxTokens: 10,
25
- modelName: "gpt-3.5-turbo",
26
- streaming: true,
27
- callbackManager: CallbackManager.fromHandlers({
28
- async handleLLMNewToken(token) {
29
- nrNewTokens += 1;
30
- streamedCompletion += token;
31
- },
32
- }),
33
- });
34
- const res = await model.invoke("Print hello world");
35
- console.log({ res });
36
- expect(nrNewTokens > 0).toBe(true);
37
- expect(res).toBe(streamedCompletion);
38
- }, 30000);
39
- test("Test OpenAI with stop", async () => {
40
- const model = new OpenAIChat({ maxTokens: 5 });
41
- const res = await model.call("Print hello world", ["world"]);
42
- console.log({ res });
43
- });
44
- test("Test OpenAI with stop in object", async () => {
45
- const model = new OpenAIChat({ maxTokens: 5 });
46
- const res = await model.invoke("Print hello world", { stop: ["world"] });
47
- console.log({ res });
48
- });
49
- test("Test OpenAI with timeout in call options", async () => {
50
- const model = new OpenAIChat({ maxTokens: 5 });
51
- await expect(() => model.invoke("Print hello world", {
52
- timeout: 10,
53
- })).rejects.toThrow();
54
- }, 5000);
55
- test("Test OpenAI with timeout in call options and node adapter", async () => {
56
- const model = new OpenAIChat({ maxTokens: 5 });
57
- await expect(() => model.invoke("Print hello world", {
58
- timeout: 10,
59
- })).rejects.toThrow();
60
- }, 5000);
61
- test("Test OpenAI with signal in call options", async () => {
62
- const model = new OpenAIChat({ maxTokens: 5 });
63
- const controller = new AbortController();
64
- await expect(() => {
65
- const ret = model.invoke("Print hello world", {
66
- signal: controller.signal,
67
- });
68
- controller.abort();
69
- return ret;
70
- }).rejects.toThrow();
71
- }, 5000);
72
- test("Test OpenAI with signal in call options and node adapter", async () => {
73
- const model = new OpenAIChat({ maxTokens: 5 });
74
- const controller = new AbortController();
75
- await expect(() => {
76
- const ret = model.invoke("Print hello world", {
77
- signal: controller.signal,
78
- });
79
- controller.abort();
80
- return ret;
81
- }).rejects.toThrow();
82
- }, 5000);
83
- test("Test OpenAIChat stream method", async () => {
84
- const model = new OpenAIChat({ maxTokens: 50, modelName: "gpt-3.5-turbo" });
85
- const stream = await model.stream("Print hello world.");
86
- const chunks = [];
87
- for await (const chunk of stream) {
88
- chunks.push(chunk);
89
- console.log(chunks);
90
- }
91
- expect(chunks.length).toBeGreaterThan(1);
92
- });
93
- test("Test OpenAIChat stream method with abort", async () => {
94
- await expect(async () => {
95
- const model = new OpenAIChat({ maxTokens: 50, modelName: "gpt-3.5-turbo" });
96
- const stream = await model.stream("How is your day going? Be extremely verbose.", {
97
- signal: AbortSignal.timeout(1000),
98
- });
99
- for await (const chunk of stream) {
100
- console.log(chunk);
101
- }
102
- }).rejects.toThrow();
103
- });
104
- test("Test OpenAIChat stream method with early break", async () => {
105
- const model = new OpenAIChat({ maxTokens: 50, modelName: "gpt-3.5-turbo" });
106
- const stream = await model.stream("How is your day going? Be extremely verbose.");
107
- let i = 0;
108
- for await (const chunk of stream) {
109
- console.log(chunk);
110
- i += 1;
111
- if (i > 5) {
112
- break;
113
- }
114
- }
115
- });
@@ -1 +0,0 @@
1
- export {};