@langchain/core 0.2.17 → 0.2.18

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.
@@ -0,0 +1,551 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable no-process-env */
3
+ /* eslint-disable no-promise-executor-return */
4
+ import { jest } from "@jest/globals";
5
+ import { traceable } from "langsmith/traceable";
6
+ import { RunnableLambda } from "../../runnables/base.js";
7
+ import { HumanMessage } from "../../messages/index.js";
8
+ let fetchMock;
9
+ const originalTracingEnvValue = process.env.LANGCHAIN_TRACING_V2;
10
+ beforeEach(() => {
11
+ fetchMock = jest
12
+ .spyOn(global, "fetch")
13
+ .mockImplementation(() => Promise.resolve({ ok: true, text: () => "" }));
14
+ process.env.LANGCHAIN_TRACING_V2 = "true";
15
+ });
16
+ afterEach(() => {
17
+ jest.restoreAllMocks();
18
+ });
19
+ afterAll(() => {
20
+ process.env.LANGCHAIN_TRACING_V2 = originalTracingEnvValue;
21
+ });
22
+ test.each(["true", "false"])("traceables nested within runnables with background callbacks %s", async (value) => {
23
+ process.env.LANGCHAIN_CALLBACKS_BACKGROUND = value;
24
+ const aiGreet = traceable(async (msg, name = "world") => {
25
+ await new Promise((resolve) => setTimeout(resolve, 300));
26
+ return msg.content + name;
27
+ }, { name: "aiGreet", tracingEnabled: true });
28
+ const root = RunnableLambda.from(async (messages) => {
29
+ const lastMsg = messages.at(-1);
30
+ const greetOne = await aiGreet(lastMsg, "David");
31
+ return [greetOne];
32
+ });
33
+ await root.invoke([new HumanMessage({ content: "Hello!" })]);
34
+ const relevantCalls = fetchMock.mock.calls.filter((call) => {
35
+ return call[0].startsWith("https://api.smith.langchain.com/runs");
36
+ });
37
+ expect(relevantCalls.length).toEqual(4);
38
+ const firstCallParams = JSON.parse(relevantCalls[0][1].body);
39
+ const secondCallParams = JSON.parse(relevantCalls[1][1].body);
40
+ const thirdCallParams = JSON.parse(relevantCalls[2][1].body);
41
+ const fourthCallParams = JSON.parse(relevantCalls[3][1].body);
42
+ expect(firstCallParams).toMatchObject({
43
+ id: firstCallParams.id,
44
+ name: "RunnableLambda",
45
+ start_time: expect.any(Number),
46
+ serialized: {
47
+ lc: 1,
48
+ type: "not_implemented",
49
+ id: ["langchain_core", "runnables", "RunnableLambda"],
50
+ },
51
+ events: [{ name: "start", time: expect.any(String) }],
52
+ inputs: {
53
+ input: [
54
+ {
55
+ lc: 1,
56
+ type: "constructor",
57
+ id: ["langchain_core", "messages", "HumanMessage"],
58
+ kwargs: {
59
+ content: "Hello!",
60
+ additional_kwargs: {},
61
+ response_metadata: {},
62
+ },
63
+ },
64
+ ],
65
+ },
66
+ execution_order: 1,
67
+ child_execution_order: 1,
68
+ run_type: "chain",
69
+ extra: expect.any(Object),
70
+ tags: [],
71
+ trace_id: firstCallParams.id,
72
+ dotted_order: expect.any(String),
73
+ });
74
+ expect(secondCallParams).toMatchObject({
75
+ id: expect.any(String),
76
+ name: "aiGreet",
77
+ start_time: expect.any(Number),
78
+ run_type: "chain",
79
+ extra: expect.any(Object),
80
+ serialized: {},
81
+ inputs: {
82
+ args: [
83
+ {
84
+ lc: 1,
85
+ type: "constructor",
86
+ id: ["langchain_core", "messages", "HumanMessage"],
87
+ kwargs: {
88
+ content: "Hello!",
89
+ additional_kwargs: {},
90
+ response_metadata: {},
91
+ },
92
+ },
93
+ "David",
94
+ ],
95
+ },
96
+ child_runs: [],
97
+ parent_run_id: firstCallParams.id,
98
+ trace_id: firstCallParams.id,
99
+ dotted_order: expect.stringContaining(`${firstCallParams.dotted_order}.`),
100
+ tags: [],
101
+ });
102
+ expect(thirdCallParams).toMatchObject({
103
+ end_time: expect.any(Number),
104
+ inputs: {
105
+ args: [
106
+ {
107
+ lc: 1,
108
+ type: "constructor",
109
+ id: ["langchain_core", "messages", "HumanMessage"],
110
+ kwargs: {
111
+ content: "Hello!",
112
+ additional_kwargs: {},
113
+ response_metadata: {},
114
+ },
115
+ },
116
+ "David",
117
+ ],
118
+ },
119
+ outputs: { outputs: "Hello!David" },
120
+ parent_run_id: firstCallParams.id,
121
+ extra: expect.any(Object),
122
+ dotted_order: secondCallParams.dotted_order,
123
+ trace_id: firstCallParams.id,
124
+ tags: [],
125
+ });
126
+ expect(fourthCallParams).toMatchObject({
127
+ end_time: expect.any(Number),
128
+ outputs: { output: ["Hello!David"] },
129
+ events: [
130
+ { name: "start", time: expect.any(String) },
131
+ { name: "end", time: expect.any(String) },
132
+ ],
133
+ inputs: {
134
+ input: [
135
+ {
136
+ lc: 1,
137
+ type: "constructor",
138
+ id: ["langchain_core", "messages", "HumanMessage"],
139
+ kwargs: {
140
+ content: "Hello!",
141
+ additional_kwargs: {},
142
+ response_metadata: {},
143
+ },
144
+ },
145
+ ],
146
+ },
147
+ trace_id: firstCallParams.id,
148
+ dotted_order: firstCallParams.dotted_order,
149
+ });
150
+ });
151
+ test.each(["true", "false"])("streaming traceables nested within runnables with background callbacks %s", async (value) => {
152
+ process.env.LANGCHAIN_CALLBACKS_BACKGROUND = value;
153
+ const aiGreet = traceable(async function* (msg, name = "world") {
154
+ const res = msg.content + name;
155
+ await new Promise((resolve) => setTimeout(resolve, 300));
156
+ for (const letter of res.split("")) {
157
+ yield letter;
158
+ }
159
+ }, { name: "aiGreet" });
160
+ const root = RunnableLambda.from(async function* (messages) {
161
+ const lastMsg = messages.at(-1);
162
+ yield* aiGreet(lastMsg, "David");
163
+ });
164
+ const stream = await root.stream([new HumanMessage({ content: "Hello!" })]);
165
+ for await (const _ of stream) {
166
+ // Just consume iterator
167
+ }
168
+ const relevantCalls = fetchMock.mock.calls.filter((call) => {
169
+ return call[0].startsWith("https://api.smith.langchain.com/runs");
170
+ });
171
+ expect(relevantCalls.length).toEqual(4);
172
+ const firstCallParams = JSON.parse(relevantCalls[0][1].body);
173
+ const secondCallParams = JSON.parse(relevantCalls[1][1].body);
174
+ const thirdCallParams = JSON.parse(relevantCalls[2][1].body);
175
+ const fourthCallParams = JSON.parse(relevantCalls[3][1].body);
176
+ expect(firstCallParams).toMatchObject({
177
+ id: firstCallParams.id,
178
+ name: "RunnableLambda",
179
+ start_time: expect.any(Number),
180
+ serialized: {
181
+ lc: 1,
182
+ type: "not_implemented",
183
+ id: ["langchain_core", "runnables", "RunnableLambda"],
184
+ },
185
+ events: [{ name: "start", time: expect.any(String) }],
186
+ inputs: {
187
+ input: "",
188
+ },
189
+ execution_order: 1,
190
+ child_execution_order: 1,
191
+ run_type: "chain",
192
+ extra: expect.any(Object),
193
+ tags: [],
194
+ trace_id: firstCallParams.id,
195
+ dotted_order: expect.any(String),
196
+ });
197
+ expect(secondCallParams).toMatchObject({
198
+ id: expect.any(String),
199
+ name: "aiGreet",
200
+ start_time: expect.any(Number),
201
+ run_type: "chain",
202
+ extra: expect.any(Object),
203
+ serialized: {},
204
+ inputs: {
205
+ args: [
206
+ {
207
+ lc: 1,
208
+ type: "constructor",
209
+ id: ["langchain_core", "messages", "HumanMessage"],
210
+ kwargs: {
211
+ content: "Hello!",
212
+ additional_kwargs: {},
213
+ response_metadata: {},
214
+ },
215
+ },
216
+ "David",
217
+ ],
218
+ },
219
+ child_runs: [],
220
+ parent_run_id: firstCallParams.id,
221
+ trace_id: firstCallParams.id,
222
+ dotted_order: expect.stringContaining(`${firstCallParams.dotted_order}.`),
223
+ tags: [],
224
+ });
225
+ expect(thirdCallParams).toMatchObject({
226
+ end_time: expect.any(Number),
227
+ inputs: {
228
+ args: [
229
+ {
230
+ lc: 1,
231
+ type: "constructor",
232
+ id: ["langchain_core", "messages", "HumanMessage"],
233
+ kwargs: {
234
+ content: "Hello!",
235
+ additional_kwargs: {},
236
+ response_metadata: {},
237
+ },
238
+ },
239
+ "David",
240
+ ],
241
+ },
242
+ outputs: {
243
+ outputs: ["H", "e", "l", "l", "o", "!", "D", "a", "v", "i", "d"],
244
+ },
245
+ parent_run_id: firstCallParams.id,
246
+ extra: expect.any(Object),
247
+ dotted_order: secondCallParams.dotted_order,
248
+ trace_id: firstCallParams.id,
249
+ tags: [],
250
+ });
251
+ expect(fourthCallParams).toMatchObject({
252
+ end_time: expect.any(Number),
253
+ outputs: { output: "Hello!David" },
254
+ events: [
255
+ { name: "start", time: expect.any(String) },
256
+ { name: "end", time: expect.any(String) },
257
+ ],
258
+ inputs: {
259
+ input: [
260
+ {
261
+ lc: 1,
262
+ type: "constructor",
263
+ id: ["langchain_core", "messages", "HumanMessage"],
264
+ kwargs: {
265
+ content: "Hello!",
266
+ additional_kwargs: {},
267
+ response_metadata: {},
268
+ },
269
+ },
270
+ ],
271
+ },
272
+ trace_id: firstCallParams.id,
273
+ dotted_order: firstCallParams.dotted_order,
274
+ });
275
+ });
276
+ test.each(["true", "false"])("runnables nested within traceables with background callbacks %s", async (value) => {
277
+ process.env.LANGCHAIN_CALLBACKS_BACKGROUND = value;
278
+ const nested = RunnableLambda.from(async (messages) => {
279
+ const lastMsg = messages.at(-1);
280
+ await new Promise((resolve) => setTimeout(resolve, 300));
281
+ return [lastMsg.content];
282
+ });
283
+ const aiGreet = traceable(async (msg, name = "world") => {
284
+ const contents = await nested.invoke([msg]);
285
+ return contents[0] + name;
286
+ }, { name: "aiGreet", tracingEnabled: true });
287
+ await aiGreet(new HumanMessage({ content: "Hello!" }), "mitochondria");
288
+ const relevantCalls = fetchMock.mock.calls.filter((call) => {
289
+ return call[0].startsWith("https://api.smith.langchain.com/runs");
290
+ });
291
+ expect(relevantCalls.length).toEqual(4);
292
+ const firstCallParams = JSON.parse(relevantCalls[0][1].body);
293
+ const secondCallParams = JSON.parse(relevantCalls[1][1].body);
294
+ const thirdCallParams = JSON.parse(relevantCalls[2][1].body);
295
+ const fourthCallParams = JSON.parse(relevantCalls[3][1].body);
296
+ expect(firstCallParams).toMatchObject({
297
+ id: firstCallParams.id,
298
+ name: "aiGreet",
299
+ start_time: expect.any(Number),
300
+ run_type: "chain",
301
+ extra: expect.any(Object),
302
+ serialized: {},
303
+ inputs: {
304
+ args: [
305
+ {
306
+ lc: 1,
307
+ type: "constructor",
308
+ id: ["langchain_core", "messages", "HumanMessage"],
309
+ kwargs: {
310
+ content: "Hello!",
311
+ additional_kwargs: {},
312
+ response_metadata: {},
313
+ },
314
+ },
315
+ "mitochondria",
316
+ ],
317
+ },
318
+ child_runs: [],
319
+ trace_id: firstCallParams.id,
320
+ dotted_order: firstCallParams.dotted_order,
321
+ tags: [],
322
+ });
323
+ expect(secondCallParams).toMatchObject({
324
+ id: secondCallParams.id,
325
+ name: "RunnableLambda",
326
+ parent_run_id: firstCallParams.id,
327
+ start_time: expect.any(Number),
328
+ serialized: {
329
+ lc: 1,
330
+ type: "not_implemented",
331
+ id: ["langchain_core", "runnables", "RunnableLambda"],
332
+ },
333
+ events: [{ name: "start", time: expect.any(String) }],
334
+ inputs: {
335
+ input: [
336
+ {
337
+ lc: 1,
338
+ type: "constructor",
339
+ id: ["langchain_core", "messages", "HumanMessage"],
340
+ kwargs: {
341
+ content: "Hello!",
342
+ additional_kwargs: {},
343
+ response_metadata: {},
344
+ },
345
+ },
346
+ ],
347
+ },
348
+ execution_order: 2,
349
+ child_execution_order: 2,
350
+ run_type: "chain",
351
+ extra: expect.any(Object),
352
+ tags: [],
353
+ trace_id: firstCallParams.id,
354
+ dotted_order: expect.stringContaining(`${firstCallParams.dotted_order}.`),
355
+ });
356
+ expect(thirdCallParams).toMatchObject({
357
+ end_time: expect.any(Number),
358
+ outputs: { output: ["Hello!"] },
359
+ events: [
360
+ { name: "start", time: expect.any(String) },
361
+ { name: "end", time: expect.any(String) },
362
+ ],
363
+ inputs: {
364
+ input: [
365
+ {
366
+ lc: 1,
367
+ type: "constructor",
368
+ id: ["langchain_core", "messages", "HumanMessage"],
369
+ kwargs: {
370
+ content: "Hello!",
371
+ additional_kwargs: {},
372
+ response_metadata: {},
373
+ },
374
+ },
375
+ ],
376
+ },
377
+ trace_id: firstCallParams.id,
378
+ dotted_order: expect.stringContaining(`${firstCallParams.dotted_order}.`),
379
+ parent_run_id: firstCallParams.id,
380
+ });
381
+ expect(fourthCallParams).toMatchObject({
382
+ end_time: expect.any(Number),
383
+ inputs: {
384
+ args: [
385
+ {
386
+ lc: 1,
387
+ type: "constructor",
388
+ id: ["langchain_core", "messages", "HumanMessage"],
389
+ kwargs: {
390
+ content: "Hello!",
391
+ additional_kwargs: {},
392
+ response_metadata: {},
393
+ },
394
+ },
395
+ "mitochondria",
396
+ ],
397
+ },
398
+ outputs: { outputs: "Hello!mitochondria" },
399
+ extra: expect.any(Object),
400
+ dotted_order: firstCallParams.dotted_order,
401
+ trace_id: firstCallParams.id,
402
+ tags: [],
403
+ });
404
+ });
405
+ test.each(["true", "false"])("streaming runnables nested within traceables with background callbacks %s", async (value) => {
406
+ process.env.LANGCHAIN_CALLBACKS_BACKGROUND = value;
407
+ const nested = RunnableLambda.from(async function* (messages) {
408
+ const lastMsg = messages.at(-1);
409
+ await new Promise((resolve) => setTimeout(resolve, 300));
410
+ for (const letter of lastMsg.content.split("")) {
411
+ yield letter;
412
+ }
413
+ });
414
+ const aiGreet = traceable(async function* (msg, name = "world") {
415
+ for await (const chunk of await nested.stream([msg])) {
416
+ yield chunk;
417
+ }
418
+ for (const letter of name.split("")) {
419
+ yield letter;
420
+ }
421
+ }, { name: "aiGreet", tracingEnabled: true });
422
+ for await (const _ of aiGreet(new HumanMessage({ content: "Hello!" }), "mitochondria")) {
423
+ // Just consume iterator
424
+ }
425
+ const relevantCalls = fetchMock.mock.calls.filter((call) => {
426
+ return call[0].startsWith("https://api.smith.langchain.com/runs");
427
+ });
428
+ expect(relevantCalls.length).toEqual(4);
429
+ const firstCallParams = JSON.parse(relevantCalls[0][1].body);
430
+ const secondCallParams = JSON.parse(relevantCalls[1][1].body);
431
+ const thirdCallParams = JSON.parse(relevantCalls[2][1].body);
432
+ const fourthCallParams = JSON.parse(relevantCalls[3][1].body);
433
+ expect(firstCallParams).toMatchObject({
434
+ id: firstCallParams.id,
435
+ name: "aiGreet",
436
+ start_time: expect.any(Number),
437
+ run_type: "chain",
438
+ extra: expect.any(Object),
439
+ serialized: {},
440
+ inputs: {
441
+ args: [
442
+ {
443
+ lc: 1,
444
+ type: "constructor",
445
+ id: ["langchain_core", "messages", "HumanMessage"],
446
+ kwargs: {
447
+ content: "Hello!",
448
+ additional_kwargs: {},
449
+ response_metadata: {},
450
+ },
451
+ },
452
+ "mitochondria",
453
+ ],
454
+ },
455
+ child_runs: [],
456
+ trace_id: firstCallParams.id,
457
+ dotted_order: firstCallParams.dotted_order,
458
+ tags: [],
459
+ });
460
+ expect(secondCallParams).toMatchObject({
461
+ id: secondCallParams.id,
462
+ name: "RunnableLambda",
463
+ parent_run_id: firstCallParams.id,
464
+ start_time: expect.any(Number),
465
+ serialized: {
466
+ lc: 1,
467
+ type: "not_implemented",
468
+ id: ["langchain_core", "runnables", "RunnableLambda"],
469
+ },
470
+ events: [{ name: "start", time: expect.any(String) }],
471
+ inputs: {
472
+ input: "",
473
+ },
474
+ execution_order: 2,
475
+ child_execution_order: 2,
476
+ run_type: "chain",
477
+ extra: expect.any(Object),
478
+ tags: [],
479
+ trace_id: firstCallParams.id,
480
+ dotted_order: expect.stringContaining(`${firstCallParams.dotted_order}.`),
481
+ });
482
+ expect(thirdCallParams).toMatchObject({
483
+ end_time: expect.any(Number),
484
+ outputs: { output: "Hello!" },
485
+ events: [
486
+ { name: "start", time: expect.any(String) },
487
+ { name: "end", time: expect.any(String) },
488
+ ],
489
+ inputs: {
490
+ input: [
491
+ {
492
+ lc: 1,
493
+ type: "constructor",
494
+ id: ["langchain_core", "messages", "HumanMessage"],
495
+ kwargs: {
496
+ content: "Hello!",
497
+ additional_kwargs: {},
498
+ response_metadata: {},
499
+ },
500
+ },
501
+ ],
502
+ },
503
+ trace_id: firstCallParams.id,
504
+ dotted_order: expect.stringContaining(`${firstCallParams.dotted_order}.`),
505
+ parent_run_id: firstCallParams.id,
506
+ });
507
+ expect(fourthCallParams).toMatchObject({
508
+ end_time: expect.any(Number),
509
+ inputs: {
510
+ args: [
511
+ {
512
+ lc: 1,
513
+ type: "constructor",
514
+ id: ["langchain_core", "messages", "HumanMessage"],
515
+ kwargs: {
516
+ content: "Hello!",
517
+ additional_kwargs: {},
518
+ response_metadata: {},
519
+ },
520
+ },
521
+ "mitochondria",
522
+ ],
523
+ },
524
+ outputs: {
525
+ outputs: [
526
+ "H",
527
+ "e",
528
+ "l",
529
+ "l",
530
+ "o",
531
+ "!",
532
+ "m",
533
+ "i",
534
+ "t",
535
+ "o",
536
+ "c",
537
+ "h",
538
+ "o",
539
+ "n",
540
+ "d",
541
+ "r",
542
+ "i",
543
+ "a",
544
+ ],
545
+ },
546
+ extra: expect.any(Object),
547
+ dotted_order: firstCallParams.dotted_order,
548
+ trace_id: firstCallParams.id,
549
+ tags: [],
550
+ });
551
+ });
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LangChainTracer = void 0;
4
4
  const langsmith_1 = require("langsmith");
