@langchain/openai 0.0.33 → 0.1.0

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.
Files changed (32) hide show
  1. package/dist/azure/chat_models.cjs +7 -3
  2. package/dist/azure/chat_models.js +7 -3
  3. package/dist/azure/embeddings.cjs +7 -3
  4. package/dist/azure/embeddings.js +7 -3
  5. package/dist/azure/llms.cjs +7 -3
  6. package/dist/azure/llms.js +7 -3
  7. package/dist/chat_models.cjs +21 -0
  8. package/dist/chat_models.d.ts +3 -0
  9. package/dist/chat_models.js +21 -0
  10. package/dist/utils/azure.cjs +1 -1
  11. package/dist/utils/azure.js +1 -1
  12. package/package.json +6 -5
  13. package/dist/tests/azure/chat_models.int.test.d.ts +0 -1
  14. package/dist/tests/azure/chat_models.int.test.js +0 -659
  15. package/dist/tests/azure/embeddings.int.test.d.ts +0 -1
  16. package/dist/tests/azure/embeddings.int.test.js +0 -67
  17. package/dist/tests/azure/llms.int.test.d.ts +0 -1
  18. package/dist/tests/azure/llms.int.test.js +0 -267
  19. package/dist/tests/chat_models-extended.int.test.d.ts +0 -1
  20. package/dist/tests/chat_models-extended.int.test.js +0 -259
  21. package/dist/tests/chat_models-vision.int.test.d.ts +0 -1
  22. package/dist/tests/chat_models-vision.int.test.js +0 -51
  23. package/dist/tests/chat_models.int.test.d.ts +0 -1
  24. package/dist/tests/chat_models.int.test.js +0 -622
  25. package/dist/tests/chat_models_structured_output.int.test.d.ts +0 -1
  26. package/dist/tests/chat_models_structured_output.int.test.js +0 -232
  27. package/dist/tests/embeddings.int.test.d.ts +0 -1
  28. package/dist/tests/embeddings.int.test.js +0 -84
  29. package/dist/tests/legacy.int.test.d.ts +0 -1
  30. package/dist/tests/legacy.int.test.js +0 -115
  31. package/dist/tests/llms.int.test.d.ts +0 -1
  32. package/dist/tests/llms.int.test.js +0 -260
