langsmith 0.3.79-rc.0 → 0.3.79
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/experimental/vercel/index.cjs +23 -0
- package/dist/experimental/vercel/index.js +23 -0
- package/dist/index.cjs +2 -5
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/run_trees.cjs +103 -36
- package/dist/run_trees.js +70 -36
- package/dist/schemas.d.ts +0 -3
- package/dist/utils/_uuid.cjs +0 -50
- package/dist/utils/_uuid.d.ts +0 -20
- package/dist/utils/_uuid.js +0 -47
- package/package.json +1 -1
- package/dist/uuid.cjs +0 -13
- package/dist/uuid.d.ts +0 -5
- package/dist/uuid.js +0 -8
|
@@ -209,6 +209,19 @@ const wrapAISDK = ({ wrapLanguageModel, generateText, streamText, streamObject,
|
|
|
209
209
|
if (outputs.outputs == null || typeof outputs.outputs !== "object") {
|
|
210
210
|
return outputs;
|
|
211
211
|
}
|
|
212
|
+
// If experimental_output is present, return it directly at top level (like generateObject)
|
|
213
|
+
// Note: accessing experimental_output throws if not specified, so wrap in try-catch
|
|
214
|
+
try {
|
|
215
|
+
if ("experimental_output" in outputs.outputs) {
|
|
216
|
+
const experimentalOutput = outputs.outputs.experimental_output;
|
|
217
|
+
if (experimentalOutput != null) {
|
|
218
|
+
return experimentalOutput;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
// experimental_output not specified, continue with normal processing
|
|
224
|
+
}
|
|
212
225
|
const { steps } = outputs.outputs;
|
|
213
226
|
if (Array.isArray(steps)) {
|
|
214
227
|
const lastStep = steps.at(-1);
|
|
@@ -368,6 +381,16 @@ const wrapAISDK = ({ wrapLanguageModel, generateText, streamText, streamObject,
|
|
|
368
381
|
!["object", "string"].includes(typeof content)) {
|
|
369
382
|
return outputs;
|
|
370
383
|
}
|
|
384
|
+
try {
|
|
385
|
+
if ("experimental_partialOutputStream" in outputs.outputs &&
|
|
386
|
+
outputs.outputs.experimental_partialOutputStream != null) {
|
|
387
|
+
const textContent = await outputs.outputs.text;
|
|
388
|
+
return JSON.parse(textContent);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
catch (e) {
|
|
392
|
+
// experimental_partialOutputStream not specified, continue with normal processing
|
|
393
|
+
}
|
|
371
394
|
let responseMetadata = undefined;
|
|
372
395
|
if (resolvedLsConfig?.traceResponseMetadata) {
|
|
373
396
|
try {
|
|
@@ -204,6 +204,19 @@ const wrapAISDK = ({ wrapLanguageModel, generateText, streamText, streamObject,
|
|
|
204
204
|
if (outputs.outputs == null || typeof outputs.outputs !== "object") {
|
|
205
205
|
return outputs;
|
|
206
206
|
}
|
|
207
|
+
// If experimental_output is present, return it directly at top level (like generateObject)
|
|
208
|
+
// Note: accessing experimental_output throws if not specified, so wrap in try-catch
|
|
209
|
+
try {
|
|
210
|
+
if ("experimental_output" in outputs.outputs) {
|
|
211
|
+
const experimentalOutput = outputs.outputs.experimental_output;
|
|
212
|
+
if (experimentalOutput != null) {
|
|
213
|
+
return experimentalOutput;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
// experimental_output not specified, continue with normal processing
|
|
219
|
+
}
|
|
207
220
|
const { steps } = outputs.outputs;
|
|
208
221
|
if (Array.isArray(steps)) {
|
|
209
222
|
const lastStep = steps.at(-1);
|
|
@@ -363,6 +376,16 @@ const wrapAISDK = ({ wrapLanguageModel, generateText, streamText, streamObject,
|
|
|
363
376
|
!["object", "string"].includes(typeof content)) {
|
|
364
377
|
return outputs;
|
|
365
378
|
}
|
|
379
|
+
try {
|
|
380
|
+
if ("experimental_partialOutputStream" in outputs.outputs &&
|
|
381
|
+
outputs.outputs.experimental_partialOutputStream != null) {
|
|
382
|
+
const textContent = await outputs.outputs.text;
|
|
383
|
+
return JSON.parse(textContent);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
catch (e) {
|
|
387
|
+
// experimental_partialOutputStream not specified, continue with normal processing
|
|
388
|
+
}
|
|
366
389
|
let responseMetadata = undefined;
|
|
367
390
|
if (resolvedLsConfig?.traceResponseMetadata) {
|
|
368
391
|
try {
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.__version__ = exports.
|
|
3
|
+
exports.__version__ = exports.getDefaultProjectName = exports.overrideFetchImplementation = exports.RunTree = exports.Client = void 0;
|
|
4
4
|
var client_js_1 = require("./client.cjs");
|
|
5
5
|
Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_js_1.Client; } });
|
|
6
6
|
var run_trees_js_1 = require("./run_trees.cjs");
|
|
@@ -9,8 +9,5 @@ var fetch_js_1 = require("./singletons/fetch.cjs");
|
|
|
9
9
|
Object.defineProperty(exports, "overrideFetchImplementation", { enumerable: true, get: function () { return fetch_js_1.overrideFetchImplementation; } });
|
|
10
10
|
var project_js_1 = require("./utils/project.cjs");
|
|
11
11
|
Object.defineProperty(exports, "getDefaultProjectName", { enumerable: true, get: function () { return project_js_1.getDefaultProjectName; } });
|
|
12
|
-
var uuid_js_1 = require("./uuid.cjs");
|
|
13
|
-
Object.defineProperty(exports, "uuid7", { enumerable: true, get: function () { return uuid_js_1.uuid7; } });
|
|
14
|
-
Object.defineProperty(exports, "uuid7FromTime", { enumerable: true, get: function () { return uuid_js_1.uuid7FromTime; } });
|
|
15
12
|
// Update using yarn bump-version
|
|
16
|
-
exports.__version__ = "0.3.79
|
|
13
|
+
exports.__version__ = "0.3.79";
|
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,4 @@ export type { Dataset, Example, TracerSession, Run, Feedback, RetrieverOutput, }
|
|
|
3
3
|
export { RunTree, type RunTreeConfig } from "./run_trees.js";
|
|
4
4
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
5
5
|
export { getDefaultProjectName } from "./utils/project.js";
|
|
6
|
-
export
|
|
7
|
-
export declare const __version__ = "0.3.79-rc.0";
|
|
6
|
+
export declare const __version__ = "0.3.79";
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,5 @@ export { Client, } from "./client.js";
|
|
|
2
2
|
export { RunTree } from "./run_trees.js";
|
|
3
3
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
4
4
|
export { getDefaultProjectName } from "./utils/project.js";
|
|
5
|
-
export { uuid7, uuid7FromTime } from "./uuid.js";
|
|
6
5
|
// Update using yarn bump-version
|
|
7
|
-
export const __version__ = "0.3.79
|
|
6
|
+
export const __version__ = "0.3.79";
|
package/dist/run_trees.cjs
CHANGED
|
@@ -1,9 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.RunTree = void 0;
|
|
4
37
|
exports.convertToDottedOrderFormat = convertToDottedOrderFormat;
|
|
5
38
|
exports.isRunTree = isRunTree;
|
|
6
39
|
exports.isRunnableConfigLike = isRunnableConfigLike;
|
|
40
|
+
const uuid = __importStar(require("uuid"));
|
|
7
41
|
const client_js_1 = require("./client.cjs");
|
|
8
42
|
const env_js_1 = require("./env.cjs");
|
|
9
43
|
const error_js_1 = require("./utils/error.cjs");
|
|
@@ -12,18 +46,16 @@ const env_js_2 = require("./utils/env.cjs");
|
|
|
12
46
|
const project_js_1 = require("./utils/project.cjs");
|
|
13
47
|
const env_js_3 = require("./utils/env.cjs");
|
|
14
48
|
const warn_js_1 = require("./utils/warn.cjs");
|
|
15
|
-
const _uuid_js_1 = require("./utils/_uuid.cjs");
|
|
16
49
|
function stripNonAlphanumeric(input) {
|
|
17
50
|
return input.replace(/[-:.]/g, "");
|
|
18
51
|
}
|
|
19
|
-
function
|
|
52
|
+
function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
|
|
20
53
|
// Date only has millisecond precision, so we use the microseconds to break
|
|
21
54
|
// possible ties, avoiding incorrect run order
|
|
22
55
|
const paddedOrder = executionOrder.toFixed(0).slice(0, 3).padStart(3, "0");
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const microsecondPrecisionDatestring = getMicrosecondPrecisionDatestring(epoch, executionOrder);
|
|
56
|
+
const microsecondPrecisionDatestring = `${new Date(epoch)
|
|
57
|
+
.toISOString()
|
|
58
|
+
.slice(0, -1)}${paddedOrder}Z`;
|
|
27
59
|
return {
|
|
28
60
|
dottedOrder: stripNonAlphanumeric(microsecondPrecisionDatestring) + runId,
|
|
29
61
|
microsecondPrecisionDatestring,
|
|
@@ -283,19 +315,6 @@ class RunTree {
|
|
|
283
315
|
delete config.id;
|
|
284
316
|
}
|
|
285
317
|
Object.assign(this, { ...defaultConfig, ...config, client });
|
|
286
|
-
this.execution_order ??= 1;
|
|
287
|
-
this.child_execution_order ??= 1;
|
|
288
|
-
// Generate serialized start time for ID generation
|
|
289
|
-
if (!this.dotted_order) {
|
|
290
|
-
this._serialized_start_time = getMicrosecondPrecisionDatestring(this.start_time, this.execution_order);
|
|
291
|
-
}
|
|
292
|
-
// Generate id from serialized start_time if not provided
|
|
293
|
-
if (!this.id) {
|
|
294
|
-
this.id = (0, _uuid_js_1.uuid7FromTime)(this._serialized_start_time ?? this.start_time);
|
|
295
|
-
}
|
|
296
|
-
if (config.id) {
|
|
297
|
-
(0, _uuid_js_1.warnIfNotUuidV7)(config.id, "run_id");
|
|
298
|
-
}
|
|
299
318
|
if (!this.trace_id) {
|
|
300
319
|
if (this.parent_run) {
|
|
301
320
|
this.trace_id = this.parent_run.trace_id ?? this.id;
|
|
@@ -304,22 +323,18 @@ class RunTree {
|
|
|
304
323
|
this.trace_id = this.id;
|
|
305
324
|
}
|
|
306
325
|
}
|
|
307
|
-
else if (config.trace_id) {
|
|
308
|
-
(0, _uuid_js_1.warnIfNotUuidV7)(config.trace_id, "trace_id");
|
|
309
|
-
}
|
|
310
|
-
if (config.parent_run_id) {
|
|
311
|
-
(0, _uuid_js_1.warnIfNotUuidV7)(config.parent_run_id, "parent_run_id");
|
|
312
|
-
}
|
|
313
326
|
this.replicas = _ensureWriteReplicas(this.replicas);
|
|
314
|
-
|
|
327
|
+
this.execution_order ??= 1;
|
|
328
|
+
this.child_execution_order ??= 1;
|
|
315
329
|
if (!this.dotted_order) {
|
|
316
|
-
const { dottedOrder } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
|
|
330
|
+
const { dottedOrder, microsecondPrecisionDatestring } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
|
|
317
331
|
if (this.parent_run) {
|
|
318
332
|
this.dotted_order = this.parent_run.dotted_order + "." + dottedOrder;
|
|
319
333
|
}
|
|
320
334
|
else {
|
|
321
335
|
this.dotted_order = dottedOrder;
|
|
322
336
|
}
|
|
337
|
+
this._serialized_start_time = microsecondPrecisionDatestring;
|
|
323
338
|
}
|
|
324
339
|
}
|
|
325
340
|
set metadata(metadata) {
|
|
@@ -335,15 +350,15 @@ class RunTree {
|
|
|
335
350
|
return this.extra?.metadata;
|
|
336
351
|
}
|
|
337
352
|
static getDefaultConfig() {
|
|
338
|
-
const start_time = Date.now();
|
|
339
353
|
return {
|
|
354
|
+
id: uuid.v4(),
|
|
340
355
|
run_type: "chain",
|
|
341
356
|
project_name: (0, project_js_1.getDefaultProjectName)(),
|
|
342
357
|
child_runs: [],
|
|
343
358
|
api_url: (0, env_js_2.getEnvironmentVariable)("LANGCHAIN_ENDPOINT") ?? "http://localhost:1984",
|
|
344
359
|
api_key: (0, env_js_2.getEnvironmentVariable)("LANGCHAIN_API_KEY"),
|
|
345
360
|
caller_options: {},
|
|
346
|
-
start_time,
|
|
361
|
+
start_time: Date.now(),
|
|
347
362
|
serialized: {},
|
|
348
363
|
inputs: {},
|
|
349
364
|
extra: {},
|
|
@@ -463,10 +478,50 @@ class RunTree {
|
|
|
463
478
|
}
|
|
464
479
|
_remapForProject(projectName, runtimeEnv, excludeChildRuns = true) {
|
|
465
480
|
const baseRun = this._convertToCreate(this, runtimeEnv, excludeChildRuns);
|
|
466
|
-
|
|
481
|
+
if (projectName === this.project_name) {
|
|
482
|
+
return baseRun;
|
|
483
|
+
}
|
|
484
|
+
// Create a deterministic UUID mapping for this project
|
|
485
|
+
const createRemappedId = (originalId) => {
|
|
486
|
+
return uuid.v5(`${originalId}:${projectName}`, uuid.v5.DNS);
|
|
487
|
+
};
|
|
488
|
+
// Remap the current run's ID
|
|
489
|
+
const newId = createRemappedId(baseRun.id);
|
|
490
|
+
const newTraceId = baseRun.trace_id
|
|
491
|
+
? createRemappedId(baseRun.trace_id)
|
|
492
|
+
: undefined;
|
|
493
|
+
const newParentRunId = baseRun.parent_run_id
|
|
494
|
+
? createRemappedId(baseRun.parent_run_id)
|
|
495
|
+
: undefined;
|
|
496
|
+
let newDottedOrder;
|
|
497
|
+
if (baseRun.dotted_order) {
|
|
498
|
+
const segments = _parseDottedOrder(baseRun.dotted_order);
|
|
499
|
+
const rebuilt = [];
|
|
500
|
+
// Process all segments except the last one
|
|
501
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
502
|
+
const [timestamp, segmentId] = segments[i];
|
|
503
|
+
const remappedId = createRemappedId(segmentId);
|
|
504
|
+
rebuilt.push(timestamp.toISOString().replace(/[-:]/g, "").replace(".", "") +
|
|
505
|
+
remappedId);
|
|
506
|
+
}
|
|
507
|
+
// Process the last segment with the new run ID
|
|
508
|
+
const [lastTimestamp] = segments[segments.length - 1];
|
|
509
|
+
rebuilt.push(lastTimestamp.toISOString().replace(/[-:]/g, "").replace(".", "") +
|
|
510
|
+
newId);
|
|
511
|
+
newDottedOrder = rebuilt.join(".");
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
newDottedOrder = undefined;
|
|
515
|
+
}
|
|
516
|
+
const remappedRun = {
|
|
467
517
|
...baseRun,
|
|
518
|
+
id: newId,
|
|
519
|
+
trace_id: newTraceId,
|
|
520
|
+
parent_run_id: newParentRunId,
|
|
521
|
+
dotted_order: newDottedOrder,
|
|
468
522
|
session_name: projectName,
|
|
469
523
|
};
|
|
524
|
+
return remappedRun;
|
|
470
525
|
}
|
|
471
526
|
async postRun(excludeChildRuns = true) {
|
|
472
527
|
try {
|
|
@@ -504,9 +559,6 @@ class RunTree {
|
|
|
504
559
|
const runData = this._remapForProject(projectName ?? this.project_name);
|
|
505
560
|
const updatePayload = {
|
|
506
561
|
id: runData.id,
|
|
507
|
-
name: runData.name,
|
|
508
|
-
run_type: runData.run_type,
|
|
509
|
-
start_time: runData.start_time,
|
|
510
562
|
outputs: runData.outputs,
|
|
511
563
|
error: runData.error,
|
|
512
564
|
parent_run_id: runData.parent_run_id,
|
|
@@ -537,9 +589,6 @@ class RunTree {
|
|
|
537
589
|
else {
|
|
538
590
|
try {
|
|
539
591
|
const runUpdate = {
|
|
540
|
-
name: this.name,
|
|
541
|
-
run_type: this.run_type,
|
|
542
|
-
start_time: this._serialized_start_time ?? this.start_time,
|
|
543
592
|
end_time: this.end_time,
|
|
544
593
|
error: this.error,
|
|
545
594
|
outputs: this.outputs,
|
|
@@ -721,6 +770,24 @@ function isRunnableConfigLike(x) {
|
|
|
721
770
|
// Or it's an array with a LangChainTracerLike object within it
|
|
722
771
|
containsLangChainTracerLike(x.callbacks)));
|
|
723
772
|
}
|
|
773
|
+
function _parseDottedOrder(dottedOrder) {
|
|
774
|
+
const parts = dottedOrder.split(".");
|
|
775
|
+
return parts.map((part) => {
|
|
776
|
+
const timestampStr = part.slice(0, -36);
|
|
777
|
+
const uuidStr = part.slice(-36);
|
|
778
|
+
// Parse timestamp: "%Y%m%dT%H%M%S%fZ" format
|
|
779
|
+
// Example: "20231215T143045123456Z"
|
|
780
|
+
const year = parseInt(timestampStr.slice(0, 4));
|
|
781
|
+
const month = parseInt(timestampStr.slice(4, 6)) - 1; // JS months are 0-indexed
|
|
782
|
+
const day = parseInt(timestampStr.slice(6, 8));
|
|
783
|
+
const hour = parseInt(timestampStr.slice(9, 11));
|
|
784
|
+
const minute = parseInt(timestampStr.slice(11, 13));
|
|
785
|
+
const second = parseInt(timestampStr.slice(13, 15));
|
|
786
|
+
const microsecond = parseInt(timestampStr.slice(15, 21));
|
|
787
|
+
const timestamp = new Date(year, month, day, hour, minute, second, microsecond / 1000);
|
|
788
|
+
return [timestamp, uuidStr];
|
|
789
|
+
});
|
|
790
|
+
}
|
|
724
791
|
function _getWriteReplicasFromEnv() {
|
|
725
792
|
const envVar = (0, env_js_2.getEnvironmentVariable)("LANGSMITH_RUNS_ENDPOINTS");
|
|
726
793
|
if (!envVar)
|
package/dist/run_trees.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as uuid from "uuid";
|
|
1
2
|
import { Client } from "./client.js";
|
|
2
3
|
import { isTracingEnabled } from "./env.js";
|
|
3
4
|
import { isConflictingEndpointsError, ConflictingEndpointsError, } from "./utils/error.js";
|
|
@@ -6,18 +7,16 @@ import { getEnvironmentVariable, getRuntimeEnvironment, } from "./utils/env.js";
|
|
|
6
7
|
import { getDefaultProjectName } from "./utils/project.js";
|
|
7
8
|
import { getLangSmithEnvironmentVariable } from "./utils/env.js";
|
|
8
9
|
import { warnOnce } from "./utils/warn.js";
|
|
9
|
-
import { warnIfNotUuidV7, uuid7FromTime } from "./utils/_uuid.js";
|
|
10
10
|
function stripNonAlphanumeric(input) {
|
|
11
11
|
return input.replace(/[-:.]/g, "");
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
export function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
|
|
14
14
|
// Date only has millisecond precision, so we use the microseconds to break
|
|
15
15
|
// possible ties, avoiding incorrect run order
|
|
16
16
|
const paddedOrder = executionOrder.toFixed(0).slice(0, 3).padStart(3, "0");
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const microsecondPrecisionDatestring = getMicrosecondPrecisionDatestring(epoch, executionOrder);
|
|
17
|
+
const microsecondPrecisionDatestring = `${new Date(epoch)
|
|
18
|
+
.toISOString()
|
|
19
|
+
.slice(0, -1)}${paddedOrder}Z`;
|
|
21
20
|
return {
|
|
22
21
|
dottedOrder: stripNonAlphanumeric(microsecondPrecisionDatestring) + runId,
|
|
23
22
|
microsecondPrecisionDatestring,
|
|
@@ -277,19 +276,6 @@ export class RunTree {
|
|
|
277
276
|
delete config.id;
|
|
278
277
|
}
|
|
279
278
|
Object.assign(this, { ...defaultConfig, ...config, client });
|
|
280
|
-
this.execution_order ??= 1;
|
|
281
|
-
this.child_execution_order ??= 1;
|
|
282
|
-
// Generate serialized start time for ID generation
|
|
283
|
-
if (!this.dotted_order) {
|
|
284
|
-
this._serialized_start_time = getMicrosecondPrecisionDatestring(this.start_time, this.execution_order);
|
|
285
|
-
}
|
|
286
|
-
// Generate id from serialized start_time if not provided
|
|
287
|
-
if (!this.id) {
|
|
288
|
-
this.id = uuid7FromTime(this._serialized_start_time ?? this.start_time);
|
|
289
|
-
}
|
|
290
|
-
if (config.id) {
|
|
291
|
-
warnIfNotUuidV7(config.id, "run_id");
|
|
292
|
-
}
|
|
293
279
|
if (!this.trace_id) {
|
|
294
280
|
if (this.parent_run) {
|
|
295
281
|
this.trace_id = this.parent_run.trace_id ?? this.id;
|
|
@@ -298,22 +284,18 @@ export class RunTree {
|
|
|
298
284
|
this.trace_id = this.id;
|
|
299
285
|
}
|
|
300
286
|
}
|
|
301
|
-
else if (config.trace_id) {
|
|
302
|
-
warnIfNotUuidV7(config.trace_id, "trace_id");
|
|
303
|
-
}
|
|
304
|
-
if (config.parent_run_id) {
|
|
305
|
-
warnIfNotUuidV7(config.parent_run_id, "parent_run_id");
|
|
306
|
-
}
|
|
307
287
|
this.replicas = _ensureWriteReplicas(this.replicas);
|
|
308
|
-
|
|
288
|
+
this.execution_order ??= 1;
|
|
289
|
+
this.child_execution_order ??= 1;
|
|
309
290
|
if (!this.dotted_order) {
|
|
310
|
-
const { dottedOrder } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
|
|
291
|
+
const { dottedOrder, microsecondPrecisionDatestring } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
|
|
311
292
|
if (this.parent_run) {
|
|
312
293
|
this.dotted_order = this.parent_run.dotted_order + "." + dottedOrder;
|
|
313
294
|
}
|
|
314
295
|
else {
|
|
315
296
|
this.dotted_order = dottedOrder;
|
|
316
297
|
}
|
|
298
|
+
this._serialized_start_time = microsecondPrecisionDatestring;
|
|
317
299
|
}
|
|
318
300
|
}
|
|
319
301
|
set metadata(metadata) {
|
|
@@ -329,15 +311,15 @@ export class RunTree {
|
|
|
329
311
|
return this.extra?.metadata;
|
|
330
312
|
}
|
|
331
313
|
static getDefaultConfig() {
|
|
332
|
-
const start_time = Date.now();
|
|
333
314
|
return {
|
|
315
|
+
id: uuid.v4(),
|
|
334
316
|
run_type: "chain",
|
|
335
317
|
project_name: getDefaultProjectName(),
|
|
336
318
|
child_runs: [],
|
|
337
319
|
api_url: getEnvironmentVariable("LANGCHAIN_ENDPOINT") ?? "http://localhost:1984",
|
|
338
320
|
api_key: getEnvironmentVariable("LANGCHAIN_API_KEY"),
|
|
339
321
|
caller_options: {},
|
|
340
|
-
start_time,
|
|
322
|
+
start_time: Date.now(),
|
|
341
323
|
serialized: {},
|
|
342
324
|
inputs: {},
|
|
343
325
|
extra: {},
|
|
@@ -457,10 +439,50 @@ export class RunTree {
|
|
|
457
439
|
}
|
|
458
440
|
_remapForProject(projectName, runtimeEnv, excludeChildRuns = true) {
|
|
459
441
|
const baseRun = this._convertToCreate(this, runtimeEnv, excludeChildRuns);
|
|
460
|
-
|
|
442
|
+
if (projectName === this.project_name) {
|
|
443
|
+
return baseRun;
|
|
444
|
+
}
|
|
445
|
+
// Create a deterministic UUID mapping for this project
|
|
446
|
+
const createRemappedId = (originalId) => {
|
|
447
|
+
return uuid.v5(`${originalId}:${projectName}`, uuid.v5.DNS);
|
|
448
|
+
};
|
|
449
|
+
// Remap the current run's ID
|
|
450
|
+
const newId = createRemappedId(baseRun.id);
|
|
451
|
+
const newTraceId = baseRun.trace_id
|
|
452
|
+
? createRemappedId(baseRun.trace_id)
|
|
453
|
+
: undefined;
|
|
454
|
+
const newParentRunId = baseRun.parent_run_id
|
|
455
|
+
? createRemappedId(baseRun.parent_run_id)
|
|
456
|
+
: undefined;
|
|
457
|
+
let newDottedOrder;
|
|
458
|
+
if (baseRun.dotted_order) {
|
|
459
|
+
const segments = _parseDottedOrder(baseRun.dotted_order);
|
|
460
|
+
const rebuilt = [];
|
|
461
|
+
// Process all segments except the last one
|
|
462
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
463
|
+
const [timestamp, segmentId] = segments[i];
|
|
464
|
+
const remappedId = createRemappedId(segmentId);
|
|
465
|
+
rebuilt.push(timestamp.toISOString().replace(/[-:]/g, "").replace(".", "") +
|
|
466
|
+
remappedId);
|
|
467
|
+
}
|
|
468
|
+
// Process the last segment with the new run ID
|
|
469
|
+
const [lastTimestamp] = segments[segments.length - 1];
|
|
470
|
+
rebuilt.push(lastTimestamp.toISOString().replace(/[-:]/g, "").replace(".", "") +
|
|
471
|
+
newId);
|
|
472
|
+
newDottedOrder = rebuilt.join(".");
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
newDottedOrder = undefined;
|
|
476
|
+
}
|
|
477
|
+
const remappedRun = {
|
|
461
478
|
...baseRun,
|
|
479
|
+
id: newId,
|
|
480
|
+
trace_id: newTraceId,
|
|
481
|
+
parent_run_id: newParentRunId,
|
|
482
|
+
dotted_order: newDottedOrder,
|
|
462
483
|
session_name: projectName,
|
|
463
484
|
};
|
|
485
|
+
return remappedRun;
|
|
464
486
|
}
|
|
465
487
|
async postRun(excludeChildRuns = true) {
|
|
466
488
|
try {
|
|
@@ -498,9 +520,6 @@ export class RunTree {
|
|
|
498
520
|
const runData = this._remapForProject(projectName ?? this.project_name);
|
|
499
521
|
const updatePayload = {
|
|
500
522
|
id: runData.id,
|
|
501
|
-
name: runData.name,
|
|
502
|
-
run_type: runData.run_type,
|
|
503
|
-
start_time: runData.start_time,
|
|
504
523
|
outputs: runData.outputs,
|
|
505
524
|
error: runData.error,
|
|
506
525
|
parent_run_id: runData.parent_run_id,
|
|
@@ -531,9 +550,6 @@ export class RunTree {
|
|
|
531
550
|
else {
|
|
532
551
|
try {
|
|
533
552
|
const runUpdate = {
|
|
534
|
-
name: this.name,
|
|
535
|
-
run_type: this.run_type,
|
|
536
|
-
start_time: this._serialized_start_time ?? this.start_time,
|
|
537
553
|
end_time: this.end_time,
|
|
538
554
|
error: this.error,
|
|
539
555
|
outputs: this.outputs,
|
|
@@ -714,6 +730,24 @@ export function isRunnableConfigLike(x) {
|
|
|
714
730
|
// Or it's an array with a LangChainTracerLike object within it
|
|
715
731
|
containsLangChainTracerLike(x.callbacks)));
|
|
716
732
|
}
|
|
733
|
+
function _parseDottedOrder(dottedOrder) {
|
|
734
|
+
const parts = dottedOrder.split(".");
|
|
735
|
+
return parts.map((part) => {
|
|
736
|
+
const timestampStr = part.slice(0, -36);
|
|
737
|
+
const uuidStr = part.slice(-36);
|
|
738
|
+
// Parse timestamp: "%Y%m%dT%H%M%S%fZ" format
|
|
739
|
+
// Example: "20231215T143045123456Z"
|
|
740
|
+
const year = parseInt(timestampStr.slice(0, 4));
|
|
741
|
+
const month = parseInt(timestampStr.slice(4, 6)) - 1; // JS months are 0-indexed
|
|
742
|
+
const day = parseInt(timestampStr.slice(6, 8));
|
|
743
|
+
const hour = parseInt(timestampStr.slice(9, 11));
|
|
744
|
+
const minute = parseInt(timestampStr.slice(11, 13));
|
|
745
|
+
const second = parseInt(timestampStr.slice(13, 15));
|
|
746
|
+
const microsecond = parseInt(timestampStr.slice(15, 21));
|
|
747
|
+
const timestamp = new Date(year, month, day, hour, minute, second, microsecond / 1000);
|
|
748
|
+
return [timestamp, uuidStr];
|
|
749
|
+
});
|
|
750
|
+
}
|
|
717
751
|
function _getWriteReplicasFromEnv() {
|
|
718
752
|
const envVar = getEnvironmentVariable("LANGSMITH_RUNS_ENDPOINTS");
|
|
719
753
|
if (!envVar)
|
package/dist/schemas.d.ts
CHANGED
package/dist/utils/_uuid.cjs
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.assertUuid = assertUuid;
|
|
4
|
-
exports.uuid7FromTime = uuid7FromTime;
|
|
5
|
-
exports.getUuidVersion = getUuidVersion;
|
|
6
|
-
exports.warnIfNotUuidV7 = warnIfNotUuidV7;
|
|
7
4
|
// Relaxed UUID validation regex (allows any valid UUID format including nil UUIDs)
|
|
8
5
|
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9
|
-
const uuid_1 = require("uuid");
|
|
10
|
-
const warn_js_1 = require("./warn.cjs");
|
|
11
|
-
let UUID7_WARNING_EMITTED = false;
|
|
12
6
|
function assertUuid(str, which) {
|
|
13
7
|
// Use relaxed regex validation instead of strict uuid.validate()
|
|
14
8
|
// This allows edge cases like nil UUIDs or test UUIDs that might not pass strict validation
|
|
@@ -20,47 +14,3 @@ function assertUuid(str, which) {
|
|
|
20
14
|
}
|
|
21
15
|
return str;
|
|
22
16
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Generate a UUID v7 from a timestamp.
|
|
25
|
-
*
|
|
26
|
-
* @param timestamp - The timestamp in milliseconds
|
|
27
|
-
* @returns A UUID v7 string
|
|
28
|
-
*/
|
|
29
|
-
function uuid7FromTime(timestamp) {
|
|
30
|
-
const msecs = typeof timestamp === "string" ? Date.parse(timestamp) : timestamp;
|
|
31
|
-
// Work around uuid@10 behavior where providing only { msecs }
|
|
32
|
-
// may not set the internal timestamp used for stringification.
|
|
33
|
-
// Providing a seq ensures the implementation updates its internal state
|
|
34
|
-
// and encodes the provided milliseconds into the UUID bytes.
|
|
35
|
-
return (0, uuid_1.v7)({ msecs, seq: 0 });
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Get the version of a UUID string.
|
|
39
|
-
* @param uuidStr - The UUID string to check
|
|
40
|
-
* @returns The version number (1-7) or null if invalid
|
|
41
|
-
*/
|
|
42
|
-
function getUuidVersion(uuidStr) {
|
|
43
|
-
if (!UUID_REGEX.test(uuidStr)) {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
// Version is in bits 48-51
|
|
47
|
-
// Format: xxxxxxxx-xxxx-Vxxx-xxxx-xxxxxxxxxxxx
|
|
48
|
-
const versionChar = uuidStr[14];
|
|
49
|
-
return parseInt(versionChar, 16);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Warn if a UUID is not version 7.
|
|
53
|
-
*
|
|
54
|
-
* @param uuidStr - The UUID string to check
|
|
55
|
-
* @param idType - The type of ID (e.g., "run_id", "trace_id") for the warning message
|
|
56
|
-
*/
|
|
57
|
-
function warnIfNotUuidV7(uuidStr, _idType) {
|
|
58
|
-
const version = getUuidVersion(uuidStr);
|
|
59
|
-
if (version !== null && version !== 7 && !UUID7_WARNING_EMITTED) {
|
|
60
|
-
UUID7_WARNING_EMITTED = true;
|
|
61
|
-
(0, warn_js_1.warnOnce)(`LangSmith now uses UUID v7 for run and trace identifiers. ` +
|
|
62
|
-
`This warning appears when passing custom IDs. ` +
|
|
63
|
-
`Please use: import { uuidv7 } from 'langsmith'; const id = uuidv7(); ` +
|
|
64
|
-
`Future versions will require UUID v7.`);
|
|
65
|
-
}
|
|
66
|
-
}
|
package/dist/utils/_uuid.d.ts
CHANGED
|
@@ -1,21 +1 @@
|
|
|
1
1
|
export declare function assertUuid(str: string, which?: string): string;
|
|
2
|
-
/**
|
|
3
|
-
* Generate a UUID v7 from a timestamp.
|
|
4
|
-
*
|
|
5
|
-
* @param timestamp - The timestamp in milliseconds
|
|
6
|
-
* @returns A UUID v7 string
|
|
7
|
-
*/
|
|
8
|
-
export declare function uuid7FromTime(timestamp: number | string): string;
|
|
9
|
-
/**
|
|
10
|
-
* Get the version of a UUID string.
|
|
11
|
-
* @param uuidStr - The UUID string to check
|
|
12
|
-
* @returns The version number (1-7) or null if invalid
|
|
13
|
-
*/
|
|
14
|
-
export declare function getUuidVersion(uuidStr: string): number | null;
|
|
15
|
-
/**
|
|
16
|
-
* Warn if a UUID is not version 7.
|
|
17
|
-
*
|
|
18
|
-
* @param uuidStr - The UUID string to check
|
|
19
|
-
* @param idType - The type of ID (e.g., "run_id", "trace_id") for the warning message
|
|
20
|
-
*/
|
|
21
|
-
export declare function warnIfNotUuidV7(uuidStr: string, _idType: string): void;
|
package/dist/utils/_uuid.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
// Relaxed UUID validation regex (allows any valid UUID format including nil UUIDs)
|
|
2
2
|
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3
|
-
import { v7 as uuidv7 } from "uuid";
|
|
4
|
-
import { warnOnce } from "./warn.js";
|
|
5
|
-
let UUID7_WARNING_EMITTED = false;
|
|
6
3
|
export function assertUuid(str, which) {
|
|
7
4
|
// Use relaxed regex validation instead of strict uuid.validate()
|
|
8
5
|
// This allows edge cases like nil UUIDs or test UUIDs that might not pass strict validation
|
|
@@ -14,47 +11,3 @@ export function assertUuid(str, which) {
|
|
|
14
11
|
}
|
|
15
12
|
return str;
|
|
16
13
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Generate a UUID v7 from a timestamp.
|
|
19
|
-
*
|
|
20
|
-
* @param timestamp - The timestamp in milliseconds
|
|
21
|
-
* @returns A UUID v7 string
|
|
22
|
-
*/
|
|
23
|
-
export function uuid7FromTime(timestamp) {
|
|
24
|
-
const msecs = typeof timestamp === "string" ? Date.parse(timestamp) : timestamp;
|
|
25
|
-
// Work around uuid@10 behavior where providing only { msecs }
|
|
26
|
-
// may not set the internal timestamp used for stringification.
|
|
27
|
-
// Providing a seq ensures the implementation updates its internal state
|
|
28
|
-
// and encodes the provided milliseconds into the UUID bytes.
|
|
29
|
-
return uuidv7({ msecs, seq: 0 });
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Get the version of a UUID string.
|
|
33
|
-
* @param uuidStr - The UUID string to check
|
|
34
|
-
* @returns The version number (1-7) or null if invalid
|
|
35
|
-
*/
|
|
36
|
-
export function getUuidVersion(uuidStr) {
|
|
37
|
-
if (!UUID_REGEX.test(uuidStr)) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
// Version is in bits 48-51
|
|
41
|
-
// Format: xxxxxxxx-xxxx-Vxxx-xxxx-xxxxxxxxxxxx
|
|
42
|
-
const versionChar = uuidStr[14];
|
|
43
|
-
return parseInt(versionChar, 16);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Warn if a UUID is not version 7.
|
|
47
|
-
*
|
|
48
|
-
* @param uuidStr - The UUID string to check
|
|
49
|
-
* @param idType - The type of ID (e.g., "run_id", "trace_id") for the warning message
|
|
50
|
-
*/
|
|
51
|
-
export function warnIfNotUuidV7(uuidStr, _idType) {
|
|
52
|
-
const version = getUuidVersion(uuidStr);
|
|
53
|
-
if (version !== null && version !== 7 && !UUID7_WARNING_EMITTED) {
|
|
54
|
-
UUID7_WARNING_EMITTED = true;
|
|
55
|
-
warnOnce(`LangSmith now uses UUID v7 for run and trace identifiers. ` +
|
|
56
|
-
`This warning appears when passing custom IDs. ` +
|
|
57
|
-
`Please use: import { uuidv7 } from 'langsmith'; const id = uuidv7(); ` +
|
|
58
|
-
`Future versions will require UUID v7.`);
|
|
59
|
-
}
|
|
60
|
-
}
|
package/package.json
CHANGED
package/dist/uuid.cjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uuid7FromTime = void 0;
|
|
4
|
-
exports.uuid7 = uuid7;
|
|
5
|
-
const uuid_1 = require("uuid");
|
|
6
|
-
var _uuid_js_1 = require("./utils/_uuid.cjs");
|
|
7
|
-
Object.defineProperty(exports, "uuid7FromTime", { enumerable: true, get: function () { return _uuid_js_1.uuid7FromTime; } });
|
|
8
|
-
/**
|
|
9
|
-
* Generate a random UUID v7 string.
|
|
10
|
-
*/
|
|
11
|
-
function uuid7() {
|
|
12
|
-
return (0, uuid_1.v7)();
|
|
13
|
-
}
|
package/dist/uuid.d.ts
DELETED