5
+ const run_trees_1 = require("langsmith/run_trees");
5
6
  const traceable_1 = require("langsmith/singletons/traceable");
6
7
  const env_js_1 = require("../utils/env.cjs");
7
8
  const base_js_1 = require("./base.cjs");
@@ -39,37 +40,9 @@ class LangChainTracer extends base_js_1.BaseTracer {
39
40
  (0, env_js_1.getEnvironmentVariable)("LANGCHAIN_SESSION");
40
41
  this.exampleId = exampleId;
41
42
  this.client = client ?? new langsmith_1.Client({});
42
- // if we're inside traceable, we can obtain the traceable tree
43
- // and populate the run map, which is used to correctly
44
- // infer dotted order and execution order
45
- const traceableTree = this.getTraceableRunTree();
43
+ const traceableTree = LangChainTracer.getTraceableRunTree();
46
44
  if (traceableTree) {
47
- let rootRun = traceableTree;
48
- const visited = new Set();
49
- while (rootRun.parent_run) {
50
- if (visited.has(rootRun.id))
51
- break;
52
- visited.add(rootRun.id);
53
- if (!rootRun.parent_run)
54
- break;
55
- rootRun = rootRun.parent_run;
56
- }
57
- visited.clear();
58
- const queue = [rootRun];
59
- while (queue.length > 0) {
60
- const current = queue.shift();
61
- if (!current || visited.has(current.id))
62
- continue;
63
- visited.add(current.id);
64
- // @ts-expect-error Types of property 'events' are incompatible.
65
- this.runMap.set(current.id, current);
66
- if (current.child_runs) {
67
- queue.push(...current.child_runs);
68
- }
69
- }
70
- this.client = traceableTree.client ?? this.client;
71
- this.projectName = traceableTree.project_name ?? this.projectName;
72
- this.exampleId = traceableTree.reference_example_id ?? this.exampleId;
45
+ this.updateFromRunTree(traceableTree);
73
46
  }
74
47
  }
