langsmith 0.0.70 → 0.0.71-rc.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.
package/dist/client.cjs CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.Client = void 0;
26
+ exports.Client = exports.Queue = void 0;
27
27
  const uuid = __importStar(require("uuid"));
28
28
  const async_caller_js_1 = require("./utils/async_caller.cjs");
29
29
  const messages_js_1 = require("./utils/messages.cjs");
@@ -98,6 +98,43 @@ function assertUuid(str) {
98
98
  throw new Error(`Invalid UUID: ${str}`);
99
99
  }
100
100
  }
101
+ class Queue {
102
+ constructor() {
103
+ Object.defineProperty(this, "items", {
104
+ enumerable: true,
105
+ configurable: true,
106
+ writable: true,
107
+ value: []
108
+ });
109
+ }
110
+ get size() {
111
+ return this.items.length;
112
+ }
113
+ push(item) {
114
+ // this.items.push is synchronous with promise creation:
115
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise
116
+ return new Promise((resolve) => {
117
+ this.items.push([item, resolve]);
118
+ });
119
+ }
120
+ pop(upToN) {
121
+ if (upToN < 1) {
122
+ throw new Error("Number of items to pop off may not be less than 1.");
123
+ }
124
+ const popped = [];
125
+ while (popped.length < upToN && this.items.length) {
126
+ const item = this.items.shift();
127
+ if (item) {
128
+ popped.push(item);
129
+ }
130
+ else {
131
+ break;
132
+ }
133
+ }
134
+ return [popped.map((it) => it[0]), () => popped.forEach((it) => it[1]())];
135
+ }
136
+ }
137
+ exports.Queue = Queue;
101
138
  class Client {
102
139
  constructor(config = {}) {
103
140
  Object.defineProperty(this, "apiKey", {
@@ -172,11 +209,11 @@ class Client {
172
209
  writable: true,
173
210
  value: void 0
174
211
  });
175
- Object.defineProperty(this, "pendingAutoBatchedRuns", {
212
+ Object.defineProperty(this, "autoBatchQueue", {
176
213
  enumerable: true,
177
214
  configurable: true,
178
215
  writable: true,
179
- value: []
216
+ value: new Queue()
180
217
  });
181
218
  Object.defineProperty(this, "pendingAutoBatchedRunLimit", {
182
219
  enumerable: true,
@@ -384,45 +421,46 @@ class Client {
384
421
  return sampled;
385
422
  }
386
423
  }
387
- async triggerAutoBatchSend(runs) {
388
- let batch = runs;
389
- if (batch === undefined) {
390
- batch = this.pendingAutoBatchedRuns.slice(0, this.pendingAutoBatchedRunLimit);
391
- this.pendingAutoBatchedRuns = this.pendingAutoBatchedRuns.slice(this.pendingAutoBatchedRunLimit);
424
+ async drainAutoBatchQueue() {
425
+ while (this.autoBatchQueue.size >= 0) {
426
+ const [batch, done] = this.autoBatchQueue.pop(this.pendingAutoBatchedRunLimit);
427
+ if (!batch.length) {
428
+ done();
429
+ return;
430
+ }
431
+ try {
432
+ await this.batchIngestRuns({
433
+ runCreates: batch
434
+ .filter((item) => item.action === "create")
435
+ .map((item) => item.item),
436
+ runUpdates: batch
437
+ .filter((item) => item.action === "update")
438
+ .map((item) => item.item),
439
+ });
440
+ }
441
+ finally {
442
+ done();
443
+ }
392
444
  }
393
- await this.batchIngestRuns({
394
- runCreates: batch
395
- .filter((item) => item.action === "create")
396
- .map((item) => item.item),
397
- runUpdates: batch
398
- .filter((item) => item.action === "update")
399
- .map((item) => item.item),
400
- });
401
445
  }
402
- appendRunCreateToAutoBatchQueue(item) {
446
+ async processRunOperation(item, immediatelyTriggerBatch) {
403
447
  const oldTimeout = this.autoBatchTimeout;
404
448
  clearTimeout(this.autoBatchTimeout);
405
449
  this.autoBatchTimeout = undefined;
406
- this.pendingAutoBatchedRuns.push(item);
407
- while (this.pendingAutoBatchedRuns.length >= this.pendingAutoBatchedRunLimit) {
408
- const batch = this.pendingAutoBatchedRuns.slice(0, this.pendingAutoBatchedRunLimit);
409
- this.pendingAutoBatchedRuns = this.pendingAutoBatchedRuns.slice(this.pendingAutoBatchedRunLimit);
410
- void this.triggerAutoBatchSend(batch);
411
- }
412
- if (this.pendingAutoBatchedRuns.length > 0) {
413
- if (!oldTimeout) {
414
- this.autoBatchTimeout = setTimeout(() => {
415
- this.autoBatchTimeout = undefined;
416
- void this.triggerAutoBatchSend();
417
- }, this.autoBatchInitialDelayMs);
418
- }
419
- else {
420
- this.autoBatchTimeout = setTimeout(() => {
421
- this.autoBatchTimeout = undefined;
422
- void this.triggerAutoBatchSend();
423
- }, this.autoBatchAggregationDelayMs);
424
- }
450
+ const itemPromise = this.autoBatchQueue.push(item);
451
+ if (immediatelyTriggerBatch ||
452
+ this.autoBatchQueue.size > this.pendingAutoBatchedRunLimit) {
453
+ await this.drainAutoBatchQueue();
454
+ }
455
+ if (this.autoBatchQueue.size > 0) {
456
+ this.autoBatchTimeout = setTimeout(() => {
457
+ this.autoBatchTimeout = undefined;
458
+ void this.drainAutoBatchQueue();
459
+ }, oldTimeout
460
+ ? this.autoBatchAggregationDelayMs
461
+ : this.autoBatchInitialDelayMs);
425
462
  }
463
+ return itemPromise;
426
464
  }
427
465
  async batchEndpointIsSupported() {
428
466
  const response = await fetch(`${this.apiUrl}/info`, {
@@ -453,7 +491,7 @@ class Client {
453
491
  if (this.autoBatchTracing &&
454
492
  runCreate.trace_id !== undefined &&
455
493
  runCreate.dotted_order !== undefined) {
456
- this.appendRunCreateToAutoBatchQueue({
494
+ void this.processRunOperation({
457
495
  action: "create",
458
496
  item: runCreate,
459
497
  });
@@ -555,7 +593,15 @@ class Client {
555
593
  if (this.autoBatchTracing &&
556
594
  data.trace_id !== undefined &&
557
595
  data.dotted_order !== undefined) {
558
- this.appendRunCreateToAutoBatchQueue({ action: "update", item: data });
596
+ if (run.end_time !== undefined && data.parent_run_id === undefined) {
597
+ // Trigger a batch as soon as a root trace ends and block to ensure trace finishes
598
+ // in serverless environments.
599
+ await this.processRunOperation({ action: "update", item: data }, true);
600
+ return;
601
+ }
602
+ else {
603
+ void this.processRunOperation({ action: "update", item: data });
604
+ }
559
605
  return;
560
606
  }
561
607
  const headers = { ...this.headers, "Content-Type": "application/json" };
package/dist/client.d.ts CHANGED
@@ -66,6 +66,12 @@ export type CreateExampleOptions = {
66
66
  createdAt?: Date;
67
67
  exampleId?: string;
68
68
  };
69
+ export declare class Queue<T> {
70
+ items: [T, () => void][];
71
+ get size(): number;
72
+ push(item: T): Promise<void>;
73
+ pop(upToN: number): [T[], () => void];
74
+ }
69
75
  export declare class Client {
70
76
  private apiKey?;
71
77
  private apiUrl;
@@ -79,7 +85,7 @@ export declare class Client {
79
85
  private sampledPostUuids;
80
86
  private autoBatchTracing;
81
87
  private batchEndpointSupported?;
82
- private pendingAutoBatchedRuns;
88
+ private autoBatchQueue;
83
89
  private pendingAutoBatchedRunLimit;
84
90
  private autoBatchTimeout;
85
91
  private autoBatchInitialDelayMs;
@@ -103,8 +109,8 @@ export declare class Client {
103
109
  private _getPaginated;
104
110
  private _getCursorPaginatedList;
105
111
  private _filterForSampling;
106
- private triggerAutoBatchSend;
107
- private appendRunCreateToAutoBatchQueue;
112
+ private drainAutoBatchQueue;
113
+ private processRunOperation;
108
114
  protected batchEndpointIsSupported(): Promise<boolean>;
109
115
  createRun(run: CreateRunParams): Promise<void>;
110
116
  /**
package/dist/client.js CHANGED
@@ -72,6 +72,42 @@ function assertUuid(str) {
72
72
  throw new Error(`Invalid UUID: ${str}`);
73
73
  }
74
74
  }
75
+ export class Queue {
76
+ constructor() {
77
+ Object.defineProperty(this, "items", {
78
+ enumerable: true,
79
+ configurable: true,
80
+ writable: true,
81
+ value: []
82
+ });
83
+ }
84
+ get size() {
85
+ return this.items.length;
86
+ }
87
+ push(item) {
88
+ // this.items.push is synchronous with promise creation:
89
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise
90
+ return new Promise((resolve) => {
91
+ this.items.push([item, resolve]);
92
+ });
93
+ }
94
+ pop(upToN) {
95
+ if (upToN < 1) {
96
+ throw new Error("Number of items to pop off may not be less than 1.");
97
+ }
98
+ const popped = [];
99
+ while (popped.length < upToN && this.items.length) {
100
+ const item = this.items.shift();
101
+ if (item) {
102
+ popped.push(item);
103
+ }
104
+ else {
105
+ break;
106
+ }
107
+ }
108
+ return [popped.map((it) => it[0]), () => popped.forEach((it) => it[1]())];
109
+ }
110
+ }
75
111
  export class Client {
76
112
  constructor(config = {}) {
77
113
  Object.defineProperty(this, "apiKey", {
@@ -146,11 +182,11 @@ export class Client {
146
182
  writable: true,
147
183
  value: void 0
148
184
  });
149
- Object.defineProperty(this, "pendingAutoBatchedRuns", {
185
+ Object.defineProperty(this, "autoBatchQueue", {
150
186
  enumerable: true,
151
187
  configurable: true,
152
188
  writable: true,
153
- value: []
189
+ value: new Queue()
154
190
  });
155
191
  Object.defineProperty(this, "pendingAutoBatchedRunLimit", {
156
192
  enumerable: true,
@@ -358,45 +394,46 @@ export class Client {
358
394
  return sampled;
359
395
  }
360
396
  }
361
- async triggerAutoBatchSend(runs) {
362
- let batch = runs;
363
- if (batch === undefined) {
364
- batch = this.pendingAutoBatchedRuns.slice(0, this.pendingAutoBatchedRunLimit);
365
- this.pendingAutoBatchedRuns = this.pendingAutoBatchedRuns.slice(this.pendingAutoBatchedRunLimit);
397
+ async drainAutoBatchQueue() {
398
+ while (this.autoBatchQueue.size >= 0) {
399
+ const [batch, done] = this.autoBatchQueue.pop(this.pendingAutoBatchedRunLimit);
400
+ if (!batch.length) {
401
+ done();
402
+ return;
403
+ }
404
+ try {
405
+ await this.batchIngestRuns({
406
+ runCreates: batch
407
+ .filter((item) => item.action === "create")
408
+ .map((item) => item.item),
409
+ runUpdates: batch
410
+ .filter((item) => item.action === "update")
411
+ .map((item) => item.item),
412
+ });
413
+ }
414
+ finally {
415
+ done();
416
+ }
366
417
  }
367
- await this.batchIngestRuns({
368
- runCreates: batch
369
- .filter((item) => item.action === "create")
370
- .map((item) => item.item),
371
- runUpdates: batch
372
- .filter((item) => item.action === "update")
373
- .map((item) => item.item),
374
- });
375
418
  }
376
- appendRunCreateToAutoBatchQueue(item) {
419
+ async processRunOperation(item, immediatelyTriggerBatch) {
377
420
  const oldTimeout = this.autoBatchTimeout;
378
421
  clearTimeout(this.autoBatchTimeout);
379
422
  this.autoBatchTimeout = undefined;
380
- this.pendingAutoBatchedRuns.push(item);
381
- while (this.pendingAutoBatchedRuns.length >= this.pendingAutoBatchedRunLimit) {
382
- const batch = this.pendingAutoBatchedRuns.slice(0, this.pendingAutoBatchedRunLimit);
383
- this.pendingAutoBatchedRuns = this.pendingAutoBatchedRuns.slice(this.pendingAutoBatchedRunLimit);
384
- void this.triggerAutoBatchSend(batch);
385
- }
386
- if (this.pendingAutoBatchedRuns.length > 0) {
387
- if (!oldTimeout) {
388
- this.autoBatchTimeout = setTimeout(() => {
389
- this.autoBatchTimeout = undefined;
390
- void this.triggerAutoBatchSend();
391
- }, this.autoBatchInitialDelayMs);
392
- }
393
- else {
394
- this.autoBatchTimeout = setTimeout(() => {
395
- this.autoBatchTimeout = undefined;
396
- void this.triggerAutoBatchSend();
397
- }, this.autoBatchAggregationDelayMs);
398
- }
423
+ const itemPromise = this.autoBatchQueue.push(item);
424
+ if (immediatelyTriggerBatch ||
425
+ this.autoBatchQueue.size > this.pendingAutoBatchedRunLimit) {
426
+ await this.drainAutoBatchQueue();
427
+ }
428
+ if (this.autoBatchQueue.size > 0) {
429
+ this.autoBatchTimeout = setTimeout(() => {
430
+ this.autoBatchTimeout = undefined;
431
+ void this.drainAutoBatchQueue();
432
+ }, oldTimeout
433
+ ? this.autoBatchAggregationDelayMs
434
+ : this.autoBatchInitialDelayMs);
399
435
  }
436
+ return itemPromise;
400
437
  }
401
438
  async batchEndpointIsSupported() {
402
439
  const response = await fetch(`${this.apiUrl}/info`, {
@@ -427,7 +464,7 @@ export class Client {
427
464
  if (this.autoBatchTracing &&
428
465
  runCreate.trace_id !== undefined &&
429
466
  runCreate.dotted_order !== undefined) {
430
- this.appendRunCreateToAutoBatchQueue({
467
+ void this.processRunOperation({
431
468
  action: "create",
432
469
  item: runCreate,
433
470
  });
@@ -529,7 +566,15 @@ export class Client {
529
566
  if (this.autoBatchTracing &&
530
567
  data.trace_id !== undefined &&
531
568
  data.dotted_order !== undefined) {
532
- this.appendRunCreateToAutoBatchQueue({ action: "update", item: data });
569
+ if (run.end_time !== undefined && data.parent_run_id === undefined) {
570
+ // Trigger a batch as soon as a root trace ends and block to ensure trace finishes
571
+ // in serverless environments.
572
+ await this.processRunOperation({ action: "update", item: data }, true);
573
+ return;
574
+ }
575
+ else {
576
+ void this.processRunOperation({ action: "update", item: data });
577
+ }
533
578
  return;
534
579
  }
535
580
  const headers = { ...this.headers, "Content-Type": "application/json" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.0.70",
3
+ "version": "0.0.71-rc.0",
4
4
  "description": "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.",
5
5
  "packageManager": "yarn@1.22.19",
6
6
  "files": [