@rpascene/mcp 0.30.11

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