75
48
  async _convertToCreate(run, example_id = undefined) {
@@ -105,7 +78,76 @@ class LangChainTracer extends base_js_1.BaseTracer {
105
78
  getRun(id) {
106
79
  return this.runMap.get(id);
107
80
  }
108
- getTraceableRunTree() {
81
+ updateFromRunTree(runTree) {
82
+ let rootRun = runTree;
83
+ const visited = new Set();
84
+ while (rootRun.parent_run) {
85
+ if (visited.has(rootRun.id))
86
+ break;
87
+ visited.add(rootRun.id);
88
+ if (!rootRun.parent_run)
89
+ break;
90
+ rootRun = rootRun.parent_run;
91
+ }
92
+ visited.clear();
93
+ const queue = [rootRun];
94
+ while (queue.length > 0) {
95
+ const current = queue.shift();
96
+ if (!current || visited.has(current.id))
97
+ continue;
98
+ visited.add(current.id);
99
+ // @ts-expect-error Types of property 'events' are incompatible.
100
+ this.runMap.set(current.id, current);
101
+ if (current.child_runs) {
102
+ queue.push(...current.child_runs);
103
+ }
104
+ }
105
+ this.client = runTree.client ?? this.client;
106
+ this.projectName = runTree.project_name ?? this.projectName;
107
+ this.exampleId = runTree.reference_example_id ?? this.exampleId;
108
+ }
109
+ convertToRunTree(id) {
110
+ const runTreeMap = {};
111
+ const runTreeList = [];
112
+ for (const [id, run] of this.runMap) {
113
+ // by converting the run map to a run tree, we are doing a copy
114
+ // thus, any mutation performed on the run tree will not be reflected
115
+ // back in the run map
116
+ // TODO: Stop using `this.runMap` in favour of LangSmith's `RunTree`
117
+ const runTree = new run_trees_1.RunTree({
118
+ ...run,
119
+ child_runs: [],
120
+ parent_run: undefined,
121
+ // inherited properties
122
+ client: this.client,
123
+ project_name: this.projectName,
124
+ reference_example_id: this.exampleId,
125
+ tracingEnabled: true,
126
+ });
127
+ runTreeMap[id] = runTree;
128
+ runTreeList.push([id, run.dotted_order]);
129
+ }
130
+ runTreeList.sort((a, b) => {
131
+ if (!a[1] || !b[1])
132
+ return 0;
133
+ return a[1].localeCompare(b[1]);
134
+ });
135
+ for (const [id] of runTreeList) {
136
+ const run = this.runMap.get(id);
137
+ const runTree = runTreeMap[id];
138
+ if (!run || !runTree)
139
+ continue;
140
+ if (run.parent_run_id) {
141
+ const parentRunTree = runTreeMap[run.parent_run_id];
142
+ if (parentRunTree) {
143
+ parentRunTree.child_runs.push(runTree);
144
+ runTree.parent_run = parentRunTree;
145
+ }
146
+ }
147
+ }
148
+ return runTreeMap[id];
149
+ }
150
+ static getTraceableRunTree() {
109
151
  try {
110
152
  return (0, traceable_1.getCurrentRunTree)();
111
153
  }
@@ -36,5 +36,7 @@ export declare class LangChainTracer extends BaseTracer implements LangChainTrac
36
36
  onRunCreate(run: Run): Promise<void>;
37
37
  onRunUpdate(run: Run): Promise<void>;
38
38
  getRun(id: string): Run | undefined;
39
- getTraceableRunTree(): RunTree | undefined;
39
+ updateFromRunTree(runTree: RunTree): void;
40
+ convertToRunTree(id: string): RunTree | undefined;
41
+ static getTraceableRunTree(): RunTree | undefined;
40
42
  }