@@ -1,622 +0,0 @@
1
- import { test, jest, expect } from "@jest/globals";
2
- import { ChatMessage, HumanMessage, SystemMessage, } from "@langchain/core/messages";
3
- import { ChatPromptValue } from "@langchain/core/prompt_values";
4
- import { PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate, } from "@langchain/core/prompts";
5
- import { CallbackManager } from "@langchain/core/callbacks/manager";
6
- import { InMemoryCache } from "@langchain/core/caches";
7
- import { ChatOpenAI } from "../chat_models.js";
8
- test("Test ChatOpenAI Generate", async () => {
9
- const chat = new ChatOpenAI({
10
- modelName: "gpt-3.5-turbo",
11
- maxTokens: 10,
12
- n: 2,
13
- });
14
- const message = new HumanMessage("Hello!");
15
- const res = await chat.generate([[message], [message]]);
16
- expect(res.generations.length).toBe(2);
17
- for (const generation of res.generations) {
18
- expect(generation.length).toBe(2);
19
- for (const message of generation) {
20
- console.log(message.text);
21
- expect(typeof message.text).toBe("string");
22
- }
23
- }
24
- console.log({ res });
25
- });
26
- test("Test ChatOpenAI Generate throws when one of the calls fails", async () => {
27
- const chat = new ChatOpenAI({
28
- modelName: "gpt-3.5-turbo",
29
- maxTokens: 10,
30
- n: 2,
31
- });
32
- const message = new HumanMessage("Hello!");
33
- await expect(() => chat.generate([[message], [message]], {
34
- signal: AbortSignal.timeout(10),
35
- })).rejects.toThrow();
36
- });
37
- test("Test ChatOpenAI tokenUsage", async () => {
38
- let tokenUsage = {
39
- completionTokens: 0,
40
- promptTokens: 0,
41
- totalTokens: 0,
42
- };
43
- const model = new ChatOpenAI({
44
- modelName: "gpt-3.5-turbo",
45
- maxTokens: 10,
46
- callbackManager: CallbackManager.fromHandlers({
47
- async handleLLMEnd(output) {
48
- tokenUsage = output.llmOutput?.tokenUsage;
49
- },
50
- }),
51
- });
52
- const message = new HumanMessage("Hello");
53
- const res = await model.invoke([message]);
54
- console.log({ res });
55
- expect(tokenUsage.promptTokens).toBeGreaterThan(0);
56
- });
57
- test("Test ChatOpenAI tokenUsage with a batch", async () => {
58
- let tokenUsage = {
59
- completionTokens: 0,
60
- promptTokens: 0,
61
- totalTokens: 0,
62
- };
63
- const model = new ChatOpenAI({
64
- temperature: 0,
65
- modelName: "gpt-3.5-turbo",
66
- callbackManager: CallbackManager.fromHandlers({
67
- async handleLLMEnd(output) {
68
- tokenUsage = output.llmOutput?.tokenUsage;
69
- },
70
- }),
71
- });
72
- const res = await model.generate([
73
- [new HumanMessage("Hello")],
74
- [new HumanMessage("Hi")],
75
- ]);
76
- console.log(res);
77
- expect(tokenUsage.promptTokens).toBeGreaterThan(0);
78
- });
79
- test("Test ChatOpenAI in streaming mode", async () => {
80
- let nrNewTokens = 0;
81
- let streamedCompletion = "";
82
- const model = new ChatOpenAI({
83
- modelName: "gpt-3.5-turbo",
84
- streaming: true,
85
- maxTokens: 10,
86
- callbacks: [
87
- {
88
- async handleLLMNewToken(token) {
89
- nrNewTokens += 1;
90
- streamedCompletion += token;
91
- },
92
- },
93
- ],
94
- });
95
- const message = new HumanMessage("Hello!");
96
- const result = await model.invoke([message]);
97
- console.log(result);
98
- expect(nrNewTokens > 0).toBe(true);
99
- expect(result.content).toBe(streamedCompletion);
100
- }, 10000);
101
- test("Test ChatOpenAI in streaming mode with n > 1 and multiple prompts", async () => {
102
- let nrNewTokens = 0;
103
- const streamedCompletions = [
104
- ["", ""],
105
- ["", ""],
106
- ];
107
- const model = new ChatOpenAI({
108
- modelName: "gpt-3.5-turbo",
109
- streaming: true,
110
- maxTokens: 10,
111
- n: 2,
112
- callbacks: [
113
- {
114
- async handleLLMNewToken(token, idx) {
115
- nrNewTokens += 1;
116
- streamedCompletions[idx.prompt][idx.completion] += token;
117
- },
118
- },
119
- ],
120
- });
121
- const message1 = new HumanMessage("Hello!");
122
- const message2 = new HumanMessage("Bye!");
123
- const result = await model.generate([[message1], [message2]]);
124
- console.log(result.generations);
125
- expect(nrNewTokens > 0).toBe(true);
126
- expect(result.generations.map((g) => g.map((gg) => gg.text))).toEqual(streamedCompletions);
127
- }, 10000);
128
- test("Test ChatOpenAI prompt value", async () => {
129
- const chat = new ChatOpenAI({
130
- modelName: "gpt-3.5-turbo",
131
- maxTokens: 10,
132
- n: 2,
133
- });
134
- const message = new HumanMessage("Hello!");
135
- const res = await chat.generatePrompt([new ChatPromptValue([message])]);
136
- expect(res.generations.length).toBe(1);
137
- for (const generation of res.generations) {
138
- expect(generation.length).toBe(2);
139
- for (const g of generation) {
140
- console.log(g.text);
141
- }
142
- }
143
- console.log({ res });
144
- });
145
- test("OpenAI Chat, docs, prompt templates", async () => {
146
- const chat = new ChatOpenAI({ temperature: 0, maxTokens: 10 });
147
- const systemPrompt = PromptTemplate.fromTemplate("You are a helpful assistant that translates {input_language} to {output_language}.");
148
- const chatPrompt = ChatPromptTemplate.fromMessages([
149
- new SystemMessagePromptTemplate(systemPrompt),
150
- HumanMessagePromptTemplate.fromTemplate("{text}"),
151
- ]);
152
- const responseA = await chat.generatePrompt([
153
- await chatPrompt.formatPromptValue({
154
- input_language: "English",
155
- output_language: "French",
156
- text: "I love programming.",
157
- }),
158
- ]);
159
- console.log(responseA.generations);
160
- }, 5000);
161
- test("Test OpenAI with stop", async () => {
162
- const model = new ChatOpenAI({ maxTokens: 5 });
163
- const res = await model.invoke([new HumanMessage("Print hello world")], {
164
- stop: ["world"],
165
- });
166
- console.log({ res });
167
- });
168
- test("Test OpenAI with stop in object", async () => {
169
- const model = new ChatOpenAI({ maxTokens: 5 });
170
- const res = await model.invoke([new HumanMessage("Print hello world")], {
171
- stop: ["world"],
172
- });
173
- console.log({ res });
174
- });
175
- test("Test OpenAI with timeout in call options", async () => {
176
- const model = new ChatOpenAI({ maxTokens: 5, maxRetries: 0 });
177
- await expect(() => model.invoke([new HumanMessage("Print hello world")], {
178
- options: { timeout: 10 },
179
- })).rejects.toThrow();
180
- }, 5000);
181
- test("Test OpenAI with timeout in call options and node adapter", async () => {
182
- const model = new ChatOpenAI({ maxTokens: 5, maxRetries: 0 });
183
- await expect(() => model.invoke([new HumanMessage("Print hello world")], {
184
- options: { timeout: 10 },
185
- })).rejects.toThrow();
186
- }, 5000);
187
- test("Test OpenAI with signal in call options", async () => {
188
- const model = new ChatOpenAI({ maxTokens: 5 });
189
- const controller = new AbortController();
190
- await expect(() => {
191
- const ret = model.invoke([new HumanMessage("Print hello world")], {
192
- options: { signal: controller.signal },
193
- });
194
- controller.abort();
195
- return ret;
196
- }).rejects.toThrow();
197
- }, 5000);
198
- test("Test OpenAI with signal in call options and node adapter", async () => {
199
- const model = new ChatOpenAI({
200
- maxTokens: 5,
201
- modelName: "gpt-3.5-turbo-instruct",
202
- });
203
- const controller = new AbortController();
204
- await expect(() => {
205
- const ret = model.invoke([new HumanMessage("Print hello world")], {
206
- options: { signal: controller.signal },
207
- });
208
- controller.abort();
209
- return ret;
210
- }).rejects.toThrow();
211
- }, 5000);
212
- function createSystemChatMessage(text, name) {
213
- const msg = new SystemMessage(text);
214
- msg.name = name;
215
- return msg;
216
- }
217
- function createSampleMessages() {
218
- // same example as in https://github.com/openai/openai-cookbook/blob/main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb
219
- return [
220
- createSystemChatMessage("You are a helpful, pattern-following assistant that translates corporate jargon into plain English."),
221
- createSystemChatMessage("New synergies will help drive top-line growth.", "example_user"),
222
- createSystemChatMessage("Things working well together will increase revenue.", "example_assistant"),
223
- createSystemChatMessage("Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage.", "example_user"),
224
- createSystemChatMessage("Let's talk later when we're less busy about how to do better.", "example_assistant"),
225
- new HumanMessage("This late pivot means we don't have time to boil the ocean for the client deliverable."),
226
- ];
227
- }
228
- test("getNumTokensFromMessages gpt-3.5-turbo-0301 model for sample input", async () => {
229
- const messages = createSampleMessages();
230
- const chat = new ChatOpenAI({
231
- openAIApiKey: "dummy",
232
- modelName: "gpt-3.5-turbo-0301",
233
- });
234
- const { totalCount } = await chat.getNumTokensFromMessages(messages);
235
- expect(totalCount).toBe(127);
236
- });
237
- test("getNumTokensFromMessages gpt-4-0314 model for sample input", async () => {
238
- const messages = createSampleMessages();
239
- const chat = new ChatOpenAI({
240
- openAIApiKey: "dummy",
241
- modelName: "gpt-4-0314",
242
- });
243
- const { totalCount } = await chat.getNumTokensFromMessages(messages);
244
- expect(totalCount).toBe(129);
245
- });
246
- test("Test OpenAI with specific roles in ChatMessage", async () => {
247
- const chat = new ChatOpenAI({ modelName: "gpt-3.5-turbo", maxTokens: 10 });
248
- const system_message = new ChatMessage("You are to chat with a user.", "system");
249
- const user_message = new ChatMessage("Hello!", "user");
250
- const res = await chat.invoke([system_message, user_message]);
251
- console.log({ res });
252
- });
253
- test("Test ChatOpenAI stream method", async () => {
254
- const model = new ChatOpenAI({ maxTokens: 50, modelName: "gpt-3.5-turbo" });
255
- const stream = await model.stream("Print hello world.");
256
- const chunks = [];
257
- for await (const chunk of stream) {
258
- console.log(chunk);
259
- chunks.push(chunk);
260
- }
261
- expect(chunks.length).toBeGreaterThan(1);
262
- });
263
- test("Test ChatOpenAI stream method with abort", async () => {
264
- await expect(async () => {
265
- const model = new ChatOpenAI({
266
- maxTokens: 100,
267
- modelName: "gpt-3.5-turbo",
268
- });
269
- const stream = await model.stream("How is your day going? Be extremely verbose.", {
270
- signal: AbortSignal.timeout(500),
271
- });
272
- for await (const chunk of stream) {
273
- console.log(chunk);
274
- }
275
- }).rejects.toThrow();
276
- });
277
- test("Test ChatOpenAI stream method with early break", async () => {
278
- const model = new ChatOpenAI({ maxTokens: 50, modelName: "gpt-3.5-turbo" });
279
- const stream = await model.stream("How is your day going? Be extremely verbose.");
280
- let i = 0;
281
- for await (const chunk of stream) {
282
- console.log(chunk);
283
- i += 1;
284
- if (i > 10) {
285
- break;
286
- }
287
- }
288
- });
289
- test("Test ChatOpenAI stream method, timeout error thrown from SDK", async () => {
290
- await expect(async () => {
291
- const model = new ChatOpenAI({
292
- maxTokens: 50,
293
- modelName: "gpt-3.5-turbo",
294
- timeout: 1,
295
- maxRetries: 0,
296
- });
297
- const stream = await model.stream("How is your day going? Be extremely verbose.");
298
- for await (const chunk of stream) {
299
- console.log(chunk);
300
- }
301
- }).rejects.toThrow();
302
- });
303
- test("Function calling with streaming", async () => {
304
- let finalResult;
305
- const modelForFunctionCalling = new ChatOpenAI({
306
- modelName: "gpt-3.5-turbo",
307
- temperature: 0,
308
- callbacks: [
309
- {
310
- handleLLMEnd(output) {
311
- finalResult = output.generations[0][0].message;
312
- },
313
- },
314
- ],
315
- });
316
- const stream = await modelForFunctionCalling.stream("What is the weather in New York?", {
317
- functions: [
318
- {
319
- name: "get_current_weather",
320
- description: "Get the current weather in a given location",
321
- parameters: {
322
- type: "object",
323
- properties: {
324
- location: {
325
- type: "string",
326
- description: "The city and state, e.g. San Francisco, CA",
327
- },
328
- unit: { type: "string", enum: ["celsius", "fahrenheit"] },
329
- },
330
- required: ["location"],
331
- },
332
- },
333
- ],
334
- function_call: {
335
- name: "get_current_weather",
336
- },
337
- });
338
- const chunks = [];
339
- let streamedOutput;
340
- for await (const chunk of stream) {
341
- chunks.push(chunk);
342
- if (!streamedOutput) {
343
- streamedOutput = chunk;
344
- }
345
- else if (chunk) {
346
- streamedOutput = streamedOutput.concat(chunk);
347
- }
348
- }
349
- expect(finalResult).toEqual(streamedOutput);
350
- expect(chunks.length).toBeGreaterThan(1);
351
- expect(finalResult?.additional_kwargs?.function_call?.name).toBe("get_current_weather");
352
- console.log(JSON.parse(finalResult?.additional_kwargs?.function_call?.arguments ?? "")
353
- .location);
354
- });
355
- test("ChatOpenAI can cache generations", async () => {
356
- const memoryCache = new InMemoryCache();
357
- const lookupSpy = jest.spyOn(memoryCache, "lookup");
358
- const updateSpy = jest.spyOn(memoryCache, "update");
359
- const chat = new ChatOpenAI({
360
- modelName: "gpt-3.5-turbo",
361
- maxTokens: 10,
362
- n: 2,
363
- cache: memoryCache,
364
- });
365
- const message = new HumanMessage("Hello");
366
- const res = await chat.generate([[message], [message]]);
367
- expect(res.generations.length).toBe(2);
368
- expect(lookupSpy).toHaveBeenCalledTimes(2);
369
- expect(updateSpy).toHaveBeenCalledTimes(2);
370
- lookupSpy.mockRestore();
371
- updateSpy.mockRestore();
372
- });
373
- test("ChatOpenAI can write and read cached generations", async () => {
374
- const memoryCache = new InMemoryCache();
375
- const lookupSpy = jest.spyOn(memoryCache, "lookup");
376
- const updateSpy = jest.spyOn(memoryCache, "update");
377
- const chat = new ChatOpenAI({
378
- modelName: "gpt-3.5-turbo",
379
- maxTokens: 100,
380
- n: 1,
381
- cache: memoryCache,
382
- });
383
- const generateUncachedSpy = jest.spyOn(chat, "_generateUncached");
384
- const messages = [
385
- [
386
- new HumanMessage("what color is the sky?"),
387
- new HumanMessage("what color is the ocean?"),
388
- ],
389
- [new HumanMessage("hello")],
390
- ];
391
- const response1 = await chat.generate(messages);
392
- expect(generateUncachedSpy).toHaveBeenCalledTimes(1);
393
- generateUncachedSpy.mockRestore();
394
- const response2 = await chat.generate(messages);
395
- expect(generateUncachedSpy).toHaveBeenCalledTimes(0); // Request should be cached, no need to generate.
396
- generateUncachedSpy.mockRestore();
397
- expect(response1.generations.length).toBe(2);
398
- expect(response2.generations).toEqual(response1.generations);
399
- expect(lookupSpy).toHaveBeenCalledTimes(4);
400
- expect(updateSpy).toHaveBeenCalledTimes(2);
401
- lookupSpy.mockRestore();
402
- updateSpy.mockRestore();
403
- });
404
- test("ChatOpenAI should not reuse cache if function call args have changed", async () => {
405
- const memoryCache = new InMemoryCache();
406
- const lookupSpy = jest.spyOn(memoryCache, "lookup");
407
- const updateSpy = jest.spyOn(memoryCache, "update");
408
- const chat = new ChatOpenAI({
409
- modelName: "gpt-3.5-turbo",
410
- maxTokens: 100,
411
- n: 1,
412
- cache: memoryCache,
413
- });
414
- const generateUncachedSpy = jest.spyOn(chat, "_generateUncached");
415
- const messages = [
416
- [
417
- new HumanMessage("what color is the sky?"),
418
- new HumanMessage("what color is the ocean?"),
419
- ],
420
- [new HumanMessage("hello")],
421
- ];
422
- const response1 = await chat.generate(messages);
423
- expect(generateUncachedSpy).toHaveBeenCalledTimes(1);
424
- generateUncachedSpy.mockRestore();
425
- const response2 = await chat.generate(messages, {
426
- functions: [
427
- {
428
- name: "extractor",
429
- description: "Extract fields from the input",
430
- parameters: {
431
- type: "object",
432
- properties: {
433
- tone: {
434
- type: "string",
435
- description: "the tone of the input",
436
- },
437
- },
438
- required: ["tone"],
439
- },
440
- },
441
- ],
442
- function_call: {
443
- name: "extractor",
444
- },
445
- });
446
- expect(generateUncachedSpy).toHaveBeenCalledTimes(0); // Request should not be cached since it's being called with different function call args
447
- expect(response1.generations.length).toBe(2);
448
- expect(response2.generations[0][0].message.additional_kwargs
449
- .function_call?.name ?? "").toEqual("extractor");
450
- const response3 = await chat.generate(messages, {
451
- functions: [
452
- {
453
- name: "extractor",
454
- description: "Extract fields from the input",
455
- parameters: {
456
- type: "object",
457
- properties: {
458
- tone: {
459
- type: "string",
460
- description: "the tone of the input",
461
- },
462
- },
463
- required: ["tone"],
464
- },
465
- },
466
- ],
467
- function_call: {
468
- name: "extractor",
469
- },
470
- });
471
- expect(response2.generations).toEqual(response3.generations);
472
- expect(lookupSpy).toHaveBeenCalledTimes(6);
473
- expect(updateSpy).toHaveBeenCalledTimes(4);
474
- lookupSpy.mockRestore();
475
- updateSpy.mockRestore();
476
- });
477
- test("Test ChatOpenAI token usage reporting for streaming function calls", async () => {
478
- let streamingTokenUsed = -1;
479
- let nonStreamingTokenUsed = -1;
480
- const humanMessage = "What a beautiful day!";
481
- const extractionFunctionSchema = {
482
- name: "extractor",
483
- description: "Extracts fields from the input.",
484
- parameters: {
485
- type: "object",
486
- properties: {
487
- tone: {
488
- type: "string",
489
- enum: ["positive", "negative"],
490
- description: "The overall tone of the input",
491
- },
492
- word_count: {
493
- type: "number",
494
- description: "The number of words in the input",
495
- },
496
- chat_response: {
497
- type: "string",
498
- description: "A response to the human's input",
499
- },
500
- },
501
- required: ["tone", "word_count", "chat_response"],
502
- },
503
- };
504
- const streamingModel = new ChatOpenAI({
505
- modelName: "gpt-3.5-turbo",
506
- streaming: true,
507
- maxRetries: 10,
508
- maxConcurrency: 10,
509
- temperature: 0,
510
- topP: 0,
511
- callbacks: [
512
- {
513
- handleLLMEnd: async (output) => {
514
- streamingTokenUsed =
515
- output.llmOutput?.estimatedTokenUsage?.totalTokens;
516
- console.log("streaming usage", output.llmOutput?.estimatedTokenUsage);
517
- },
518
- handleLLMError: async (err) => {
519
- console.error(err);
520
- },
521
- },
522
- ],
523
- }).bind({
524
- seed: 42,
525
- functions: [extractionFunctionSchema],
526
- function_call: { name: "extractor" },
527
- });
528
- const nonStreamingModel = new ChatOpenAI({
529
- modelName: "gpt-3.5-turbo",
530
- streaming: false,
531
- maxRetries: 10,
532
- maxConcurrency: 10,
533
- temperature: 0,
534
- topP: 0,
535
- callbacks: [
536
- {
537
- handleLLMEnd: async (output) => {
538
- nonStreamingTokenUsed = output.llmOutput?.tokenUsage?.totalTokens;
539
- console.log("non-streaming usage", output.llmOutput?.tokenUsage);
540
- },
541
- handleLLMError: async (err) => {
542
- console.error(err);
543
- },
544
- },
545
- ],
546
- }).bind({
547
- seed: 42,
548
- functions: [extractionFunctionSchema],
549
- function_call: { name: "extractor" },
550
- });
551
- const [nonStreamingResult, streamingResult] = await Promise.all([
552
- nonStreamingModel.invoke([new HumanMessage(humanMessage)]),
553
- streamingModel.invoke([new HumanMessage(humanMessage)]),
554
- ]);
555
- if (nonStreamingResult.additional_kwargs.function_call?.arguments &&
556
- streamingResult.additional_kwargs.function_call?.arguments) {
557
- const nonStreamingArguments = JSON.stringify(JSON.parse(nonStreamingResult.additional_kwargs.function_call.arguments));
558
- const streamingArguments = JSON.stringify(JSON.parse(streamingResult.additional_kwargs.function_call.arguments));
559
- if (nonStreamingArguments === streamingArguments) {
560
- expect(streamingTokenUsed).toEqual(nonStreamingTokenUsed);
561
- }
562
- }
563
- expect(streamingTokenUsed).toBeGreaterThan(-1);
564
- });
565
- test("Test ChatOpenAI token usage reporting for streaming calls", async () => {
566
- let streamingTokenUsed = -1;
567
- let nonStreamingTokenUsed = -1;
568
- const systemPrompt = "You are a helpful assistant";
569
- const question = "What is the color of the night sky?";
570
- const streamingModel = new ChatOpenAI({
571
- modelName: "gpt-3.5-turbo",
572
- streaming: true,
573
- maxRetries: 10,
574
- maxConcurrency: 10,
575
- temperature: 0,
576
- topP: 0,
577
- callbacks: [
578
- {
579
- handleLLMEnd: async (output) => {
580
- streamingTokenUsed =
581
- output.llmOutput?.estimatedTokenUsage?.totalTokens;
582
- console.log("streaming usage", output.llmOutput?.estimatedTokenUsage);
583
- },
584
- handleLLMError: async (err) => {
585
- console.error(err);
586
- },
587
- },
588
- ],
589
- });
590
- const nonStreamingModel = new ChatOpenAI({
591
- modelName: "gpt-3.5-turbo",
592
- streaming: false,
593
- maxRetries: 10,
594
- maxConcurrency: 10,
595
- temperature: 0,
596
- topP: 0,
597
- callbacks: [
598
- {
599
- handleLLMEnd: async (output) => {
600
- nonStreamingTokenUsed = output.llmOutput?.tokenUsage?.totalTokens;
601
- console.log("non-streaming usage", output.llmOutput?.estimated);
602
- },
603
- handleLLMError: async (err) => {
604
- console.error(err);
605
- },
606
- },
607
- ],
608
- });
609
- const [nonStreamingResult, streamingResult] = await Promise.all([
610
- nonStreamingModel.generate([
611
- [new SystemMessage(systemPrompt), new HumanMessage(question)],
612
- ]),
613
- streamingModel.generate([
614
- [new SystemMessage(systemPrompt), new HumanMessage(question)],
615
- ]),
616
- ]);
617
- expect(streamingTokenUsed).toBeGreaterThan(-1);
618
- if (nonStreamingResult.generations[0][0].text ===
619
- streamingResult.generations[0][0].text) {
620
- expect(streamingTokenUsed).toEqual(nonStreamingTokenUsed);
621
- }
622
- });