@sqaitech/mcp 0.5.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/217.js ADDED
@@ -0,0 +1,4744 @@
1
+ exports.ids = [
2
+ "217"
3
+ ];
4
+ exports.modules = {
5
+ "../../node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.js": function(module) {
6
+ "use strict";
7
+ var has = Object.prototype.hasOwnProperty, prefix = '~';
8
+ function Events() {}
9
+ if (Object.create) {
10
+ Events.prototype = Object.create(null);
11
+ if (!new Events().__proto__) prefix = false;
12
+ }
13
+ function EE(fn, context, once) {
14
+ this.fn = fn;
15
+ this.context = context;
16
+ this.once = once || false;
17
+ }
18
+ function addListener(emitter, event, fn, context, once) {
19
+ if ('function' != typeof fn) throw new TypeError('The listener must be a function');
20
+ var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
21
+ if (emitter._events[evt]) if (emitter._events[evt].fn) emitter._events[evt] = [
22
+ emitter._events[evt],
23
+ listener
24
+ ];
25
+ else emitter._events[evt].push(listener);
26
+ else emitter._events[evt] = listener, emitter._eventsCount++;
27
+ return emitter;
28
+ }
29
+ function clearEvent(emitter, evt) {
30
+ if (0 === --emitter._eventsCount) emitter._events = new Events();
31
+ else delete emitter._events[evt];
32
+ }
33
+ function EventEmitter() {
34
+ this._events = new Events();
35
+ this._eventsCount = 0;
36
+ }
37
+ EventEmitter.prototype.eventNames = function() {
38
+ var names = [], events, name;
39
+ if (0 === this._eventsCount) return names;
40
+ for(name in events = this._events)if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
41
+ if (Object.getOwnPropertySymbols) return names.concat(Object.getOwnPropertySymbols(events));
42
+ return names;
43
+ };
44
+ EventEmitter.prototype.listeners = function(event) {
45
+ var evt = prefix ? prefix + event : event, handlers = this._events[evt];
46
+ if (!handlers) return [];
47
+ if (handlers.fn) return [
48
+ handlers.fn
49
+ ];
50
+ for(var i = 0, l = handlers.length, ee = new Array(l); i < l; i++)ee[i] = handlers[i].fn;
51
+ return ee;
52
+ };
53
+ EventEmitter.prototype.listenerCount = function(event) {
54
+ var evt = prefix ? prefix + event : event, listeners = this._events[evt];
55
+ if (!listeners) return 0;
56
+ if (listeners.fn) return 1;
57
+ return listeners.length;
58
+ };
59
+ EventEmitter.prototype.emit = function(event, a1, a2, a3, a4, a5) {
60
+ var evt = prefix ? prefix + event : event;
61
+ if (!this._events[evt]) return false;
62
+ var listeners = this._events[evt], len = arguments.length, args, i;
63
+ if (listeners.fn) {
64
+ if (listeners.once) this.removeListener(event, listeners.fn, void 0, true);
65
+ switch(len){
66
+ case 1:
67
+ return listeners.fn.call(listeners.context), true;
68
+ case 2:
69
+ return listeners.fn.call(listeners.context, a1), true;
70
+ case 3:
71
+ return listeners.fn.call(listeners.context, a1, a2), true;
72
+ case 4:
73
+ return listeners.fn.call(listeners.context, a1, a2, a3), true;
74
+ case 5:
75
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
76
+ case 6:
77
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
78
+ }
79
+ for(i = 1, args = new Array(len - 1); i < len; i++)args[i - 1] = arguments[i];
80
+ listeners.fn.apply(listeners.context, args);
81
+ } else {
82
+ var length = listeners.length, j;
83
+ for(i = 0; i < length; i++){
84
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true);
85
+ switch(len){
86
+ case 1:
87
+ listeners[i].fn.call(listeners[i].context);
88
+ break;
89
+ case 2:
90
+ listeners[i].fn.call(listeners[i].context, a1);
91
+ break;
92
+ case 3:
93
+ listeners[i].fn.call(listeners[i].context, a1, a2);
94
+ break;
95
+ case 4:
96
+ listeners[i].fn.call(listeners[i].context, a1, a2, a3);
97
+ break;
98
+ default:
99
+ if (!args) for(j = 1, args = new Array(len - 1); j < len; j++)args[j - 1] = arguments[j];
100
+ listeners[i].fn.apply(listeners[i].context, args);
101
+ }
102
+ }
103
+ }
104
+ return true;
105
+ };
106
+ EventEmitter.prototype.on = function(event, fn, context) {
107
+ return addListener(this, event, fn, context, false);
108
+ };
109
+ EventEmitter.prototype.once = function(event, fn, context) {
110
+ return addListener(this, event, fn, context, true);
111
+ };
112
+ EventEmitter.prototype.removeListener = function(event, fn, context, once) {
113
+ var evt = prefix ? prefix + event : event;
114
+ if (!this._events[evt]) return this;
115
+ if (!fn) {
116
+ clearEvent(this, evt);
117
+ return this;
118
+ }
119
+ var listeners = this._events[evt];
120
+ if (listeners.fn) {
121
+ if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) clearEvent(this, evt);
122
+ } else {
123
+ for(var i = 0, events = [], length = listeners.length; i < length; i++)if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) events.push(listeners[i]);
124
+ if (events.length) this._events[evt] = 1 === events.length ? events[0] : events;
125
+ else clearEvent(this, evt);
126
+ }
127
+ return this;
128
+ };
129
+ EventEmitter.prototype.removeAllListeners = function(event) {
130
+ var evt;
131
+ if (event) {
132
+ evt = prefix ? prefix + event : event;
133
+ if (this._events[evt]) clearEvent(this, evt);
134
+ } else {
135
+ this._events = new Events();
136
+ this._eventsCount = 0;
137
+ }
138
+ return this;
139
+ };
140
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
141
+ EventEmitter.prototype.addListener = EventEmitter.prototype.on;
142
+ EventEmitter.prefixed = prefix;
143
+ EventEmitter.EventEmitter = EventEmitter;
144
+ module.exports = EventEmitter;
145
+ },
146
+ "../../node_modules/.pnpm/p-finally@1.0.0/node_modules/p-finally/index.js": function(module) {
147
+ "use strict";
148
+ module.exports = (promise, onFinally)=>{
149
+ onFinally = onFinally || (()=>{});
150
+ return promise.then((val)=>new Promise((resolve)=>{
151
+ resolve(onFinally());
152
+ }).then(()=>val), (err)=>new Promise((resolve)=>{
153
+ resolve(onFinally());
154
+ }).then(()=>{
155
+ throw err;
156
+ }));
157
+ };
158
+ },
159
+ "../../node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/index.js": function(__unused_webpack_module, exports1, __webpack_require__) {
160
+ "use strict";
161
+ Object.defineProperty(exports1, "__esModule", {
162
+ value: true
163
+ });
164
+ const EventEmitter = __webpack_require__("../../node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.js");
165
+ const p_timeout_1 = __webpack_require__("../../node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.js");
166
+ const priority_queue_1 = __webpack_require__("../../node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/priority-queue.js");
167
+ const empty = ()=>{};
168
+ const timeoutError = new p_timeout_1.TimeoutError();
169
+ class PQueue extends EventEmitter {
170
+ constructor(options){
171
+ var _a, _b, _c, _d;
172
+ super();
173
+ this._intervalCount = 0;
174
+ this._intervalEnd = 0;
175
+ this._pendingCount = 0;
176
+ this._resolveEmpty = empty;
177
+ this._resolveIdle = empty;
178
+ options = Object.assign({
179
+ carryoverConcurrencyCount: false,
180
+ intervalCap: 1 / 0,
181
+ interval: 0,
182
+ concurrency: 1 / 0,
183
+ autoStart: true,
184
+ queueClass: priority_queue_1.default
185
+ }, options);
186
+ if (!('number' == typeof options.intervalCap && options.intervalCap >= 1)) throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${null != (_b = null == (_a = options.intervalCap) ? void 0 : _a.toString()) ? _b : ''}\` (${typeof options.intervalCap})`);
187
+ if (void 0 === options.interval || !(Number.isFinite(options.interval) && options.interval >= 0)) throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${null != (_d = null == (_c = options.interval) ? void 0 : _c.toString()) ? _d : ''}\` (${typeof options.interval})`);
188
+ this._carryoverConcurrencyCount = options.carryoverConcurrencyCount;
189
+ this._isIntervalIgnored = options.intervalCap === 1 / 0 || 0 === options.interval;
190
+ this._intervalCap = options.intervalCap;
191
+ this._interval = options.interval;
192
+ this._queue = new options.queueClass();
193
+ this._queueClass = options.queueClass;
194
+ this.concurrency = options.concurrency;
195
+ this._timeout = options.timeout;
196
+ this._throwOnTimeout = true === options.throwOnTimeout;
197
+ this._isPaused = false === options.autoStart;
198
+ }
199
+ get _doesIntervalAllowAnother() {
200
+ return this._isIntervalIgnored || this._intervalCount < this._intervalCap;
201
+ }
202
+ get _doesConcurrentAllowAnother() {
203
+ return this._pendingCount < this._concurrency;
204
+ }
205
+ _next() {
206
+ this._pendingCount--;
207
+ this._tryToStartAnother();
208
+ this.emit('next');
209
+ }
210
+ _resolvePromises() {
211
+ this._resolveEmpty();
212
+ this._resolveEmpty = empty;
213
+ if (0 === this._pendingCount) {
214
+ this._resolveIdle();
215
+ this._resolveIdle = empty;
216
+ this.emit('idle');
217
+ }
218
+ }
219
+ _onResumeInterval() {
220
+ this._onInterval();
221
+ this._initializeIntervalIfNeeded();
222
+ this._timeoutId = void 0;
223
+ }
224
+ _isIntervalPaused() {
225
+ const now = Date.now();
226
+ if (void 0 === this._intervalId) {
227
+ const delay = this._intervalEnd - now;
228
+ if (delay < 0) this._intervalCount = this._carryoverConcurrencyCount ? this._pendingCount : 0;
229
+ else {
230
+ if (void 0 === this._timeoutId) this._timeoutId = setTimeout(()=>{
231
+ this._onResumeInterval();
232
+ }, delay);
233
+ return true;
234
+ }
235
+ }
236
+ return false;
237
+ }
238
+ _tryToStartAnother() {
239
+ if (0 === this._queue.size) {
240
+ if (this._intervalId) clearInterval(this._intervalId);
241
+ this._intervalId = void 0;
242
+ this._resolvePromises();
243
+ return false;
244
+ }
245
+ if (!this._isPaused) {
246
+ const canInitializeInterval = !this._isIntervalPaused();
247
+ if (this._doesIntervalAllowAnother && this._doesConcurrentAllowAnother) {
248
+ const job = this._queue.dequeue();
249
+ if (!job) return false;
250
+ this.emit('active');
251
+ job();
252
+ if (canInitializeInterval) this._initializeIntervalIfNeeded();
253
+ return true;
254
+ }
255
+ }
256
+ return false;
257
+ }
258
+ _initializeIntervalIfNeeded() {
259
+ if (this._isIntervalIgnored || void 0 !== this._intervalId) return;
260
+ this._intervalId = setInterval(()=>{
261
+ this._onInterval();
262
+ }, this._interval);
263
+ this._intervalEnd = Date.now() + this._interval;
264
+ }
265
+ _onInterval() {
266
+ if (0 === this._intervalCount && 0 === this._pendingCount && this._intervalId) {
267
+ clearInterval(this._intervalId);
268
+ this._intervalId = void 0;
269
+ }
270
+ this._intervalCount = this._carryoverConcurrencyCount ? this._pendingCount : 0;
271
+ this._processQueue();
272
+ }
273
+ _processQueue() {
274
+ while(this._tryToStartAnother());
275
+ }
276
+ get concurrency() {
277
+ return this._concurrency;
278
+ }
279
+ set concurrency(newConcurrency) {
280
+ if (!('number' == typeof newConcurrency && newConcurrency >= 1)) throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${newConcurrency}\` (${typeof newConcurrency})`);
281
+ this._concurrency = newConcurrency;
282
+ this._processQueue();
283
+ }
284
+ async add(fn, options = {}) {
285
+ return new Promise((resolve, reject)=>{
286
+ const run = async ()=>{
287
+ this._pendingCount++;
288
+ this._intervalCount++;
289
+ try {
290
+ const operation = void 0 === this._timeout && void 0 === options.timeout ? fn() : p_timeout_1.default(Promise.resolve(fn()), void 0 === options.timeout ? this._timeout : options.timeout, ()=>{
291
+ if (void 0 === options.throwOnTimeout ? this._throwOnTimeout : options.throwOnTimeout) reject(timeoutError);
292
+ });
293
+ resolve(await operation);
294
+ } catch (error) {
295
+ reject(error);
296
+ }
297
+ this._next();
298
+ };
299
+ this._queue.enqueue(run, options);
300
+ this._tryToStartAnother();
301
+ this.emit('add');
302
+ });
303
+ }
304
+ async addAll(functions, options) {
305
+ return Promise.all(functions.map(async (function_)=>this.add(function_, options)));
306
+ }
307
+ start() {
308
+ if (!this._isPaused) return this;
309
+ this._isPaused = false;
310
+ this._processQueue();
311
+ return this;
312
+ }
313
+ pause() {
314
+ this._isPaused = true;
315
+ }
316
+ clear() {
317
+ this._queue = new this._queueClass();
318
+ }
319
+ async onEmpty() {
320
+ if (0 === this._queue.size) return;
321
+ return new Promise((resolve)=>{
322
+ const existingResolve = this._resolveEmpty;
323
+ this._resolveEmpty = ()=>{
324
+ existingResolve();
325
+ resolve();
326
+ };
327
+ });
328
+ }
329
+ async onIdle() {
330
+ if (0 === this._pendingCount && 0 === this._queue.size) return;
331
+ return new Promise((resolve)=>{
332
+ const existingResolve = this._resolveIdle;
333
+ this._resolveIdle = ()=>{
334
+ existingResolve();
335
+ resolve();
336
+ };
337
+ });
338
+ }
339
+ get size() {
340
+ return this._queue.size;
341
+ }
342
+ sizeBy(options) {
343
+ return this._queue.filter(options).length;
344
+ }
345
+ get pending() {
346
+ return this._pendingCount;
347
+ }
348
+ get isPaused() {
349
+ return this._isPaused;
350
+ }
351
+ get timeout() {
352
+ return this._timeout;
353
+ }
354
+ set timeout(milliseconds) {
355
+ this._timeout = milliseconds;
356
+ }
357
+ }
358
+ exports1["default"] = PQueue;
359
+ },
360
+ "../../node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/lower-bound.js": function(__unused_webpack_module, exports1) {
361
+ "use strict";
362
+ Object.defineProperty(exports1, "__esModule", {
363
+ value: true
364
+ });
365
+ function lowerBound(array, value, comparator) {
366
+ let first = 0;
367
+ let count = array.length;
368
+ while(count > 0){
369
+ const step = count / 2 | 0;
370
+ let it = first + step;
371
+ if (comparator(array[it], value) <= 0) {
372
+ first = ++it;
373
+ count -= step + 1;
374
+ } else count = step;
375
+ }
376
+ return first;
377
+ }
378
+ exports1["default"] = lowerBound;
379
+ },
380
+ "../../node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/priority-queue.js": function(__unused_webpack_module, exports1, __webpack_require__) {
381
+ "use strict";
382
+ Object.defineProperty(exports1, "__esModule", {
383
+ value: true
384
+ });
385
+ const lower_bound_1 = __webpack_require__("../../node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/lower-bound.js");
386
+ class PriorityQueue {
387
+ constructor(){
388
+ this._queue = [];
389
+ }
390
+ enqueue(run, options) {
391
+ options = Object.assign({
392
+ priority: 0
393
+ }, options);
394
+ const element = {
395
+ priority: options.priority,
396
+ run
397
+ };
398
+ if (this.size && this._queue[this.size - 1].priority >= options.priority) return void this._queue.push(element);
399
+ const index = lower_bound_1.default(this._queue, element, (a, b)=>b.priority - a.priority);
400
+ this._queue.splice(index, 0, element);
401
+ }
402
+ dequeue() {
403
+ const item = this._queue.shift();
404
+ return null == item ? void 0 : item.run;
405
+ }
406
+ filter(options) {
407
+ return this._queue.filter((element)=>element.priority === options.priority).map((element)=>element.run);
408
+ }
409
+ get size() {
410
+ return this._queue.length;
411
+ }
412
+ }
413
+ exports1["default"] = PriorityQueue;
414
+ },
415
+ "../../node_modules/.pnpm/p-retry@4.6.2/node_modules/p-retry/index.js": function(module, __unused_webpack_exports, __webpack_require__) {
416
+ "use strict";
417
+ const retry = __webpack_require__("../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.js");
418
+ const networkErrorMsgs = [
419
+ 'Failed to fetch',
420
+ 'NetworkError when attempting to fetch resource.',
421
+ 'The Internet connection appears to be offline.',
422
+ 'Network request failed'
423
+ ];
424
+ class AbortError extends Error {
425
+ constructor(message){
426
+ super();
427
+ if (message instanceof Error) {
428
+ this.originalError = message;
429
+ ({ message } = message);
430
+ } else {
431
+ this.originalError = new Error(message);
432
+ this.originalError.stack = this.stack;
433
+ }
434
+ this.name = 'AbortError';
435
+ this.message = message;
436
+ }
437
+ }
438
+ const decorateErrorWithCounts = (error, attemptNumber, options)=>{
439
+ const retriesLeft = options.retries - (attemptNumber - 1);
440
+ error.attemptNumber = attemptNumber;
441
+ error.retriesLeft = retriesLeft;
442
+ return error;
443
+ };
444
+ const isNetworkError = (errorMessage)=>networkErrorMsgs.includes(errorMessage);
445
+ const pRetry = (input, options)=>new Promise((resolve, reject)=>{
446
+ options = {
447
+ onFailedAttempt: ()=>{},
448
+ retries: 10,
449
+ ...options
450
+ };
451
+ const operation = retry.operation(options);
452
+ operation.attempt(async (attemptNumber)=>{
453
+ try {
454
+ resolve(await input(attemptNumber));
455
+ } catch (error) {
456
+ if (!(error instanceof Error)) return void reject(new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`));
457
+ if (error instanceof AbortError) {
458
+ operation.stop();
459
+ reject(error.originalError);
460
+ } else if (error instanceof TypeError && !isNetworkError(error.message)) {
461
+ operation.stop();
462
+ reject(error);
463
+ } else {
464
+ decorateErrorWithCounts(error, attemptNumber, options);
465
+ try {
466
+ await options.onFailedAttempt(error);
467
+ } catch (error) {
468
+ reject(error);
469
+ return;
470
+ }
471
+ if (!operation.retry(error)) reject(operation.mainError());
472
+ }
473
+ }
474
+ });
475
+ });
476
+ module.exports = pRetry;
477
+ module.exports["default"] = pRetry;
478
+ module.exports.AbortError = AbortError;
479
+ },
480
+ "../../node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.js": function(module, __unused_webpack_exports, __webpack_require__) {
481
+ "use strict";
482
+ const pFinally = __webpack_require__("../../node_modules/.pnpm/p-finally@1.0.0/node_modules/p-finally/index.js");
483
+ class TimeoutError extends Error {
484
+ constructor(message){
485
+ super(message);
486
+ this.name = 'TimeoutError';
487
+ }
488
+ }
489
+ const pTimeout = (promise, milliseconds, fallback)=>new Promise((resolve, reject)=>{
490
+ if ('number' != typeof milliseconds || milliseconds < 0) throw new TypeError('Expected `milliseconds` to be a positive number');
491
+ if (milliseconds === 1 / 0) return void resolve(promise);
492
+ const timer = setTimeout(()=>{
493
+ if ('function' == typeof fallback) {
494
+ try {
495
+ resolve(fallback());
496
+ } catch (error) {
497
+ reject(error);
498
+ }
499
+ return;
500
+ }
501
+ const message = 'string' == typeof fallback ? fallback : `Promise timed out after ${milliseconds} milliseconds`;
502
+ const timeoutError = fallback instanceof Error ? fallback : new TimeoutError(message);
503
+ if ('function' == typeof promise.cancel) promise.cancel();
504
+ reject(timeoutError);
505
+ }, milliseconds);
506
+ pFinally(promise.then(resolve, reject), ()=>{
507
+ clearTimeout(timer);
508
+ });
509
+ });
510
+ module.exports = pTimeout;
511
+ module.exports["default"] = pTimeout;
512
+ module.exports.TimeoutError = TimeoutError;
513
+ },
514
+ "../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.js": function(module, __unused_webpack_exports, __webpack_require__) {
515
+ module.exports = __webpack_require__("../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.js");
516
+ },
517
+ "../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.js": function(__unused_webpack_module, exports1, __webpack_require__) {
518
+ var RetryOperation = __webpack_require__("../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js");
519
+ exports1.operation = function(options) {
520
+ var timeouts = exports1.timeouts(options);
521
+ return new RetryOperation(timeouts, {
522
+ forever: options && (options.forever || options.retries === 1 / 0),
523
+ unref: options && options.unref,
524
+ maxRetryTime: options && options.maxRetryTime
525
+ });
526
+ };
527
+ exports1.timeouts = function(options) {
528
+ if (options instanceof Array) return [].concat(options);
529
+ var opts = {
530
+ retries: 10,
531
+ factor: 2,
532
+ minTimeout: 1000,
533
+ maxTimeout: 1 / 0,
534
+ randomize: false
535
+ };
536
+ for(var key in options)opts[key] = options[key];
537
+ if (opts.minTimeout > opts.maxTimeout) throw new Error('minTimeout is greater than maxTimeout');
538
+ var timeouts = [];
539
+ for(var i = 0; i < opts.retries; i++)timeouts.push(this.createTimeout(i, opts));
540
+ if (options && options.forever && !timeouts.length) timeouts.push(this.createTimeout(i, opts));
541
+ timeouts.sort(function(a, b) {
542
+ return a - b;
543
+ });
544
+ return timeouts;
545
+ };
546
+ exports1.createTimeout = function(attempt, opts) {
547
+ var random = opts.randomize ? Math.random() + 1 : 1;
548
+ var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));
549
+ timeout = Math.min(timeout, opts.maxTimeout);
550
+ return timeout;
551
+ };
552
+ exports1.wrap = function(obj, options, methods) {
553
+ if (options instanceof Array) {
554
+ methods = options;
555
+ options = null;
556
+ }
557
+ if (!methods) {
558
+ methods = [];
559
+ for(var key in obj)if ('function' == typeof obj[key]) methods.push(key);
560
+ }
561
+ for(var i = 0; i < methods.length; i++){
562
+ var method = methods[i];
563
+ var original = obj[method];
564
+ obj[method] = (function(original) {
565
+ var op = exports1.operation(options);
566
+ var args = Array.prototype.slice.call(arguments, 1);
567
+ var callback = args.pop();
568
+ args.push(function(err) {
569
+ if (op.retry(err)) return;
570
+ if (err) arguments[0] = op.mainError();
571
+ callback.apply(this, arguments);
572
+ });
573
+ op.attempt(function() {
574
+ original.apply(obj, args);
575
+ });
576
+ }).bind(obj, original);
577
+ obj[method].options = options;
578
+ }
579
+ };
580
+ },
581
+ "../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js": function(module) {
582
+ function RetryOperation(timeouts, options) {
583
+ if ('boolean' == typeof options) options = {
584
+ forever: options
585
+ };
586
+ this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
587
+ this._timeouts = timeouts;
588
+ this._options = options || {};
589
+ this._maxRetryTime = options && options.maxRetryTime || 1 / 0;
590
+ this._fn = null;
591
+ this._errors = [];
592
+ this._attempts = 1;
593
+ this._operationTimeout = null;
594
+ this._operationTimeoutCb = null;
595
+ this._timeout = null;
596
+ this._operationStart = null;
597
+ this._timer = null;
598
+ if (this._options.forever) this._cachedTimeouts = this._timeouts.slice(0);
599
+ }
600
+ module.exports = RetryOperation;
601
+ RetryOperation.prototype.reset = function() {
602
+ this._attempts = 1;
603
+ this._timeouts = this._originalTimeouts.slice(0);
604
+ };
605
+ RetryOperation.prototype.stop = function() {
606
+ if (this._timeout) clearTimeout(this._timeout);
607
+ if (this._timer) clearTimeout(this._timer);
608
+ this._timeouts = [];
609
+ this._cachedTimeouts = null;
610
+ };
611
+ RetryOperation.prototype.retry = function(err) {
612
+ if (this._timeout) clearTimeout(this._timeout);
613
+ if (!err) return false;
614
+ var currentTime = new Date().getTime();
615
+ if (err && currentTime - this._operationStart >= this._maxRetryTime) {
616
+ this._errors.push(err);
617
+ this._errors.unshift(new Error('RetryOperation timeout occurred'));
618
+ return false;
619
+ }
620
+ this._errors.push(err);
621
+ var timeout = this._timeouts.shift();
622
+ if (void 0 === timeout) if (!this._cachedTimeouts) return false;
623
+ else {
624
+ this._errors.splice(0, this._errors.length - 1);
625
+ timeout = this._cachedTimeouts.slice(-1);
626
+ }
627
+ var self = this;
628
+ this._timer = setTimeout(function() {
629
+ self._attempts++;
630
+ if (self._operationTimeoutCb) {
631
+ self._timeout = setTimeout(function() {
632
+ self._operationTimeoutCb(self._attempts);
633
+ }, self._operationTimeout);
634
+ if (self._options.unref) self._timeout.unref();
635
+ }
636
+ self._fn(self._attempts);
637
+ }, timeout);
638
+ if (this._options.unref) this._timer.unref();
639
+ return true;
640
+ };
641
+ RetryOperation.prototype.attempt = function(fn, timeoutOps) {
642
+ this._fn = fn;
643
+ if (timeoutOps) {
644
+ if (timeoutOps.timeout) this._operationTimeout = timeoutOps.timeout;
645
+ if (timeoutOps.cb) this._operationTimeoutCb = timeoutOps.cb;
646
+ }
647
+ var self = this;
648
+ if (this._operationTimeoutCb) this._timeout = setTimeout(function() {
649
+ self._operationTimeoutCb();
650
+ }, self._operationTimeout);
651
+ this._operationStart = new Date().getTime();
652
+ this._fn(this._attempts);
653
+ };
654
+ RetryOperation.prototype.try = function(fn) {
655
+ console.log('Using RetryOperation.try() is deprecated');
656
+ this.attempt(fn);
657
+ };
658
+ RetryOperation.prototype.start = function(fn) {
659
+ console.log('Using RetryOperation.start() is deprecated');
660
+ this.attempt(fn);
661
+ };
662
+ RetryOperation.prototype.start = RetryOperation.prototype.try;
663
+ RetryOperation.prototype.errors = function() {
664
+ return this._errors;
665
+ };
666
+ RetryOperation.prototype.attempts = function() {
667
+ return this._attempts;
668
+ };
669
+ RetryOperation.prototype.mainError = function() {
670
+ if (0 === this._errors.length) return null;
671
+ var counts = {};
672
+ var mainError = null;
673
+ var mainErrorCount = 0;
674
+ for(var i = 0; i < this._errors.length; i++){
675
+ var error = this._errors[i];
676
+ var message = error.message;
677
+ var count = (counts[message] || 0) + 1;
678
+ counts[message] = count;
679
+ if (count >= mainErrorCount) {
680
+ mainError = error;
681
+ mainErrorCount = count;
682
+ }
683
+ }
684
+ return mainError;
685
+ };
686
+ },
687
+ "../../node_modules/.pnpm/langsmith@0.3.7_openai@4.81.0_ws@8.18.3_zod@3.24.3_/node_modules/langsmith/wrappers.js": function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
688
+ "use strict";
689
+ __webpack_require__.d(__webpack_exports__, {
690
+ wrapOpenAI: ()=>wrapOpenAI
691
+ });
692
+ var external_node_async_hooks_ = __webpack_require__("node:async_hooks");
693
+ var external_node_crypto_ = __webpack_require__("node:crypto");
694
+ var external_node_crypto_default = /*#__PURE__*/ __webpack_require__.n(external_node_crypto_);
695
+ const esm_node_native = {
696
+ randomUUID: external_node_crypto_default().randomUUID
697
+ };
698
+ const rnds8Pool = new Uint8Array(256);
699
+ let poolPtr = rnds8Pool.length;
700
+ function rng() {
701
+ if (poolPtr > rnds8Pool.length - 16) {
702
+ external_node_crypto_default().randomFillSync(rnds8Pool);
703
+ poolPtr = 0;
704
+ }
705
+ return rnds8Pool.slice(poolPtr, poolPtr += 16);
706
+ }
707
+ const byteToHex = [];
708
+ for(let i = 0; i < 256; ++i)byteToHex.push((i + 0x100).toString(16).slice(1));
709
+ function unsafeStringify(arr, offset = 0) {
710
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
711
+ }
712
+ function v4_v4(options, buf, offset) {
713
+ if (esm_node_native.randomUUID && !buf && !options) return esm_node_native.randomUUID();
714
+ options = options || {};
715
+ const rnds = options.random || (options.rng || rng)();
716
+ rnds[6] = 0x0f & rnds[6] | 0x40;
717
+ rnds[8] = 0x3f & rnds[8] | 0x80;
718
+ if (buf) {
719
+ offset = offset || 0;
720
+ for(let i = 0; i < 16; ++i)buf[offset + i] = rnds[i];
721
+ return buf;
722
+ }
723
+ return unsafeStringify(rnds);
724
+ }
725
+ const v4 = v4_v4;
726
+ var p_retry = __webpack_require__("../../node_modules/.pnpm/p-retry@4.6.2/node_modules/p-retry/index.js");
727
+ var dist = __webpack_require__("../../node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/index.js");
728
+ const DEFAULT_FETCH_IMPLEMENTATION = (...args)=>fetch(...args);
729
+ const LANGSMITH_FETCH_IMPLEMENTATION_KEY = Symbol.for("ls:fetch_implementation");
730
+ const _getFetchImplementation = ()=>globalThis[LANGSMITH_FETCH_IMPLEMENTATION_KEY] ?? DEFAULT_FETCH_IMPLEMENTATION;
731
+ const STATUS_NO_RETRY = [
732
+ 400,
733
+ 401,
734
+ 403,
735
+ 404,
736
+ 405,
737
+ 406,
738
+ 407,
739
+ 408
740
+ ];
741
+ const STATUS_IGNORE = [
742
+ 409
743
+ ];
744
+ class AsyncCaller {
745
+ constructor(params){
746
+ Object.defineProperty(this, "maxConcurrency", {
747
+ enumerable: true,
748
+ configurable: true,
749
+ writable: true,
750
+ value: void 0
751
+ });
752
+ Object.defineProperty(this, "maxRetries", {
753
+ enumerable: true,
754
+ configurable: true,
755
+ writable: true,
756
+ value: void 0
757
+ });
758
+ Object.defineProperty(this, "queue", {
759
+ enumerable: true,
760
+ configurable: true,
761
+ writable: true,
762
+ value: void 0
763
+ });
764
+ Object.defineProperty(this, "onFailedResponseHook", {
765
+ enumerable: true,
766
+ configurable: true,
767
+ writable: true,
768
+ value: void 0
769
+ });
770
+ this.maxConcurrency = params.maxConcurrency ?? 1 / 0;
771
+ this.maxRetries = params.maxRetries ?? 6;
772
+ if ("default" in dist) this.queue = new dist["default"]({
773
+ concurrency: this.maxConcurrency
774
+ });
775
+ else this.queue = new dist({
776
+ concurrency: this.maxConcurrency
777
+ });
778
+ this.onFailedResponseHook = params?.onFailedResponseHook;
779
+ }
780
+ call(callable, ...args) {
781
+ const onFailedResponseHook = this.onFailedResponseHook;
782
+ return this.queue.add(()=>p_retry(()=>callable(...args).catch((error)=>{
783
+ if (error instanceof Error) throw error;
784
+ throw new Error(error);
785
+ }), {
786
+ async onFailedAttempt (error) {
787
+ if (error.message.startsWith("Cancel") || error.message.startsWith("TimeoutError") || error.message.startsWith("AbortError")) throw error;
788
+ if (error?.code === "ECONNABORTED") throw error;
789
+ const response = error?.response;
790
+ const status = response?.status;
791
+ if (status) {
792
+ if (STATUS_NO_RETRY.includes(+status)) throw error;
793
+ if (STATUS_IGNORE.includes(+status)) return;
794
+ if (onFailedResponseHook) await onFailedResponseHook(response);
795
+ }
796
+ },
797
+ retries: this.maxRetries,
798
+ randomize: true
799
+ }), {
800
+ throwOnTimeout: true
801
+ });
802
+ }
803
+ callWithOptions(options, callable, ...args) {
804
+ if (options.signal) return Promise.race([
805
+ this.call(callable, ...args),
806
+ new Promise((_, reject)=>{
807
+ options.signal?.addEventListener("abort", ()=>{
808
+ reject(new Error("AbortError"));
809
+ });
810
+ })
811
+ ]);
812
+ return this.call(callable, ...args);
813
+ }
814
+ fetch(...args) {
815
+ return this.call(()=>_getFetchImplementation()(...args).then((res)=>res.ok ? res : Promise.reject(res)));
816
+ }
817
+ }
818
+ function isLangChainMessage(message) {
819
+ return "function" == typeof message?._getType;
820
+ }
821
+ function convertLangChainMessageToExample(message) {
822
+ const converted = {
823
+ type: message._getType(),
824
+ data: {
825
+ content: message.content
826
+ }
827
+ };
828
+ if (message?.additional_kwargs && Object.keys(message.additional_kwargs).length > 0) converted.data.additional_kwargs = {
829
+ ...message.additional_kwargs
830
+ };
831
+ return converted;
832
+ }
833
+ const regex = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
834
+ function validate_validate(uuid) {
835
+ return 'string' == typeof uuid && regex.test(uuid);
836
+ }
837
+ const esm_node_validate = validate_validate;
838
+ function assertUuid(str, which) {
839
+ if (!esm_node_validate(str)) {
840
+ const msg = void 0 !== which ? `Invalid UUID for ${which}: ${str}` : `Invalid UUID: ${str}`;
841
+ throw new Error(msg);
842
+ }
843
+ return str;
844
+ }
845
+ const warnedMessages = {};
846
+ function warnOnce(message) {
847
+ if (!warnedMessages[message]) {
848
+ console.warn(message);
849
+ warnedMessages[message] = true;
850
+ }
851
+ }
852
+ __webpack_require__("../../node_modules/.pnpm/semver@7.7.2/node_modules/semver/index.js");
853
+ function parsePromptIdentifier(identifier) {
854
+ if (!identifier || identifier.split("/").length > 2 || identifier.startsWith("/") || identifier.endsWith("/") || identifier.split(":").length > 2) throw new Error(`Invalid identifier format: ${identifier}`);
855
+ const [ownerNamePart, commitPart] = identifier.split(":");
856
+ const commit = commitPart || "latest";
857
+ if (ownerNamePart.includes("/")) {
858
+ const [owner, name] = ownerNamePart.split("/", 2);
859
+ if (!owner || !name) throw new Error(`Invalid identifier format: ${identifier}`);
860
+ return [
861
+ owner,
862
+ name,
863
+ commit
864
+ ];
865
+ }
866
+ if (!ownerNamePart) throw new Error(`Invalid identifier format: ${identifier}`);
867
+ return [
868
+ "-",
869
+ ownerNamePart,
870
+ commit
871
+ ];
872
+ }
873
+ class LangSmithConflictError extends Error {
874
+ constructor(message){
875
+ super(message);
876
+ this.name = "LangSmithConflictError";
877
+ }
878
+ }
879
+ async function raiseForStatus(response, context, consume) {
880
+ let errorBody;
881
+ if (response.ok) {
882
+ if (consume) errorBody = await response.text();
883
+ return;
884
+ }
885
+ errorBody = await response.text();
886
+ const fullMessage = `Failed to ${context}. Received status [${response.status}]: ${response.statusText}. Server response: ${errorBody}`;
887
+ if (409 === response.status) throw new LangSmithConflictError(fullMessage);
888
+ throw new Error(fullMessage);
889
+ }
890
+ var LIMIT_REPLACE_NODE = "[...]";
891
+ var CIRCULAR_REPLACE_NODE = {
892
+ result: "[Circular]"
893
+ };
894
+ var fast_safe_stringify_arr = [];
895
+ var replacerStack = [];
896
+ const encoder = new TextEncoder();
897
+ function defaultOptions() {
898
+ return {
899
+ depthLimit: Number.MAX_SAFE_INTEGER,
900
+ edgesLimit: Number.MAX_SAFE_INTEGER
901
+ };
902
+ }
903
+ function encodeString(str) {
904
+ return encoder.encode(str);
905
+ }
906
+ function serialize(obj, replacer, spacer, options) {
907
+ try {
908
+ const str = JSON.stringify(obj, replacer, spacer);
909
+ return encodeString(str);
910
+ } catch (e) {
911
+ if (!e.message?.includes("Converting circular structure to JSON")) {
912
+ console.warn("[WARNING]: LangSmith received unserializable value.");
913
+ return encodeString("[Unserializable]");
914
+ }
915
+ console.warn("[WARNING]: LangSmith received circular JSON. This will decrease tracer performance.");
916
+ if (void 0 === options) options = defaultOptions();
917
+ decirc(obj, "", 0, [], void 0, 0, options);
918
+ let res;
919
+ try {
920
+ res = 0 === replacerStack.length ? JSON.stringify(obj, replacer, spacer) : JSON.stringify(obj, replaceGetterValues(replacer), spacer);
921
+ } catch (_) {
922
+ return encodeString("[unable to serialize, circular reference is too complex to analyze]");
923
+ } finally{
924
+ while(0 !== fast_safe_stringify_arr.length){
925
+ const part = fast_safe_stringify_arr.pop();
926
+ if (4 === part.length) Object.defineProperty(part[0], part[1], part[3]);
927
+ else part[0][part[1]] = part[2];
928
+ }
929
+ }
930
+ return encodeString(res);
931
+ }
932
+ }
933
+ function setReplace(replace, val, k, parent) {
934
+ var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
935
+ if (void 0 !== propertyDescriptor.get) if (propertyDescriptor.configurable) {
936
+ Object.defineProperty(parent, k, {
937
+ value: replace
938
+ });
939
+ fast_safe_stringify_arr.push([
940
+ parent,
941
+ k,
942
+ val,
943
+ propertyDescriptor
944
+ ]);
945
+ } else replacerStack.push([
946
+ val,
947
+ k,
948
+ replace
949
+ ]);
950
+ else {
951
+ parent[k] = replace;
952
+ fast_safe_stringify_arr.push([
953
+ parent,
954
+ k,
955
+ val
956
+ ]);
957
+ }
958
+ }
959
+ function decirc(val, k, edgeIndex, stack, parent, depth, options) {
960
+ depth += 1;
961
+ var i;
962
+ if ("object" == typeof val && null !== val) {
963
+ for(i = 0; i < stack.length; i++)if (stack[i] === val) return void setReplace(CIRCULAR_REPLACE_NODE, val, k, parent);
964
+ if (void 0 !== options.depthLimit && depth > options.depthLimit) return void setReplace(LIMIT_REPLACE_NODE, val, k, parent);
965
+ if (void 0 !== options.edgesLimit && edgeIndex + 1 > options.edgesLimit) return void setReplace(LIMIT_REPLACE_NODE, val, k, parent);
966
+ stack.push(val);
967
+ if (Array.isArray(val)) for(i = 0; i < val.length; i++)decirc(val[i], i, i, stack, val, depth, options);
968
+ else {
969
+ var keys = Object.keys(val);
970
+ for(i = 0; i < keys.length; i++){
971
+ var key = keys[i];
972
+ decirc(val[key], key, i, stack, val, depth, options);
973
+ }
974
+ }
975
+ stack.pop();
976
+ }
977
+ }
978
+ function replaceGetterValues(replacer) {
979
+ replacer = void 0 !== replacer ? replacer : function(k, v) {
980
+ return v;
981
+ };
982
+ return function(key, val) {
983
+ if (replacerStack.length > 0) for(var i = 0; i < replacerStack.length; i++){
984
+ var part = replacerStack[i];
985
+ if (part[1] === key && part[0] === val) {
986
+ val = part[2];
987
+ replacerStack.splice(i, 1);
988
+ break;
989
+ }
990
+ }
991
+ return replacer.call(this, key, val);
992
+ };
993
+ }
994
+ function mergeRuntimeEnvIntoRunCreate(run) {
995
+ const runtimeEnv = getRuntimeEnvironment();
996
+ const envVars = getLangChainEnvVarsMetadata();
997
+ const extra = run.extra ?? {};
998
+ const metadata = extra.metadata;
999
+ run.extra = {
1000
+ ...extra,
1001
+ runtime: {
1002
+ ...runtimeEnv,
1003
+ ...extra?.runtime
1004
+ },
1005
+ metadata: {
1006
+ ...envVars,
1007
+ ...envVars.revision_id || run.revision_id ? {
1008
+ revision_id: run.revision_id ?? envVars.revision_id
1009
+ } : {},
1010
+ ...metadata
1011
+ }
1012
+ };
1013
+ return run;
1014
+ }
1015
+ const getTracingSamplingRate = ()=>{
1016
+ const samplingRateStr = getLangSmithEnvironmentVariable("TRACING_SAMPLING_RATE");
1017
+ if (void 0 === samplingRateStr) return;
1018
+ const samplingRate = parseFloat(samplingRateStr);
1019
+ if (samplingRate < 0 || samplingRate > 1) throw new Error(`LANGSMITH_TRACING_SAMPLING_RATE must be between 0 and 1 if set. Got: ${samplingRate}`);
1020
+ return samplingRate;
1021
+ };
1022
+ const isLocalhost = (url)=>{
1023
+ const strippedUrl = url.replace("http://", "").replace("https://", "");
1024
+ const hostname = strippedUrl.split("/")[0].split(":")[0];
1025
+ return "localhost" === hostname || "127.0.0.1" === hostname || "::1" === hostname;
1026
+ };
1027
+ async function toArray(iterable) {
1028
+ const result = [];
1029
+ for await (const item of iterable)result.push(item);
1030
+ return result;
1031
+ }
1032
+ function trimQuotes(str) {
1033
+ if (void 0 === str) return;
1034
+ return str.trim().replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1");
1035
+ }
1036
+ const handle429 = async (response)=>{
1037
+ if (response?.status === 429) {
1038
+ const retryAfter = 1000 * parseInt(response.headers.get("retry-after") ?? "30", 10);
1039
+ if (retryAfter > 0) {
1040
+ await new Promise((resolve)=>setTimeout(resolve, retryAfter));
1041
+ return true;
1042
+ }
1043
+ }
1044
+ return false;
1045
+ };
1046
+ class AutoBatchQueue {
1047
+ constructor(){
1048
+ Object.defineProperty(this, "items", {
1049
+ enumerable: true,
1050
+ configurable: true,
1051
+ writable: true,
1052
+ value: []
1053
+ });
1054
+ Object.defineProperty(this, "sizeBytes", {
1055
+ enumerable: true,
1056
+ configurable: true,
1057
+ writable: true,
1058
+ value: 0
1059
+ });
1060
+ }
1061
+ peek() {
1062
+ return this.items[0];
1063
+ }
1064
+ push(item) {
1065
+ let itemPromiseResolve;
1066
+ const itemPromise = new Promise((resolve)=>{
1067
+ itemPromiseResolve = resolve;
1068
+ });
1069
+ const size = serialize(item.item).length;
1070
+ this.items.push({
1071
+ action: item.action,
1072
+ payload: item.item,
1073
+ itemPromiseResolve: itemPromiseResolve,
1074
+ itemPromise,
1075
+ size
1076
+ });
1077
+ this.sizeBytes += size;
1078
+ return itemPromise;
1079
+ }
1080
+ pop(upToSizeBytes) {
1081
+ if (upToSizeBytes < 1) throw new Error("Number of bytes to pop off may not be less than 1.");
1082
+ const popped = [];
1083
+ let poppedSizeBytes = 0;
1084
+ while(poppedSizeBytes + (this.peek()?.size ?? 0) < upToSizeBytes && this.items.length > 0){
1085
+ const item = this.items.shift();
1086
+ if (item) {
1087
+ popped.push(item);
1088
+ poppedSizeBytes += item.size;
1089
+ this.sizeBytes -= item.size;
1090
+ }
1091
+ }
1092
+ if (0 === popped.length && this.items.length > 0) {
1093
+ const item = this.items.shift();
1094
+ popped.push(item);
1095
+ poppedSizeBytes += item.size;
1096
+ this.sizeBytes -= item.size;
1097
+ }
1098
+ return [
1099
+ popped.map((it)=>({
1100
+ action: it.action,
1101
+ item: it.payload
1102
+ })),
1103
+ ()=>popped.forEach((it)=>it.itemPromiseResolve())
1104
+ ];
1105
+ }
1106
+ }
1107
+ const DEFAULT_BATCH_SIZE_LIMIT_BYTES = 20971520;
1108
+ const SERVER_INFO_REQUEST_TIMEOUT = 2500;
1109
+ class Client {
1110
+ constructor(config = {}){
1111
+ Object.defineProperty(this, "apiKey", {
1112
+ enumerable: true,
1113
+ configurable: true,
1114
+ writable: true,
1115
+ value: void 0
1116
+ });
1117
+ Object.defineProperty(this, "apiUrl", {
1118
+ enumerable: true,
1119
+ configurable: true,
1120
+ writable: true,
1121
+ value: void 0
1122
+ });
1123
+ Object.defineProperty(this, "webUrl", {
1124
+ enumerable: true,
1125
+ configurable: true,
1126
+ writable: true,
1127
+ value: void 0
1128
+ });
1129
+ Object.defineProperty(this, "caller", {
1130
+ enumerable: true,
1131
+ configurable: true,
1132
+ writable: true,
1133
+ value: void 0
1134
+ });
1135
+ Object.defineProperty(this, "batchIngestCaller", {
1136
+ enumerable: true,
1137
+ configurable: true,
1138
+ writable: true,
1139
+ value: void 0
1140
+ });
1141
+ Object.defineProperty(this, "timeout_ms", {
1142
+ enumerable: true,
1143
+ configurable: true,
1144
+ writable: true,
1145
+ value: void 0
1146
+ });
1147
+ Object.defineProperty(this, "_tenantId", {
1148
+ enumerable: true,
1149
+ configurable: true,
1150
+ writable: true,
1151
+ value: null
1152
+ });
1153
+ Object.defineProperty(this, "hideInputs", {
1154
+ enumerable: true,
1155
+ configurable: true,
1156
+ writable: true,
1157
+ value: void 0
1158
+ });
1159
+ Object.defineProperty(this, "hideOutputs", {
1160
+ enumerable: true,
1161
+ configurable: true,
1162
+ writable: true,
1163
+ value: void 0
1164
+ });
1165
+ Object.defineProperty(this, "tracingSampleRate", {
1166
+ enumerable: true,
1167
+ configurable: true,
1168
+ writable: true,
1169
+ value: void 0
1170
+ });
1171
+ Object.defineProperty(this, "filteredPostUuids", {
1172
+ enumerable: true,
1173
+ configurable: true,
1174
+ writable: true,
1175
+ value: new Set()
1176
+ });
1177
+ Object.defineProperty(this, "autoBatchTracing", {
1178
+ enumerable: true,
1179
+ configurable: true,
1180
+ writable: true,
1181
+ value: true
1182
+ });
1183
+ Object.defineProperty(this, "autoBatchQueue", {
1184
+ enumerable: true,
1185
+ configurable: true,
1186
+ writable: true,
1187
+ value: new AutoBatchQueue()
1188
+ });
1189
+ Object.defineProperty(this, "autoBatchTimeout", {
1190
+ enumerable: true,
1191
+ configurable: true,
1192
+ writable: true,
1193
+ value: void 0
1194
+ });
1195
+ Object.defineProperty(this, "autoBatchAggregationDelayMs", {
1196
+ enumerable: true,
1197
+ configurable: true,
1198
+ writable: true,
1199
+ value: 250
1200
+ });
1201
+ Object.defineProperty(this, "batchSizeBytesLimit", {
1202
+ enumerable: true,
1203
+ configurable: true,
1204
+ writable: true,
1205
+ value: void 0
1206
+ });
1207
+ Object.defineProperty(this, "fetchOptions", {
1208
+ enumerable: true,
1209
+ configurable: true,
1210
+ writable: true,
1211
+ value: void 0
1212
+ });
1213
+ Object.defineProperty(this, "settings", {
1214
+ enumerable: true,
1215
+ configurable: true,
1216
+ writable: true,
1217
+ value: void 0
1218
+ });
1219
+ Object.defineProperty(this, "blockOnRootRunFinalization", {
1220
+ enumerable: true,
1221
+ configurable: true,
1222
+ writable: true,
1223
+ value: "false" === getEnvironmentVariable("LANGSMITH_TRACING_BACKGROUND")
1224
+ });
1225
+ Object.defineProperty(this, "traceBatchConcurrency", {
1226
+ enumerable: true,
1227
+ configurable: true,
1228
+ writable: true,
1229
+ value: 5
1230
+ });
1231
+ Object.defineProperty(this, "_serverInfo", {
1232
+ enumerable: true,
1233
+ configurable: true,
1234
+ writable: true,
1235
+ value: void 0
1236
+ });
1237
+ Object.defineProperty(this, "_getServerInfoPromise", {
1238
+ enumerable: true,
1239
+ configurable: true,
1240
+ writable: true,
1241
+ value: void 0
1242
+ });
1243
+ Object.defineProperty(this, "manualFlushMode", {
1244
+ enumerable: true,
1245
+ configurable: true,
1246
+ writable: true,
1247
+ value: false
1248
+ });
1249
+ const defaultConfig = Client.getDefaultClientConfig();
1250
+ this.tracingSampleRate = getTracingSamplingRate();
1251
+ this.apiUrl = trimQuotes(config.apiUrl ?? defaultConfig.apiUrl) ?? "";
1252
+ if (this.apiUrl.endsWith("/")) this.apiUrl = this.apiUrl.slice(0, -1);
1253
+ this.apiKey = trimQuotes(config.apiKey ?? defaultConfig.apiKey);
1254
+ this.webUrl = trimQuotes(config.webUrl ?? defaultConfig.webUrl);
1255
+ if (this.webUrl?.endsWith("/")) this.webUrl = this.webUrl.slice(0, -1);
1256
+ this.timeout_ms = config.timeout_ms ?? 90000;
1257
+ this.caller = new AsyncCaller(config.callerOptions ?? {});
1258
+ this.traceBatchConcurrency = config.traceBatchConcurrency ?? this.traceBatchConcurrency;
1259
+ if (this.traceBatchConcurrency < 1) throw new Error("Trace batch concurrency must be positive.");
1260
+ this.batchIngestCaller = new AsyncCaller({
1261
+ maxRetries: 2,
1262
+ maxConcurrency: this.traceBatchConcurrency,
1263
+ ...config.callerOptions ?? {},
1264
+ onFailedResponseHook: handle429
1265
+ });
1266
+ this.hideInputs = config.hideInputs ?? config.anonymizer ?? defaultConfig.hideInputs;
1267
+ this.hideOutputs = config.hideOutputs ?? config.anonymizer ?? defaultConfig.hideOutputs;
1268
+ this.autoBatchTracing = config.autoBatchTracing ?? this.autoBatchTracing;
1269
+ this.blockOnRootRunFinalization = config.blockOnRootRunFinalization ?? this.blockOnRootRunFinalization;
1270
+ this.batchSizeBytesLimit = config.batchSizeBytesLimit;
1271
+ this.fetchOptions = config.fetchOptions || {};
1272
+ this.manualFlushMode = config.manualFlushMode ?? this.manualFlushMode;
1273
+ }
1274
+ static getDefaultClientConfig() {
1275
+ const apiKey = getLangSmithEnvironmentVariable("API_KEY");
1276
+ const apiUrl = getLangSmithEnvironmentVariable("ENDPOINT") ?? "https://api.smith.langchain.com";
1277
+ const hideInputs = "true" === getLangSmithEnvironmentVariable("HIDE_INPUTS");
1278
+ const hideOutputs = "true" === getLangSmithEnvironmentVariable("HIDE_OUTPUTS");
1279
+ return {
1280
+ apiUrl: apiUrl,
1281
+ apiKey: apiKey,
1282
+ webUrl: void 0,
1283
+ hideInputs: hideInputs,
1284
+ hideOutputs: hideOutputs
1285
+ };
1286
+ }
1287
+ getHostUrl() {
1288
+ if (this.webUrl) return this.webUrl;
1289
+ if (isLocalhost(this.apiUrl)) {
1290
+ this.webUrl = "http://localhost:3000";
1291
+ return this.webUrl;
1292
+ }
1293
+ if (this.apiUrl.endsWith("/api/v1")) {
1294
+ this.webUrl = this.apiUrl.replace("/api/v1", "");
1295
+ return this.webUrl;
1296
+ }
1297
+ if (this.apiUrl.includes("/api") && !this.apiUrl.split(".", 1)[0].endsWith("api")) {
1298
+ this.webUrl = this.apiUrl.replace("/api", "");
1299
+ return this.webUrl;
1300
+ }
1301
+ if (this.apiUrl.split(".", 1)[0].includes("dev")) {
1302
+ this.webUrl = "https://dev.smith.langchain.com";
1303
+ return this.webUrl;
1304
+ } else if (this.apiUrl.split(".", 1)[0].includes("eu")) {
1305
+ this.webUrl = "https://eu.smith.langchain.com";
1306
+ return this.webUrl;
1307
+ } else if (this.apiUrl.split(".", 1)[0].includes("beta")) {
1308
+ this.webUrl = "https://beta.smith.langchain.com";
1309
+ return this.webUrl;
1310
+ } else {
1311
+ this.webUrl = "https://smith.langchain.com";
1312
+ return this.webUrl;
1313
+ }
1314
+ }
1315
+ get headers() {
1316
+ const headers = {
1317
+ "User-Agent": `langsmith-js/${__version__}`
1318
+ };
1319
+ if (this.apiKey) headers["x-api-key"] = `${this.apiKey}`;
1320
+ return headers;
1321
+ }
1322
+ processInputs(inputs) {
1323
+ if (false === this.hideInputs) return inputs;
1324
+ if (true === this.hideInputs) return {};
1325
+ if ("function" == typeof this.hideInputs) return this.hideInputs(inputs);
1326
+ return inputs;
1327
+ }
1328
+ processOutputs(outputs) {
1329
+ if (false === this.hideOutputs) return outputs;
1330
+ if (true === this.hideOutputs) return {};
1331
+ if ("function" == typeof this.hideOutputs) return this.hideOutputs(outputs);
1332
+ return outputs;
1333
+ }
1334
+ prepareRunCreateOrUpdateInputs(run) {
1335
+ const runParams = {
1336
+ ...run
1337
+ };
1338
+ if (void 0 !== runParams.inputs) runParams.inputs = this.processInputs(runParams.inputs);
1339
+ if (void 0 !== runParams.outputs) runParams.outputs = this.processOutputs(runParams.outputs);
1340
+ return runParams;
1341
+ }
1342
+ async _getResponse(path, queryParams) {
1343
+ const paramsString = queryParams?.toString() ?? "";
1344
+ const url = `${this.apiUrl}${path}?${paramsString}`;
1345
+ const response = await this.caller.call(_getFetchImplementation(), url, {
1346
+ method: "GET",
1347
+ headers: this.headers,
1348
+ signal: AbortSignal.timeout(this.timeout_ms),
1349
+ ...this.fetchOptions
1350
+ });
1351
+ await raiseForStatus(response, `Failed to fetch ${path}`);
1352
+ return response;
1353
+ }
1354
+ async _get(path, queryParams) {
1355
+ const response = await this._getResponse(path, queryParams);
1356
+ return response.json();
1357
+ }
1358
+ async *_getPaginated(path, queryParams = new URLSearchParams(), transform) {
1359
+ let offset = Number(queryParams.get("offset")) || 0;
1360
+ const limit = Number(queryParams.get("limit")) || 100;
1361
+ while(true){
1362
+ queryParams.set("offset", String(offset));
1363
+ queryParams.set("limit", String(limit));
1364
+ const url = `${this.apiUrl}${path}?${queryParams}`;
1365
+ const response = await this.caller.call(_getFetchImplementation(), url, {
1366
+ method: "GET",
1367
+ headers: this.headers,
1368
+ signal: AbortSignal.timeout(this.timeout_ms),
1369
+ ...this.fetchOptions
1370
+ });
1371
+ await raiseForStatus(response, `Failed to fetch ${path}`);
1372
+ const items = transform ? transform(await response.json()) : await response.json();
1373
+ if (0 === items.length) break;
1374
+ yield items;
1375
+ if (items.length < limit) break;
1376
+ offset += items.length;
1377
+ }
1378
+ }
1379
+ async *_getCursorPaginatedList(path, body = null, requestMethod = "POST", dataKey = "runs") {
1380
+ const bodyParams = body ? {
1381
+ ...body
1382
+ } : {};
1383
+ while(true){
1384
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}${path}`, {
1385
+ method: requestMethod,
1386
+ headers: {
1387
+ ...this.headers,
1388
+ "Content-Type": "application/json"
1389
+ },
1390
+ signal: AbortSignal.timeout(this.timeout_ms),
1391
+ ...this.fetchOptions,
1392
+ body: JSON.stringify(bodyParams)
1393
+ });
1394
+ const responseBody = await response.json();
1395
+ if (!responseBody) break;
1396
+ if (!responseBody[dataKey]) break;
1397
+ yield responseBody[dataKey];
1398
+ const cursors = responseBody.cursors;
1399
+ if (!cursors) break;
1400
+ if (!cursors.next) break;
1401
+ bodyParams.cursor = cursors.next;
1402
+ }
1403
+ }
1404
+ _filterForSampling(runs, patch = false) {
1405
+ if (void 0 === this.tracingSampleRate) return runs;
1406
+ if (patch) {
1407
+ const sampled = [];
1408
+ for (const run of runs)if (this.filteredPostUuids.has(run.id)) this.filteredPostUuids.delete(run.id);
1409
+ else sampled.push(run);
1410
+ return sampled;
1411
+ }
1412
+ {
1413
+ const sampled = [];
1414
+ for (const run of runs)if (run.id !== run.trace_id && !this.filteredPostUuids.has(run.trace_id) || Math.random() < this.tracingSampleRate) sampled.push(run);
1415
+ else this.filteredPostUuids.add(run.id);
1416
+ return sampled;
1417
+ }
1418
+ }
1419
+ async _getBatchSizeLimitBytes() {
1420
+ const serverInfo = await this._ensureServerInfo();
1421
+ return this.batchSizeBytesLimit ?? serverInfo.batch_ingest_config?.size_limit_bytes ?? DEFAULT_BATCH_SIZE_LIMIT_BYTES;
1422
+ }
1423
+ async _getMultiPartSupport() {
1424
+ const serverInfo = await this._ensureServerInfo();
1425
+ return serverInfo.instance_flags?.dataset_examples_multipart_enabled ?? false;
1426
+ }
1427
+ drainAutoBatchQueue(batchSizeLimit) {
1428
+ const promises = [];
1429
+ while(this.autoBatchQueue.items.length > 0){
1430
+ const [batch, done] = this.autoBatchQueue.pop(batchSizeLimit);
1431
+ if (!batch.length) {
1432
+ done();
1433
+ break;
1434
+ }
1435
+ const batchPromise = this._processBatch(batch, done).catch(console.error);
1436
+ promises.push(batchPromise);
1437
+ }
1438
+ return Promise.all(promises);
1439
+ }
1440
+ async _processBatch(batch, done) {
1441
+ if (!batch.length) return void done();
1442
+ try {
1443
+ const ingestParams = {
1444
+ runCreates: batch.filter((item)=>"create" === item.action).map((item)=>item.item),
1445
+ runUpdates: batch.filter((item)=>"update" === item.action).map((item)=>item.item)
1446
+ };
1447
+ const serverInfo = await this._ensureServerInfo();
1448
+ if (serverInfo?.batch_ingest_config?.use_multipart_endpoint) await this.multipartIngestRuns(ingestParams);
1449
+ else await this.batchIngestRuns(ingestParams);
1450
+ } finally{
1451
+ done();
1452
+ }
1453
+ }
1454
+ async processRunOperation(item) {
1455
+ clearTimeout(this.autoBatchTimeout);
1456
+ this.autoBatchTimeout = void 0;
1457
+ if ("create" === item.action) item.item = mergeRuntimeEnvIntoRunCreate(item.item);
1458
+ const itemPromise = this.autoBatchQueue.push(item);
1459
+ if (this.manualFlushMode) return itemPromise;
1460
+ const sizeLimitBytes = await this._getBatchSizeLimitBytes();
1461
+ if (this.autoBatchQueue.sizeBytes > sizeLimitBytes) this.drainAutoBatchQueue(sizeLimitBytes);
1462
+ if (this.autoBatchQueue.items.length > 0) this.autoBatchTimeout = setTimeout(()=>{
1463
+ this.autoBatchTimeout = void 0;
1464
+ this.drainAutoBatchQueue(sizeLimitBytes);
1465
+ }, this.autoBatchAggregationDelayMs);
1466
+ return itemPromise;
1467
+ }
1468
+ async _getServerInfo() {
1469
+ const response = await _getFetchImplementation()(`${this.apiUrl}/info`, {
1470
+ method: "GET",
1471
+ headers: {
1472
+ Accept: "application/json"
1473
+ },
1474
+ signal: AbortSignal.timeout(SERVER_INFO_REQUEST_TIMEOUT),
1475
+ ...this.fetchOptions
1476
+ });
1477
+ await raiseForStatus(response, "get server info");
1478
+ return response.json();
1479
+ }
1480
+ async _ensureServerInfo() {
1481
+ if (void 0 === this._getServerInfoPromise) this._getServerInfoPromise = (async ()=>{
1482
+ if (void 0 === this._serverInfo) try {
1483
+ this._serverInfo = await this._getServerInfo();
1484
+ } catch (e) {
1485
+ console.warn("[WARNING]: LangSmith failed to fetch info on supported operations. Falling back to batch operations and default limits.");
1486
+ }
1487
+ return this._serverInfo ?? {};
1488
+ })();
1489
+ return this._getServerInfoPromise.then((serverInfo)=>{
1490
+ if (void 0 === this._serverInfo) this._getServerInfoPromise = void 0;
1491
+ return serverInfo;
1492
+ });
1493
+ }
1494
+ async _getSettings() {
1495
+ if (!this.settings) this.settings = this._get("/settings");
1496
+ return await this.settings;
1497
+ }
1498
+ async flush() {
1499
+ const sizeLimitBytes = await this._getBatchSizeLimitBytes();
1500
+ await this.drainAutoBatchQueue(sizeLimitBytes);
1501
+ }
1502
+ async createRun(run) {
1503
+ if (!this._filterForSampling([
1504
+ run
1505
+ ]).length) return;
1506
+ const headers = {
1507
+ ...this.headers,
1508
+ "Content-Type": "application/json"
1509
+ };
1510
+ const session_name = run.project_name;
1511
+ delete run.project_name;
1512
+ const runCreate = this.prepareRunCreateOrUpdateInputs({
1513
+ session_name,
1514
+ ...run,
1515
+ start_time: run.start_time ?? Date.now()
1516
+ });
1517
+ if (this.autoBatchTracing && void 0 !== runCreate.trace_id && void 0 !== runCreate.dotted_order) return void this.processRunOperation({
1518
+ action: "create",
1519
+ item: runCreate
1520
+ }).catch(console.error);
1521
+ const mergedRunCreateParam = mergeRuntimeEnvIntoRunCreate(runCreate);
1522
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs`, {
1523
+ method: "POST",
1524
+ headers,
1525
+ body: serialize(mergedRunCreateParam),
1526
+ signal: AbortSignal.timeout(this.timeout_ms),
1527
+ ...this.fetchOptions
1528
+ });
1529
+ await raiseForStatus(response, "create run", true);
1530
+ }
1531
+ async batchIngestRuns({ runCreates, runUpdates }) {
1532
+ if (void 0 === runCreates && void 0 === runUpdates) return;
1533
+ let preparedCreateParams = runCreates?.map((create)=>this.prepareRunCreateOrUpdateInputs(create)) ?? [];
1534
+ let preparedUpdateParams = runUpdates?.map((update)=>this.prepareRunCreateOrUpdateInputs(update)) ?? [];
1535
+ if (preparedCreateParams.length > 0 && preparedUpdateParams.length > 0) {
1536
+ const createById = preparedCreateParams.reduce((params, run)=>{
1537
+ if (!run.id) return params;
1538
+ params[run.id] = run;
1539
+ return params;
1540
+ }, {});
1541
+ const standaloneUpdates = [];
1542
+ for (const updateParam of preparedUpdateParams)if (void 0 !== updateParam.id && createById[updateParam.id]) createById[updateParam.id] = {
1543
+ ...createById[updateParam.id],
1544
+ ...updateParam
1545
+ };
1546
+ else standaloneUpdates.push(updateParam);
1547
+ preparedCreateParams = Object.values(createById);
1548
+ preparedUpdateParams = standaloneUpdates;
1549
+ }
1550
+ const rawBatch = {
1551
+ post: this._filterForSampling(preparedCreateParams),
1552
+ patch: this._filterForSampling(preparedUpdateParams, true)
1553
+ };
1554
+ if (!rawBatch.post.length && !rawBatch.patch.length) return;
1555
+ const batchChunks = {
1556
+ post: [],
1557
+ patch: []
1558
+ };
1559
+ for (const k of [
1560
+ "post",
1561
+ "patch"
1562
+ ]){
1563
+ const key = k;
1564
+ const batchItems = rawBatch[key].reverse();
1565
+ let batchItem = batchItems.pop();
1566
+ while(void 0 !== batchItem){
1567
+ batchChunks[key].push(batchItem);
1568
+ batchItem = batchItems.pop();
1569
+ }
1570
+ }
1571
+ if (batchChunks.post.length > 0 || batchChunks.patch.length > 0) await this._postBatchIngestRuns(serialize(batchChunks));
1572
+ }
1573
+ async _postBatchIngestRuns(body) {
1574
+ const headers = {
1575
+ ...this.headers,
1576
+ "Content-Type": "application/json",
1577
+ Accept: "application/json"
1578
+ };
1579
+ const response = await this.batchIngestCaller.call(_getFetchImplementation(), `${this.apiUrl}/runs/batch`, {
1580
+ method: "POST",
1581
+ headers,
1582
+ body: body,
1583
+ signal: AbortSignal.timeout(this.timeout_ms),
1584
+ ...this.fetchOptions
1585
+ });
1586
+ await raiseForStatus(response, "batch create run", true);
1587
+ }
1588
+ async multipartIngestRuns({ runCreates, runUpdates }) {
1589
+ if (void 0 === runCreates && void 0 === runUpdates) return;
1590
+ const allAttachments = {};
1591
+ let preparedCreateParams = [];
1592
+ for (const create of runCreates ?? []){
1593
+ const preparedCreate = this.prepareRunCreateOrUpdateInputs(create);
1594
+ if (void 0 !== preparedCreate.id && void 0 !== preparedCreate.attachments) allAttachments[preparedCreate.id] = preparedCreate.attachments;
1595
+ delete preparedCreate.attachments;
1596
+ preparedCreateParams.push(preparedCreate);
1597
+ }
1598
+ let preparedUpdateParams = [];
1599
+ for (const update of runUpdates ?? [])preparedUpdateParams.push(this.prepareRunCreateOrUpdateInputs(update));
1600
+ const invalidRunCreate = preparedCreateParams.find((runCreate)=>void 0 === runCreate.trace_id || void 0 === runCreate.dotted_order);
1601
+ if (void 0 !== invalidRunCreate) throw new Error('Multipart ingest requires "trace_id" and "dotted_order" to be set when creating a run');
1602
+ const invalidRunUpdate = preparedUpdateParams.find((runUpdate)=>void 0 === runUpdate.trace_id || void 0 === runUpdate.dotted_order);
1603
+ if (void 0 !== invalidRunUpdate) throw new Error('Multipart ingest requires "trace_id" and "dotted_order" to be set when updating a run');
1604
+ if (preparedCreateParams.length > 0 && preparedUpdateParams.length > 0) {
1605
+ const createById = preparedCreateParams.reduce((params, run)=>{
1606
+ if (!run.id) return params;
1607
+ params[run.id] = run;
1608
+ return params;
1609
+ }, {});
1610
+ const standaloneUpdates = [];
1611
+ for (const updateParam of preparedUpdateParams)if (void 0 !== updateParam.id && createById[updateParam.id]) createById[updateParam.id] = {
1612
+ ...createById[updateParam.id],
1613
+ ...updateParam
1614
+ };
1615
+ else standaloneUpdates.push(updateParam);
1616
+ preparedCreateParams = Object.values(createById);
1617
+ preparedUpdateParams = standaloneUpdates;
1618
+ }
1619
+ if (0 === preparedCreateParams.length && 0 === preparedUpdateParams.length) return;
1620
+ const accumulatedContext = [];
1621
+ const accumulatedParts = [];
1622
+ for (const [method, payloads] of [
1623
+ [
1624
+ "post",
1625
+ preparedCreateParams
1626
+ ],
1627
+ [
1628
+ "patch",
1629
+ preparedUpdateParams
1630
+ ]
1631
+ ])for (const originalPayload of payloads){
1632
+ const { inputs, outputs, events, attachments, ...payload } = originalPayload;
1633
+ const fields = {
1634
+ inputs,
1635
+ outputs,
1636
+ events
1637
+ };
1638
+ const stringifiedPayload = serialize(payload);
1639
+ accumulatedParts.push({
1640
+ name: `${method}.${payload.id}`,
1641
+ payload: new Blob([
1642
+ stringifiedPayload
1643
+ ], {
1644
+ type: `application/json; length=${stringifiedPayload.length}`
1645
+ })
1646
+ });
1647
+ for (const [key, value] of Object.entries(fields)){
1648
+ if (void 0 === value) continue;
1649
+ const stringifiedValue = serialize(value);
1650
+ accumulatedParts.push({
1651
+ name: `${method}.${payload.id}.${key}`,
1652
+ payload: new Blob([
1653
+ stringifiedValue
1654
+ ], {
1655
+ type: `application/json; length=${stringifiedValue.length}`
1656
+ })
1657
+ });
1658
+ }
1659
+ if (void 0 !== payload.id) {
1660
+ const attachments = allAttachments[payload.id];
1661
+ if (attachments) {
1662
+ delete allAttachments[payload.id];
1663
+ for (const [name, attachment] of Object.entries(attachments)){
1664
+ let contentType;
1665
+ let content;
1666
+ if (Array.isArray(attachment)) [contentType, content] = attachment;
1667
+ else {
1668
+ contentType = attachment.mimeType;
1669
+ content = attachment.data;
1670
+ }
1671
+ if (name.includes(".")) {
1672
+ console.warn(`Skipping attachment '${name}' for run ${payload.id}: Invalid attachment name. Attachment names must not contain periods ('.'). Please rename the attachment and try again.`);
1673
+ continue;
1674
+ }
1675
+ accumulatedParts.push({
1676
+ name: `attachment.${payload.id}.${name}`,
1677
+ payload: new Blob([
1678
+ content
1679
+ ], {
1680
+ type: `${contentType}; length=${content.byteLength}`
1681
+ })
1682
+ });
1683
+ }
1684
+ }
1685
+ }
1686
+ accumulatedContext.push(`trace=${payload.trace_id},id=${payload.id}`);
1687
+ }
1688
+ await this._sendMultipartRequest(accumulatedParts, accumulatedContext.join("; "));
1689
+ }
1690
+ async _sendMultipartRequest(parts, context) {
1691
+ try {
1692
+ const boundary = "----LangSmithFormBoundary" + Math.random().toString(36).slice(2);
1693
+ const chunks = [];
1694
+ for (const part of parts){
1695
+ chunks.push(new Blob([
1696
+ `--${boundary}\r\n`
1697
+ ]));
1698
+ chunks.push(new Blob([
1699
+ `Content-Disposition: form-data; name="${part.name}"\r\n`,
1700
+ `Content-Type: ${part.payload.type}\r\n\r\n`
1701
+ ]));
1702
+ chunks.push(part.payload);
1703
+ chunks.push(new Blob([
1704
+ "\r\n"
1705
+ ]));
1706
+ }
1707
+ chunks.push(new Blob([
1708
+ `--${boundary}--\r\n`
1709
+ ]));
1710
+ const body = new Blob(chunks);
1711
+ const arrayBuffer = await body.arrayBuffer();
1712
+ const res = await this.batchIngestCaller.call(_getFetchImplementation(), `${this.apiUrl}/runs/multipart`, {
1713
+ method: "POST",
1714
+ headers: {
1715
+ ...this.headers,
1716
+ "Content-Type": `multipart/form-data; boundary=${boundary}`
1717
+ },
1718
+ body: arrayBuffer,
1719
+ signal: AbortSignal.timeout(this.timeout_ms),
1720
+ ...this.fetchOptions
1721
+ });
1722
+ await raiseForStatus(res, "ingest multipart runs", true);
1723
+ } catch (e) {
1724
+ console.warn(`${e.message.trim()}\n\nContext: ${context}`);
1725
+ }
1726
+ }
1727
+ async updateRun(runId, run) {
1728
+ assertUuid(runId);
1729
+ if (run.inputs) run.inputs = this.processInputs(run.inputs);
1730
+ if (run.outputs) run.outputs = this.processOutputs(run.outputs);
1731
+ const data = {
1732
+ ...run,
1733
+ id: runId
1734
+ };
1735
+ if (!this._filterForSampling([
1736
+ data
1737
+ ], true).length) return;
1738
+ if (this.autoBatchTracing && void 0 !== data.trace_id && void 0 !== data.dotted_order) {
1739
+ if (void 0 !== run.end_time && void 0 === data.parent_run_id && this.blockOnRootRunFinalization && !this.manualFlushMode) return void await this.processRunOperation({
1740
+ action: "update",
1741
+ item: data
1742
+ }).catch(console.error);
1743
+ this.processRunOperation({
1744
+ action: "update",
1745
+ item: data
1746
+ }).catch(console.error);
1747
+ return;
1748
+ }
1749
+ const headers = {
1750
+ ...this.headers,
1751
+ "Content-Type": "application/json"
1752
+ };
1753
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs/${runId}`, {
1754
+ method: "PATCH",
1755
+ headers,
1756
+ body: serialize(run),
1757
+ signal: AbortSignal.timeout(this.timeout_ms),
1758
+ ...this.fetchOptions
1759
+ });
1760
+ await raiseForStatus(response, "update run", true);
1761
+ }
1762
+ async readRun(runId, { loadChildRuns } = {
1763
+ loadChildRuns: false
1764
+ }) {
1765
+ assertUuid(runId);
1766
+ let run = await this._get(`/runs/${runId}`);
1767
+ if (loadChildRuns && run.child_run_ids) run = await this._loadChildRuns(run);
1768
+ return run;
1769
+ }
1770
+ async getRunUrl({ runId, run, projectOpts }) {
1771
+ if (void 0 !== run) {
1772
+ let sessionId;
1773
+ if (run.session_id) sessionId = run.session_id;
1774
+ else if (projectOpts?.projectName) sessionId = (await this.readProject({
1775
+ projectName: projectOpts?.projectName
1776
+ })).id;
1777
+ else if (projectOpts?.projectId) sessionId = projectOpts?.projectId;
1778
+ else {
1779
+ const project = await this.readProject({
1780
+ projectName: getLangSmithEnvironmentVariable("PROJECT") || "default"
1781
+ });
1782
+ sessionId = project.id;
1783
+ }
1784
+ const tenantId = await this._getTenantId();
1785
+ return `${this.getHostUrl()}/o/${tenantId}/projects/p/${sessionId}/r/${run.id}?poll=true`;
1786
+ }
1787
+ if (void 0 !== runId) {
1788
+ const run_ = await this.readRun(runId);
1789
+ if (!run_.app_path) throw new Error(`Run ${runId} has no app_path`);
1790
+ const baseUrl = this.getHostUrl();
1791
+ return `${baseUrl}${run_.app_path}`;
1792
+ }
1793
+ throw new Error("Must provide either runId or run");
1794
+ }
1795
+ async _loadChildRuns(run) {
1796
+ const childRuns = await toArray(this.listRuns({
1797
+ id: run.child_run_ids
1798
+ }));
1799
+ const treemap = {};
1800
+ const runs = {};
1801
+ childRuns.sort((a, b)=>(a?.dotted_order ?? "").localeCompare(b?.dotted_order ?? ""));
1802
+ for (const childRun of childRuns){
1803
+ if (null === childRun.parent_run_id || void 0 === childRun.parent_run_id) throw new Error(`Child run ${childRun.id} has no parent`);
1804
+ if (!(childRun.parent_run_id in treemap)) treemap[childRun.parent_run_id] = [];
1805
+ treemap[childRun.parent_run_id].push(childRun);
1806
+ runs[childRun.id] = childRun;
1807
+ }
1808
+ run.child_runs = treemap[run.id] || [];
1809
+ for(const runId in treemap)if (runId !== run.id) runs[runId].child_runs = treemap[runId];
1810
+ return run;
1811
+ }
1812
+ async *listRuns(props) {
1813
+ const { projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, isRoot, runType, error, id, query, filter, traceFilter, treeFilter, limit, select } = props;
1814
+ let projectIds = [];
1815
+ if (projectId) projectIds = Array.isArray(projectId) ? projectId : [
1816
+ projectId
1817
+ ];
1818
+ if (projectName) {
1819
+ const projectNames = Array.isArray(projectName) ? projectName : [
1820
+ projectName
1821
+ ];
1822
+ const projectIds_ = await Promise.all(projectNames.map((name)=>this.readProject({
1823
+ projectName: name
1824
+ }).then((project)=>project.id)));
1825
+ projectIds.push(...projectIds_);
1826
+ }
1827
+ const default_select = [
1828
+ "app_path",
1829
+ "child_run_ids",
1830
+ "completion_cost",
1831
+ "completion_tokens",
1832
+ "dotted_order",
1833
+ "end_time",
1834
+ "error",
1835
+ "events",
1836
+ "extra",
1837
+ "feedback_stats",
1838
+ "first_token_time",
1839
+ "id",
1840
+ "inputs",
1841
+ "name",
1842
+ "outputs",
1843
+ "parent_run_id",
1844
+ "parent_run_ids",
1845
+ "prompt_cost",
1846
+ "prompt_tokens",
1847
+ "reference_example_id",
1848
+ "run_type",
1849
+ "session_id",
1850
+ "start_time",
1851
+ "status",
1852
+ "tags",
1853
+ "total_cost",
1854
+ "total_tokens",
1855
+ "trace_id"
1856
+ ];
1857
+ const body = {
1858
+ session: projectIds.length ? projectIds : null,
1859
+ run_type: runType,
1860
+ reference_example: referenceExampleId,
1861
+ query,
1862
+ filter,
1863
+ trace_filter: traceFilter,
1864
+ tree_filter: treeFilter,
1865
+ execution_order: executionOrder,
1866
+ parent_run: parentRunId,
1867
+ start_time: startTime ? startTime.toISOString() : null,
1868
+ error,
1869
+ id,
1870
+ limit,
1871
+ trace: traceId,
1872
+ select: select ? select : default_select,
1873
+ is_root: isRoot
1874
+ };
1875
+ let runsYielded = 0;
1876
+ for await (const runs of this._getCursorPaginatedList("/runs/query", body))if (limit) {
1877
+ if (runsYielded >= limit) break;
1878
+ if (runs.length + runsYielded > limit) {
1879
+ const newRuns = runs.slice(0, limit - runsYielded);
1880
+ yield* newRuns;
1881
+ break;
1882
+ }
1883
+ runsYielded += runs.length;
1884
+ yield* runs;
1885
+ } else yield* runs;
1886
+ }
1887
+ async getRunStats({ id, trace, parentRun, runType, projectNames, projectIds, referenceExampleIds, startTime, endTime, error, query, filter, traceFilter, treeFilter, isRoot, dataSourceType }) {
1888
+ let projectIds_ = projectIds || [];
1889
+ if (projectNames) projectIds_ = [
1890
+ ...projectIds || [],
1891
+ ...await Promise.all(projectNames.map((name)=>this.readProject({
1892
+ projectName: name
1893
+ }).then((project)=>project.id)))
1894
+ ];
1895
+ const payload = {
1896
+ id,
1897
+ trace,
1898
+ parent_run: parentRun,
1899
+ run_type: runType,
1900
+ session: projectIds_,
1901
+ reference_example: referenceExampleIds,
1902
+ start_time: startTime,
1903
+ end_time: endTime,
1904
+ error,
1905
+ query,
1906
+ filter,
1907
+ trace_filter: traceFilter,
1908
+ tree_filter: treeFilter,
1909
+ is_root: isRoot,
1910
+ data_source_type: dataSourceType
1911
+ };
1912
+ const filteredPayload = Object.fromEntries(Object.entries(payload).filter(([_, value])=>void 0 !== value));
1913
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs/stats`, {
1914
+ method: "POST",
1915
+ headers: this.headers,
1916
+ body: JSON.stringify(filteredPayload),
1917
+ signal: AbortSignal.timeout(this.timeout_ms),
1918
+ ...this.fetchOptions
1919
+ });
1920
+ const result = await response.json();
1921
+ return result;
1922
+ }
1923
+ async shareRun(runId, { shareId } = {}) {
1924
+ const data = {
1925
+ run_id: runId,
1926
+ share_token: shareId || v4()
1927
+ };
1928
+ assertUuid(runId);
1929
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs/${runId}/share`, {
1930
+ method: "PUT",
1931
+ headers: this.headers,
1932
+ body: JSON.stringify(data),
1933
+ signal: AbortSignal.timeout(this.timeout_ms),
1934
+ ...this.fetchOptions
1935
+ });
1936
+ const result = await response.json();
1937
+ if (null === result || !("share_token" in result)) throw new Error("Invalid response from server");
1938
+ return `${this.getHostUrl()}/public/${result["share_token"]}/r`;
1939
+ }
1940
+ async unshareRun(runId) {
1941
+ assertUuid(runId);
1942
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs/${runId}/share`, {
1943
+ method: "DELETE",
1944
+ headers: this.headers,
1945
+ signal: AbortSignal.timeout(this.timeout_ms),
1946
+ ...this.fetchOptions
1947
+ });
1948
+ await raiseForStatus(response, "unshare run", true);
1949
+ }
1950
+ async readRunSharedLink(runId) {
1951
+ assertUuid(runId);
1952
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs/${runId}/share`, {
1953
+ method: "GET",
1954
+ headers: this.headers,
1955
+ signal: AbortSignal.timeout(this.timeout_ms),
1956
+ ...this.fetchOptions
1957
+ });
1958
+ const result = await response.json();
1959
+ if (null === result || !("share_token" in result)) return;
1960
+ return `${this.getHostUrl()}/public/${result["share_token"]}/r`;
1961
+ }
1962
+ async listSharedRuns(shareToken, { runIds } = {}) {
1963
+ const queryParams = new URLSearchParams({
1964
+ share_token: shareToken
1965
+ });
1966
+ if (void 0 !== runIds) for (const runId of runIds)queryParams.append("id", runId);
1967
+ assertUuid(shareToken);
1968
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/public/${shareToken}/runs${queryParams}`, {
1969
+ method: "GET",
1970
+ headers: this.headers,
1971
+ signal: AbortSignal.timeout(this.timeout_ms),
1972
+ ...this.fetchOptions
1973
+ });
1974
+ const runs = await response.json();
1975
+ return runs;
1976
+ }
1977
+ async readDatasetSharedSchema(datasetId, datasetName) {
1978
+ if (!datasetId && !datasetName) throw new Error("Either datasetId or datasetName must be given");
1979
+ if (!datasetId) {
1980
+ const dataset = await this.readDataset({
1981
+ datasetName
1982
+ });
1983
+ datasetId = dataset.id;
1984
+ }
1985
+ assertUuid(datasetId);
1986
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${datasetId}/share`, {
1987
+ method: "GET",
1988
+ headers: this.headers,
1989
+ signal: AbortSignal.timeout(this.timeout_ms),
1990
+ ...this.fetchOptions
1991
+ });
1992
+ const shareSchema = await response.json();
1993
+ shareSchema.url = `${this.getHostUrl()}/public/${shareSchema.share_token}/d`;
1994
+ return shareSchema;
1995
+ }
1996
+ async shareDataset(datasetId, datasetName) {
1997
+ if (!datasetId && !datasetName) throw new Error("Either datasetId or datasetName must be given");
1998
+ if (!datasetId) {
1999
+ const dataset = await this.readDataset({
2000
+ datasetName
2001
+ });
2002
+ datasetId = dataset.id;
2003
+ }
2004
+ const data = {
2005
+ dataset_id: datasetId
2006
+ };
2007
+ assertUuid(datasetId);
2008
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${datasetId}/share`, {
2009
+ method: "PUT",
2010
+ headers: this.headers,
2011
+ body: JSON.stringify(data),
2012
+ signal: AbortSignal.timeout(this.timeout_ms),
2013
+ ...this.fetchOptions
2014
+ });
2015
+ const shareSchema = await response.json();
2016
+ shareSchema.url = `${this.getHostUrl()}/public/${shareSchema.share_token}/d`;
2017
+ return shareSchema;
2018
+ }
2019
+ async unshareDataset(datasetId) {
2020
+ assertUuid(datasetId);
2021
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${datasetId}/share`, {
2022
+ method: "DELETE",
2023
+ headers: this.headers,
2024
+ signal: AbortSignal.timeout(this.timeout_ms),
2025
+ ...this.fetchOptions
2026
+ });
2027
+ await raiseForStatus(response, "unshare dataset", true);
2028
+ }
2029
+ async readSharedDataset(shareToken) {
2030
+ assertUuid(shareToken);
2031
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/public/${shareToken}/datasets`, {
2032
+ method: "GET",
2033
+ headers: this.headers,
2034
+ signal: AbortSignal.timeout(this.timeout_ms),
2035
+ ...this.fetchOptions
2036
+ });
2037
+ const dataset = await response.json();
2038
+ return dataset;
2039
+ }
2040
+ async listSharedExamples(shareToken, options) {
2041
+ const params = {};
2042
+ if (options?.exampleIds) params.id = options.exampleIds;
2043
+ const urlParams = new URLSearchParams();
2044
+ Object.entries(params).forEach(([key, value])=>{
2045
+ if (Array.isArray(value)) value.forEach((v)=>urlParams.append(key, v));
2046
+ else urlParams.append(key, value);
2047
+ });
2048
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/public/${shareToken}/examples?${urlParams.toString()}`, {
2049
+ method: "GET",
2050
+ headers: this.headers,
2051
+ signal: AbortSignal.timeout(this.timeout_ms),
2052
+ ...this.fetchOptions
2053
+ });
2054
+ const result = await response.json();
2055
+ if (!response.ok) {
2056
+ if ("detail" in result) throw new Error(`Failed to list shared examples.\nStatus: ${response.status}\nMessage: ${result.detail.join("\n")}`);
2057
+ throw new Error(`Failed to list shared examples: ${response.status} ${response.statusText}`);
2058
+ }
2059
+ return result.map((example)=>({
2060
+ ...example,
2061
+ _hostUrl: this.getHostUrl()
2062
+ }));
2063
+ }
2064
+ async createProject({ projectName, description = null, metadata = null, upsert = false, projectExtra = null, referenceDatasetId = null }) {
2065
+ const upsert_ = upsert ? "?upsert=true" : "";
2066
+ const endpoint = `${this.apiUrl}/sessions${upsert_}`;
2067
+ const extra = projectExtra || {};
2068
+ if (metadata) extra["metadata"] = metadata;
2069
+ const body = {
2070
+ name: projectName,
2071
+ extra,
2072
+ description
2073
+ };
2074
+ if (null !== referenceDatasetId) body["reference_dataset_id"] = referenceDatasetId;
2075
+ const response = await this.caller.call(_getFetchImplementation(), endpoint, {
2076
+ method: "POST",
2077
+ headers: {
2078
+ ...this.headers,
2079
+ "Content-Type": "application/json"
2080
+ },
2081
+ body: JSON.stringify(body),
2082
+ signal: AbortSignal.timeout(this.timeout_ms),
2083
+ ...this.fetchOptions
2084
+ });
2085
+ await raiseForStatus(response, "create project");
2086
+ const result = await response.json();
2087
+ return result;
2088
+ }
2089
+ async updateProject(projectId, { name = null, description = null, metadata = null, projectExtra = null, endTime = null }) {
2090
+ const endpoint = `${this.apiUrl}/sessions/${projectId}`;
2091
+ let extra = projectExtra;
2092
+ if (metadata) extra = {
2093
+ ...extra || {},
2094
+ metadata
2095
+ };
2096
+ const body = {
2097
+ name,
2098
+ extra,
2099
+ description,
2100
+ end_time: endTime ? new Date(endTime).toISOString() : null
2101
+ };
2102
+ const response = await this.caller.call(_getFetchImplementation(), endpoint, {
2103
+ method: "PATCH",
2104
+ headers: {
2105
+ ...this.headers,
2106
+ "Content-Type": "application/json"
2107
+ },
2108
+ body: JSON.stringify(body),
2109
+ signal: AbortSignal.timeout(this.timeout_ms),
2110
+ ...this.fetchOptions
2111
+ });
2112
+ await raiseForStatus(response, "update project");
2113
+ const result = await response.json();
2114
+ return result;
2115
+ }
2116
+ async hasProject({ projectId, projectName }) {
2117
+ let path = "/sessions";
2118
+ const params = new URLSearchParams();
2119
+ if (void 0 !== projectId && void 0 !== projectName) throw new Error("Must provide either projectName or projectId, not both");
2120
+ if (void 0 !== projectId) {
2121
+ assertUuid(projectId);
2122
+ path += `/${projectId}`;
2123
+ } else if (void 0 !== projectName) params.append("name", projectName);
2124
+ else throw new Error("Must provide projectName or projectId");
2125
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}${path}?${params}`, {
2126
+ method: "GET",
2127
+ headers: this.headers,
2128
+ signal: AbortSignal.timeout(this.timeout_ms),
2129
+ ...this.fetchOptions
2130
+ });
2131
+ try {
2132
+ const result = await response.json();
2133
+ if (!response.ok) return false;
2134
+ if (Array.isArray(result)) return result.length > 0;
2135
+ return true;
2136
+ } catch (e) {
2137
+ return false;
2138
+ }
2139
+ }
2140
+ async readProject({ projectId, projectName, includeStats }) {
2141
+ let path = "/sessions";
2142
+ const params = new URLSearchParams();
2143
+ if (void 0 !== projectId && void 0 !== projectName) throw new Error("Must provide either projectName or projectId, not both");
2144
+ if (void 0 !== projectId) {
2145
+ assertUuid(projectId);
2146
+ path += `/${projectId}`;
2147
+ } else if (void 0 !== projectName) params.append("name", projectName);
2148
+ else throw new Error("Must provide projectName or projectId");
2149
+ if (void 0 !== includeStats) params.append("include_stats", includeStats.toString());
2150
+ const response = await this._get(path, params);
2151
+ let result;
2152
+ if (Array.isArray(response)) {
2153
+ if (0 === response.length) throw new Error(`Project[id=${projectId}, name=${projectName}] not found`);
2154
+ result = response[0];
2155
+ } else result = response;
2156
+ return result;
2157
+ }
2158
+ async getProjectUrl({ projectId, projectName }) {
2159
+ if (void 0 === projectId && void 0 === projectName) throw new Error("Must provide either projectName or projectId");
2160
+ const project = await this.readProject({
2161
+ projectId,
2162
+ projectName
2163
+ });
2164
+ const tenantId = await this._getTenantId();
2165
+ return `${this.getHostUrl()}/o/${tenantId}/projects/p/${project.id}`;
2166
+ }
2167
+ async getDatasetUrl({ datasetId, datasetName }) {
2168
+ if (void 0 === datasetId && void 0 === datasetName) throw new Error("Must provide either datasetName or datasetId");
2169
+ const dataset = await this.readDataset({
2170
+ datasetId,
2171
+ datasetName
2172
+ });
2173
+ const tenantId = await this._getTenantId();
2174
+ return `${this.getHostUrl()}/o/${tenantId}/datasets/${dataset.id}`;
2175
+ }
2176
+ async _getTenantId() {
2177
+ if (null !== this._tenantId) return this._tenantId;
2178
+ const queryParams = new URLSearchParams({
2179
+ limit: "1"
2180
+ });
2181
+ for await (const projects of this._getPaginated("/sessions", queryParams)){
2182
+ this._tenantId = projects[0].tenant_id;
2183
+ return projects[0].tenant_id;
2184
+ }
2185
+ throw new Error("No projects found to resolve tenant.");
2186
+ }
2187
+ async *listProjects({ projectIds, name, nameContains, referenceDatasetId, referenceDatasetName, referenceFree, metadata } = {}) {
2188
+ const params = new URLSearchParams();
2189
+ if (void 0 !== projectIds) for (const projectId of projectIds)params.append("id", projectId);
2190
+ if (void 0 !== name) params.append("name", name);
2191
+ if (void 0 !== nameContains) params.append("name_contains", nameContains);
2192
+ if (void 0 !== referenceDatasetId) params.append("reference_dataset", referenceDatasetId);
2193
+ else if (void 0 !== referenceDatasetName) {
2194
+ const dataset = await this.readDataset({
2195
+ datasetName: referenceDatasetName
2196
+ });
2197
+ params.append("reference_dataset", dataset.id);
2198
+ }
2199
+ if (void 0 !== referenceFree) params.append("reference_free", referenceFree.toString());
2200
+ if (void 0 !== metadata) params.append("metadata", JSON.stringify(metadata));
2201
+ for await (const projects of this._getPaginated("/sessions", params))yield* projects;
2202
+ }
2203
+ async deleteProject({ projectId, projectName }) {
2204
+ let projectId_;
2205
+ if (void 0 === projectId && void 0 === projectName) throw new Error("Must provide projectName or projectId");
2206
+ if (void 0 !== projectId && void 0 !== projectName) throw new Error("Must provide either projectName or projectId, not both");
2207
+ projectId_ = void 0 === projectId ? (await this.readProject({
2208
+ projectName
2209
+ })).id : projectId;
2210
+ assertUuid(projectId_);
2211
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/sessions/${projectId_}`, {
2212
+ method: "DELETE",
2213
+ headers: this.headers,
2214
+ signal: AbortSignal.timeout(this.timeout_ms),
2215
+ ...this.fetchOptions
2216
+ });
2217
+ await raiseForStatus(response, `delete session ${projectId_} (${projectName})`, true);
2218
+ }
2219
+ async uploadCsv({ csvFile, fileName, inputKeys, outputKeys, description, dataType, name }) {
2220
+ const url = `${this.apiUrl}/datasets/upload`;
2221
+ const formData = new FormData();
2222
+ formData.append("file", csvFile, fileName);
2223
+ inputKeys.forEach((key)=>{
2224
+ formData.append("input_keys", key);
2225
+ });
2226
+ outputKeys.forEach((key)=>{
2227
+ formData.append("output_keys", key);
2228
+ });
2229
+ if (description) formData.append("description", description);
2230
+ if (dataType) formData.append("data_type", dataType);
2231
+ if (name) formData.append("name", name);
2232
+ const response = await this.caller.call(_getFetchImplementation(), url, {
2233
+ method: "POST",
2234
+ headers: this.headers,
2235
+ body: formData,
2236
+ signal: AbortSignal.timeout(this.timeout_ms),
2237
+ ...this.fetchOptions
2238
+ });
2239
+ await raiseForStatus(response, "upload CSV");
2240
+ const result = await response.json();
2241
+ return result;
2242
+ }
2243
+ async createDataset(name, { description, dataType, inputsSchema, outputsSchema, metadata } = {}) {
2244
+ const body = {
2245
+ name,
2246
+ description,
2247
+ extra: metadata ? {
2248
+ metadata
2249
+ } : void 0
2250
+ };
2251
+ if (dataType) body.data_type = dataType;
2252
+ if (inputsSchema) body.inputs_schema_definition = inputsSchema;
2253
+ if (outputsSchema) body.outputs_schema_definition = outputsSchema;
2254
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets`, {
2255
+ method: "POST",
2256
+ headers: {
2257
+ ...this.headers,
2258
+ "Content-Type": "application/json"
2259
+ },
2260
+ body: JSON.stringify(body),
2261
+ signal: AbortSignal.timeout(this.timeout_ms),
2262
+ ...this.fetchOptions
2263
+ });
2264
+ await raiseForStatus(response, "create dataset");
2265
+ const result = await response.json();
2266
+ return result;
2267
+ }
2268
+ async readDataset({ datasetId, datasetName }) {
2269
+ let path = "/datasets";
2270
+ const params = new URLSearchParams({
2271
+ limit: "1"
2272
+ });
2273
+ if (void 0 !== datasetId && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2274
+ if (void 0 !== datasetId) {
2275
+ assertUuid(datasetId);
2276
+ path += `/${datasetId}`;
2277
+ } else if (void 0 !== datasetName) params.append("name", datasetName);
2278
+ else throw new Error("Must provide datasetName or datasetId");
2279
+ const response = await this._get(path, params);
2280
+ let result;
2281
+ if (Array.isArray(response)) {
2282
+ if (0 === response.length) throw new Error(`Dataset[id=${datasetId}, name=${datasetName}] not found`);
2283
+ result = response[0];
2284
+ } else result = response;
2285
+ return result;
2286
+ }
2287
+ async hasDataset({ datasetId, datasetName }) {
2288
+ try {
2289
+ await this.readDataset({
2290
+ datasetId,
2291
+ datasetName
2292
+ });
2293
+ return true;
2294
+ } catch (e) {
2295
+ if (e instanceof Error && e.message.toLocaleLowerCase().includes("not found")) return false;
2296
+ throw e;
2297
+ }
2298
+ }
2299
+ async diffDatasetVersions({ datasetId, datasetName, fromVersion, toVersion }) {
2300
+ let datasetId_ = datasetId;
2301
+ if (void 0 === datasetId_ && void 0 === datasetName) throw new Error("Must provide either datasetName or datasetId");
2302
+ if (void 0 !== datasetId_ && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2303
+ if (void 0 === datasetId_) {
2304
+ const dataset = await this.readDataset({
2305
+ datasetName
2306
+ });
2307
+ datasetId_ = dataset.id;
2308
+ }
2309
+ const urlParams = new URLSearchParams({
2310
+ from_version: "string" == typeof fromVersion ? fromVersion : fromVersion.toISOString(),
2311
+ to_version: "string" == typeof toVersion ? toVersion : toVersion.toISOString()
2312
+ });
2313
+ const response = await this._get(`/datasets/${datasetId_}/versions/diff`, urlParams);
2314
+ return response;
2315
+ }
2316
+ async readDatasetOpenaiFinetuning({ datasetId, datasetName }) {
2317
+ const path = "/datasets";
2318
+ if (void 0 !== datasetId) ;
2319
+ else if (void 0 !== datasetName) datasetId = (await this.readDataset({
2320
+ datasetName
2321
+ })).id;
2322
+ else throw new Error("Must provide datasetName or datasetId");
2323
+ const response = await this._getResponse(`${path}/${datasetId}/openai_ft`);
2324
+ const datasetText = await response.text();
2325
+ const dataset = datasetText.trim().split("\n").map((line)=>JSON.parse(line));
2326
+ return dataset;
2327
+ }
2328
+ async *listDatasets({ limit = 100, offset = 0, datasetIds, datasetName, datasetNameContains, metadata } = {}) {
2329
+ const path = "/datasets";
2330
+ const params = new URLSearchParams({
2331
+ limit: limit.toString(),
2332
+ offset: offset.toString()
2333
+ });
2334
+ if (void 0 !== datasetIds) for (const id_ of datasetIds)params.append("id", id_);
2335
+ if (void 0 !== datasetName) params.append("name", datasetName);
2336
+ if (void 0 !== datasetNameContains) params.append("name_contains", datasetNameContains);
2337
+ if (void 0 !== metadata) params.append("metadata", JSON.stringify(metadata));
2338
+ for await (const datasets of this._getPaginated(path, params))yield* datasets;
2339
+ }
2340
+ async updateDataset(props) {
2341
+ const { datasetId, datasetName, ...update } = props;
2342
+ if (!datasetId && !datasetName) throw new Error("Must provide either datasetName or datasetId");
2343
+ const _datasetId = datasetId ?? (await this.readDataset({
2344
+ datasetName
2345
+ })).id;
2346
+ assertUuid(_datasetId);
2347
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${_datasetId}`, {
2348
+ method: "PATCH",
2349
+ headers: {
2350
+ ...this.headers,
2351
+ "Content-Type": "application/json"
2352
+ },
2353
+ body: JSON.stringify(update),
2354
+ signal: AbortSignal.timeout(this.timeout_ms),
2355
+ ...this.fetchOptions
2356
+ });
2357
+ await raiseForStatus(response, "update dataset");
2358
+ return await response.json();
2359
+ }
2360
+ async updateDatasetTag(props) {
2361
+ const { datasetId, datasetName, asOf, tag } = props;
2362
+ if (!datasetId && !datasetName) throw new Error("Must provide either datasetName or datasetId");
2363
+ const _datasetId = datasetId ?? (await this.readDataset({
2364
+ datasetName
2365
+ })).id;
2366
+ assertUuid(_datasetId);
2367
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${_datasetId}/tags`, {
2368
+ method: "PUT",
2369
+ headers: {
2370
+ ...this.headers,
2371
+ "Content-Type": "application/json"
2372
+ },
2373
+ body: JSON.stringify({
2374
+ as_of: "string" == typeof asOf ? asOf : asOf.toISOString(),
2375
+ tag
2376
+ }),
2377
+ signal: AbortSignal.timeout(this.timeout_ms),
2378
+ ...this.fetchOptions
2379
+ });
2380
+ await raiseForStatus(response, "update dataset tags");
2381
+ }
2382
+ async deleteDataset({ datasetId, datasetName }) {
2383
+ let path = "/datasets";
2384
+ let datasetId_ = datasetId;
2385
+ if (void 0 !== datasetId && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2386
+ if (void 0 !== datasetName) {
2387
+ const dataset = await this.readDataset({
2388
+ datasetName
2389
+ });
2390
+ datasetId_ = dataset.id;
2391
+ }
2392
+ if (void 0 !== datasetId_) {
2393
+ assertUuid(datasetId_);
2394
+ path += `/${datasetId_}`;
2395
+ } else throw new Error("Must provide datasetName or datasetId");
2396
+ const response = await this.caller.call(_getFetchImplementation(), this.apiUrl + path, {
2397
+ method: "DELETE",
2398
+ headers: this.headers,
2399
+ signal: AbortSignal.timeout(this.timeout_ms),
2400
+ ...this.fetchOptions
2401
+ });
2402
+ await raiseForStatus(response, `delete ${path}`);
2403
+ await response.json();
2404
+ }
2405
+ async indexDataset({ datasetId, datasetName, tag }) {
2406
+ let datasetId_ = datasetId;
2407
+ if (datasetId_ || datasetName) {
2408
+ if (datasetId_ && datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2409
+ else if (!datasetId_) {
2410
+ const dataset = await this.readDataset({
2411
+ datasetName
2412
+ });
2413
+ datasetId_ = dataset.id;
2414
+ }
2415
+ } else throw new Error("Must provide either datasetName or datasetId");
2416
+ assertUuid(datasetId_);
2417
+ const data = {
2418
+ tag: tag
2419
+ };
2420
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${datasetId_}/index`, {
2421
+ method: "POST",
2422
+ headers: {
2423
+ ...this.headers,
2424
+ "Content-Type": "application/json"
2425
+ },
2426
+ body: JSON.stringify(data),
2427
+ signal: AbortSignal.timeout(this.timeout_ms),
2428
+ ...this.fetchOptions
2429
+ });
2430
+ await raiseForStatus(response, "index dataset");
2431
+ await response.json();
2432
+ }
2433
+ async similarExamples(inputs, datasetId, limit, { filter } = {}) {
2434
+ const data = {
2435
+ limit: limit,
2436
+ inputs: inputs
2437
+ };
2438
+ if (void 0 !== filter) data["filter"] = filter;
2439
+ assertUuid(datasetId);
2440
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${datasetId}/search`, {
2441
+ method: "POST",
2442
+ headers: {
2443
+ ...this.headers,
2444
+ "Content-Type": "application/json"
2445
+ },
2446
+ body: JSON.stringify(data),
2447
+ signal: AbortSignal.timeout(this.timeout_ms),
2448
+ ...this.fetchOptions
2449
+ });
2450
+ await raiseForStatus(response, "fetch similar examples");
2451
+ const result = await response.json();
2452
+ return result["examples"];
2453
+ }
2454
+ async createExample(inputs, outputs, { datasetId, datasetName, createdAt, exampleId, metadata, split, sourceRunId }) {
2455
+ let datasetId_ = datasetId;
2456
+ if (void 0 === datasetId_ && void 0 === datasetName) throw new Error("Must provide either datasetName or datasetId");
2457
+ if (void 0 !== datasetId_ && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2458
+ if (void 0 === datasetId_) {
2459
+ const dataset = await this.readDataset({
2460
+ datasetName
2461
+ });
2462
+ datasetId_ = dataset.id;
2463
+ }
2464
+ const createdAt_ = createdAt || new Date();
2465
+ const data = {
2466
+ dataset_id: datasetId_,
2467
+ inputs,
2468
+ outputs,
2469
+ created_at: createdAt_?.toISOString(),
2470
+ id: exampleId,
2471
+ metadata,
2472
+ split,
2473
+ source_run_id: sourceRunId
2474
+ };
2475
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/examples`, {
2476
+ method: "POST",
2477
+ headers: {
2478
+ ...this.headers,
2479
+ "Content-Type": "application/json"
2480
+ },
2481
+ body: JSON.stringify(data),
2482
+ signal: AbortSignal.timeout(this.timeout_ms),
2483
+ ...this.fetchOptions
2484
+ });
2485
+ await raiseForStatus(response, "create example");
2486
+ const result = await response.json();
2487
+ return result;
2488
+ }
2489
+ async createExamples(props) {
2490
+ const { inputs, outputs, metadata, sourceRunIds, exampleIds, datasetId, datasetName } = props;
2491
+ let datasetId_ = datasetId;
2492
+ if (void 0 === datasetId_ && void 0 === datasetName) throw new Error("Must provide either datasetName or datasetId");
2493
+ if (void 0 !== datasetId_ && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2494
+ if (void 0 === datasetId_) {
2495
+ const dataset = await this.readDataset({
2496
+ datasetName
2497
+ });
2498
+ datasetId_ = dataset.id;
2499
+ }
2500
+ const formattedExamples = inputs.map((input, idx)=>({
2501
+ dataset_id: datasetId_,
2502
+ inputs: input,
2503
+ outputs: outputs ? outputs[idx] : void 0,
2504
+ metadata: metadata ? metadata[idx] : void 0,
2505
+ split: props.splits ? props.splits[idx] : void 0,
2506
+ id: exampleIds ? exampleIds[idx] : void 0,
2507
+ source_run_id: sourceRunIds ? sourceRunIds[idx] : void 0
2508
+ }));
2509
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/examples/bulk`, {
2510
+ method: "POST",
2511
+ headers: {
2512
+ ...this.headers,
2513
+ "Content-Type": "application/json"
2514
+ },
2515
+ body: JSON.stringify(formattedExamples),
2516
+ signal: AbortSignal.timeout(this.timeout_ms),
2517
+ ...this.fetchOptions
2518
+ });
2519
+ await raiseForStatus(response, "create examples");
2520
+ const result = await response.json();
2521
+ return result;
2522
+ }
2523
+ async createLLMExample(input, generation, options) {
2524
+ return this.createExample({
2525
+ input
2526
+ }, {
2527
+ output: generation
2528
+ }, options);
2529
+ }
2530
+ async createChatExample(input, generations, options) {
2531
+ const finalInput = input.map((message)=>{
2532
+ if (isLangChainMessage(message)) return convertLangChainMessageToExample(message);
2533
+ return message;
2534
+ });
2535
+ const finalOutput = isLangChainMessage(generations) ? convertLangChainMessageToExample(generations) : generations;
2536
+ return this.createExample({
2537
+ input: finalInput
2538
+ }, {
2539
+ output: finalOutput
2540
+ }, options);
2541
+ }
2542
+ async readExample(exampleId) {
2543
+ assertUuid(exampleId);
2544
+ const path = `/examples/${exampleId}`;
2545
+ const rawExample = await this._get(path);
2546
+ const { attachment_urls, ...rest } = rawExample;
2547
+ const example = rest;
2548
+ if (attachment_urls) example.attachments = Object.entries(attachment_urls).reduce((acc, [key, value])=>{
2549
+ acc[key.slice(11)] = {
2550
+ presigned_url: value.presigned_url,
2551
+ mime_type: value.mime_type
2552
+ };
2553
+ return acc;
2554
+ }, {});
2555
+ return example;
2556
+ }
2557
+ async *listExamples({ datasetId, datasetName, exampleIds, asOf, splits, inlineS3Urls, metadata, limit, offset, filter, includeAttachments } = {}) {
2558
+ let datasetId_;
2559
+ if (void 0 !== datasetId && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2560
+ if (void 0 !== datasetId) datasetId_ = datasetId;
2561
+ else if (void 0 !== datasetName) {
2562
+ const dataset = await this.readDataset({
2563
+ datasetName
2564
+ });
2565
+ datasetId_ = dataset.id;
2566
+ } else throw new Error("Must provide a datasetName or datasetId");
2567
+ const params = new URLSearchParams({
2568
+ dataset: datasetId_
2569
+ });
2570
+ const dataset_version = asOf ? "string" == typeof asOf ? asOf : asOf?.toISOString() : void 0;
2571
+ if (dataset_version) params.append("as_of", dataset_version);
2572
+ const inlineS3Urls_ = inlineS3Urls ?? true;
2573
+ params.append("inline_s3_urls", inlineS3Urls_.toString());
2574
+ if (void 0 !== exampleIds) for (const id_ of exampleIds)params.append("id", id_);
2575
+ if (void 0 !== splits) for (const split of splits)params.append("splits", split);
2576
+ if (void 0 !== metadata) {
2577
+ const serializedMetadata = JSON.stringify(metadata);
2578
+ params.append("metadata", serializedMetadata);
2579
+ }
2580
+ if (void 0 !== limit) params.append("limit", limit.toString());
2581
+ if (void 0 !== offset) params.append("offset", offset.toString());
2582
+ if (void 0 !== filter) params.append("filter", filter);
2583
+ if (true === includeAttachments) [
2584
+ "attachment_urls",
2585
+ "outputs",
2586
+ "metadata"
2587
+ ].forEach((field)=>params.append("select", field));
2588
+ let i = 0;
2589
+ for await (const rawExamples of this._getPaginated("/examples", params)){
2590
+ for (const rawExample of rawExamples){
2591
+ const { attachment_urls, ...rest } = rawExample;
2592
+ const example = rest;
2593
+ if (attachment_urls) example.attachments = Object.entries(attachment_urls).reduce((acc, [key, value])=>{
2594
+ acc[key.slice(11)] = {
2595
+ presigned_url: value.presigned_url,
2596
+ mime_type: value.mime_type || void 0
2597
+ };
2598
+ return acc;
2599
+ }, {});
2600
+ yield example;
2601
+ i++;
2602
+ }
2603
+ if (void 0 !== limit && i >= limit) break;
2604
+ }
2605
+ }
2606
+ async deleteExample(exampleId) {
2607
+ assertUuid(exampleId);
2608
+ const path = `/examples/${exampleId}`;
2609
+ const response = await this.caller.call(_getFetchImplementation(), this.apiUrl + path, {
2610
+ method: "DELETE",
2611
+ headers: this.headers,
2612
+ signal: AbortSignal.timeout(this.timeout_ms),
2613
+ ...this.fetchOptions
2614
+ });
2615
+ await raiseForStatus(response, `delete ${path}`);
2616
+ await response.json();
2617
+ }
2618
+ async updateExample(exampleId, update) {
2619
+ assertUuid(exampleId);
2620
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/examples/${exampleId}`, {
2621
+ method: "PATCH",
2622
+ headers: {
2623
+ ...this.headers,
2624
+ "Content-Type": "application/json"
2625
+ },
2626
+ body: JSON.stringify(update),
2627
+ signal: AbortSignal.timeout(this.timeout_ms),
2628
+ ...this.fetchOptions
2629
+ });
2630
+ await raiseForStatus(response, "update example");
2631
+ const result = await response.json();
2632
+ return result;
2633
+ }
2634
+ async updateExamples(update) {
2635
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/examples/bulk`, {
2636
+ method: "PATCH",
2637
+ headers: {
2638
+ ...this.headers,
2639
+ "Content-Type": "application/json"
2640
+ },
2641
+ body: JSON.stringify(update),
2642
+ signal: AbortSignal.timeout(this.timeout_ms),
2643
+ ...this.fetchOptions
2644
+ });
2645
+ await raiseForStatus(response, "update examples");
2646
+ const result = await response.json();
2647
+ return result;
2648
+ }
2649
+ async readDatasetVersion({ datasetId, datasetName, asOf, tag }) {
2650
+ let resolvedDatasetId;
2651
+ if (datasetId) resolvedDatasetId = datasetId;
2652
+ else {
2653
+ const dataset = await this.readDataset({
2654
+ datasetName
2655
+ });
2656
+ resolvedDatasetId = dataset.id;
2657
+ }
2658
+ assertUuid(resolvedDatasetId);
2659
+ if (asOf && tag || !asOf && !tag) throw new Error("Exactly one of asOf and tag must be specified.");
2660
+ const params = new URLSearchParams();
2661
+ if (void 0 !== asOf) params.append("as_of", "string" == typeof asOf ? asOf : asOf.toISOString());
2662
+ if (void 0 !== tag) params.append("tag", tag);
2663
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${resolvedDatasetId}/version?${params.toString()}`, {
2664
+ method: "GET",
2665
+ headers: {
2666
+ ...this.headers
2667
+ },
2668
+ signal: AbortSignal.timeout(this.timeout_ms),
2669
+ ...this.fetchOptions
2670
+ });
2671
+ await raiseForStatus(response, "read dataset version");
2672
+ return await response.json();
2673
+ }
2674
+ async listDatasetSplits({ datasetId, datasetName, asOf }) {
2675
+ let datasetId_;
2676
+ if (void 0 === datasetId && void 0 === datasetName) throw new Error("Must provide dataset name or ID");
2677
+ if (void 0 !== datasetId && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2678
+ if (void 0 === datasetId) {
2679
+ const dataset = await this.readDataset({
2680
+ datasetName
2681
+ });
2682
+ datasetId_ = dataset.id;
2683
+ } else datasetId_ = datasetId;
2684
+ assertUuid(datasetId_);
2685
+ const params = new URLSearchParams();
2686
+ const dataset_version = asOf ? "string" == typeof asOf ? asOf : asOf?.toISOString() : void 0;
2687
+ if (dataset_version) params.append("as_of", dataset_version);
2688
+ const response = await this._get(`/datasets/${datasetId_}/splits`, params);
2689
+ return response;
2690
+ }
2691
+ async updateDatasetSplits({ datasetId, datasetName, splitName, exampleIds, remove = false }) {
2692
+ let datasetId_;
2693
+ if (void 0 === datasetId && void 0 === datasetName) throw new Error("Must provide dataset name or ID");
2694
+ if (void 0 !== datasetId && void 0 !== datasetName) throw new Error("Must provide either datasetName or datasetId, not both");
2695
+ if (void 0 === datasetId) {
2696
+ const dataset = await this.readDataset({
2697
+ datasetName
2698
+ });
2699
+ datasetId_ = dataset.id;
2700
+ } else datasetId_ = datasetId;
2701
+ assertUuid(datasetId_);
2702
+ const data = {
2703
+ split_name: splitName,
2704
+ examples: exampleIds.map((id)=>{
2705
+ assertUuid(id);
2706
+ return id;
2707
+ }),
2708
+ remove
2709
+ };
2710
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/${datasetId_}/splits`, {
2711
+ method: "PUT",
2712
+ headers: {
2713
+ ...this.headers,
2714
+ "Content-Type": "application/json"
2715
+ },
2716
+ body: JSON.stringify(data),
2717
+ signal: AbortSignal.timeout(this.timeout_ms),
2718
+ ...this.fetchOptions
2719
+ });
2720
+ await raiseForStatus(response, "update dataset splits", true);
2721
+ }
2722
+ async evaluateRun(run, evaluator, { sourceInfo, loadChildRuns, referenceExample } = {
2723
+ loadChildRuns: false
2724
+ }) {
2725
+ warnOnce("This method is deprecated and will be removed in future LangSmith versions, use `evaluate` from `langsmith/evaluation` instead.");
2726
+ let run_;
2727
+ if ("string" == typeof run) run_ = await this.readRun(run, {
2728
+ loadChildRuns
2729
+ });
2730
+ else if ("object" == typeof run && "id" in run) run_ = run;
2731
+ else throw new Error(`Invalid run type: ${typeof run}`);
2732
+ if (null !== run_.reference_example_id && void 0 !== run_.reference_example_id) referenceExample = await this.readExample(run_.reference_example_id);
2733
+ const feedbackResult = await evaluator.evaluateRun(run_, referenceExample);
2734
+ const [_, feedbacks] = await this._logEvaluationFeedback(feedbackResult, run_, sourceInfo);
2735
+ return feedbacks[0];
2736
+ }
2737
+ async createFeedback(runId, key, { score, value, correction, comment, sourceInfo, feedbackSourceType = "api", sourceRunId, feedbackId, feedbackConfig, projectId, comparativeExperimentId }) {
2738
+ if (!runId && !projectId) throw new Error("One of runId or projectId must be provided");
2739
+ if (runId && projectId) throw new Error("Only one of runId or projectId can be provided");
2740
+ const feedback_source = {
2741
+ type: feedbackSourceType ?? "api",
2742
+ metadata: sourceInfo ?? {}
2743
+ };
2744
+ if (void 0 !== sourceRunId && feedback_source?.metadata !== void 0 && !feedback_source.metadata["__run"]) feedback_source.metadata["__run"] = {
2745
+ run_id: sourceRunId
2746
+ };
2747
+ if (feedback_source?.metadata !== void 0 && feedback_source.metadata["__run"]?.run_id !== void 0) assertUuid(feedback_source.metadata["__run"].run_id);
2748
+ const feedback = {
2749
+ id: feedbackId ?? v4(),
2750
+ run_id: runId,
2751
+ key,
2752
+ score,
2753
+ value,
2754
+ correction,
2755
+ comment,
2756
+ feedback_source: feedback_source,
2757
+ comparative_experiment_id: comparativeExperimentId,
2758
+ feedbackConfig,
2759
+ session_id: projectId
2760
+ };
2761
+ const url = `${this.apiUrl}/feedback`;
2762
+ const response = await this.caller.call(_getFetchImplementation(), url, {
2763
+ method: "POST",
2764
+ headers: {
2765
+ ...this.headers,
2766
+ "Content-Type": "application/json"
2767
+ },
2768
+ body: JSON.stringify(feedback),
2769
+ signal: AbortSignal.timeout(this.timeout_ms),
2770
+ ...this.fetchOptions
2771
+ });
2772
+ await raiseForStatus(response, "create feedback", true);
2773
+ return feedback;
2774
+ }
2775
+ async updateFeedback(feedbackId, { score, value, correction, comment }) {
2776
+ const feedbackUpdate = {};
2777
+ if (null != score) feedbackUpdate["score"] = score;
2778
+ if (null != value) feedbackUpdate["value"] = value;
2779
+ if (null != correction) feedbackUpdate["correction"] = correction;
2780
+ if (null != comment) feedbackUpdate["comment"] = comment;
2781
+ assertUuid(feedbackId);
2782
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/feedback/${feedbackId}`, {
2783
+ method: "PATCH",
2784
+ headers: {
2785
+ ...this.headers,
2786
+ "Content-Type": "application/json"
2787
+ },
2788
+ body: JSON.stringify(feedbackUpdate),
2789
+ signal: AbortSignal.timeout(this.timeout_ms),
2790
+ ...this.fetchOptions
2791
+ });
2792
+ await raiseForStatus(response, "update feedback", true);
2793
+ }
2794
+ async readFeedback(feedbackId) {
2795
+ assertUuid(feedbackId);
2796
+ const path = `/feedback/${feedbackId}`;
2797
+ const response = await this._get(path);
2798
+ return response;
2799
+ }
2800
+ async deleteFeedback(feedbackId) {
2801
+ assertUuid(feedbackId);
2802
+ const path = `/feedback/${feedbackId}`;
2803
+ const response = await this.caller.call(_getFetchImplementation(), this.apiUrl + path, {
2804
+ method: "DELETE",
2805
+ headers: this.headers,
2806
+ signal: AbortSignal.timeout(this.timeout_ms),
2807
+ ...this.fetchOptions
2808
+ });
2809
+ await raiseForStatus(response, `delete ${path}`);
2810
+ await response.json();
2811
+ }
2812
+ async *listFeedback({ runIds, feedbackKeys, feedbackSourceTypes } = {}) {
2813
+ const queryParams = new URLSearchParams();
2814
+ if (runIds) queryParams.append("run", runIds.join(","));
2815
+ if (feedbackKeys) for (const key of feedbackKeys)queryParams.append("key", key);
2816
+ if (feedbackSourceTypes) for (const type of feedbackSourceTypes)queryParams.append("source", type);
2817
+ for await (const feedbacks of this._getPaginated("/feedback", queryParams))yield* feedbacks;
2818
+ }
2819
+ async createPresignedFeedbackToken(runId, feedbackKey, { expiration, feedbackConfig } = {}) {
2820
+ const body = {
2821
+ run_id: runId,
2822
+ feedback_key: feedbackKey,
2823
+ feedback_config: feedbackConfig
2824
+ };
2825
+ if (expiration) {
2826
+ if ("string" == typeof expiration) body["expires_at"] = expiration;
2827
+ else if (expiration?.hours || expiration?.minutes || expiration?.days) body["expires_in"] = expiration;
2828
+ } else body["expires_in"] = {
2829
+ hours: 3
2830
+ };
2831
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/feedback/tokens`, {
2832
+ method: "POST",
2833
+ headers: {
2834
+ ...this.headers,
2835
+ "Content-Type": "application/json"
2836
+ },
2837
+ body: JSON.stringify(body),
2838
+ signal: AbortSignal.timeout(this.timeout_ms),
2839
+ ...this.fetchOptions
2840
+ });
2841
+ const result = await response.json();
2842
+ return result;
2843
+ }
2844
+ async createComparativeExperiment({ name, experimentIds, referenceDatasetId, createdAt, description, metadata, id }) {
2845
+ if (0 === experimentIds.length) throw new Error("At least one experiment is required");
2846
+ if (!referenceDatasetId) referenceDatasetId = (await this.readProject({
2847
+ projectId: experimentIds[0]
2848
+ })).reference_dataset_id;
2849
+ if (null == !referenceDatasetId) throw new Error("A reference dataset is required");
2850
+ const body = {
2851
+ id,
2852
+ name,
2853
+ experiment_ids: experimentIds,
2854
+ reference_dataset_id: referenceDatasetId,
2855
+ description,
2856
+ created_at: (createdAt ?? new Date())?.toISOString(),
2857
+ extra: {}
2858
+ };
2859
+ if (metadata) body.extra["metadata"] = metadata;
2860
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/datasets/comparative`, {
2861
+ method: "POST",
2862
+ headers: {
2863
+ ...this.headers,
2864
+ "Content-Type": "application/json"
2865
+ },
2866
+ body: JSON.stringify(body),
2867
+ signal: AbortSignal.timeout(this.timeout_ms),
2868
+ ...this.fetchOptions
2869
+ });
2870
+ return await response.json();
2871
+ }
2872
+ async *listPresignedFeedbackTokens(runId) {
2873
+ assertUuid(runId);
2874
+ const params = new URLSearchParams({
2875
+ run_id: runId
2876
+ });
2877
+ for await (const tokens of this._getPaginated("/feedback/tokens", params))yield* tokens;
2878
+ }
2879
+ _selectEvalResults(results) {
2880
+ let results_;
2881
+ results_ = "results" in results ? results.results : [
2882
+ results
2883
+ ];
2884
+ return results_;
2885
+ }
2886
+ async _logEvaluationFeedback(evaluatorResponse, run, sourceInfo) {
2887
+ const evalResults = this._selectEvalResults(evaluatorResponse);
2888
+ const feedbacks = [];
2889
+ for (const res of evalResults){
2890
+ let sourceInfo_ = sourceInfo || {};
2891
+ if (res.evaluatorInfo) sourceInfo_ = {
2892
+ ...res.evaluatorInfo,
2893
+ ...sourceInfo_
2894
+ };
2895
+ let runId_ = null;
2896
+ if (res.targetRunId) runId_ = res.targetRunId;
2897
+ else if (run) runId_ = run.id;
2898
+ feedbacks.push(await this.createFeedback(runId_, res.key, {
2899
+ score: res.score,
2900
+ value: res.value,
2901
+ comment: res.comment,
2902
+ correction: res.correction,
2903
+ sourceInfo: sourceInfo_,
2904
+ sourceRunId: res.sourceRunId,
2905
+ feedbackConfig: res.feedbackConfig,
2906
+ feedbackSourceType: "model"
2907
+ }));
2908
+ }
2909
+ return [
2910
+ evalResults,
2911
+ feedbacks
2912
+ ];
2913
+ }
2914
+ async logEvaluationFeedback(evaluatorResponse, run, sourceInfo) {
2915
+ const [results] = await this._logEvaluationFeedback(evaluatorResponse, run, sourceInfo);
2916
+ return results;
2917
+ }
2918
+ async *listAnnotationQueues(options = {}) {
2919
+ const { queueIds, name, nameContains, limit } = options;
2920
+ const params = new URLSearchParams();
2921
+ if (queueIds) queueIds.forEach((id, i)=>{
2922
+ assertUuid(id, `queueIds[${i}]`);
2923
+ params.append("ids", id);
2924
+ });
2925
+ if (name) params.append("name", name);
2926
+ if (nameContains) params.append("name_contains", nameContains);
2927
+ params.append("limit", (void 0 !== limit ? Math.min(limit, 100) : 100).toString());
2928
+ let count = 0;
2929
+ for await (const queues of this._getPaginated("/annotation-queues", params)){
2930
+ yield* queues;
2931
+ count++;
2932
+ if (void 0 !== limit && count >= limit) break;
2933
+ }
2934
+ }
2935
+ async createAnnotationQueue(options) {
2936
+ const { name, description, queueId } = options;
2937
+ const body = {
2938
+ name,
2939
+ description,
2940
+ id: queueId || v4()
2941
+ };
2942
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues`, {
2943
+ method: "POST",
2944
+ headers: {
2945
+ ...this.headers,
2946
+ "Content-Type": "application/json"
2947
+ },
2948
+ body: JSON.stringify(Object.fromEntries(Object.entries(body).filter(([_, v])=>void 0 !== v))),
2949
+ signal: AbortSignal.timeout(this.timeout_ms),
2950
+ ...this.fetchOptions
2951
+ });
2952
+ await raiseForStatus(response, "create annotation queue");
2953
+ const data = await response.json();
2954
+ return data;
2955
+ }
2956
+ async readAnnotationQueue(queueId) {
2957
+ const queueIteratorResult = await this.listAnnotationQueues({
2958
+ queueIds: [
2959
+ queueId
2960
+ ]
2961
+ }).next();
2962
+ if (queueIteratorResult.done) throw new Error(`Annotation queue with ID ${queueId} not found`);
2963
+ return queueIteratorResult.value;
2964
+ }
2965
+ async updateAnnotationQueue(queueId, options) {
2966
+ const { name, description } = options;
2967
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}`, {
2968
+ method: "PATCH",
2969
+ headers: {
2970
+ ...this.headers,
2971
+ "Content-Type": "application/json"
2972
+ },
2973
+ body: JSON.stringify({
2974
+ name,
2975
+ description
2976
+ }),
2977
+ signal: AbortSignal.timeout(this.timeout_ms),
2978
+ ...this.fetchOptions
2979
+ });
2980
+ await raiseForStatus(response, "update annotation queue");
2981
+ }
2982
+ async deleteAnnotationQueue(queueId) {
2983
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}`, {
2984
+ method: "DELETE",
2985
+ headers: {
2986
+ ...this.headers,
2987
+ Accept: "application/json"
2988
+ },
2989
+ signal: AbortSignal.timeout(this.timeout_ms),
2990
+ ...this.fetchOptions
2991
+ });
2992
+ await raiseForStatus(response, "delete annotation queue");
2993
+ }
2994
+ async addRunsToAnnotationQueue(queueId, runIds) {
2995
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}/runs`, {
2996
+ method: "POST",
2997
+ headers: {
2998
+ ...this.headers,
2999
+ "Content-Type": "application/json"
3000
+ },
3001
+ body: JSON.stringify(runIds.map((id, i)=>assertUuid(id, `runIds[${i}]`).toString())),
3002
+ signal: AbortSignal.timeout(this.timeout_ms),
3003
+ ...this.fetchOptions
3004
+ });
3005
+ await raiseForStatus(response, "add runs to annotation queue");
3006
+ }
3007
+ async getRunFromAnnotationQueue(queueId, index) {
3008
+ const baseUrl = `/annotation-queues/${assertUuid(queueId, "queueId")}/run`;
3009
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}${baseUrl}/${index}`, {
3010
+ method: "GET",
3011
+ headers: this.headers,
3012
+ signal: AbortSignal.timeout(this.timeout_ms),
3013
+ ...this.fetchOptions
3014
+ });
3015
+ await raiseForStatus(response, "get run from annotation queue");
3016
+ return await response.json();
3017
+ }
3018
+ async deleteRunFromAnnotationQueue(queueId, queueRunId) {
3019
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}/runs/${assertUuid(queueRunId, "queueRunId")}`, {
3020
+ method: "DELETE",
3021
+ headers: {
3022
+ ...this.headers,
3023
+ Accept: "application/json"
3024
+ },
3025
+ signal: AbortSignal.timeout(this.timeout_ms),
3026
+ ...this.fetchOptions
3027
+ });
3028
+ await raiseForStatus(response, "delete run from annotation queue");
3029
+ }
3030
+ async getSizeFromAnnotationQueue(queueId) {
3031
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}/size`, {
3032
+ method: "GET",
3033
+ headers: this.headers,
3034
+ signal: AbortSignal.timeout(this.timeout_ms),
3035
+ ...this.fetchOptions
3036
+ });
3037
+ await raiseForStatus(response, "get size from annotation queue");
3038
+ return await response.json();
3039
+ }
3040
+ async _currentTenantIsOwner(owner) {
3041
+ const settings = await this._getSettings();
3042
+ return "-" == owner || settings.tenant_handle === owner;
3043
+ }
3044
+ async _ownerConflictError(action, owner) {
3045
+ const settings = await this._getSettings();
3046
+ return new Error(`Cannot ${action} for another tenant.\n
3047
+ Current tenant: ${settings.tenant_handle}\n
3048
+ Requested tenant: ${owner}`);
3049
+ }
3050
+ async _getLatestCommitHash(promptOwnerAndName) {
3051
+ const res = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/commits/${promptOwnerAndName}/?limit=1&offset=0`, {
3052
+ method: "GET",
3053
+ headers: this.headers,
3054
+ signal: AbortSignal.timeout(this.timeout_ms),
3055
+ ...this.fetchOptions
3056
+ });
3057
+ const json = await res.json();
3058
+ if (!res.ok) {
3059
+ const detail = "string" == typeof json.detail ? json.detail : JSON.stringify(json.detail);
3060
+ const error = new Error(`Error ${res.status}: ${res.statusText}\n${detail}`);
3061
+ error.statusCode = res.status;
3062
+ throw error;
3063
+ }
3064
+ if (0 === json.commits.length) return;
3065
+ return json.commits[0].commit_hash;
3066
+ }
3067
+ async _likeOrUnlikePrompt(promptIdentifier, like) {
3068
+ const [owner, promptName, _] = parsePromptIdentifier(promptIdentifier);
3069
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/likes/${owner}/${promptName}`, {
3070
+ method: "POST",
3071
+ body: JSON.stringify({
3072
+ like: like
3073
+ }),
3074
+ headers: {
3075
+ ...this.headers,
3076
+ "Content-Type": "application/json"
3077
+ },
3078
+ signal: AbortSignal.timeout(this.timeout_ms),
3079
+ ...this.fetchOptions
3080
+ });
3081
+ await raiseForStatus(response, `${like ? "like" : "unlike"} prompt`);
3082
+ return await response.json();
3083
+ }
3084
+ async _getPromptUrl(promptIdentifier) {
3085
+ const [owner, promptName, commitHash] = parsePromptIdentifier(promptIdentifier);
3086
+ if (await this._currentTenantIsOwner(owner)) {
3087
+ const settings = await this._getSettings();
3088
+ if ("latest" !== commitHash) return `${this.getHostUrl()}/prompts/${promptName}/${commitHash.substring(0, 8)}?organizationId=${settings.id}`;
3089
+ return `${this.getHostUrl()}/prompts/${promptName}?organizationId=${settings.id}`;
3090
+ }
3091
+ if ("latest" !== commitHash) return `${this.getHostUrl()}/hub/${owner}/${promptName}/${commitHash.substring(0, 8)}`;
3092
+ return `${this.getHostUrl()}/hub/${owner}/${promptName}`;
3093
+ }
3094
+ async promptExists(promptIdentifier) {
3095
+ const prompt = await this.getPrompt(promptIdentifier);
3096
+ return !!prompt;
3097
+ }
3098
+ async likePrompt(promptIdentifier) {
3099
+ return this._likeOrUnlikePrompt(promptIdentifier, true);
3100
+ }
3101
+ async unlikePrompt(promptIdentifier) {
3102
+ return this._likeOrUnlikePrompt(promptIdentifier, false);
3103
+ }
3104
+ async *listCommits(promptOwnerAndName) {
3105
+ for await (const commits of this._getPaginated(`/commits/${promptOwnerAndName}/`, new URLSearchParams(), (res)=>res.commits))yield* commits;
3106
+ }
3107
+ async *listPrompts(options) {
3108
+ const params = new URLSearchParams();
3109
+ params.append("sort_field", options?.sortField ?? "updated_at");
3110
+ params.append("sort_direction", "desc");
3111
+ params.append("is_archived", (!!options?.isArchived).toString());
3112
+ if (options?.isPublic !== void 0) params.append("is_public", options.isPublic.toString());
3113
+ if (options?.query) params.append("query", options.query);
3114
+ for await (const prompts of this._getPaginated("/repos", params, (res)=>res.repos))yield* prompts;
3115
+ }
3116
+ async getPrompt(promptIdentifier) {
3117
+ const [owner, promptName, _] = parsePromptIdentifier(promptIdentifier);
3118
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/repos/${owner}/${promptName}`, {
3119
+ method: "GET",
3120
+ headers: this.headers,
3121
+ signal: AbortSignal.timeout(this.timeout_ms),
3122
+ ...this.fetchOptions
3123
+ });
3124
+ if (404 === response.status) return null;
3125
+ await raiseForStatus(response, "get prompt");
3126
+ const result = await response.json();
3127
+ if (result.repo) return result.repo;
3128
+ return null;
3129
+ }
3130
+ async createPrompt(promptIdentifier, options) {
3131
+ const settings = await this._getSettings();
3132
+ if (options?.isPublic && !settings.tenant_handle) throw new Error(`Cannot create a public prompt without first\n
3133
+ creating a LangChain Hub handle.
3134
+ You can add a handle by creating a public prompt at:\n
3135
+ https://smith.langchain.com/prompts`);
3136
+ const [owner, promptName, _] = parsePromptIdentifier(promptIdentifier);
3137
+ if (!await this._currentTenantIsOwner(owner)) throw await this._ownerConflictError("create a prompt", owner);
3138
+ const data = {
3139
+ repo_handle: promptName,
3140
+ ...options?.description && {
3141
+ description: options.description
3142
+ },
3143
+ ...options?.readme && {
3144
+ readme: options.readme
3145
+ },
3146
+ ...options?.tags && {
3147
+ tags: options.tags
3148
+ },
3149
+ is_public: !!options?.isPublic
3150
+ };
3151
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/repos/`, {
3152
+ method: "POST",
3153
+ headers: {
3154
+ ...this.headers,
3155
+ "Content-Type": "application/json"
3156
+ },
3157
+ body: JSON.stringify(data),
3158
+ signal: AbortSignal.timeout(this.timeout_ms),
3159
+ ...this.fetchOptions
3160
+ });
3161
+ await raiseForStatus(response, "create prompt");
3162
+ const { repo } = await response.json();
3163
+ return repo;
3164
+ }
3165
+ async createCommit(promptIdentifier, object, options) {
3166
+ if (!await this.promptExists(promptIdentifier)) throw new Error("Prompt does not exist, you must create it first.");
3167
+ const [owner, promptName, _] = parsePromptIdentifier(promptIdentifier);
3168
+ const resolvedParentCommitHash = options?.parentCommitHash !== "latest" && options?.parentCommitHash ? options?.parentCommitHash : await this._getLatestCommitHash(`${owner}/${promptName}`);
3169
+ const payload = {
3170
+ manifest: JSON.parse(JSON.stringify(object)),
3171
+ parent_commit: resolvedParentCommitHash
3172
+ };
3173
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/commits/${owner}/${promptName}`, {
3174
+ method: "POST",
3175
+ headers: {
3176
+ ...this.headers,
3177
+ "Content-Type": "application/json"
3178
+ },
3179
+ body: JSON.stringify(payload),
3180
+ signal: AbortSignal.timeout(this.timeout_ms),
3181
+ ...this.fetchOptions
3182
+ });
3183
+ await raiseForStatus(response, "create commit");
3184
+ const result = await response.json();
3185
+ return this._getPromptUrl(`${owner}/${promptName}${result.commit_hash ? `:${result.commit_hash}` : ""}`);
3186
+ }
3187
+ async updateExamplesMultipart(datasetId, updates = []) {
3188
+ if (!await this._getMultiPartSupport()) throw new Error("Your LangSmith version does not allow using the multipart examples endpoint, please update to the latest version.");
3189
+ const formData = new FormData();
3190
+ for (const example of updates){
3191
+ const exampleId = example.id;
3192
+ const exampleBody = {
3193
+ ...example.metadata && {
3194
+ metadata: example.metadata
3195
+ },
3196
+ ...example.split && {
3197
+ split: example.split
3198
+ }
3199
+ };
3200
+ const stringifiedExample = serialize(exampleBody);
3201
+ const exampleBlob = new Blob([
3202
+ stringifiedExample
3203
+ ], {
3204
+ type: "application/json"
3205
+ });
3206
+ formData.append(exampleId, exampleBlob);
3207
+ if (example.inputs) {
3208
+ const stringifiedInputs = serialize(example.inputs);
3209
+ const inputsBlob = new Blob([
3210
+ stringifiedInputs
3211
+ ], {
3212
+ type: "application/json"
3213
+ });
3214
+ formData.append(`${exampleId}.inputs`, inputsBlob);
3215
+ }
3216
+ if (example.outputs) {
3217
+ const stringifiedOutputs = serialize(example.outputs);
3218
+ const outputsBlob = new Blob([
3219
+ stringifiedOutputs
3220
+ ], {
3221
+ type: "application/json"
3222
+ });
3223
+ formData.append(`${exampleId}.outputs`, outputsBlob);
3224
+ }
3225
+ if (example.attachments) for (const [name, attachment] of Object.entries(example.attachments)){
3226
+ let mimeType;
3227
+ let data;
3228
+ if (Array.isArray(attachment)) [mimeType, data] = attachment;
3229
+ else {
3230
+ mimeType = attachment.mimeType;
3231
+ data = attachment.data;
3232
+ }
3233
+ const attachmentBlob = new Blob([
3234
+ data
3235
+ ], {
3236
+ type: `${mimeType}; length=${data.byteLength}`
3237
+ });
3238
+ formData.append(`${exampleId}.attachment.${name}`, attachmentBlob);
3239
+ }
3240
+ if (example.attachments_operations) {
3241
+ const stringifiedAttachmentsOperations = serialize(example.attachments_operations);
3242
+ const attachmentsOperationsBlob = new Blob([
3243
+ stringifiedAttachmentsOperations
3244
+ ], {
3245
+ type: "application/json"
3246
+ });
3247
+ formData.append(`${exampleId}.attachments_operations`, attachmentsOperationsBlob);
3248
+ }
3249
+ }
3250
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/v1/platform/datasets/${datasetId}/examples`, {
3251
+ method: "PATCH",
3252
+ headers: this.headers,
3253
+ body: formData
3254
+ });
3255
+ const result = await response.json();
3256
+ return result;
3257
+ }
3258
+ async uploadExamplesMultipart(datasetId, uploads = []) {
3259
+ if (!await this._getMultiPartSupport()) throw new Error("Your LangSmith version does not allow using the multipart examples endpoint, please update to the latest version.");
3260
+ const formData = new FormData();
3261
+ for (const example of uploads){
3262
+ const exampleId = (example.id ?? v4()).toString();
3263
+ const exampleBody = {
3264
+ created_at: example.created_at,
3265
+ ...example.metadata && {
3266
+ metadata: example.metadata
3267
+ },
3268
+ ...example.split && {
3269
+ split: example.split
3270
+ }
3271
+ };
3272
+ const stringifiedExample = serialize(exampleBody);
3273
+ const exampleBlob = new Blob([
3274
+ stringifiedExample
3275
+ ], {
3276
+ type: "application/json"
3277
+ });
3278
+ formData.append(exampleId, exampleBlob);
3279
+ const stringifiedInputs = serialize(example.inputs);
3280
+ const inputsBlob = new Blob([
3281
+ stringifiedInputs
3282
+ ], {
3283
+ type: "application/json"
3284
+ });
3285
+ formData.append(`${exampleId}.inputs`, inputsBlob);
3286
+ if (example.outputs) {
3287
+ const stringifiedOutputs = serialize(example.outputs);
3288
+ const outputsBlob = new Blob([
3289
+ stringifiedOutputs
3290
+ ], {
3291
+ type: "application/json"
3292
+ });
3293
+ formData.append(`${exampleId}.outputs`, outputsBlob);
3294
+ }
3295
+ if (example.attachments) for (const [name, attachment] of Object.entries(example.attachments)){
3296
+ let mimeType;
3297
+ let data;
3298
+ if (Array.isArray(attachment)) [mimeType, data] = attachment;
3299
+ else {
3300
+ mimeType = attachment.mimeType;
3301
+ data = attachment.data;
3302
+ }
3303
+ const attachmentBlob = new Blob([
3304
+ data
3305
+ ], {
3306
+ type: `${mimeType}; length=${data.byteLength}`
3307
+ });
3308
+ formData.append(`${exampleId}.attachment.${name}`, attachmentBlob);
3309
+ }
3310
+ }
3311
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/v1/platform/datasets/${datasetId}/examples`, {
3312
+ method: "POST",
3313
+ headers: this.headers,
3314
+ body: formData
3315
+ });
3316
+ const result = await response.json();
3317
+ return result;
3318
+ }
3319
+ async updatePrompt(promptIdentifier, options) {
3320
+ if (!await this.promptExists(promptIdentifier)) throw new Error("Prompt does not exist, you must create it first.");
3321
+ const [owner, promptName] = parsePromptIdentifier(promptIdentifier);
3322
+ if (!await this._currentTenantIsOwner(owner)) throw await this._ownerConflictError("update a prompt", owner);
3323
+ const payload = {};
3324
+ if (options?.description !== void 0) payload.description = options.description;
3325
+ if (options?.readme !== void 0) payload.readme = options.readme;
3326
+ if (options?.tags !== void 0) payload.tags = options.tags;
3327
+ if (options?.isPublic !== void 0) payload.is_public = options.isPublic;
3328
+ if (options?.isArchived !== void 0) payload.is_archived = options.isArchived;
3329
+ if (0 === Object.keys(payload).length) throw new Error("No valid update options provided");
3330
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/repos/${owner}/${promptName}`, {
3331
+ method: "PATCH",
3332
+ body: JSON.stringify(payload),
3333
+ headers: {
3334
+ ...this.headers,
3335
+ "Content-Type": "application/json"
3336
+ },
3337
+ signal: AbortSignal.timeout(this.timeout_ms),
3338
+ ...this.fetchOptions
3339
+ });
3340
+ await raiseForStatus(response, "update prompt");
3341
+ return response.json();
3342
+ }
3343
+ async deletePrompt(promptIdentifier) {
3344
+ if (!await this.promptExists(promptIdentifier)) throw new Error("Prompt does not exist, you must create it first.");
3345
+ const [owner, promptName, _] = parsePromptIdentifier(promptIdentifier);
3346
+ if (!await this._currentTenantIsOwner(owner)) throw await this._ownerConflictError("delete a prompt", owner);
3347
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/repos/${owner}/${promptName}`, {
3348
+ method: "DELETE",
3349
+ headers: this.headers,
3350
+ signal: AbortSignal.timeout(this.timeout_ms),
3351
+ ...this.fetchOptions
3352
+ });
3353
+ return await response.json();
3354
+ }
3355
+ async pullPromptCommit(promptIdentifier, options) {
3356
+ const [owner, promptName, commitHash] = parsePromptIdentifier(promptIdentifier);
3357
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/commits/${owner}/${promptName}/${commitHash}${options?.includeModel ? "?include_model=true" : ""}`, {
3358
+ method: "GET",
3359
+ headers: this.headers,
3360
+ signal: AbortSignal.timeout(this.timeout_ms),
3361
+ ...this.fetchOptions
3362
+ });
3363
+ await raiseForStatus(response, "pull prompt commit");
3364
+ const result = await response.json();
3365
+ return {
3366
+ owner,
3367
+ repo: promptName,
3368
+ commit_hash: result.commit_hash,
3369
+ manifest: result.manifest,
3370
+ examples: result.examples
3371
+ };
3372
+ }
3373
+ async _pullPrompt(promptIdentifier, options) {
3374
+ const promptObject = await this.pullPromptCommit(promptIdentifier, {
3375
+ includeModel: options?.includeModel
3376
+ });
3377
+ const prompt = JSON.stringify(promptObject.manifest);
3378
+ return prompt;
3379
+ }
3380
+ async pushPrompt(promptIdentifier, options) {
3381
+ if (await this.promptExists(promptIdentifier)) {
3382
+ if (options && Object.keys(options).some((key)=>"object" !== key)) await this.updatePrompt(promptIdentifier, {
3383
+ description: options?.description,
3384
+ readme: options?.readme,
3385
+ tags: options?.tags,
3386
+ isPublic: options?.isPublic
3387
+ });
3388
+ } else await this.createPrompt(promptIdentifier, {
3389
+ description: options?.description,
3390
+ readme: options?.readme,
3391
+ tags: options?.tags,
3392
+ isPublic: options?.isPublic
3393
+ });
3394
+ if (!options?.object) return await this._getPromptUrl(promptIdentifier);
3395
+ const url = await this.createCommit(promptIdentifier, options?.object, {
3396
+ parentCommitHash: options?.parentCommitHash
3397
+ });
3398
+ return url;
3399
+ }
3400
+ async clonePublicDataset(tokenOrUrl, options = {}) {
3401
+ const { sourceApiUrl = this.apiUrl, datasetName } = options;
3402
+ const [parsedApiUrl, tokenUuid] = this.parseTokenOrUrl(tokenOrUrl, sourceApiUrl);
3403
+ const sourceClient = new Client({
3404
+ apiUrl: parsedApiUrl,
3405
+ apiKey: "placeholder"
3406
+ });
3407
+ const ds = await sourceClient.readSharedDataset(tokenUuid);
3408
+ const finalDatasetName = datasetName || ds.name;
3409
+ try {
3410
+ if (await this.hasDataset({
3411
+ datasetId: finalDatasetName
3412
+ })) return void console.log(`Dataset ${finalDatasetName} already exists in your tenant. Skipping.`);
3413
+ } catch (_) {}
3414
+ const examples = await sourceClient.listSharedExamples(tokenUuid);
3415
+ const dataset = await this.createDataset(finalDatasetName, {
3416
+ description: ds.description,
3417
+ dataType: ds.data_type || "kv",
3418
+ inputsSchema: ds.inputs_schema_definition ?? void 0,
3419
+ outputsSchema: ds.outputs_schema_definition ?? void 0
3420
+ });
3421
+ try {
3422
+ await this.createExamples({
3423
+ inputs: examples.map((e)=>e.inputs),
3424
+ outputs: examples.flatMap((e)=>e.outputs ? [
3425
+ e.outputs
3426
+ ] : []),
3427
+ datasetId: dataset.id
3428
+ });
3429
+ } catch (e) {
3430
+ console.error(`An error occurred while creating dataset ${finalDatasetName}. You should delete it manually.`);
3431
+ throw e;
3432
+ }
3433
+ }
3434
+ parseTokenOrUrl(urlOrToken, apiUrl, numParts = 2, kind = "dataset") {
3435
+ try {
3436
+ assertUuid(urlOrToken);
3437
+ return [
3438
+ apiUrl,
3439
+ urlOrToken
3440
+ ];
3441
+ } catch (_) {}
3442
+ try {
3443
+ const parsedUrl = new URL(urlOrToken);
3444
+ const pathParts = parsedUrl.pathname.split("/").filter((part)=>"" !== part);
3445
+ if (pathParts.length >= numParts) {
3446
+ const tokenUuid = pathParts[pathParts.length - numParts];
3447
+ return [
3448
+ apiUrl,
3449
+ tokenUuid
3450
+ ];
3451
+ }
3452
+ throw new Error(`Invalid public ${kind} URL: ${urlOrToken}`);
3453
+ } catch (error) {
3454
+ throw new Error(`Invalid public ${kind} URL or token: ${urlOrToken}`);
3455
+ }
3456
+ }
3457
+ awaitPendingTraceBatches() {
3458
+ if (this.manualFlushMode) {
3459
+ console.warn("[WARNING]: When tracing in manual flush mode, you must call `await client.flush()` manually to submit trace batches.");
3460
+ return Promise.resolve();
3461
+ }
3462
+ return Promise.all([
3463
+ ...this.autoBatchQueue.items.map(({ itemPromise })=>itemPromise),
3464
+ this.batchIngestCaller.queue.onIdle()
3465
+ ]);
3466
+ }
3467
+ }
3468
+ const __version__ = "0.3.7";
3469
+ let globalEnv;
3470
+ const isBrowser = ()=>"undefined" != typeof window && void 0 !== window.document;
3471
+ const isWebWorker = ()=>"object" == typeof globalThis && globalThis.constructor && "DedicatedWorkerGlobalScope" === globalThis.constructor.name;
3472
+ const isJsDom = ()=>"undefined" != typeof window && "nodejs" === window.name || "undefined" != typeof navigator && (navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom"));
3473
+ const isDeno = ()=>"undefined" != typeof Deno;
3474
+ const isNode = ()=>"undefined" != typeof process && void 0 !== process.versions && void 0 !== process.versions.node && !isDeno();
3475
+ const getEnv = ()=>{
3476
+ if (globalEnv) return globalEnv;
3477
+ globalEnv = isBrowser() ? "browser" : isNode() ? "node" : isWebWorker() ? "webworker" : isJsDom() ? "jsdom" : isDeno() ? "deno" : "other";
3478
+ return globalEnv;
3479
+ };
3480
+ let runtimeEnvironment;
3481
+ function getRuntimeEnvironment() {
3482
+ if (void 0 === runtimeEnvironment) {
3483
+ const env = getEnv();
3484
+ const releaseEnv = getShas();
3485
+ runtimeEnvironment = {
3486
+ library: "langsmith",
3487
+ runtime: env,
3488
+ sdk: "langsmith-js",
3489
+ sdk_version: __version__,
3490
+ ...releaseEnv
3491
+ };
3492
+ }
3493
+ return runtimeEnvironment;
3494
+ }
3495
+ function getLangChainEnvVarsMetadata() {
3496
+ const allEnvVars = getEnvironmentVariables() || {};
3497
+ const envVars = {};
3498
+ const excluded = [
3499
+ "LANGCHAIN_API_KEY",
3500
+ "LANGCHAIN_ENDPOINT",
3501
+ "LANGCHAIN_TRACING_V2",
3502
+ "LANGCHAIN_PROJECT",
3503
+ "LANGCHAIN_SESSION",
3504
+ "LANGSMITH_API_KEY",
3505
+ "LANGSMITH_ENDPOINT",
3506
+ "LANGSMITH_TRACING_V2",
3507
+ "LANGSMITH_PROJECT",
3508
+ "LANGSMITH_SESSION"
3509
+ ];
3510
+ for (const [key, value] of Object.entries(allEnvVars))if ((key.startsWith("LANGCHAIN_") || key.startsWith("LANGSMITH_")) && "string" == typeof value && !excluded.includes(key) && !key.toLowerCase().includes("key") && !key.toLowerCase().includes("secret") && !key.toLowerCase().includes("token")) if ("LANGCHAIN_REVISION_ID" === key) envVars["revision_id"] = value;
3511
+ else envVars[key] = value;
3512
+ return envVars;
3513
+ }
3514
+ function getEnvironmentVariables() {
3515
+ try {
3516
+ if ("undefined" != typeof process && process.env) return Object.entries(process.env).reduce((acc, [key, value])=>{
3517
+ acc[key] = String(value);
3518
+ return acc;
3519
+ }, {});
3520
+ return;
3521
+ } catch (e) {
3522
+ return;
3523
+ }
3524
+ }
3525
+ function getEnvironmentVariable(name) {
3526
+ try {
3527
+ return "undefined" != typeof process ? process.env?.[name] : void 0;
3528
+ } catch (e) {
3529
+ return;
3530
+ }
3531
+ }
3532
+ function getLangSmithEnvironmentVariable(name) {
3533
+ return getEnvironmentVariable(`LANGSMITH_${name}`) || getEnvironmentVariable(`LANGCHAIN_${name}`);
3534
+ }
3535
+ let cachedCommitSHAs;
3536
+ function getShas() {
3537
+ if (void 0 !== cachedCommitSHAs) return cachedCommitSHAs;
3538
+ const common_release_envs = [
3539
+ "VERCEL_GIT_COMMIT_SHA",
3540
+ "NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA",
3541
+ "COMMIT_REF",
3542
+ "RENDER_GIT_COMMIT",
3543
+ "CI_COMMIT_SHA",
3544
+ "CIRCLE_SHA1",
3545
+ "CF_PAGES_COMMIT_SHA",
3546
+ "REACT_APP_GIT_SHA",
3547
+ "SOURCE_VERSION",
3548
+ "GITHUB_SHA",
3549
+ "TRAVIS_COMMIT",
3550
+ "GIT_COMMIT",
3551
+ "BUILD_VCS_NUMBER",
3552
+ "bamboo_planRepository_revision",
3553
+ "Build.SourceVersion",
3554
+ "BITBUCKET_COMMIT",
3555
+ "DRONE_COMMIT_SHA",
3556
+ "SEMAPHORE_GIT_SHA",
3557
+ "BUILDKITE_COMMIT"
3558
+ ];
3559
+ const shas = {};
3560
+ for (const env of common_release_envs){
3561
+ const envVar = getEnvironmentVariable(env);
3562
+ if (void 0 !== envVar) shas[env] = envVar;
3563
+ }
3564
+ cachedCommitSHAs = shas;
3565
+ return shas;
3566
+ }
3567
+ const isTracingEnabled = (tracingEnabled)=>{
3568
+ if (void 0 !== tracingEnabled) return tracingEnabled;
3569
+ const envVars = [
3570
+ "TRACING_V2",
3571
+ "TRACING"
3572
+ ];
3573
+ return !!envVars.find((envVar)=>"true" === getLangSmithEnvironmentVariable(envVar));
3574
+ };
3575
+ const _LC_CONTEXT_VARIABLES_KEY = Symbol.for("lc:context_variables");
3576
+ function stripNonAlphanumeric(input) {
3577
+ return input.replace(/[-:.]/g, "");
3578
+ }
3579
+ function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
3580
+ const paddedOrder = executionOrder.toFixed(0).slice(0, 3).padStart(3, "0");
3581
+ return stripNonAlphanumeric(`${new Date(epoch).toISOString().slice(0, -1)}${paddedOrder}Z`) + runId;
3582
+ }
3583
+ class Baggage {
3584
+ constructor(metadata, tags){
3585
+ Object.defineProperty(this, "metadata", {
3586
+ enumerable: true,
3587
+ configurable: true,
3588
+ writable: true,
3589
+ value: void 0
3590
+ });
3591
+ Object.defineProperty(this, "tags", {
3592
+ enumerable: true,
3593
+ configurable: true,
3594
+ writable: true,
3595
+ value: void 0
3596
+ });
3597
+ this.metadata = metadata;
3598
+ this.tags = tags;
3599
+ }
3600
+ static fromHeader(value) {
3601
+ const items = value.split(",");
3602
+ let metadata = {};
3603
+ let tags = [];
3604
+ for (const item of items){
3605
+ const [key, uriValue] = item.split("=");
3606
+ const value = decodeURIComponent(uriValue);
3607
+ if ("langsmith-metadata" === key) metadata = JSON.parse(value);
3608
+ else if ("langsmith-tags" === key) tags = value.split(",");
3609
+ }
3610
+ return new Baggage(metadata, tags);
3611
+ }
3612
+ toHeader() {
3613
+ const items = [];
3614
+ if (this.metadata && Object.keys(this.metadata).length > 0) items.push(`langsmith-metadata=${encodeURIComponent(JSON.stringify(this.metadata))}`);
3615
+ if (this.tags && this.tags.length > 0) items.push(`langsmith-tags=${encodeURIComponent(this.tags.join(","))}`);
3616
+ return items.join(",");
3617
+ }
3618
+ }
3619
+ class RunTree {
3620
+ constructor(originalConfig){
3621
+ Object.defineProperty(this, "id", {
3622
+ enumerable: true,
3623
+ configurable: true,
3624
+ writable: true,
3625
+ value: void 0
3626
+ });
3627
+ Object.defineProperty(this, "name", {
3628
+ enumerable: true,
3629
+ configurable: true,
3630
+ writable: true,
3631
+ value: void 0
3632
+ });
3633
+ Object.defineProperty(this, "run_type", {
3634
+ enumerable: true,
3635
+ configurable: true,
3636
+ writable: true,
3637
+ value: void 0
3638
+ });
3639
+ Object.defineProperty(this, "project_name", {
3640
+ enumerable: true,
3641
+ configurable: true,
3642
+ writable: true,
3643
+ value: void 0
3644
+ });
3645
+ Object.defineProperty(this, "parent_run", {
3646
+ enumerable: true,
3647
+ configurable: true,
3648
+ writable: true,
3649
+ value: void 0
3650
+ });
3651
+ Object.defineProperty(this, "child_runs", {
3652
+ enumerable: true,
3653
+ configurable: true,
3654
+ writable: true,
3655
+ value: void 0
3656
+ });
3657
+ Object.defineProperty(this, "start_time", {
3658
+ enumerable: true,
3659
+ configurable: true,
3660
+ writable: true,
3661
+ value: void 0
3662
+ });
3663
+ Object.defineProperty(this, "end_time", {
3664
+ enumerable: true,
3665
+ configurable: true,
3666
+ writable: true,
3667
+ value: void 0
3668
+ });
3669
+ Object.defineProperty(this, "extra", {
3670
+ enumerable: true,
3671
+ configurable: true,
3672
+ writable: true,
3673
+ value: void 0
3674
+ });
3675
+ Object.defineProperty(this, "tags", {
3676
+ enumerable: true,
3677
+ configurable: true,
3678
+ writable: true,
3679
+ value: void 0
3680
+ });
3681
+ Object.defineProperty(this, "error", {
3682
+ enumerable: true,
3683
+ configurable: true,
3684
+ writable: true,
3685
+ value: void 0
3686
+ });
3687
+ Object.defineProperty(this, "serialized", {
3688
+ enumerable: true,
3689
+ configurable: true,
3690
+ writable: true,
3691
+ value: void 0
3692
+ });
3693
+ Object.defineProperty(this, "inputs", {
3694
+ enumerable: true,
3695
+ configurable: true,
3696
+ writable: true,
3697
+ value: void 0
3698
+ });
3699
+ Object.defineProperty(this, "outputs", {
3700
+ enumerable: true,
3701
+ configurable: true,
3702
+ writable: true,
3703
+ value: void 0
3704
+ });
3705
+ Object.defineProperty(this, "reference_example_id", {
3706
+ enumerable: true,
3707
+ configurable: true,
3708
+ writable: true,
3709
+ value: void 0
3710
+ });
3711
+ Object.defineProperty(this, "client", {
3712
+ enumerable: true,
3713
+ configurable: true,
3714
+ writable: true,
3715
+ value: void 0
3716
+ });
3717
+ Object.defineProperty(this, "events", {
3718
+ enumerable: true,
3719
+ configurable: true,
3720
+ writable: true,
3721
+ value: void 0
3722
+ });
3723
+ Object.defineProperty(this, "trace_id", {
3724
+ enumerable: true,
3725
+ configurable: true,
3726
+ writable: true,
3727
+ value: void 0
3728
+ });
3729
+ Object.defineProperty(this, "dotted_order", {
3730
+ enumerable: true,
3731
+ configurable: true,
3732
+ writable: true,
3733
+ value: void 0
3734
+ });
3735
+ Object.defineProperty(this, "tracingEnabled", {
3736
+ enumerable: true,
3737
+ configurable: true,
3738
+ writable: true,
3739
+ value: void 0
3740
+ });
3741
+ Object.defineProperty(this, "execution_order", {
3742
+ enumerable: true,
3743
+ configurable: true,
3744
+ writable: true,
3745
+ value: void 0
3746
+ });
3747
+ Object.defineProperty(this, "child_execution_order", {
3748
+ enumerable: true,
3749
+ configurable: true,
3750
+ writable: true,
3751
+ value: void 0
3752
+ });
3753
+ Object.defineProperty(this, "attachments", {
3754
+ enumerable: true,
3755
+ configurable: true,
3756
+ writable: true,
3757
+ value: void 0
3758
+ });
3759
+ if (run_trees_isRunTree(originalConfig)) return void Object.assign(this, {
3760
+ ...originalConfig
3761
+ });
3762
+ const defaultConfig = RunTree.getDefaultConfig();
3763
+ const { metadata, ...config } = originalConfig;
3764
+ const client = config.client ?? RunTree.getSharedClient();
3765
+ const dedupedMetadata = {
3766
+ ...metadata,
3767
+ ...config?.extra?.metadata
3768
+ };
3769
+ config.extra = {
3770
+ ...config.extra,
3771
+ metadata: dedupedMetadata
3772
+ };
3773
+ Object.assign(this, {
3774
+ ...defaultConfig,
3775
+ ...config,
3776
+ client
3777
+ });
3778
+ if (!this.trace_id) if (this.parent_run) this.trace_id = this.parent_run.trace_id ?? this.id;
3779
+ else this.trace_id = this.id;
3780
+ this.execution_order ??= 1;
3781
+ this.child_execution_order ??= 1;
3782
+ if (!this.dotted_order) {
3783
+ const currentDottedOrder = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
3784
+ if (this.parent_run) this.dotted_order = this.parent_run.dotted_order + "." + currentDottedOrder;
3785
+ else this.dotted_order = currentDottedOrder;
3786
+ }
3787
+ }
3788
+ static getDefaultConfig() {
3789
+ return {
3790
+ id: v4(),
3791
+ run_type: "chain",
3792
+ project_name: getLangSmithEnvironmentVariable("PROJECT") ?? getEnvironmentVariable("LANGCHAIN_SESSION") ?? "default",
3793
+ child_runs: [],
3794
+ api_url: getEnvironmentVariable("LANGCHAIN_ENDPOINT") ?? "http://localhost:1984",
3795
+ api_key: getEnvironmentVariable("LANGCHAIN_API_KEY"),
3796
+ caller_options: {},
3797
+ start_time: Date.now(),
3798
+ serialized: {},
3799
+ inputs: {},
3800
+ extra: {}
3801
+ };
3802
+ }
3803
+ static getSharedClient() {
3804
+ if (!RunTree.sharedClient) RunTree.sharedClient = new Client();
3805
+ return RunTree.sharedClient;
3806
+ }
3807
+ createChild(config) {
3808
+ const child_execution_order = this.child_execution_order + 1;
3809
+ const child = new RunTree({
3810
+ ...config,
3811
+ parent_run: this,
3812
+ project_name: this.project_name,
3813
+ client: this.client,
3814
+ tracingEnabled: this.tracingEnabled,
3815
+ execution_order: child_execution_order,
3816
+ child_execution_order: child_execution_order
3817
+ });
3818
+ if (_LC_CONTEXT_VARIABLES_KEY in this) child[_LC_CONTEXT_VARIABLES_KEY] = this[_LC_CONTEXT_VARIABLES_KEY];
3819
+ const LC_CHILD = Symbol.for("lc:child_config");
3820
+ const presentConfig = config.extra?.[LC_CHILD] ?? this.extra[LC_CHILD];
3821
+ if (isRunnableConfigLike(presentConfig)) {
3822
+ const newConfig = {
3823
+ ...presentConfig
3824
+ };
3825
+ const callbacks = isCallbackManagerLike(newConfig.callbacks) ? newConfig.callbacks.copy?.() : void 0;
3826
+ if (callbacks) {
3827
+ Object.assign(callbacks, {
3828
+ _parentRunId: child.id
3829
+ });
3830
+ callbacks.handlers?.find(isLangChainTracerLike)?.updateFromRunTree?.(child);
3831
+ newConfig.callbacks = callbacks;
3832
+ }
3833
+ child.extra[LC_CHILD] = newConfig;
3834
+ }
3835
+ const visited = new Set();
3836
+ let current = this;
3837
+ while(null != current && !visited.has(current.id)){
3838
+ visited.add(current.id);
3839
+ current.child_execution_order = Math.max(current.child_execution_order, child_execution_order);
3840
+ current = current.parent_run;
3841
+ }
3842
+ this.child_runs.push(child);
3843
+ return child;
3844
+ }
3845
+ async end(outputs, error, endTime = Date.now(), metadata) {
3846
+ this.outputs = this.outputs ?? outputs;
3847
+ this.error = this.error ?? error;
3848
+ this.end_time = this.end_time ?? endTime;
3849
+ if (metadata && Object.keys(metadata).length > 0) this.extra = this.extra ? {
3850
+ ...this.extra,
3851
+ metadata: {
3852
+ ...this.extra.metadata,
3853
+ ...metadata
3854
+ }
3855
+ } : {
3856
+ metadata
3857
+ };
3858
+ }
3859
+ _convertToCreate(run, runtimeEnv, excludeChildRuns = true) {
3860
+ const runExtra = run.extra ?? {};
3861
+ if (!runExtra.runtime) runExtra.runtime = {};
3862
+ if (runtimeEnv) {
3863
+ for (const [k, v] of Object.entries(runtimeEnv))if (!runExtra.runtime[k]) runExtra.runtime[k] = v;
3864
+ }
3865
+ let child_runs;
3866
+ let parent_run_id;
3867
+ if (excludeChildRuns) {
3868
+ parent_run_id = run.parent_run?.id;
3869
+ child_runs = [];
3870
+ } else {
3871
+ child_runs = run.child_runs.map((child_run)=>this._convertToCreate(child_run, runtimeEnv, excludeChildRuns));
3872
+ parent_run_id = void 0;
3873
+ }
3874
+ const persistedRun = {
3875
+ id: run.id,
3876
+ name: run.name,
3877
+ start_time: run.start_time,
3878
+ end_time: run.end_time,
3879
+ run_type: run.run_type,
3880
+ reference_example_id: run.reference_example_id,
3881
+ extra: runExtra,
3882
+ serialized: run.serialized,
3883
+ error: run.error,
3884
+ inputs: run.inputs,
3885
+ outputs: run.outputs,
3886
+ session_name: run.project_name,
3887
+ child_runs: child_runs,
3888
+ parent_run_id: parent_run_id,
3889
+ trace_id: run.trace_id,
3890
+ dotted_order: run.dotted_order,
3891
+ tags: run.tags,
3892
+ attachments: run.attachments
3893
+ };
3894
+ return persistedRun;
3895
+ }
3896
+ async postRun(excludeChildRuns = true) {
3897
+ try {
3898
+ const runtimeEnv = getRuntimeEnvironment();
3899
+ const runCreate = await this._convertToCreate(this, runtimeEnv, true);
3900
+ await this.client.createRun(runCreate);
3901
+ if (!excludeChildRuns) {
3902
+ warnOnce("Posting with excludeChildRuns=false is deprecated and will be removed in a future version.");
3903
+ for (const childRun of this.child_runs)await childRun.postRun(false);
3904
+ }
3905
+ } catch (error) {
3906
+ console.error(`Error in postRun for run ${this.id}:`, error);
3907
+ }
3908
+ }
3909
+ async patchRun() {
3910
+ try {
3911
+ const runUpdate = {
3912
+ end_time: this.end_time,
3913
+ error: this.error,
3914
+ inputs: this.inputs,
3915
+ outputs: this.outputs,
3916
+ parent_run_id: this.parent_run?.id,
3917
+ reference_example_id: this.reference_example_id,
3918
+ extra: this.extra,
3919
+ events: this.events,
3920
+ dotted_order: this.dotted_order,
3921
+ trace_id: this.trace_id,
3922
+ tags: this.tags,
3923
+ attachments: this.attachments
3924
+ };
3925
+ await this.client.updateRun(this.id, runUpdate);
3926
+ } catch (error) {
3927
+ console.error(`Error in patchRun for run ${this.id}`, error);
3928
+ }
3929
+ }
3930
+ toJSON() {
3931
+ return this._convertToCreate(this, void 0, false);
3932
+ }
3933
+ static fromRunnableConfig(parentConfig, props) {
3934
+ const callbackManager = parentConfig?.callbacks;
3935
+ let parentRun;
3936
+ let projectName;
3937
+ let client;
3938
+ let tracingEnabled = isTracingEnabled();
3939
+ if (callbackManager) {
3940
+ const parentRunId = callbackManager?.getParentRunId?.() ?? "";
3941
+ const langChainTracer = callbackManager?.handlers?.find((handler)=>handler?.name == "langchain_tracer");
3942
+ parentRun = langChainTracer?.getRun?.(parentRunId);
3943
+ projectName = langChainTracer?.projectName;
3944
+ client = langChainTracer?.client;
3945
+ tracingEnabled = tracingEnabled || !!langChainTracer;
3946
+ }
3947
+ if (!parentRun) return new RunTree({
3948
+ ...props,
3949
+ client,
3950
+ tracingEnabled,
3951
+ project_name: projectName
3952
+ });
3953
+ const parentRunTree = new RunTree({
3954
+ name: parentRun.name,
3955
+ id: parentRun.id,
3956
+ trace_id: parentRun.trace_id,
3957
+ dotted_order: parentRun.dotted_order,
3958
+ client,
3959
+ tracingEnabled,
3960
+ project_name: projectName,
3961
+ tags: [
3962
+ ...new Set((parentRun?.tags ?? []).concat(parentConfig?.tags ?? []))
3963
+ ],
3964
+ extra: {
3965
+ metadata: {
3966
+ ...parentRun?.extra?.metadata,
3967
+ ...parentConfig?.metadata
3968
+ }
3969
+ }
3970
+ });
3971
+ return parentRunTree.createChild(props);
3972
+ }
3973
+ static fromDottedOrder(dottedOrder) {
3974
+ return this.fromHeaders({
3975
+ "langsmith-trace": dottedOrder
3976
+ });
3977
+ }
3978
+ static fromHeaders(headers, inheritArgs) {
3979
+ const rawHeaders = "get" in headers && "function" == typeof headers.get ? {
3980
+ "langsmith-trace": headers.get("langsmith-trace"),
3981
+ baggage: headers.get("baggage")
3982
+ } : headers;
3983
+ const headerTrace = rawHeaders["langsmith-trace"];
3984
+ if (!headerTrace || "string" != typeof headerTrace) return;
3985
+ const parentDottedOrder = headerTrace.trim();
3986
+ const parsedDottedOrder = parentDottedOrder.split(".").map((part)=>{
3987
+ const [strTime, uuid] = part.split("Z");
3988
+ return {
3989
+ strTime,
3990
+ time: Date.parse(strTime + "Z"),
3991
+ uuid
3992
+ };
3993
+ });
3994
+ const traceId = parsedDottedOrder[0].uuid;
3995
+ const config = {
3996
+ ...inheritArgs,
3997
+ name: inheritArgs?.["name"] ?? "parent",
3998
+ run_type: inheritArgs?.["run_type"] ?? "chain",
3999
+ start_time: inheritArgs?.["start_time"] ?? Date.now(),
4000
+ id: parsedDottedOrder.at(-1)?.uuid,
4001
+ trace_id: traceId,
4002
+ dotted_order: parentDottedOrder
4003
+ };
4004
+ if (rawHeaders["baggage"] && "string" == typeof rawHeaders["baggage"]) {
4005
+ const baggage = Baggage.fromHeader(rawHeaders["baggage"]);
4006
+ config.metadata = baggage.metadata;
4007
+ config.tags = baggage.tags;
4008
+ }
4009
+ return new RunTree(config);
4010
+ }
4011
+ toHeaders(headers) {
4012
+ const result = {
4013
+ "langsmith-trace": this.dotted_order,
4014
+ baggage: new Baggage(this.extra?.metadata, this.tags).toHeader()
4015
+ };
4016
+ if (headers) for (const [key, value] of Object.entries(result))headers.set(key, value);
4017
+ return result;
4018
+ }
4019
+ }
4020
+ Object.defineProperty(RunTree, "sharedClient", {
4021
+ enumerable: true,
4022
+ configurable: true,
4023
+ writable: true,
4024
+ value: null
4025
+ });
4026
+ function run_trees_isRunTree(x) {
4027
+ return void 0 !== x && "function" == typeof x.createChild && "function" == typeof x.postRun;
4028
+ }
4029
+ function isLangChainTracerLike(x) {
4030
+ return "object" == typeof x && null != x && "string" == typeof x.name && "langchain_tracer" === x.name;
4031
+ }
4032
+ function containsLangChainTracerLike(x) {
4033
+ return Array.isArray(x) && x.some((callback)=>isLangChainTracerLike(callback));
4034
+ }
4035
+ function isCallbackManagerLike(x) {
4036
+ return "object" == typeof x && null != x && Array.isArray(x.handlers);
4037
+ }
4038
+ function isRunnableConfigLike(x) {
4039
+ return void 0 !== x && "object" == typeof x.callbacks && (containsLangChainTracerLike(x.callbacks?.handlers) || containsLangChainTracerLike(x.callbacks));
4040
+ }
4041
+ class MockAsyncLocalStorage {
4042
+ getStore() {}
4043
+ run(_, callback) {
4044
+ return callback();
4045
+ }
4046
+ }
4047
+ const TRACING_ALS_KEY = Symbol.for("ls:tracing_async_local_storage");
4048
+ const mockAsyncLocalStorage = new MockAsyncLocalStorage();
4049
+ class AsyncLocalStorageProvider {
4050
+ getInstance() {
4051
+ return globalThis[TRACING_ALS_KEY] ?? mockAsyncLocalStorage;
4052
+ }
4053
+ initializeGlobalInstance(instance) {
4054
+ if (void 0 === globalThis[TRACING_ALS_KEY]) globalThis[TRACING_ALS_KEY] = instance;
4055
+ }
4056
+ }
4057
+ const AsyncLocalStorageProviderSingleton = new AsyncLocalStorageProvider();
4058
+ const ROOT = Symbol.for("langsmith:traceable:root");
4059
+ function isTraceableFunction(x) {
4060
+ return "function" == typeof x && "langsmith:traceable" in x;
4061
+ }
4062
+ function isPromiseMethod(x) {
4063
+ if ("then" === x || "catch" === x || "finally" === x) return true;
4064
+ return false;
4065
+ }
4066
+ function isKVMap(x) {
4067
+ if ("object" != typeof x || null == x) return false;
4068
+ const prototype = Object.getPrototypeOf(x);
4069
+ return (null === prototype || prototype === Object.prototype || null === Object.getPrototypeOf(prototype)) && !(Symbol.toStringTag in x) && !(Symbol.iterator in x);
4070
+ }
4071
+ const isAsyncIterable = (x)=>null != x && "object" == typeof x && "function" == typeof x[Symbol.asyncIterator];
4072
+ const isIteratorLike = (x)=>null != x && "object" == typeof x && "next" in x && "function" == typeof x.next;
4073
+ const GeneratorFunction = (function*() {}).constructor;
4074
+ const isGenerator = (x)=>null != x && "function" == typeof x && x instanceof GeneratorFunction;
4075
+ const isThenable = (x)=>null != x && "object" == typeof x && "then" in x && "function" == typeof x.then;
4076
+ const isReadableStream = (x)=>null != x && "object" == typeof x && "getReader" in x && "function" == typeof x.getReader;
4077
+ AsyncLocalStorageProviderSingleton.initializeGlobalInstance(new external_node_async_hooks_.AsyncLocalStorage());
4078
+ const runInputsToMap = (rawInputs)=>{
4079
+ const firstInput = rawInputs[0];
4080
+ let inputs;
4081
+ inputs = null == firstInput ? {} : rawInputs.length > 1 ? {
4082
+ args: rawInputs
4083
+ } : isKVMap(firstInput) ? firstInput : {
4084
+ input: firstInput
4085
+ };
4086
+ return inputs;
4087
+ };
4088
+ const handleRunInputs = (inputs, processInputs)=>{
4089
+ try {
4090
+ return processInputs(inputs);
4091
+ } catch (e) {
4092
+ console.error("Error occurred during processInputs. Sending raw inputs:", e);
4093
+ return inputs;
4094
+ }
4095
+ };
4096
+ const handleRunOutputs = (rawOutputs, processOutputs)=>{
4097
+ let outputs;
4098
+ outputs = isKVMap(rawOutputs) ? rawOutputs : {
4099
+ outputs: rawOutputs
4100
+ };
4101
+ try {
4102
+ return processOutputs(outputs);
4103
+ } catch (e) {
4104
+ console.error("Error occurred during processOutputs. Sending raw outputs:", e);
4105
+ return outputs;
4106
+ }
4107
+ };
4108
+ const handleRunAttachments = (rawInputs, extractAttachments)=>{
4109
+ if (!extractAttachments) return [
4110
+ void 0,
4111
+ rawInputs
4112
+ ];
4113
+ try {
4114
+ const [attachments, remainingArgs] = extractAttachments(...rawInputs);
4115
+ return [
4116
+ attachments,
4117
+ remainingArgs
4118
+ ];
4119
+ } catch (e) {
4120
+ console.error("Error occurred during extractAttachments:", e);
4121
+ return [
4122
+ void 0,
4123
+ rawInputs
4124
+ ];
4125
+ }
4126
+ };
4127
+ const getTracingRunTree = (runTree, inputs, getInvocationParams, processInputs, extractAttachments)=>{
4128
+ if (!isTracingEnabled(runTree.tracingEnabled)) return;
4129
+ const [attached, args] = handleRunAttachments(inputs, extractAttachments);
4130
+ runTree.attachments = attached;
4131
+ runTree.inputs = handleRunInputs(args, processInputs);
4132
+ const invocationParams = getInvocationParams?.(...inputs);
4133
+ if (null != invocationParams) {
4134
+ runTree.extra ??= {};
4135
+ runTree.extra.metadata = {
4136
+ ...invocationParams,
4137
+ ...runTree.extra.metadata
4138
+ };
4139
+ }
4140
+ return runTree;
4141
+ };
4142
+ const getSerializablePromise = (arg)=>{
4143
+ const proxyState = {
4144
+ current: void 0
4145
+ };
4146
+ const promiseProxy = new Proxy(arg, {
4147
+ get (target, prop, receiver) {
4148
+ if ("then" === prop) {
4149
+ const boundThen = arg[prop].bind(arg);
4150
+ return (resolve, reject = (x)=>{
4151
+ throw x;
4152
+ })=>boundThen((value)=>{
4153
+ proxyState.current = [
4154
+ "resolve",
4155
+ value
4156
+ ];
4157
+ return resolve(value);
4158
+ }, (error)=>{
4159
+ proxyState.current = [
4160
+ "reject",
4161
+ error
4162
+ ];
4163
+ return reject(error);
4164
+ });
4165
+ }
4166
+ if ("catch" === prop) {
4167
+ const boundCatch = arg[prop].bind(arg);
4168
+ return (reject)=>boundCatch((error)=>{
4169
+ proxyState.current = [
4170
+ "reject",
4171
+ error
4172
+ ];
4173
+ return reject(error);
4174
+ });
4175
+ }
4176
+ if ("toJSON" === prop) return ()=>{
4177
+ if (!proxyState.current) return;
4178
+ const [type, value] = proxyState.current ?? [];
4179
+ if ("resolve" === type) return value;
4180
+ return {
4181
+ error: value
4182
+ };
4183
+ };
4184
+ return Reflect.get(target, prop, receiver);
4185
+ }
4186
+ });
4187
+ return promiseProxy;
4188
+ };
4189
+ const convertSerializableArg = (arg)=>{
4190
+ if (isReadableStream(arg)) {
4191
+ const proxyState = [];
4192
+ const transform = new TransformStream({
4193
+ start: ()=>void 0,
4194
+ transform: (chunk, controller)=>{
4195
+ proxyState.push(chunk);
4196
+ controller.enqueue(chunk);
4197
+ },
4198
+ flush: ()=>void 0
4199
+ });
4200
+ const pipeThrough = arg.pipeThrough(transform);
4201
+ Object.assign(pipeThrough, {
4202
+ toJSON: ()=>proxyState
4203
+ });
4204
+ return pipeThrough;
4205
+ }
4206
+ if (isAsyncIterable(arg)) {
4207
+ const proxyState = {
4208
+ current: []
4209
+ };
4210
+ return new Proxy(arg, {
4211
+ get (target, prop, receiver) {
4212
+ if (prop === Symbol.asyncIterator) return ()=>{
4213
+ const boundIterator = arg[Symbol.asyncIterator].bind(arg);
4214
+ const iterator = boundIterator();
4215
+ return new Proxy(iterator, {
4216
+ get (target, prop, receiver) {
4217
+ if ("next" === prop || "return" === prop || "throw" === prop) {
4218
+ const bound = iterator.next.bind(iterator);
4219
+ return (...args)=>{
4220
+ const wrapped = getSerializablePromise(bound(...args));
4221
+ proxyState.current.push(wrapped);
4222
+ return wrapped;
4223
+ };
4224
+ }
4225
+ if ("return" === prop || "throw" === prop) return iterator.next.bind(iterator);
4226
+ return Reflect.get(target, prop, receiver);
4227
+ }
4228
+ });
4229
+ };
4230
+ if ("toJSON" === prop) return ()=>{
4231
+ const onlyNexts = proxyState.current;
4232
+ const serialized = onlyNexts.map((next)=>next.toJSON());
4233
+ const chunks = serialized.reduce((memo, next)=>{
4234
+ if (next?.value) memo.push(next.value);
4235
+ return memo;
4236
+ }, []);
4237
+ return chunks;
4238
+ };
4239
+ return Reflect.get(target, prop, receiver);
4240
+ }
4241
+ });
4242
+ }
4243
+ if (!Array.isArray(arg) && isIteratorLike(arg)) {
4244
+ const proxyState = [];
4245
+ return new Proxy(arg, {
4246
+ get (target, prop, receiver) {
4247
+ if ("next" === prop || "return" === prop || "throw" === prop) {
4248
+ const bound = arg[prop]?.bind(arg);
4249
+ return (...args)=>{
4250
+ const next = bound?.(...args);
4251
+ if (null != next) proxyState.push(next);
4252
+ return next;
4253
+ };
4254
+ }
4255
+ if ("toJSON" === prop) return ()=>{
4256
+ const chunks = proxyState.reduce((memo, next)=>{
4257
+ if (next.value) memo.push(next.value);
4258
+ return memo;
4259
+ }, []);
4260
+ return chunks;
4261
+ };
4262
+ return Reflect.get(target, prop, receiver);
4263
+ }
4264
+ });
4265
+ }
4266
+ if (isThenable(arg)) return getSerializablePromise(arg);
4267
+ return arg;
4268
+ };
4269
+ function traceable_traceable(wrappedFunc, config) {
4270
+ const { aggregator, argsConfigPath, __finalTracedIteratorKey, processInputs, processOutputs, extractAttachments, ...runTreeConfig } = config ?? {};
4271
+ const processInputsFn = processInputs ?? ((x)=>x);
4272
+ const processOutputsFn = processOutputs ?? ((x)=>x);
4273
+ const extractAttachmentsFn = extractAttachments ?? ((...x)=>[
4274
+ void 0,
4275
+ runInputsToMap(x)
4276
+ ]);
4277
+ const traceableFunc = (...args)=>{
4278
+ let ensuredConfig;
4279
+ try {
4280
+ let runtimeConfig;
4281
+ if (argsConfigPath) {
4282
+ const [index, path] = argsConfigPath;
4283
+ if (index !== args.length - 1 || path) {
4284
+ if (index <= args.length && "object" == typeof args[index] && null !== args[index]) if (path) {
4285
+ const { [path]: extracted, ...rest } = args[index];
4286
+ runtimeConfig = extracted;
4287
+ args[index] = rest;
4288
+ } else {
4289
+ runtimeConfig = args[index];
4290
+ args.splice(index, 1);
4291
+ }
4292
+ } else runtimeConfig = args.pop();
4293
+ }
4294
+ ensuredConfig = {
4295
+ name: wrappedFunc.name || "<lambda>",
4296
+ ...runTreeConfig,
4297
+ ...runtimeConfig,
4298
+ tags: [
4299
+ ...new Set([
4300
+ ...runTreeConfig?.tags ?? [],
4301
+ ...runtimeConfig?.tags ?? []
4302
+ ])
4303
+ ],
4304
+ metadata: {
4305
+ ...runTreeConfig?.metadata,
4306
+ ...runtimeConfig?.metadata
4307
+ }
4308
+ };
4309
+ } catch (err) {
4310
+ console.warn(`Failed to extract runtime config from args for ${runTreeConfig?.name ?? wrappedFunc.name}`, err);
4311
+ ensuredConfig = {
4312
+ name: wrappedFunc.name || "<lambda>",
4313
+ ...runTreeConfig
4314
+ };
4315
+ }
4316
+ const asyncLocalStorage = AsyncLocalStorageProviderSingleton.getInstance();
4317
+ const processedArgs = args;
4318
+ for(let i = 0; i < processedArgs.length; i++)processedArgs[i] = convertSerializableArg(processedArgs[i]);
4319
+ const [currentRunTree, rawInputs] = (()=>{
4320
+ const [firstArg, ...restArgs] = processedArgs;
4321
+ if (isRunnableConfigLike(firstArg)) return [
4322
+ getTracingRunTree(RunTree.fromRunnableConfig(firstArg, ensuredConfig), restArgs, config?.getInvocationParams, processInputsFn, extractAttachmentsFn),
4323
+ restArgs
4324
+ ];
4325
+ if (run_trees_isRunTree(firstArg) && "callbackManager" in firstArg && null != firstArg.callbackManager) return [
4326
+ firstArg,
4327
+ restArgs
4328
+ ];
4329
+ if (firstArg === ROOT || run_trees_isRunTree(firstArg)) {
4330
+ const currentRunTree = getTracingRunTree(firstArg === ROOT ? new RunTree(ensuredConfig) : firstArg.createChild(ensuredConfig), restArgs, config?.getInvocationParams, processInputsFn, extractAttachmentsFn);
4331
+ return [
4332
+ currentRunTree,
4333
+ [
4334
+ currentRunTree,
4335
+ ...restArgs
4336
+ ]
4337
+ ];
4338
+ }
4339
+ const prevRunFromStore = asyncLocalStorage.getStore();
4340
+ if (run_trees_isRunTree(prevRunFromStore)) return [
4341
+ getTracingRunTree(prevRunFromStore.createChild(ensuredConfig), processedArgs, config?.getInvocationParams, processInputsFn, extractAttachmentsFn),
4342
+ processedArgs
4343
+ ];
4344
+ const currentRunTree = getTracingRunTree(new RunTree(ensuredConfig), processedArgs, config?.getInvocationParams, processInputsFn, extractAttachmentsFn);
4345
+ if (void 0 !== prevRunFromStore && _LC_CONTEXT_VARIABLES_KEY in prevRunFromStore) currentRunTree[_LC_CONTEXT_VARIABLES_KEY] = prevRunFromStore[_LC_CONTEXT_VARIABLES_KEY];
4346
+ return [
4347
+ currentRunTree,
4348
+ processedArgs
4349
+ ];
4350
+ })();
4351
+ return asyncLocalStorage.run(currentRunTree, ()=>{
4352
+ const postRunPromise = currentRunTree?.postRun();
4353
+ async function handleChunks(chunks) {
4354
+ if (void 0 !== aggregator) try {
4355
+ return await aggregator(chunks);
4356
+ } catch (e) {
4357
+ console.error("[ERROR]: LangSmith aggregation failed: ", e);
4358
+ }
4359
+ return chunks;
4360
+ }
4361
+ function tapReadableStreamForTracing(stream, snapshot) {
4362
+ const reader = stream.getReader();
4363
+ let finished = false;
4364
+ const chunks = [];
4365
+ const tappedStream = new ReadableStream({
4366
+ async start (controller) {
4367
+ while(true){
4368
+ const result = await (snapshot ? snapshot(()=>reader.read()) : reader.read());
4369
+ if (result.done) {
4370
+ finished = true;
4371
+ await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
4372
+ await handleEnd();
4373
+ controller.close();
4374
+ break;
4375
+ }
4376
+ chunks.push(result.value);
4377
+ controller.enqueue(result.value);
4378
+ }
4379
+ },
4380
+ async cancel (reason) {
4381
+ if (!finished) await currentRunTree?.end(void 0, "Cancelled");
4382
+ await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
4383
+ await handleEnd();
4384
+ return reader.cancel(reason);
4385
+ }
4386
+ });
4387
+ return tappedStream;
4388
+ }
4389
+ async function* wrapAsyncIteratorForTracing(iterator, snapshot) {
4390
+ let finished = false;
4391
+ const chunks = [];
4392
+ try {
4393
+ while(true){
4394
+ const { value, done } = await (snapshot ? snapshot(()=>iterator.next()) : iterator.next());
4395
+ if (done) {
4396
+ finished = true;
4397
+ break;
4398
+ }
4399
+ chunks.push(value);
4400
+ yield value;
4401
+ }
4402
+ } catch (e) {
4403
+ await currentRunTree?.end(void 0, String(e));
4404
+ throw e;
4405
+ } finally{
4406
+ if (!finished) await currentRunTree?.end(void 0, "Cancelled");
4407
+ await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
4408
+ await handleEnd();
4409
+ }
4410
+ }
4411
+ function wrapAsyncGeneratorForTracing(iterable, snapshot) {
4412
+ if (isReadableStream(iterable)) return tapReadableStreamForTracing(iterable, snapshot);
4413
+ const iterator = iterable[Symbol.asyncIterator]();
4414
+ const wrappedIterator = wrapAsyncIteratorForTracing(iterator, snapshot);
4415
+ iterable[Symbol.asyncIterator] = ()=>wrappedIterator;
4416
+ return iterable;
4417
+ }
4418
+ async function handleEnd() {
4419
+ const onEnd = config?.on_end;
4420
+ if (onEnd) if (currentRunTree) onEnd(currentRunTree);
4421
+ else console.warn("Can not call 'on_end' if currentRunTree is undefined");
4422
+ await postRunPromise;
4423
+ await currentRunTree?.patchRun();
4424
+ }
4425
+ function gatherAll(iterator) {
4426
+ const chunks = [];
4427
+ while(true){
4428
+ const next = iterator.next();
4429
+ chunks.push(next);
4430
+ if (next.done) break;
4431
+ }
4432
+ return chunks;
4433
+ }
4434
+ let returnValue;
4435
+ try {
4436
+ returnValue = wrappedFunc(...rawInputs);
4437
+ } catch (err) {
4438
+ returnValue = Promise.reject(err);
4439
+ }
4440
+ if (isAsyncIterable(returnValue)) {
4441
+ const snapshot = external_node_async_hooks_.AsyncLocalStorage.snapshot();
4442
+ return wrapAsyncGeneratorForTracing(returnValue, snapshot);
4443
+ }
4444
+ if (!Array.isArray(returnValue) && "object" == typeof returnValue && null != returnValue && void 0 !== __finalTracedIteratorKey && isAsyncIterable(returnValue[__finalTracedIteratorKey])) {
4445
+ const snapshot = external_node_async_hooks_.AsyncLocalStorage.snapshot();
4446
+ return {
4447
+ ...returnValue,
4448
+ [__finalTracedIteratorKey]: wrapAsyncGeneratorForTracing(returnValue[__finalTracedIteratorKey], snapshot)
4449
+ };
4450
+ }
4451
+ const tracedPromise = new Promise((resolve, reject)=>{
4452
+ Promise.resolve(returnValue).then(async (rawOutput)=>{
4453
+ if (isAsyncIterable(rawOutput)) {
4454
+ const snapshot = external_node_async_hooks_.AsyncLocalStorage.snapshot();
4455
+ return resolve(wrapAsyncGeneratorForTracing(rawOutput, snapshot));
4456
+ }
4457
+ if (!Array.isArray(rawOutput) && "object" == typeof rawOutput && null != rawOutput && void 0 !== __finalTracedIteratorKey && isAsyncIterable(rawOutput[__finalTracedIteratorKey])) {
4458
+ const snapshot = external_node_async_hooks_.AsyncLocalStorage.snapshot();
4459
+ return {
4460
+ ...rawOutput,
4461
+ [__finalTracedIteratorKey]: wrapAsyncGeneratorForTracing(rawOutput[__finalTracedIteratorKey], snapshot)
4462
+ };
4463
+ }
4464
+ if (isGenerator(wrappedFunc) && isIteratorLike(rawOutput)) {
4465
+ const chunks = gatherAll(rawOutput);
4466
+ try {
4467
+ await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks.reduce((memo, { value, done })=>{
4468
+ if (!done || void 0 !== value) memo.push(value);
4469
+ return memo;
4470
+ }, [])), processOutputsFn));
4471
+ await handleEnd();
4472
+ } catch (e) {
4473
+ console.error("Error occurred during handleEnd:", e);
4474
+ }
4475
+ return function*() {
4476
+ for (const ret of chunks){
4477
+ if (ret.done) return ret.value;
4478
+ yield ret.value;
4479
+ }
4480
+ }();
4481
+ }
4482
+ try {
4483
+ await currentRunTree?.end(handleRunOutputs(rawOutput, processOutputsFn));
4484
+ await handleEnd();
4485
+ } finally{
4486
+ return rawOutput;
4487
+ }
4488
+ }, async (error)=>{
4489
+ await currentRunTree?.end(void 0, String(error));
4490
+ await handleEnd();
4491
+ throw error;
4492
+ }).then(resolve, reject);
4493
+ });
4494
+ if ("object" != typeof returnValue || null === returnValue) return tracedPromise;
4495
+ return new Proxy(returnValue, {
4496
+ get (target, prop, receiver) {
4497
+ if (isPromiseMethod(prop)) return tracedPromise[prop].bind(tracedPromise);
4498
+ return Reflect.get(target, prop, receiver);
4499
+ }
4500
+ });
4501
+ });
4502
+ };
4503
+ Object.defineProperty(traceableFunc, "langsmith:traceable", {
4504
+ value: runTreeConfig
4505
+ });
4506
+ return traceableFunc;
4507
+ }
4508
+ function _combineChatCompletionChoices(choices) {
4509
+ const reversedChoices = choices.slice().reverse();
4510
+ const message = {
4511
+ role: "assistant",
4512
+ content: ""
4513
+ };
4514
+ for (const c of reversedChoices)if (c.delta.role) {
4515
+ message["role"] = c.delta.role;
4516
+ break;
4517
+ }
4518
+ const toolCalls = {};
4519
+ for (const c of choices){
4520
+ if (c.delta.content) message.content = message.content.concat(c.delta.content);
4521
+ if (c.delta.function_call) {
4522
+ if (!message.function_call) message.function_call = {
4523
+ name: "",
4524
+ arguments: ""
4525
+ };
4526
+ if (c.delta.function_call.name) message.function_call.name += c.delta.function_call.name;
4527
+ if (c.delta.function_call.arguments) message.function_call.arguments += c.delta.function_call.arguments;
4528
+ }
4529
+ if (c.delta.tool_calls) for (const tool_call of c.delta.tool_calls){
4530
+ if (!toolCalls[c.index]) toolCalls[c.index] = [];
4531
+ toolCalls[c.index].push(tool_call);
4532
+ }
4533
+ }
4534
+ if (Object.keys(toolCalls).length > 0) {
4535
+ message.tool_calls = [
4536
+ ...Array(Object.keys(toolCalls).length)
4537
+ ];
4538
+ for (const [index, toolCallChunks] of Object.entries(toolCalls)){
4539
+ const idx = parseInt(index);
4540
+ message.tool_calls[idx] = {
4541
+ index: idx,
4542
+ id: toolCallChunks.find((c)=>c.id)?.id || null,
4543
+ type: toolCallChunks.find((c)=>c.type)?.type || null
4544
+ };
4545
+ for (const chunk of toolCallChunks)if (chunk.function) {
4546
+ if (!message.tool_calls[idx].function) message.tool_calls[idx].function = {
4547
+ name: "",
4548
+ arguments: ""
4549
+ };
4550
+ if (chunk.function.name) message.tool_calls[idx].function.name += chunk.function.name;
4551
+ if (chunk.function.arguments) message.tool_calls[idx].function.arguments += chunk.function.arguments;
4552
+ }
4553
+ }
4554
+ }
4555
+ return {
4556
+ index: choices[0].index,
4557
+ finish_reason: reversedChoices.find((c)=>c.finish_reason) || null,
4558
+ message: message
4559
+ };
4560
+ }
4561
+ const chatAggregator = (chunks)=>{
4562
+ if (!chunks || 0 === chunks.length) return {
4563
+ choices: [
4564
+ {
4565
+ message: {
4566
+ role: "assistant",
4567
+ content: ""
4568
+ }
4569
+ }
4570
+ ]
4571
+ };
4572
+ const choicesByIndex = {};
4573
+ for (const chunk of chunks)for (const choice of chunk.choices){
4574
+ if (void 0 === choicesByIndex[choice.index]) choicesByIndex[choice.index] = [];
4575
+ choicesByIndex[choice.index].push(choice);
4576
+ }
4577
+ const aggregatedOutput = chunks[chunks.length - 1];
4578
+ aggregatedOutput.choices = Object.values(choicesByIndex).map((choices)=>_combineChatCompletionChoices(choices));
4579
+ return aggregatedOutput;
4580
+ };
4581
+ const textAggregator = (allChunks)=>{
4582
+ if (0 === allChunks.length) return {
4583
+ choices: [
4584
+ {
4585
+ text: ""
4586
+ }
4587
+ ]
4588
+ };
4589
+ const allContent = [];
4590
+ for (const chunk of allChunks){
4591
+ const content = chunk.choices[0].text;
4592
+ if (null != content) allContent.push(content);
4593
+ }
4594
+ const content = allContent.join("");
4595
+ const aggregatedOutput = allChunks[allChunks.length - 1];
4596
+ aggregatedOutput.choices = [
4597
+ {
4598
+ ...aggregatedOutput.choices[0],
4599
+ text: content
4600
+ }
4601
+ ];
4602
+ return aggregatedOutput;
4603
+ };
4604
+ function processChatCompletion(outputs) {
4605
+ const chatCompletion = outputs;
4606
+ const result = {
4607
+ ...chatCompletion
4608
+ };
4609
+ const usage = chatCompletion.usage;
4610
+ if (usage) {
4611
+ const inputTokenDetails = {
4612
+ ...usage.prompt_tokens_details?.audio_tokens !== null && {
4613
+ audio: usage.prompt_tokens_details?.audio_tokens
4614
+ },
4615
+ ...usage.prompt_tokens_details?.cached_tokens !== null && {
4616
+ cache_read: usage.prompt_tokens_details?.cached_tokens
4617
+ }
4618
+ };
4619
+ const outputTokenDetails = {
4620
+ ...usage.completion_tokens_details?.audio_tokens !== null && {
4621
+ audio: usage.completion_tokens_details?.audio_tokens
4622
+ },
4623
+ ...usage.completion_tokens_details?.reasoning_tokens !== null && {
4624
+ reasoning: usage.completion_tokens_details?.reasoning_tokens
4625
+ }
4626
+ };
4627
+ result.usage_metadata = {
4628
+ input_tokens: usage.prompt_tokens ?? 0,
4629
+ output_tokens: usage.completion_tokens ?? 0,
4630
+ total_tokens: usage.total_tokens ?? 0,
4631
+ ...Object.keys(inputTokenDetails).length > 0 && {
4632
+ input_token_details: inputTokenDetails
4633
+ },
4634
+ ...Object.keys(outputTokenDetails).length > 0 && {
4635
+ output_token_details: outputTokenDetails
4636
+ }
4637
+ };
4638
+ }
4639
+ delete result.usage;
4640
+ return result;
4641
+ }
4642
+ const wrapOpenAI = (openai, options)=>{
4643
+ if (isTraceableFunction(openai.chat.completions.create) || isTraceableFunction(openai.completions.create)) throw new Error("This instance of OpenAI client has been already wrapped once.");
4644
+ const tracedOpenAIClient = {
4645
+ ...openai
4646
+ };
4647
+ if (openai.beta && openai.beta.chat && openai.beta.chat.completions && "function" == typeof openai.beta.chat.completions.parse) tracedOpenAIClient.beta = {
4648
+ ...openai.beta,
4649
+ chat: {
4650
+ ...openai.beta.chat,
4651
+ completions: {
4652
+ ...openai.beta.chat.completions,
4653
+ parse: traceable_traceable(openai.beta.chat.completions.parse.bind(openai.beta.chat.completions), {
4654
+ name: "ChatOpenAI",
4655
+ run_type: "llm",
4656
+ aggregator: chatAggregator,
4657
+ argsConfigPath: [
4658
+ 1,
4659
+ "langsmithExtra"
4660
+ ],
4661
+ getInvocationParams: (payload)=>{
4662
+ if ("object" != typeof payload || null == payload) return;
4663
+ const params = payload;
4664
+ const ls_stop = ("string" == typeof params.stop ? [
4665
+ params.stop
4666
+ ] : params.stop) ?? void 0;
4667
+ return {
4668
+ ls_provider: "openai",
4669
+ ls_model_type: "chat",
4670
+ ls_model_name: params.model,
4671
+ ls_max_tokens: params.max_tokens ?? void 0,
4672
+ ls_temperature: params.temperature ?? void 0,
4673
+ ls_stop
4674
+ };
4675
+ },
4676
+ ...options
4677
+ })
4678
+ }
4679
+ }
4680
+ };
4681
+ tracedOpenAIClient.chat = {
4682
+ ...openai.chat,
4683
+ completions: {
4684
+ ...openai.chat.completions,
4685
+ create: traceable_traceable(openai.chat.completions.create.bind(openai.chat.completions), {
4686
+ name: "ChatOpenAI",
4687
+ run_type: "llm",
4688
+ aggregator: chatAggregator,
4689
+ argsConfigPath: [
4690
+ 1,
4691
+ "langsmithExtra"
4692
+ ],
4693
+ getInvocationParams: (payload)=>{
4694
+ if ("object" != typeof payload || null == payload) return;
4695
+ const params = payload;
4696
+ const ls_stop = ("string" == typeof params.stop ? [
4697
+ params.stop
4698
+ ] : params.stop) ?? void 0;
4699
+ return {
4700
+ ls_provider: "openai",
4701
+ ls_model_type: "chat",
4702
+ ls_model_name: params.model,
4703
+ ls_max_tokens: params.max_tokens ?? void 0,
4704
+ ls_temperature: params.temperature ?? void 0,
4705
+ ls_stop
4706
+ };
4707
+ },
4708
+ processOutputs: processChatCompletion,
4709
+ ...options
4710
+ })
4711
+ }
4712
+ };
4713
+ tracedOpenAIClient.completions = {
4714
+ ...openai.completions,
4715
+ create: traceable_traceable(openai.completions.create.bind(openai.completions), {
4716
+ name: "OpenAI",
4717
+ run_type: "llm",
4718
+ aggregator: textAggregator,
4719
+ argsConfigPath: [
4720
+ 1,
4721
+ "langsmithExtra"
4722
+ ],
4723
+ getInvocationParams: (payload)=>{
4724
+ if ("object" != typeof payload || null == payload) return;
4725
+ const params = payload;
4726
+ const ls_stop = ("string" == typeof params.stop ? [
4727
+ params.stop
4728
+ ] : params.stop) ?? void 0;
4729
+ return {
4730
+ ls_provider: "openai",
4731
+ ls_model_type: "llm",
4732
+ ls_model_name: params.model,
4733
+ ls_max_tokens: params.max_tokens ?? void 0,
4734
+ ls_temperature: params.temperature ?? void 0,
4735
+ ls_stop
4736
+ };
4737
+ },
4738
+ ...options
4739
+ })
4740
+ };
4741
+ return tracedOpenAIClient;
4742
+ };
4743
+ }
4744
+ };