langsmith 0.2.15-rc.8 → 0.2.15

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.
Files changed (44) hide show
  1. package/dist/client.cjs +28 -0
  2. package/dist/client.d.ts +21 -9
  3. package/dist/client.js +28 -0
  4. package/dist/index.cjs +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/run_trees.d.ts +1 -1
  8. package/dist/singletons/traceable.cjs +1 -1
  9. package/dist/singletons/traceable.js +1 -1
  10. package/dist/vercel.cjs +85 -79
  11. package/dist/vercel.js +86 -80
  12. package/package.json +4 -30
  13. package/dist/jest.cjs +0 -45
  14. package/dist/jest.d.ts +0 -99
  15. package/dist/jest.js +0 -20
  16. package/dist/utils/jestlike/globals.cjs +0 -37
  17. package/dist/utils/jestlike/globals.d.ts +0 -32
  18. package/dist/utils/jestlike/globals.js +0 -32
  19. package/dist/utils/jestlike/index.cjs +0 -418
  20. package/dist/utils/jestlike/index.d.ts +0 -89
  21. package/dist/utils/jestlike/index.js +0 -409
  22. package/dist/utils/jestlike/matchers.cjs +0 -104
  23. package/dist/utils/jestlike/matchers.d.ts +0 -27
  24. package/dist/utils/jestlike/matchers.js +0 -98
  25. package/dist/utils/jestlike/types.cjs +0 -2
  26. package/dist/utils/jestlike/types.d.ts +0 -13
  27. package/dist/utils/jestlike/types.js +0 -1
  28. package/dist/utils/jestlike/vendor/chain.cjs +0 -93
  29. package/dist/utils/jestlike/vendor/chain.d.ts +0 -2
  30. package/dist/utils/jestlike/vendor/chain.js +0 -89
  31. package/dist/utils/jestlike/vendor/evaluatedBy.cjs +0 -49
  32. package/dist/utils/jestlike/vendor/evaluatedBy.d.ts +0 -8
  33. package/dist/utils/jestlike/vendor/evaluatedBy.js +0 -45
  34. package/dist/vitest.cjs +0 -45
  35. package/dist/vitest.d.ts +0 -97
  36. package/dist/vitest.js +0 -20
  37. package/jest.cjs +0 -1
  38. package/jest.d.cts +0 -1
  39. package/jest.d.ts +0 -1
  40. package/jest.js +0 -1
  41. package/vitest.cjs +0 -1
  42. package/vitest.d.cts +0 -1
  43. package/vitest.d.ts +0 -1
  44. package/vitest.js +0 -1
package/dist/client.cjs CHANGED
@@ -2555,6 +2555,34 @@ class Client {
2555
2555
  await (0, error_js_1.raiseForStatus)(response, "get run from annotation queue");
2556
2556
  return await response.json();
2557
2557
  }
