@langchain/core 0.2.0 → 0.2.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.
Files changed (113) hide show
  1. package/dist/callbacks/tests/callbacks.test.d.ts +1 -0
  2. package/dist/callbacks/tests/callbacks.test.js +492 -0
  3. package/dist/callbacks/tests/manager.int.test.d.ts +1 -0
  4. package/dist/callbacks/tests/manager.int.test.js +29 -0
  5. package/dist/callbacks/tests/run_collector.test.d.ts +1 -0
  6. package/dist/callbacks/tests/run_collector.test.js +58 -0
  7. package/dist/chat_history.cjs +13 -0
  8. package/dist/chat_history.d.ts +9 -0
  9. package/dist/chat_history.js +13 -0
  10. package/dist/language_models/chat_models.d.ts +2 -2
  11. package/dist/language_models/tests/chat_models.test.d.ts +1 -0
  12. package/dist/language_models/tests/chat_models.test.js +154 -0
  13. package/dist/language_models/tests/count_tokens.test.d.ts +1 -0
  14. package/dist/language_models/tests/count_tokens.test.js +19 -0
  15. package/dist/language_models/tests/llms.test.d.ts +1 -0
  16. package/dist/language_models/tests/llms.test.js +39 -0
  17. package/dist/messages/tests/base_message.test.d.ts +1 -0
  18. package/dist/messages/tests/base_message.test.js +97 -0
  19. package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.d.ts +1 -0
  20. package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.js +81 -0
  21. package/dist/output_parsers/tests/json.test.d.ts +1 -0
  22. package/dist/output_parsers/tests/json.test.js +427 -0
  23. package/dist/output_parsers/tests/output_parser.test.d.ts +1 -0
  24. package/dist/output_parsers/tests/output_parser.test.js +78 -0
  25. package/dist/output_parsers/tests/string.test.d.ts +1 -0
  26. package/dist/output_parsers/tests/string.test.js +68 -0
  27. package/dist/output_parsers/tests/structured.test.d.ts +1 -0
  28. package/dist/output_parsers/tests/structured.test.js +166 -0
  29. package/dist/output_parsers/tests/xml.test.d.ts +1 -0
  30. package/dist/output_parsers/tests/xml.test.js +81 -0
  31. package/dist/prompts/tests/chat.mustache.test.d.ts +1 -0
  32. package/dist/prompts/tests/chat.mustache.test.js +61 -0
  33. package/dist/prompts/tests/chat.test.d.ts +1 -0
  34. package/dist/prompts/tests/chat.test.js +507 -0
  35. package/dist/prompts/tests/few_shot.test.d.ts +1 -0
  36. package/dist/prompts/tests/few_shot.test.js +224 -0
  37. package/dist/prompts/tests/pipeline.test.d.ts +1 -0
  38. package/dist/prompts/tests/pipeline.test.js +101 -0
  39. package/dist/prompts/tests/prompt.mustache.test.d.ts +1 -0
  40. package/dist/prompts/tests/prompt.mustache.test.js +85 -0
  41. package/dist/prompts/tests/prompt.test.d.ts +1 -0
  42. package/dist/prompts/tests/prompt.test.js +78 -0
  43. package/dist/prompts/tests/structured.test.d.ts +1 -0
  44. package/dist/prompts/tests/structured.test.js +37 -0
  45. package/dist/prompts/tests/template.test.d.ts +1 -0
  46. package/dist/prompts/tests/template.test.js +24 -0
  47. package/dist/runnables/base.cjs +87 -6
  48. package/dist/runnables/base.d.ts +45 -26
  49. package/dist/runnables/base.js +87 -6
  50. package/dist/runnables/history.cjs +87 -32
  51. package/dist/runnables/history.d.ts +1 -1
  52. package/dist/runnables/history.js +87 -32
  53. package/dist/runnables/remote.cjs +2 -2
  54. package/dist/runnables/remote.d.ts +3 -3
  55. package/dist/runnables/remote.js +2 -2
  56. package/dist/runnables/tests/runnable.test.d.ts +1 -0
  57. package/dist/runnables/tests/runnable.test.js +491 -0
  58. package/dist/runnables/tests/runnable_binding.test.d.ts +1 -0
  59. package/dist/runnables/tests/runnable_binding.test.js +46 -0
  60. package/dist/runnables/tests/runnable_branch.test.d.ts +1 -0
  61. package/dist/runnables/tests/runnable_branch.test.js +116 -0
  62. package/dist/runnables/tests/runnable_graph.test.d.ts +1 -0
  63. package/dist/runnables/tests/runnable_graph.test.js +84 -0
  64. package/dist/runnables/tests/runnable_history.test.d.ts +1 -0
  65. package/dist/runnables/tests/runnable_history.test.js +177 -0
  66. package/dist/runnables/tests/runnable_interface.test.d.ts +1 -0
  67. package/dist/runnables/tests/runnable_interface.test.js +209 -0
  68. package/dist/runnables/tests/runnable_map.test.d.ts +1 -0
  69. package/dist/runnables/tests/runnable_map.test.js +238 -0
  70. package/dist/runnables/tests/runnable_passthrough.test.d.ts +1 -0
  71. package/dist/runnables/tests/runnable_passthrough.test.js +96 -0
  72. package/dist/runnables/tests/runnable_remote.int.test.d.ts +1 -0
  73. package/dist/runnables/tests/runnable_remote.int.test.js +138 -0
  74. package/dist/runnables/tests/runnable_remote.test.d.ts +1 -0
  75. package/dist/runnables/tests/runnable_remote.test.js +200 -0
  76. package/dist/runnables/tests/runnable_retry.test.d.ts +1 -0
  77. package/dist/runnables/tests/runnable_retry.test.js +125 -0
  78. package/dist/runnables/tests/runnable_stream_events.test.d.ts +1 -0
  79. package/dist/runnables/tests/runnable_stream_events.test.js +1013 -0
  80. package/dist/runnables/tests/runnable_stream_events_v2.test.d.ts +1 -0
  81. package/dist/runnables/tests/runnable_stream_events_v2.test.js +973 -0
  82. package/dist/runnables/tests/runnable_stream_log.test.d.ts +1 -0
  83. package/dist/runnables/tests/runnable_stream_log.test.js +282 -0
  84. package/dist/runnables/tests/runnable_tracing.int.test.d.ts +1 -0
  85. package/dist/runnables/tests/runnable_tracing.int.test.js +37 -0
  86. package/dist/runnables/tests/runnable_with_fallbacks.test.d.ts +1 -0
  87. package/dist/runnables/tests/runnable_with_fallbacks.test.js +36 -0
  88. package/dist/runnables/utils.d.ts +1 -1
  89. package/dist/singletons/tests/async_local_storage.test.d.ts +1 -0
  90. package/dist/singletons/tests/async_local_storage.test.js +120 -0
  91. package/dist/structured_query/tests/utils.test.d.ts +1 -0
  92. package/dist/structured_query/tests/utils.test.js +47 -0
  93. package/dist/tracers/event_stream.cjs +493 -0
  94. package/dist/tracers/event_stream.d.ts +137 -0
  95. package/dist/tracers/event_stream.js +489 -0
  96. package/dist/tracers/log_stream.d.ts +2 -77
  97. package/dist/tracers/tests/langchain_tracer.int.test.d.ts +1 -0
  98. package/dist/tracers/tests/langchain_tracer.int.test.js +74 -0
  99. package/dist/tracers/tests/tracer.test.d.ts +1 -0
  100. package/dist/tracers/tests/tracer.test.js +378 -0
  101. package/dist/utils/testing/tests/chatfake.test.d.ts +1 -0
  102. package/dist/utils/testing/tests/chatfake.test.js +112 -0
  103. package/dist/utils/tests/async_caller.test.d.ts +1 -0
  104. package/dist/utils/tests/async_caller.test.js +27 -0
  105. package/dist/utils/tests/enviroment.test.d.ts +1 -0
  106. package/dist/utils/tests/enviroment.test.js +6 -0
  107. package/dist/utils/tests/function_calling.test.d.ts +1 -0
  108. package/dist/utils/tests/function_calling.test.js +107 -0
  109. package/dist/utils/tests/math_utils.test.d.ts +1 -0
  110. package/dist/utils/tests/math_utils.test.js +139 -0
  111. package/dist/utils/tests/polyfill_stream.test.d.ts +1 -0
  112. package/dist/utils/tests/polyfill_stream.test.js +15 -0
  113. package/package.json +6 -6
