langsmith 0.3.78 → 0.3.79-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.__version__ = exports.getDefaultProjectName = exports.overrideFetchImplementation = exports.RunTree = exports.Client = void 0;
3
+ exports.__version__ = exports.uuid7FromTime = exports.uuid7 = 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,5 +9,8 @@ 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; } });
12
15
  // Update using yarn bump-version
13
- exports.__version__ = "0.3.78";
16
+ exports.__version__ = "0.3.79-rc.0";
package/dist/index.d.ts CHANGED
@@ -3,4 +3,5 @@ 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 declare const __version__ = "0.3.78";
6
+ export { uuid7, uuid7FromTime } from "./uuid.js";
7
+ export declare const __version__ = "0.3.79-rc.0";
package/dist/index.js CHANGED
@@ -2,5 +2,6 @@ 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";
5
6
  // Update using yarn bump-version
6
- export const __version__ = "0.3.78";
7
+ export const __version__ = "0.3.79-rc.0";
@@ -1,43 +1,9 @@
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
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.RunTree = void 0;
37
4
  exports.convertToDottedOrderFormat = convertToDottedOrderFormat;
38
5
  exports.isRunTree = isRunTree;
39
6
  exports.isRunnableConfigLike = isRunnableConfigLike;
40
- const uuid = __importStar(require("uuid"));
41
7
  const client_js_1 = require("./client.cjs");
42
8
  const env_js_1 = require("./env.cjs");
43
9
  const error_js_1 = require("./utils/error.cjs");
@@ -46,16 +12,18 @@ const env_js_2 = require("./utils/env.cjs");
46
12
  const project_js_1 = require("./utils/project.cjs");
47
13
  const env_js_3 = require("./utils/env.cjs");
48
14
  const warn_js_1 = require("./utils/warn.cjs");
15
+ const _uuid_js_1 = require("./utils/_uuid.cjs");
49
16
  function stripNonAlphanumeric(input) {
50
17
  return input.replace(/[-:.]/g, "");
51
18
  }
52
- function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
19
+ function getMicrosecondPrecisionDatestring(epoch, executionOrder = 1) {
53
20
  // Date only has millisecond precision, so we use the microseconds to break
54
21
  // possible ties, avoiding incorrect run order
55
22
  const paddedOrder = executionOrder.toFixed(0).slice(0, 3).padStart(3, "0");
56
- const microsecondPrecisionDatestring = `${new Date(epoch)
57
- .toISOString()
58
- .slice(0, -1)}${paddedOrder}Z`;
23
+ return `${new Date(epoch).toISOString().slice(0, -1)}${paddedOrder}Z`;
24
+ }
25
+ function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
26
+ const microsecondPrecisionDatestring = getMicrosecondPrecisionDatestring(epoch, executionOrder);
59
27
  return {
60
28
  dottedOrder: stripNonAlphanumeric(microsecondPrecisionDatestring) + runId,
61
29
  microsecondPrecisionDatestring,
@@ -315,6 +283,19 @@ class RunTree {
315
283
  delete config.id;
316
284
  }
317
285
  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
+ }
318
299
  if (!this.trace_id) {
319
300
  if (this.parent_run) {
320
301
  this.trace_id = this.parent_run.trace_id ?? this.id;
@@ -323,18 +304,22 @@ class RunTree {
323
304
  this.trace_id = this.id;
324
305
  }
325
306
  }
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
+ }
326
313
  this.replicas = _ensureWriteReplicas(this.replicas);
327
- this.execution_order ??= 1;
328
- this.child_execution_order ??= 1;
314
+ // Now set the dotted order with the actual ID
329
315
  if (!this.dotted_order) {
330
- const { dottedOrder, microsecondPrecisionDatestring } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
316
+ const { dottedOrder } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
331
317
  if (this.parent_run) {
332
318
  this.dotted_order = this.parent_run.dotted_order + "." + dottedOrder;
333
319
  }
334
320
  else {
335
321
  this.dotted_order = dottedOrder;
336
322
  }
337
- this._serialized_start_time = microsecondPrecisionDatestring;
338
323
  }
339
324
  }