2558
+ /**
2559
+ * Delete a run from an an annotation queue.
2560
+ * @param queueId - The ID of the annotation queue to delete the run from
2561
+ * @param queueRunId - The ID of the run to delete from the annotation queue
2562
+ */
2563
+ async deleteRunFromAnnotationQueue(queueId, queueRunId) {
2564
+ const response = await this.caller.call((0, fetch_js_1._getFetchImplementation)(), `${this.apiUrl}/annotation-queues/${(0, _uuid_js_1.assertUuid)(queueId, "queueId")}/runs/${(0, _uuid_js_1.assertUuid)(queueRunId, "queueRunId")}`, {
2565
+ method: "DELETE",
2566
+ headers: { ...this.headers, Accept: "application/json" },
2567
+ signal: AbortSignal.timeout(this.timeout_ms),
2568
+ ...this.fetchOptions,
2569
+ });
2570
+ await (0, error_js_1.raiseForStatus)(response, "delete run from annotation queue");
2571
+ }
2572
+ /**
2573
+ * Get the size of an annotation queue.
2574
+ * @param queueId - The ID of the annotation queue
2575
+ */
2576
+ async getSizeFromAnnotationQueue(queueId) {
2577
+ const response = await this.caller.call((0, fetch_js_1._getFetchImplementation)(), `${this.apiUrl}/annotation-queues/${(0, _uuid_js_1.assertUuid)(queueId, "queueId")}/size`, {
2578
+ method: "GET",
2579
+ headers: this.headers,
2580
+ signal: AbortSignal.timeout(this.timeout_ms),
2581
+ ...this.fetchOptions,
2582
+ });
2583
+ await (0, error_js_1.raiseForStatus)(response, "get size from annotation queue");
2584
+ return await response.json();
2585
+ }
2558
2586
  async _currentTenantIsOwner(owner) {
2559
2587
  const settings = await this._getSettings();
2560
2588
  return owner == "-" || settings.tenant_handle === owner;
package/dist/client.d.ts CHANGED
@@ -164,14 +164,6 @@ export type CreateExampleOptions = {
164
164
  /** The ID of the source run associated with this example. */
165
165
  sourceRunId?: string;
166
166
  };
167
- export type CreateProjectParams = {
168
- projectName: string;
169
- description?: string | null;
170
- metadata?: RecordStringAny | null;
171
- upsert?: boolean;
172
- projectExtra?: RecordStringAny | null;
173
- referenceDatasetId?: string | null;
174
- };
175
167
  type AutoBatchQueueItem = {
176
168
  action: "create" | "update";
177
169
  item: RunCreate | RunUpdate;
@@ -403,7 +395,14 @@ export declare class Client implements LangSmithTracingClientInterface {
403
395
  listSharedExamples(shareToken: string, options?: {
404
396
  exampleIds?: string[];
405
397
  }): Promise<Example[]>;
406
- createProject({ projectName, description, metadata, upsert, projectExtra, referenceDatasetId, }: CreateProjectParams): Promise<TracerSession>;
398
+ createProject({ projectName, description, metadata, upsert, projectExtra, referenceDatasetId, }: {
399
+ projectName: string;
400
+ description?: string | null;
401
+ metadata?: RecordStringAny | null;
402
+ upsert?: boolean;
403
+ projectExtra?: RecordStringAny | null;
404
+ referenceDatasetId?: string | null;
405
+ }): Promise<TracerSession>;
407
406
  updateProject(projectId: string, { name, description, metadata, projectExtra, endTime, }: {
408
407
  name?: string | null;
409
408
  description?: string | null;
@@ -714,6 +713,19 @@ export declare class Client implements LangSmithTracingClientInterface {
714
713
  * @throws {Error} If the run is not found at the given index or for other API-related errors
715
714
  */
716
715
  getRunFromAnnotationQueue(queueId: string, index: number): Promise<RunWithAnnotationQueueInfo>;
716
+ /**
717
+ * Delete a run from an an annotation queue.
718
+ * @param queueId - The ID of the annotation queue to delete the run from
719
+ * @param queueRunId - The ID of the run to delete from the annotation queue
720
+ */
721
+ deleteRunFromAnnotationQueue(queueId: string, queueRunId: string): Promise<void>;
722
+ /**
723
+ * Get the size of an annotation queue.
724
+ * @param queueId - The ID of the annotation queue
725
+ */
726
+ getSizeFromAnnotationQueue(queueId: string): Promise<{
727
+ size: number;
728
+ }>;
717
729
  protected _currentTenantIsOwner(owner: string): Promise<boolean>;
718
730
  protected _ownerConflictError(action: string, owner: string): Promise<Error>;
719
731
  protected _getLatestCommitHash(promptOwnerAndName: string): Promise<string | undefined>;
package/dist/client.js CHANGED
@@ -2527,6 +2527,34 @@ export class Client {
2527
2527
  await raiseForStatus(response, "get run from annotation queue");
2528
2528
  return await response.json();
2529
2529
  }
2530
+ /**
2531
+ * Delete a run from an an annotation queue.
2532
+ * @param queueId - The ID of the annotation queue to delete the run from
2533
+ * @param queueRunId - The ID of the run to delete from the annotation queue
2534
+ */
2535
+ async deleteRunFromAnnotationQueue(queueId, queueRunId) {
2536
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}/runs/${assertUuid(queueRunId, "queueRunId")}`, {
2537
+ method: "DELETE",
2538
+ headers: { ...this.headers, Accept: "application/json" },
2539
+ signal: AbortSignal.timeout(this.timeout_ms),
2540
+ ...this.fetchOptions,
2541
+ });
2542
+ await raiseForStatus(response, "delete run from annotation queue");
2543
+ }
2544
+ /**
2545
+ * Get the size of an annotation queue.
2546
+ * @param queueId - The ID of the annotation queue
2547
+ */
2548
+ async getSizeFromAnnotationQueue(queueId) {
2549
+ const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}/size`, {
2550
+ method: "GET",
2551
+ headers: this.headers,
2552
+ signal: AbortSignal.timeout(this.timeout_ms),
2553
+ ...this.fetchOptions,
2554
+ });
2555
+ await raiseForStatus(response, "get size from annotation queue");
2556
+ return await response.json();
2557
+ }
2530
2558
  async _currentTenantIsOwner(owner) {
2531
2559
  const settings = await this._getSettings();
2532
2560
  return owner == "-" || settings.tenant_handle === owner;
package/dist/index.cjs CHANGED
@@ -8,4 +8,4 @@ Object.defineProperty(exports, "RunTree", { enumerable: true, get: function () {
8
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
  // Update using yarn bump-version
11
- exports.__version__ = "0.2.15-rc.8";
11
+ exports.__version__ = "0.2.15";
package/dist/index.d.ts CHANGED
@@ -2,4 +2,4 @@ export { Client, type ClientConfig, type LangSmithTracingClientInterface, } from
2
2
  export type { Dataset, Example, TracerSession, Run, Feedback, RetrieverOutput, } from "./schemas.js";
3
3
  export { RunTree, type RunTreeConfig } from "./run_trees.js";
4
4
  export { overrideFetchImplementation } from "./singletons/fetch.js";
5
- export declare const __version__ = "0.2.15-rc.8";
5
+ export declare const __version__ = "0.2.15";
package/dist/index.js CHANGED
@@ -2,4 +2,4 @@ export { Client, } from "./client.js";
2
2
  export { RunTree } from "./run_trees.js";
3
3
  export { overrideFetchImplementation } from "./singletons/fetch.js";
4
4
  // Update using yarn bump-version
5
- export const __version__ = "0.2.15-rc.8";
5
+ export const __version__ = "0.2.15";
@@ -80,7 +80,7 @@ export declare class RunTree implements BaseRun {
80
80
  attachments?: Attachments;
81
81
  constructor(originalConfig: RunTreeConfig | RunTree);
82
82
  private static getDefaultConfig;
83
- static getSharedClient(): Client;
83
+ private static getSharedClient;
84
84
  createChild(config: RunTreeConfig): RunTree;
85
85
  end(outputs?: KVMap, error?: string, endTime?: number, metadata?: KVMap): Promise<void>;
86
86
  private _convertToCreate;
@@ -38,7 +38,7 @@ const getCurrentRunTree = () => {
38
38
  throw new Error([
39
39
  "Could not get the current run tree.",
40
40
  "",
41
- "Please make sure you are calling this method within a traceable function and that tracing is enabled.",
41
+ "Please make sure you are calling this method within a traceable function or the tracing is enabled.",
42
42
  ].join("\n"));
43
43
  }
44
44
  return runTree;
@@ -35,7 +35,7 @@ export const getCurrentRunTree = () => {
35
35
  throw new Error([
36
36
  "Could not get the current run tree.",
37
37
  "",
38
- "Please make sure you are calling this method within a traceable function and that tracing is enabled.",
38
+ "Please make sure you are calling this method within a traceable function or the tracing is enabled.",
39
39
  ].join("\n"));
40
40
  }
41
41
  return runTree;
package/dist/vercel.cjs CHANGED
@@ -107,15 +107,49 @@ const tryJson = (str) => {
107
107
  function stripNonAlphanumeric(input) {
108
108
  return input.replace(/[-:.]/g, "");
109
109
  }
110
- function convertToDottedOrderFormat([seconds, nanoseconds], runId, executionOrder) {
110
+ function getDotOrder(item) {
111
+ const { startTime: [seconds, nanoseconds], id: runId, executionOrder, } = item;
111
112
  // Date only has millisecond precision, so we use the microseconds to break
112
113
  // possible ties, avoiding incorrect run order
113
- const ms = Number(String(nanoseconds).slice(0, 3));
114
- const ns = String(Number(String(nanoseconds).slice(3, 6)) + executionOrder)
115
- .padStart(3, "0")
116
- .slice(0, 3);
114
+ const nanosecondString = String(nanoseconds).padStart(9, "0");
115
+ const msFull = Number(nanosecondString.slice(0, 6)) + executionOrder;
116
+ const msString = String(msFull).padStart(6, "0");
117
+ const ms = Number(msString.slice(0, -3));
118
+ const ns = msString.slice(-3);
117
119
  return (stripNonAlphanumeric(`${new Date(seconds * 1000 + ms).toISOString().slice(0, -1)}${ns}Z`) + runId);
118
120
  }
121
+ function joinDotOrder(...segments) {
122
+ return segments.filter(Boolean).join(".");
123
+ }
124
+ function removeDotOrder(dotOrder, ...ids) {
125
+ return dotOrder
126
+ .split(".")
127
+ .filter((i) => !ids.some((id) => i.includes(id)))
128
+ .join(".");
129
+ }
130
+ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
131
+ const segments = dotOrder.split(".");
132
+ const sourceIndex = segments.findIndex((i) => i.includes(sourceRunId));
133
+ if (sourceIndex === -1)
134
+ return dotOrder;
135
+ return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
136
+ }
137
+ function getMutableRunCreate(dotOrder) {
138
+ const segments = dotOrder.split(".").map((i) => {
139
+ const [startTime, runId] = i.split("Z");
140
+ return { startTime, runId };
141
+ });
142
+ const traceId = segments[0].runId;
143
+ const parentRunId = segments.at(-2)?.runId;
144
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
145
+ const runId = segments.at(-1).runId;
146
+ return {
147
+ id: runId,
148
+ trace_id: traceId,
149
+ dotted_order: dotOrder,
150
+ parent_run_id: parentRunId,
151
+ };
152
+ }
119
153
  function convertToTimestamp([seconds, nanoseconds]) {
120
154
  const ms = String(nanoseconds).slice(0, 3);
121
155
  return Number(String(seconds) + ms);
@@ -256,6 +290,8 @@ class AISDKExporter {
256
290
  }
257
291
  /** @internal */
258
292
  parseInteropFromMetadata(span) {
293
+ if (!this.isRootRun(span))
294
+ return undefined;
259
295
  const userTraceId = this.getSpanAttributeKey(span, RUN_ID_METADATA_KEY.output);
260
296
  const parentTrace = this.getSpanAttributeKey(span, TRACE_METADATA_KEY.output);
261
297
  if (parentTrace && userTraceId) {
@@ -271,15 +307,11 @@ class AISDKExporter {
271
307
  return { type: "traceable", parentRunTree };
272
308
  }
273
309
  if (userTraceId)
274
- return { type: "user", userTraceId };
310
+ return { type: "user", userRunId: userTraceId };
275
311
  return undefined;
276
312
  }
277
313
  /** @internal */
278
314
  getRunCreate(span) {
279
- const runId = (0, uuid_1.v5)(span.spanContext().spanId, RUN_ID_NAMESPACE);
280
- const parentRunId = span.parentSpanId
281
- ? (0, uuid_1.v5)(span.parentSpanId, RUN_ID_NAMESPACE)
282
- : undefined;
283
315
  const asRunCreate = (rawConfig) => {
284
316
  const aiMetadata = Object.keys(span.attributes)
285
317
  .filter((key) => key.startsWith("ai.telemetry.metadata.") &&
@@ -307,8 +339,6 @@ class AISDKExporter {
307
339
  const config = {
308
340
  ...rawConfig,
309
341
  name,
310
- id: runId,
311
- parent_run_id: parentRunId,
312
342
  extra: {
313
343
  ...rawConfig.extra,
314
344
  metadata: {
@@ -540,43 +570,33 @@ class AISDKExporter {
540
570
  relativeExecutionOrder: {},
541
571
  };
542
572
  const runId = (0, uuid_1.v5)(spanId, RUN_ID_NAMESPACE);
543
- let parentRunId = parentId
573
+ const parentRunId = parentId
544
574
  ? (0, uuid_1.v5)(parentId, RUN_ID_NAMESPACE)
545
575
  : undefined;
546
- // in LangSmith we currently only support certain spans
547
- // which may be deeply nested within other traces
548
- if (this.isRootRun(span))
549
- parentRunId = undefined;
550
576
  const traceMap = this.traceByMap[traceId];
551
577
  const run = this.getRunCreate(span);
552
- if (!run) {
553
- this.logDebug("skipping span", span);
554
- continue;
555
- }
556
578
  traceMap.relativeExecutionOrder[parentRunId ?? ROOT] ??= -1;
557
579
  traceMap.relativeExecutionOrder[parentRunId ?? ROOT] += 1;
558
580
  traceMap.nodeMap[runId] ??= {
559
581
  id: runId,
560
- parentId: parentRunId,
561
582
  startTime: span.startTime,
562
583
  run,
563
584
  sent: false,
585
+ interop: this.parseInteropFromMetadata(span),
564
586
  executionOrder: traceMap.relativeExecutionOrder[parentRunId ?? ROOT],
565
587
  };
566
588
  if (this.debug)
567
589
  console.log(`[${span.name}] ${runId}`, run);
568
590
  traceMap.childMap[parentRunId ?? ROOT] ??= [];
569
591
  traceMap.childMap[parentRunId ?? ROOT].push(traceMap.nodeMap[runId]);
570
- traceMap.interop = this.parseInteropFromMetadata(span);
571
592
  }
572
- // We separate `id`,
573
593
  const sampled = [];
594
+ const actions = [];
574
595
  for (const traceId of Object.keys(this.traceByMap)) {
575
596
  const traceMap = this.traceByMap[traceId];
576
597
  const queue = traceMap.childMap[ROOT]?.map((item) => ({
577
598
  item,
578
- dottedOrder: convertToDottedOrderFormat(item.startTime, item.id, item.executionOrder),
579
- traceId: item.id,
599
+ dotOrder: getDotOrder(item),
580
600
  })) ?? [];
581
601
  const seen = new Set();
582
602
  while (queue.length) {
@@ -585,71 +605,57 @@ class AISDKExporter {
585
605
  if (seen.has(task.item.id))
586
606
  continue;
587
607
  if (!task.item.sent) {
588
- let override = {
589
- id: task.item.id,
590
- parent_run_id: task.item.parentId,
591
- dotted_order: task.dottedOrder,
592
- trace_id: task.traceId,
593
- };
594
- if (traceMap.interop) {
595
- // attach the run to a parent run tree
596
- // - id: preserve
597
- // - parent_run_id: use existing parent run id or hook to the provided run tree
598
- // - dotted_order: append to the dotted_order of the parent run tree
599
- // - trace_id: use from the existing run tree
600
- if (traceMap.interop.type === "traceable") {
601
- override = {
602
- id: override.id,
603
- parent_run_id: override.parent_run_id ?? traceMap.interop.parentRunTree.id,
604
- dotted_order: [
605
- traceMap.interop.parentRunTree.dotted_order,
606
- override.dotted_order,
607
- ]
608
- .filter(Boolean)
609
- .join("."),
610
- trace_id: traceMap.interop.parentRunTree.trace_id,
611
- };
608
+ if (task.item.run != null) {
609
+ if (task.item.interop?.type === "user") {
610
+ actions.push({
611
+ type: "rename",
612
+ sourceRunId: task.item.id,
613
+ targetRunId: task.item.interop.userRunId,
614
+ });
612
615
  }
613
- else if (traceMap.interop.type === "user") {
614
- // Allow user to specify custom trace ID = run ID of the root run
615
- // - id: use user provided run ID if root run, otherwise preserve
616
- // - parent_run_id: use user provided run ID if root run, otherwise preserve
617
- // - dotted_order: replace the trace_id with the user provided run ID
618
- // - trace_id: use user provided run ID
619
- const userTraceId = traceMap.interop.userTraceId ?? (0, uuid_1.v4)();
620
- override = {
621
- id: override.id === override.trace_id ? userTraceId : override.id,
622
- parent_run_id: override.parent_run_id === override.trace_id
623
- ? userTraceId
624
- : override.parent_run_id,
625
- dotted_order: override.dotted_order.replace(override.trace_id, userTraceId),
626
- trace_id: userTraceId,
627
- };
616
+ if (task.item.interop?.type === "traceable") {
617
+ actions.push({
618
+ type: "reparent",
619
+ runId: task.item.id,
620
+ parentDotOrder: task.item.interop.parentRunTree.dotted_order,
621
+ });
622
+ }
623
+ let dotOrder = task.dotOrder;
624
+ for (const action of actions) {
625
+ if (action.type === "delete") {
626
+ dotOrder = removeDotOrder(dotOrder, action.runId);
627
+ }
628
+ if (action.type === "reparent") {
629
+ dotOrder = reparentDotOrder(dotOrder, action.runId, action.parentDotOrder);
630
+ }
631
+ if (action.type === "rename") {
632
+ dotOrder = dotOrder.replace(action.sourceRunId, action.targetRunId);
633
+ }
628
634
  }
635
+ sampled.push({
636
+ ...task.item.run,
637
+ ...getMutableRunCreate(dotOrder),
638
+ });
639
+ }
640
+ else {
641
+ actions.push({ type: "delete", runId: task.item.id });
629
642
  }
630
- sampled.push([override, task.item.run]);
631
643
  task.item.sent = true;
632
644
  }
633
645
  const children = traceMap.childMap[task.item.id] ?? [];
634
- queue.push(...children.map((child) => {
635
- return {
636
- item: child,
637
- dottedOrder: [
638
- task.dottedOrder,
639
- convertToDottedOrderFormat(child.startTime, child.id, child.executionOrder),
640
- ].join("."),
641
- traceId: task.traceId,
642
- };
643
- }));
646
+ queue.push(...children.map((item) => ({
647
+ item,
648
+ dotOrder: joinDotOrder(task.dotOrder, getDotOrder(item)),
649
+ })));
644
650
  }
645
651
  }
646
652
  this.logDebug(`sampled runs to be sent to LangSmith`, sampled);
647
- Promise.all(sampled.map(([override, value]) => this.client.createRun({ ...value, ...override }))).then(() => resultCallback({ code: 0 }), (error) => resultCallback({ code: 1, error }));
653
+ Promise.all(sampled.map((run) => this.client.createRun(run))).then(() => resultCallback({ code: 0 }), (error) => resultCallback({ code: 1, error }));
648
654
  }
649
655
  async shutdown() {
650
656
  // find nodes which are incomplete
651
- const incompleteNodes = Object.values(this.traceByMap).flatMap((trace) => Object.values(trace.nodeMap).filter((i) => !i.sent));
652
- this.logDebug("shutting down", { incompleteNodes: incompleteNodes.length });
657
+ const incompleteNodes = Object.values(this.traceByMap).flatMap((trace) => Object.values(trace.nodeMap).filter((i) => !i.sent && i.run != null));
658
+ this.logDebug("shutting down", { incompleteNodes });
653
659
  if (incompleteNodes.length > 0) {
654
660
  console.warn("Some incomplete nodes were found before shutdown and not sent to LangSmith.");
655
661
  }