@@ -0,0 +1,1013 @@
1
+ /* eslint-disable no-promise-executor-return */
2
+ /* eslint-disable no-process-env */
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ import { test } from "@jest/globals";
5
+ import { z } from "zod";
6
+ import { RunnableLambda, RunnableMap, RunnablePassthrough, RunnablePick, } from "../index.js";
7
+ import { ChatPromptTemplate } from "../../prompts/chat.js";
8
+ import { FakeListChatModel, FakeRetriever, FakeStreamingLLM, } from "../../utils/testing/index.js";
9
+ import { AIMessageChunk, HumanMessage, SystemMessage, } from "../../messages/index.js";
10
+ import { ChatGenerationChunk, GenerationChunk } from "../../outputs.js";
11
+ import { DynamicStructuredTool, DynamicTool } from "../../tools.js";
12
+ import { Document } from "../../documents/document.js";
13
+ function reverse(s) {
14
+ // Reverse a string.
15
+ return s.split("").reverse().join("");
16
+ }
17
+ const originalCallbackValue = process.env.LANGCHAIN_CALLBACKS_BACKGROUND;
18
+ afterEach(() => {
19
+ process.env.LANGCHAIN_CALLBACKS_BACKGROUND = originalCallbackValue;
20
+ });
21
+ test("Runnable streamEvents method", async () => {
22
+ const chain = RunnableLambda.from(reverse).withConfig({
23
+ runName: "reverse",
24
+ });
25
+ const events = [];
26
+ const eventStream = await chain.streamEvents("hello", { version: "v1" });
27
+ for await (const event of eventStream) {
28
+ events.push(event);
29
+ }
30
+ expect(events).toEqual([
31
+ {
32
+ data: { input: "hello" },
33
+ event: "on_chain_start",
34
+ metadata: {},
35
+ name: "reverse",
36
+ run_id: expect.any(String),
37
+ tags: [],
38
+ },
39
+ {
40
+ data: { chunk: "olleh" },
41
+ event: "on_chain_stream",
42
+ metadata: {},
43
+ name: "reverse",
44
+ run_id: expect.any(String),
45
+ tags: [],
46
+ },
47
+ {
48
+ data: { output: "olleh" },
49
+ event: "on_chain_end",
50
+ metadata: {},
51
+ name: "reverse",
52
+ run_id: expect.any(String),
53
+ tags: [],
54
+ },
55
+ ]);
56
+ });
57
+ test("Runnable streamEvents method with three runnables", async () => {
58
+ const r = RunnableLambda.from(reverse);
59
+ const chain = r
60
+ .withConfig({ runName: "1" })
61
+ .pipe(r.withConfig({ runName: "2" }))
62
+ .pipe(r.withConfig({ runName: "3" }));
63
+ const events = [];
64
+ const eventStream = await chain.streamEvents("hello", { version: "v1" });
65
+ for await (const event of eventStream) {
66
+ events.push(event);
67
+ }
68
+ expect(events).toEqual([
69
+ {
70
+ data: { input: "hello" },
71
+ event: "on_chain_start",
72
+ metadata: {},
73
+ name: "RunnableSequence",
74
+ run_id: expect.any(String),
75
+ tags: [],
76
+ },
77
+ {
78
+ data: {},
79
+ event: "on_chain_start",
80
+ metadata: {},
81
+ name: "1",
82
+ run_id: expect.any(String),
83
+ tags: ["seq:step:1"],
84
+ },
85
+ {
86
+ data: { chunk: "olleh" },
87
+ event: "on_chain_stream",
88
+ metadata: {},
89
+ name: "1",
90
+ run_id: expect.any(String),
91
+ tags: ["seq:step:1"],
92
+ },
93
+ {
94
+ data: {},
95
+ event: "on_chain_start",
96
+ metadata: {},
97
+ name: "2",
98
+ run_id: expect.any(String),
99
+ tags: ["seq:step:2"],
100
+ },
101
+ {
102
+ data: { input: "hello", output: "olleh" },
103
+ event: "on_chain_end",
104
+ metadata: {},
105
+ name: "1",
106
+ run_id: expect.any(String),
107
+ tags: ["seq:step:1"],
108
+ },
109
+ {
110
+ data: { chunk: "hello" },
111
+ event: "on_chain_stream",
112
+ metadata: {},
113
+ name: "2",
114
+ run_id: expect.any(String),
115
+ tags: ["seq:step:2"],
116
+ },
117
+ {
118
+ data: {},
119
+ event: "on_chain_start",
120
+ metadata: {},
121
+ name: "3",
122
+ run_id: expect.any(String),
123
+ tags: ["seq:step:3"],
124
+ },
125
+ {
126
+ data: { input: "olleh", output: "hello" },
127
+ event: "on_chain_end",
128
+ metadata: {},
129
+ name: "2",
130
+ run_id: expect.any(String),
131
+ tags: ["seq:step:2"],
132
+ },
133
+ {
134
+ data: { chunk: "olleh" },
135
+ event: "on_chain_stream",
136
+ metadata: {},
137
+ name: "3",
138
+ run_id: expect.any(String),
139
+ tags: ["seq:step:3"],
140
+ },
141
+ {
142
+ data: { chunk: "olleh" },
143
+ event: "on_chain_stream",
144
+ metadata: {},
145
+ name: "RunnableSequence",
146
+ run_id: expect.any(String),
147
+ tags: [],
148
+ },
149
+ {
150
+ data: { input: "hello", output: "olleh" },
151
+ event: "on_chain_end",
152
+ metadata: {},
153
+ name: "3",
154
+ run_id: expect.any(String),
155
+ tags: ["seq:step:3"],
156
+ },
157
+ {
158
+ data: { output: "olleh" },
159
+ event: "on_chain_end",
160
+ metadata: {},
161
+ name: "RunnableSequence",
162
+ run_id: expect.any(String),
163
+ tags: [],
164
+ },
165
+ ]);
166
+ });
167
+ test("Runnable streamEvents method with three runnables with backgrounded callbacks set to true", async () => {
168
+ process.env.LANGCHAIN_CALLBACKS_BACKGROUND = "true";
169
+ const r = RunnableLambda.from(reverse);
170
+ const chain = r
171
+ .withConfig({ runName: "1" })
172
+ .pipe(r.withConfig({ runName: "2" }))
173
+ .pipe(r.withConfig({ runName: "3" }));
174
+ const events = [];
175
+ const eventStream = await chain.streamEvents("hello", { version: "v1" });
176
+ for await (const event of eventStream) {
177
+ events.push(event);
178
+ }
179
+ expect(events).toEqual([
180
+ {
181
+ data: { input: "hello" },
182
+ event: "on_chain_start",
183
+ metadata: {},
184
+ name: "RunnableSequence",
185
+ run_id: expect.any(String),
186
+ tags: [],
187
+ },
188
+ {
189
+ data: {},
190
+ event: "on_chain_start",
191
+ metadata: {},
192
+ name: "1",
193
+ run_id: expect.any(String),
194
+ tags: ["seq:step:1"],
195
+ },
196
+ {
197
+ data: { chunk: "olleh" },
198
+ event: "on_chain_stream",
199
+ metadata: {},
200
+ name: "1",
201
+ run_id: expect.any(String),
202
+ tags: ["seq:step:1"],
203
+ },
204
+ {
205
+ data: {},
206
+ event: "on_chain_start",
207
+ metadata: {},
208
+ name: "2",
209
+ run_id: expect.any(String),
210
+ tags: ["seq:step:2"],
211
+ },
212
+ {
213
+ data: { input: "hello", output: "olleh" },
214
+ event: "on_chain_end",
215
+ metadata: {},
216
+ name: "1",
217
+ run_id: expect.any(String),
218
+ tags: ["seq:step:1"],
219
+ },
220
+ {
221
+ data: { chunk: "hello" },
222
+ event: "on_chain_stream",
223
+ metadata: {},
224
+ name: "2",
225
+ run_id: expect.any(String),
226
+ tags: ["seq:step:2"],
227
+ },
228
+ {
229
+ data: {},
230
+ event: "on_chain_start",
231
+ metadata: {},
232
+ name: "3",
233
+ run_id: expect.any(String),
234
+ tags: ["seq:step:3"],
235
+ },
236
+ {
237
+ data: { input: "olleh", output: "hello" },
238
+ event: "on_chain_end",
239
+ metadata: {},
240
+ name: "2",
241
+ run_id: expect.any(String),
242
+ tags: ["seq:step:2"],
243
+ },
244
+ {
245
+ data: { chunk: "olleh" },
246
+ event: "on_chain_stream",
247
+ metadata: {},
248
+ name: "3",
249
+ run_id: expect.any(String),
250
+ tags: ["seq:step:3"],
251
+ },
252
+ {
253
+ data: { chunk: "olleh" },
254
+ event: "on_chain_stream",
255
+ metadata: {},
256
+ name: "RunnableSequence",
257
+ run_id: expect.any(String),
258
+ tags: [],
259
+ },
260
+ {
261
+ data: { input: "hello", output: "olleh" },
262
+ event: "on_chain_end",
263
+ metadata: {},
264
+ name: "3",
265
+ run_id: expect.any(String),
266
+ tags: ["seq:step:3"],
267
+ },
268
+ {
269
+ data: { output: "olleh" },
270
+ event: "on_chain_end",
271
+ metadata: {},
272
+ name: "RunnableSequence",
273
+ run_id: expect.any(String),
274
+ tags: [],
275
+ },
276
+ ]);
277
+ });
278
+ test("Runnable streamEvents method with three runnables with filtering", async () => {
279
+ const r = RunnableLambda.from(reverse);
280
+ const chain = r
281
+ .withConfig({ runName: "1" })
282
+ .pipe(r.withConfig({ runName: "2", tags: ["my_tag"] }))
283
+ .pipe(r.withConfig({ runName: "3", tags: ["my_tag"] }));
284
+ const events = [];
285
+ const eventStream = await chain.streamEvents("hello", { version: "v1" }, {
286
+ includeNames: ["1"],
287
+ });
288
+ for await (const event of eventStream) {
289
+ events.push(event);
290
+ }
291
+ expect(events).toEqual([
292
+ {
293
+ data: {},
294
+ event: "on_chain_start",
295
+ metadata: {},
296
+ name: "1",
297
+ run_id: expect.any(String),
298
+ tags: ["seq:step:1"],
299
+ },
300
+ {
301
+ data: { chunk: "olleh" },
302
+ event: "on_chain_stream",
303
+ metadata: {},
304
+ name: "1",
305
+ run_id: expect.any(String),
306
+ tags: ["seq:step:1"],
307
+ },
308
+ {
309
+ data: { input: "hello", output: "olleh" },
310
+ event: "on_chain_end",
311
+ metadata: {},
312
+ name: "1",
313
+ run_id: expect.any(String),
314
+ tags: ["seq:step:1"],
315
+ },
316
+ ]);
317
+ const events2 = [];
318
+ const eventStream2 = await chain.streamEvents("hello", { version: "v1" }, {
319
+ excludeNames: ["2"],
320
+ includeTags: ["my_tag"],
321
+ });
322
+ for await (const event of eventStream2) {
323
+ events2.push(event);
324
+ }
325
+ expect(events2).toEqual([
326
+ {
327
+ data: {},
328
+ event: "on_chain_start",
329
+ metadata: {},
330
+ name: "3",
331
+ run_id: expect.any(String),
332
+ tags: expect.arrayContaining(["seq:step:3", "my_tag"]),
333
+ },
334
+ {
335
+ data: { chunk: "olleh" },
336
+ event: "on_chain_stream",
337
+ metadata: {},
338
+ name: "3",
339
+ run_id: expect.any(String),
340
+ tags: expect.arrayContaining(["seq:step:3", "my_tag"]),
341
+ },
342
+ {
343
+ data: { input: "hello", output: "olleh" },
344
+ event: "on_chain_end",
345
+ metadata: {},
346
+ name: "3",
347
+ run_id: expect.any(String),
348
+ tags: expect.arrayContaining(["seq:step:3", "my_tag"]),
349
+ },
350
+ ]);
351
+ });
352
+ test("Runnable streamEvents method with a runnable map", async () => {
353
+ const r = RunnableLambda.from(reverse);
354
+ const chain = RunnableMap.from({
355
+ reversed: r,
356
+ original: new RunnablePassthrough(),
357
+ }).pipe(new RunnablePick("reversed"));
358
+ const events = [];
359
+ const eventStream = await chain.streamEvents("hello", { version: "v1" });
360
+ for await (const event of eventStream) {
361
+ events.push(event);
362
+ }
363
+ console.log(events);
364
+ expect(events).toEqual([
365
+ {
366
+ run_id: expect.any(String),
367
+ event: "on_chain_start",
368
+ name: "RunnableSequence",
369
+ tags: [],
370
+ metadata: {},
371
+ data: { input: "hello" },
372
+ },
373
+ {
374
+ event: "on_chain_start",
375
+ name: "RunnableMap",
376
+ run_id: expect.any(String),
377
+ tags: ["seq:step:1"],
378
+ metadata: {},
379
+ data: {},
380
+ },
381
+ {
382
+ event: "on_chain_start",
383
+ name: "RunnableLambda",
384
+ run_id: expect.any(String),
385
+ tags: ["map:key:reversed"],
386
+ metadata: {},
387
+ data: {},
388
+ },
389
+ {
390
+ event: "on_chain_start",
391
+ name: "RunnablePassthrough",
392
+ run_id: expect.any(String),
393
+ tags: ["map:key:original"],
394
+ metadata: {},
395
+ data: {},
396
+ },
397
+ {
398
+ event: "on_chain_stream",
399
+ name: "RunnablePassthrough",
400
+ run_id: expect.any(String),
401
+ tags: ["map:key:original"],
402
+ metadata: {},
403
+ data: { chunk: "hello" },
404
+ },
405
+ {
406
+ event: "on_chain_stream",
407
+ name: "RunnableLambda",
408
+ run_id: expect.any(String),
409
+ tags: ["map:key:reversed"],
410
+ metadata: {},
411
+ data: { chunk: "olleh" },
412
+ },
413
+ {
414
+ event: "on_chain_stream",
415
+ name: "RunnableMap",
416
+ run_id: expect.any(String),
417
+ tags: ["seq:step:1"],
418
+ metadata: {},
419
+ data: {
420
+ chunk: {
421
+ original: "hello",
422
+ },
423
+ },
424
+ },
425
+ {
426
+ event: "on_chain_start",
427
+ name: "RunnablePick",
428
+ run_id: expect.any(String),
429
+ tags: ["seq:step:2"],
430
+ metadata: {},
431
+ data: {},
432
+ },
433
+ {
434
+ event: "on_chain_stream",
435
+ name: "RunnableMap",
436
+ run_id: expect.any(String),
437
+ tags: ["seq:step:1"],
438
+ metadata: {},
439
+ data: {
440
+ chunk: {
441
+ reversed: "olleh",
442
+ },
443
+ },
444
+ },
445
+ {
446
+ event: "on_chain_end",
447
+ name: "RunnablePassthrough",
448
+ run_id: expect.any(String),
449
+ tags: ["map:key:original"],
450
+ metadata: {},
451
+ data: { input: "hello", output: "hello" },
452
+ },
453
+ {
454
+ event: "on_chain_stream",
455
+ name: "RunnablePick",
456
+ run_id: expect.any(String),
457
+ tags: ["seq:step:2"],
458
+ metadata: {},
459
+ data: { chunk: "olleh" },
460
+ },
461
+ {
462
+ event: "on_chain_stream",
463
+ run_id: expect.any(String),
464
+ tags: [],
465
+ metadata: {},
466
+ name: "RunnableSequence",
467
+ data: { chunk: "olleh" },
468
+ },
469
+ {
470
+ event: "on_chain_end",
471
+ name: "RunnableLambda",
472
+ run_id: expect.any(String),
473
+ tags: ["map:key:reversed"],
474
+ metadata: {},
475
+ data: { input: "hello", output: "olleh" },
476
+ },
477
+ {
478
+ event: "on_chain_end",
479
+ name: "RunnableMap",
480
+ run_id: expect.any(String),
481
+ tags: ["seq:step:1"],
482
+ metadata: {},
483
+ data: {
484
+ input: "hello",
485
+ output: {
486
+ original: "hello",
487
+ reversed: "olleh",
488
+ },
489
+ },
490
+ },
491
+ {
492
+ event: "on_chain_end",
493
+ name: "RunnablePick",
494
+ run_id: expect.any(String),
495
+ tags: ["seq:step:2"],
496
+ metadata: {},
497
+ data: { output: "olleh" },
498
+ },
499
+ {
500
+ event: "on_chain_end",
501
+ name: "RunnableSequence",
502
+ run_id: expect.any(String),
503
+ tags: [],
504
+ metadata: {},
505
+ data: { output: "olleh" },
506
+ },
507
+ ]);
508
+ });
509
+ test("Runnable streamEvents method with llm", async () => {
510
+ const model = new FakeStreamingLLM({
511
+ responses: ["hey!"],
512
+ }).withConfig({
513
+ metadata: { a: "b" },
514
+ tags: ["my_model"],
515
+ runName: "my_model",
516
+ });
517
+ const events = [];
518
+ const eventStream = await model.streamEvents("hello", { version: "v1" });
519
+ for await (const event of eventStream) {
520
+ events.push(event);
521
+ }
522
+ expect(events).toEqual([
523
+ {
524
+ event: "on_llm_start",
525
+ name: "my_model",
526
+ run_id: expect.any(String),
527
+ tags: expect.arrayContaining(["my_model"]),
528
+ metadata: {
529
+ a: "b",
530
+ },
531
+ data: {
532
+ input: "hello",
533
+ },
534
+ },
535
+ {
536
+ event: "on_llm_stream",
537
+ run_id: expect.any(String),
538
+ tags: expect.arrayContaining(["my_model"]),
539
+ metadata: {
540
+ a: "b",
541
+ },
542
+ name: "my_model",
543
+ data: { chunk: "h" },
544
+ },
545
+ {
546
+ event: "on_llm_stream",
547
+ run_id: expect.any(String),
548
+ tags: expect.arrayContaining(["my_model"]),
549
+ metadata: {
550
+ a: "b",
551
+ },
552
+ name: "my_model",
553
+ data: { chunk: "e" },
554
+ },
555
+ {
556
+ event: "on_llm_stream",
557
+ run_id: expect.any(String),
558
+ tags: expect.arrayContaining(["my_model"]),
559
+ metadata: {
560
+ a: "b",
561
+ },
562
+ name: "my_model",
563
+ data: { chunk: "y" },
564
+ },
565
+ {
566
+ event: "on_llm_stream",
567
+ run_id: expect.any(String),
568
+ tags: expect.arrayContaining(["my_model"]),
569
+ metadata: {
570
+ a: "b",
571
+ },
572
+ name: "my_model",
573
+ data: { chunk: "!" },
574
+ },
575
+ {
576
+ event: "on_llm_end",
577
+ name: "my_model",
578
+ run_id: expect.any(String),
579
+ tags: expect.arrayContaining(["my_model"]),
580
+ metadata: {
581
+ a: "b",
582
+ },
583
+ data: {
584
+ output: {
585
+ generations: [
586
+ [
587
+ new GenerationChunk({
588
+ generationInfo: {},
589
+ text: "hey!",
590
+ }),
591
+ ],
592
+ ],
593
+ },
594
+ },
595
+ },
596
+ ]);
597
+ });
598
+ test("Runnable streamEvents method with chat model chain", async () => {
599
+ const template = ChatPromptTemplate.fromMessages([
600
+ ["system", "You are Godzilla"],
601
+ ["human", "{question}"],
602
+ ]).withConfig({
603
+ runName: "my_template",
604
+ tags: ["my_template"],
605
+ });
606
+ const model = new FakeListChatModel({
607
+ responses: ["ROAR"],
608
+ }).withConfig({
609
+ metadata: { a: "b" },
610
+ tags: ["my_model"],
611
+ runName: "my_model",
612
+ });
613
+ const chain = template.pipe(model).withConfig({
614
+ metadata: { foo: "bar" },
615
+ tags: ["my_chain"],
616
+ runName: "my_chain",
617
+ });
618
+ const events = [];
619
+ const eventStream = await chain.streamEvents({ question: "hello" }, { version: "v1" });
620
+ for await (const event of eventStream) {
621
+ events.push(event);
622
+ }
623
+ expect(events).toEqual([
624
+ {
625
+ run_id: expect.any(String),
626
+ event: "on_chain_start",
627
+ name: "my_chain",
628
+ tags: ["my_chain"],
629
+ metadata: {
630
+ foo: "bar",
631
+ },
632
+ data: {
633
+ input: {
634
+ question: "hello",
635
+ },
636
+ },
637
+ },
638
+ {
639
+ data: { input: { question: "hello" } },
640
+ event: "on_prompt_start",
641
+ metadata: { foo: "bar" },
642
+ name: "my_template",
643
+ run_id: expect.any(String),
644
+ tags: expect.arrayContaining(["my_chain", "seq:step:1", "my_template"]),
645
+ },
646
+ {
647
+ event: "on_prompt_end",
648
+ name: "my_template",
649
+ run_id: expect.any(String),
650
+ tags: expect.arrayContaining(["seq:step:1", "my_template", "my_chain"]),
651
+ metadata: {
652
+ foo: "bar",
653
+ },
654
+ data: {
655
+ input: {
656
+ question: "hello",
657
+ },
658
+ output: await template.invoke({ question: "hello" }),
659
+ },
660
+ },
661
+ {
662
+ event: "on_llm_start",
663
+ name: "my_model",
664
+ run_id: expect.any(String),
665
+ tags: expect.arrayContaining(["seq:step:2", "my_model", "my_chain"]),
666
+ metadata: {
667
+ foo: "bar",
668
+ a: "b",
669
+ ls_model_type: "chat",
670
+ ls_stop: undefined,
671
+ },
672
+ data: {
673
+ input: {
674
+ messages: [
675
+ [new SystemMessage("You are Godzilla"), new HumanMessage("hello")],
676
+ ],
677
+ },
678
+ },
679
+ },
680
+ {
681
+ event: "on_llm_stream",
682
+ run_id: expect.any(String),
683
+ tags: expect.arrayContaining(["my_chain", "my_model", "seq:step:2"]),
684
+ metadata: {
685
+ a: "b",
686
+ foo: "bar",
687
+ ls_model_type: "chat",
688
+ ls_stop: undefined,
689
+ },
690
+ name: "my_model",
691
+ data: { chunk: new AIMessageChunk("R") },
692
+ },
693
+ {
694
+ event: "on_chain_stream",
695
+ run_id: expect.any(String),
696
+ tags: ["my_chain"],
697
+ metadata: {
698
+ foo: "bar",
699
+ },
700
+ name: "my_chain",
701
+ data: { chunk: new AIMessageChunk("R") },
702
+ },
703
+ {
704
+ event: "on_llm_stream",
705
+ run_id: expect.any(String),
706
+ tags: expect.arrayContaining(["my_chain", "my_model", "seq:step:2"]),
707
+ metadata: {
708
+ a: "b",
709
+ foo: "bar",
710
+ ls_model_type: "chat",
711
+ ls_stop: undefined,
712
+ },
713
+ name: "my_model",
714
+ data: { chunk: new AIMessageChunk("O") },
715
+ },
716
+ {
717
+ event: "on_chain_stream",
718
+ run_id: expect.any(String),
719
+ tags: ["my_chain"],
720
+ metadata: {
721
+ foo: "bar",
722
+ },
723
+ name: "my_chain",
724
+ data: { chunk: new AIMessageChunk("O") },
725
+ },
726
+ {
727
+ event: "on_llm_stream",
728
+ run_id: expect.any(String),
729
+ tags: expect.arrayContaining(["my_chain", "my_model", "seq:step:2"]),
730
+ metadata: {
731
+ a: "b",
732
+ foo: "bar",
733
+ ls_model_type: "chat",
734
+ ls_stop: undefined,
735
+ },
736
+ name: "my_model",
737
+ data: { chunk: new AIMessageChunk("A") },
738
+ },
739
+ {
740
+ event: "on_chain_stream",
741
+ run_id: expect.any(String),
742
+ tags: ["my_chain"],
743
+ metadata: {
744
+ foo: "bar",
745
+ },
746
+ name: "my_chain",
747
+ data: { chunk: new AIMessageChunk("A") },
748
+ },
749
+ {
750
+ event: "on_llm_stream",
751
+ run_id: expect.any(String),
752
+ tags: expect.arrayContaining(["my_chain", "my_model", "seq:step:2"]),
753
+ metadata: {
754
+ a: "b",
755
+ foo: "bar",
756
+ ls_model_type: "chat",
757
+ ls_stop: undefined,
758
+ },
759
+ name: "my_model",
760
+ data: { chunk: new AIMessageChunk("R") },
761
+ },
762
+ {
763
+ event: "on_chain_stream",
764
+ run_id: expect.any(String),
765
+ tags: ["my_chain"],
766
+ metadata: {
767
+ foo: "bar",
768
+ },
769
+ name: "my_chain",
770
+ data: { chunk: new AIMessageChunk("R") },
771
+ },
772
+ {
773
+ event: "on_llm_end",
774
+ name: "my_model",
775
+ run_id: expect.any(String),
776
+ tags: expect.arrayContaining(["seq:step:2", "my_model", "my_chain"]),
777
+ metadata: {
778
+ foo: "bar",
779
+ a: "b",
780
+ ls_model_type: "chat",
781
+ ls_stop: undefined,
782
+ },
783
+ data: {
784
+ input: {
785
+ messages: [
786
+ [new SystemMessage("You are Godzilla"), new HumanMessage("hello")],
787
+ ],
788
+ },
789
+ output: {
790
+ generations: [
791
+ [
792
+ new ChatGenerationChunk({
793
+ generationInfo: {},
794
+ message: new AIMessageChunk("ROAR"),
795
+ text: "ROAR",
796
+ }),
797
+ ],
798
+ ],
799
+ },
800
+ },
801
+ },
802
+ {
803
+ event: "on_chain_end",
804
+ name: "my_chain",
805
+ run_id: expect.any(String),
806
+ tags: ["my_chain"],
807
+ metadata: {
808
+ foo: "bar",
809
+ },
810
+ data: {
811
+ output: new AIMessageChunk("ROAR"),
812
+ },
813
+ },
814
+ ]);
815
+ });
816
+ test("Runnable streamEvents method with simple tools", async () => {
817
+ const tool = new DynamicTool({
818
+ func: async () => "hello",
819
+ name: "parameterless",
820
+ description: "A tool that does nothing",
821
+ });
822
+ const events = [];
823
+ const eventStream = await tool.streamEvents({}, { version: "v1" });
824
+ for await (const event of eventStream) {
825
+ events.push(event);
826
+ }
827
+ expect(events).toEqual([
828
+ {
829
+ data: { input: {} },
830
+ event: "on_tool_start",
831
+ metadata: {},
832
+ name: "parameterless",
833
+ run_id: expect.any(String),
834
+ tags: [],
835
+ },
836
+ {
837
+ data: { chunk: "hello" },
838
+ event: "on_tool_stream",
839
+ metadata: {},
840
+ name: "parameterless",
841
+ run_id: expect.any(String),
842
+ tags: [],
843
+ },
844
+ {
845
+ data: { output: "hello" },
846
+ event: "on_tool_end",
847
+ metadata: {},
848
+ name: "parameterless",
849
+ run_id: expect.any(String),
850
+ tags: [],
851
+ },
852
+ ]);
853
+ const toolWithParams = new DynamicStructuredTool({
854
+ func: async (params) => JSON.stringify({ x: params.x, y: params.y }),
855
+ schema: z.object({
856
+ x: z.number(),
857
+ y: z.string(),
858
+ }),
859
+ name: "with_parameters",
860
+ description: "A tool that does nothing",
861
+ });
862
+ const events2 = [];
863
+ const eventStream2 = await toolWithParams.streamEvents({ x: 1, y: "2" }, { version: "v1" });
864
+ for await (const event of eventStream2) {
865
+ events2.push(event);
866
+ }
867
+ expect(events2).toEqual([
868
+ {
869
+ data: { input: { x: 1, y: "2" } },
870
+ event: "on_tool_start",
871
+ metadata: {},
872
+ name: "with_parameters",
873
+ run_id: expect.any(String),
874
+ tags: [],
875
+ },
876
+ {
877
+ data: { chunk: JSON.stringify({ x: 1, y: "2" }) },
878
+ event: "on_tool_stream",
879
+ metadata: {},
880
+ name: "with_parameters",
881
+ run_id: expect.any(String),
882
+ tags: [],
883
+ },
884
+ {
885
+ data: { output: JSON.stringify({ x: 1, y: "2" }) },
886
+ event: "on_tool_end",
887
+ metadata: {},
888
+ name: "with_parameters",
889
+ run_id: expect.any(String),
890
+ tags: [],
891
+ },
892
+ ]);
893
+ });
894
+ test("Runnable streamEvents method with a retriever", async () => {
895
+ const retriever = new FakeRetriever({
896
+ output: [
897
+ new Document({ pageContent: "hello world!", metadata: { foo: "bar" } }),
898
+ new Document({
899
+ pageContent: "goodbye world!",
900
+ metadata: { food: "spare" },
901
+ }),
902
+ ],
903
+ });
904
+ const events = [];
905
+ const eventStream = await retriever.streamEvents("hello", {
906
+ version: "v1",
907
+ });
908
+ for await (const event of eventStream) {
909
+ events.push(event);
910
+ }
911
+ expect(events).toEqual([
912
+ {
913
+ data: {
914
+ input: "hello",
915
+ },
916
+ event: "on_retriever_start",
917
+ metadata: {},
918
+ name: "FakeRetriever",
919
+ run_id: expect.any(String),
920
+ tags: [],
921
+ },
922
+ {
923
+ data: {
924
+ chunk: [
925
+ new Document({
926
+ pageContent: "hello world!",
927
+ metadata: { foo: "bar" },
928
+ }),
929
+ new Document({
930
+ pageContent: "goodbye world!",
931
+ metadata: { food: "spare" },
932
+ }),
933
+ ],
934
+ },
935
+ event: "on_retriever_stream",
936
+ metadata: {},
937
+ name: "FakeRetriever",
938
+ run_id: expect.any(String),
939
+ tags: [],
940
+ },
941
+ {
942
+ data: {
943
+ output: {
944
+ documents: [
945
+ new Document({
946
+ pageContent: "hello world!",
947
+ metadata: { foo: "bar" },
948
+ }),
949
+ new Document({
950
+ pageContent: "goodbye world!",
951
+ metadata: { food: "spare" },
952
+ }),
953
+ ],
954
+ },
955
+ },
956
+ event: "on_retriever_end",
957
+ metadata: {},
958
+ name: "FakeRetriever",
959
+ run_id: expect.any(String),
960
+ tags: [],
961
+ },
962
+ ]);
963
+ });
964
+ test("Runnable streamEvents method with text/event-stream encoding", async () => {
965
+ const chain = RunnableLambda.from(reverse).withConfig({
966
+ runName: "reverse",
967
+ });
968
+ const events = [];
969
+ const eventStream = await chain.streamEvents("hello", {
970
+ version: "v1",
971
+ encoding: "text/event-stream",
972
+ runId: "1234",
973
+ });
974
+ for await (const event of eventStream) {
975
+ events.push(event);
976
+ }
977
+ const decoder = new TextDecoder();
978
+ expect(events.length).toEqual(4);
979
+ const dataEvents = events
980
+ .slice(0, 3)
981
+ .map((event) => decoder.decode(event).split("event: data\ndata: ")[1]);
982
+ const expectedPayloads = [
983
+ {
984
+ data: { input: "hello" },
985
+ event: "on_chain_start",
986
+ metadata: {},
987
+ name: "reverse",
988
+ run_id: "1234",
989
+ tags: [],
990
+ },
991
+ {
992
+ data: { chunk: "olleh" },
993
+ event: "on_chain_stream",
994
+ metadata: {},
995
+ name: "reverse",
996
+ run_id: "1234",
997
+ tags: [],
998
+ },
999
+ {
1000
+ data: { output: "olleh" },
1001
+ event: "on_chain_end",
1002
+ metadata: {},
1003
+ name: "reverse",
1004
+ run_id: "1234",
1005
+ tags: [],
1006
+ },
1007
+ ];
1008
+ for (let i = 0; i < dataEvents.length; i += 1) {
1009
+ expect(dataEvents[i].endsWith("\n\n")).toBe(true);
1010
+ expect(JSON.parse(dataEvents[i].replace("\n\n", ""))).toEqual(expectedPayloads[i]);
1011
+ }
1012
+ expect(decoder.decode(events[3])).toEqual("event: end\n\n");
1013
+ });