340
325
  set metadata(metadata) {
@@ -350,15 +335,15 @@ class RunTree {
350
335
  return this.extra?.metadata;
351
336
  }
352
337
  static getDefaultConfig() {
338
+ const start_time = Date.now();
353
339
  return {
354
- id: uuid.v4(),
355
340
  run_type: "chain",
356
341
  project_name: (0, project_js_1.getDefaultProjectName)(),
357
342
  child_runs: [],
358
343
  api_url: (0, env_js_2.getEnvironmentVariable)("LANGCHAIN_ENDPOINT") ?? "http://localhost:1984",
359
344
  api_key: (0, env_js_2.getEnvironmentVariable)("LANGCHAIN_API_KEY"),
360
345
  caller_options: {},
361
- start_time: Date.now(),
346
+ start_time,
362
347
  serialized: {},
363
348
  inputs: {},
364
349
  extra: {},
@@ -478,50 +463,10 @@ class RunTree {
478
463
  }
479
464
  _remapForProject(projectName, runtimeEnv, excludeChildRuns = true) {
480
465
  const baseRun = this._convertToCreate(this, runtimeEnv, excludeChildRuns);
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 = {
466
+ return {
517
467
  ...baseRun,
518
- id: newId,
519
- trace_id: newTraceId,
520
- parent_run_id: newParentRunId,
521
- dotted_order: newDottedOrder,
522
468
  session_name: projectName,
523
469
  };
524
- return remappedRun;
525
470
  }
526
471
  async postRun(excludeChildRuns = true) {
527
472
  try {
@@ -559,6 +504,9 @@ class RunTree {
559
504
  const runData = this._remapForProject(projectName ?? this.project_name);
560
505
  const updatePayload = {
561
506
  id: runData.id,
507
+ name: runData.name,
508
+ run_type: runData.run_type,
509
+ start_time: runData.start_time,
562
510
  outputs: runData.outputs,
563
511
  error: runData.error,
564
512
  parent_run_id: runData.parent_run_id,
@@ -589,6 +537,9 @@ class RunTree {
589
537
  else {
590
538
  try {
591
539
  const runUpdate = {
540
+ name: this.name,
541
+ run_type: this.run_type,
542
+ start_time: this._serialized_start_time ?? this.start_time,
592
543
  end_time: this.end_time,
593
544
  error: this.error,
594
545
  outputs: this.outputs,
@@ -770,24 +721,6 @@ function isRunnableConfigLike(x) {
770
721
  // Or it's an array with a LangChainTracerLike object within it
771
722
  containsLangChainTracerLike(x.callbacks)));
772
723
  }
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
- }
791
724
  function _getWriteReplicasFromEnv() {
792
725
  const envVar = (0, env_js_2.getEnvironmentVariable)("LANGSMITH_RUNS_ENDPOINTS");
793
726
  if (!envVar)
package/dist/run_trees.js CHANGED
@@ -1,4 +1,3 @@
1
- import * as uuid from "uuid";
2
1
  import { Client } from "./client.js";
3
2
  import { isTracingEnabled } from "./env.js";
4
3
  import { isConflictingEndpointsError, ConflictingEndpointsError, } from "./utils/error.js";
@@ -7,16 +6,18 @@ import { getEnvironmentVariable, getRuntimeEnvironment, } from "./utils/env.js";
7
6
  import { getDefaultProjectName } from "./utils/project.js";
8
7
  import { getLangSmithEnvironmentVariable } from "./utils/env.js";
9
8
  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
- export function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
13
+ function getMicrosecondPrecisionDatestring(epoch, 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
- const microsecondPrecisionDatestring = `${new Date(epoch)
18
- .toISOString()
19
- .slice(0, -1)}${paddedOrder}Z`;
17
+ return `${new Date(epoch).toISOString().slice(0, -1)}${paddedOrder}Z`;
18
+ }
19
+ export function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
20
+ const microsecondPrecisionDatestring = getMicrosecondPrecisionDatestring(epoch, executionOrder);
20
21
  return {
21
22
  dottedOrder: stripNonAlphanumeric(microsecondPrecisionDatestring) + runId,
22
23
  microsecondPrecisionDatestring,
@@ -276,6 +277,19 @@ export class RunTree {
276
277
  delete config.id;
277
278
  }
278
279
  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
+ }
279
293
  if (!this.trace_id) {
280
294
  if (this.parent_run) {
281
295
  this.trace_id = this.parent_run.trace_id ?? this.id;
@@ -284,18 +298,22 @@ export class RunTree {
284
298
  this.trace_id = this.id;
285
299
  }
286
300
  }
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
+ }
287
307
  this.replicas = _ensureWriteReplicas(this.replicas);
288
- this.execution_order ??= 1;
289
- this.child_execution_order ??= 1;
308
+ // Now set the dotted order with the actual ID
290
309
  if (!this.dotted_order) {
291
- const { dottedOrder, microsecondPrecisionDatestring } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
310
+ const { dottedOrder } = convertToDottedOrderFormat(this.start_time, this.id, this.execution_order);
292
311
  if (this.parent_run) {
293
312
  this.dotted_order = this.parent_run.dotted_order + "." + dottedOrder;
294
313
  }
295
314
  else {
296
315
  this.dotted_order = dottedOrder;
297
316
  }
298
- this._serialized_start_time = microsecondPrecisionDatestring;
299
317
  }
300
318
  }
301
319
  set metadata(metadata) {
@@ -311,15 +329,15 @@ export class RunTree {
311
329
  return this.extra?.metadata;
312
330
  }
313
331
  static getDefaultConfig() {
332
+ const start_time = Date.now();
314
333
  return {
315
- id: uuid.v4(),
316
334
  run_type: "chain",
317
335
  project_name: getDefaultProjectName(),
318
336
  child_runs: [],
319
337
  api_url: getEnvironmentVariable("LANGCHAIN_ENDPOINT") ?? "http://localhost:1984",
320
338
  api_key: getEnvironmentVariable("LANGCHAIN_API_KEY"),
321
339
  caller_options: {},
322
- start_time: Date.now(),
340
+ start_time,
323
341
  serialized: {},
324
342
  inputs: {},
325
343
  extra: {},
@@ -439,50 +457,10 @@ export class RunTree {
439
457
  }
440
458
  _remapForProject(projectName, runtimeEnv, excludeChildRuns = true) {
441
459
  const baseRun = this._convertToCreate(this, runtimeEnv, excludeChildRuns);
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 = {
460
+ return {
478
461
  ...baseRun,
479
- id: newId,
480
- trace_id: newTraceId,
481
- parent_run_id: newParentRunId,
482
- dotted_order: newDottedOrder,
483
462
  session_name: projectName,
484
463
  };
485
- return remappedRun;
486
464
  }
487
465
  async postRun(excludeChildRuns = true) {
488
466
  try {
@@ -520,6 +498,9 @@ export class RunTree {
520
498
  const runData = this._remapForProject(projectName ?? this.project_name);
521
499
  const updatePayload = {
522
500
  id: runData.id,
501
+ name: runData.name,
502
+ run_type: runData.run_type,
503
+ start_time: runData.start_time,
523
504
  outputs: runData.outputs,
524
505
  error: runData.error,
525
506
  parent_run_id: runData.parent_run_id,
@@ -550,6 +531,9 @@ export class RunTree {
550
531
  else {
551
532
  try {
552
533
  const runUpdate = {
534
+ name: this.name,
535
+ run_type: this.run_type,
536
+ start_time: this._serialized_start_time ?? this.start_time,
553
537
  end_time: this.end_time,
554
538
  error: this.error,
555
539
  outputs: this.outputs,
@@ -730,24 +714,6 @@ export function isRunnableConfigLike(x) {
730
714
  // Or it's an array with a LangChainTracerLike object within it
731
715
  containsLangChainTracerLike(x.callbacks)));
732
716
  }
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
- }
751
717
  function _getWriteReplicasFromEnv() {
752
718
  const envVar = getEnvironmentVariable("LANGSMITH_RUNS_ENDPOINTS");
753
719
  if (!envVar)
package/dist/schemas.d.ts CHANGED
@@ -152,6 +152,9 @@ export interface RunCreate extends BaseRun {
152
152
  }
153
153
  export interface RunUpdate {
154
154
  id?: string;
155
+ name?: string;
156
+ run_type?: string;
157
+ start_time?: number | string;
155
158
  end_time?: number | string;
156
159
  extra?: KVMap;
157
160
  tags?: string[];
@@ -1,8 +1,14 @@
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;
4
7
  // Relaxed UUID validation regex (allows any valid UUID format including nil UUIDs)
5
8
  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;
6
12
  function assertUuid(str, which) {
7
13
  // Use relaxed regex validation instead of strict uuid.validate()
8
14
  // This allows edge cases like nil UUIDs or test UUIDs that might not pass strict validation
@@ -14,3 +20,47 @@ function assertUuid(str, which) {
14
20
  }
15
21
  return str;
16
22
  }
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
+ }
@@ -1 +1,21 @@
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;
@@ -1,5 +1,8 @@
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;
3
6
  export function assertUuid(str, which) {
4
7
  // Use relaxed regex validation instead of strict uuid.validate()
5
8
  // This allows edge cases like nil UUIDs or test UUIDs that might not pass strict validation
@@ -11,3 +14,47 @@ export function assertUuid(str, which) {
11
14
  }
12
15
  return str;
13
16
  }
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/dist/uuid.cjs ADDED
@@ -0,0 +1,13 @@
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 ADDED
@@ -0,0 +1,5 @@
1
+ export { uuid7FromTime } from "./utils/_uuid.js";
2
+ /**
3
+ * Generate a random UUID v7 string.
4
+ */
5
+ export declare function uuid7(): string;
package/dist/uuid.js ADDED
@@ -0,0 +1,8 @@
1
+ import { v7 as uuidv7 } from "uuid";
2
+ export { uuid7FromTime } from "./utils/_uuid.js";
3
+ /**
4
+ * Generate a random UUID v7 string.
5
+ */
6
+ export function uuid7() {
7
+ return uuidv7();
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.3.78",
3
+ "version": "0.3.79-rc.0",
4
4
  "description": "Client library to connect to the LangSmith Observability and Evaluation Platform.",
5
5
  "packageManager": "yarn@1.22.19",
6
6
  "files": [