langsmith 0.3.4 → 0.3.6

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/client.cjs CHANGED
@@ -127,7 +127,7 @@ class AutoBatchQueue {
127
127
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise
128
128
  itemPromiseResolve = resolve;
129
129
  });
130
- const size = (0, index_js_2.stringify)(item.item).length;
130
+ const size = (0, index_js_2.serialize)(item.item).length;
131
131
  this.items.push({
132
132
  action: item.action,
133
133
  payload: item.item,
@@ -683,7 +683,7 @@ class Client {
683
683
  const response = await this.caller.call((0, fetch_js_1._getFetchImplementation)(), `${this.apiUrl}/runs`, {
684
684
  method: "POST",
685
685
  headers,
686
- body: (0, index_js_2.stringify)(mergedRunCreateParam),
686
+ body: (0, index_js_2.serialize)(mergedRunCreateParam),
687
687
  signal: AbortSignal.timeout(this.timeout_ms),
688
688
  ...this.fetchOptions,
689
689
  });
@@ -743,7 +743,7 @@ class Client {
743
743
  }
744
744
  }
745
745
  if (batchChunks.post.length > 0 || batchChunks.patch.length > 0) {
746
- await this._postBatchIngestRuns((0, index_js_2.stringify)(batchChunks));
746
+ await this._postBatchIngestRuns((0, index_js_2.serialize)(batchChunks));
747
747
  }
748
748
  }
749
749
  async _postBatchIngestRuns(body) {
@@ -838,7 +838,7 @@ class Client {
838
838
  const { inputs, outputs, events, attachments, ...payload } = originalPayload;
839
839
  const fields = { inputs, outputs, events };
840
840
  // encode the main run payload
841
- const stringifiedPayload = (0, index_js_2.stringify)(payload);
841
+ const stringifiedPayload = (0, index_js_2.serialize)(payload);
842
842
  accumulatedParts.push({
843
843
  name: `${method}.${payload.id}`,
844
844
  payload: new Blob([stringifiedPayload], {
@@ -850,7 +850,7 @@ class Client {
850
850
  if (value === undefined) {
851
851
  continue;
852
852
  }
853
- const stringifiedValue = (0, index_js_2.stringify)(value);
853
+ const stringifiedValue = (0, index_js_2.serialize)(value);
854
854
  accumulatedParts.push({
855
855
  name: `${method}.${payload.id}.${key}`,
856
856
  payload: new Blob([stringifiedValue], {
@@ -966,7 +966,7 @@ class Client {
966
966
  const response = await this.caller.call((0, fetch_js_1._getFetchImplementation)(), `${this.apiUrl}/runs/${runId}`, {
967
967
  method: "PATCH",
968
968
  headers,
969
- body: (0, index_js_2.stringify)(run),
969
+ body: (0, index_js_2.serialize)(run),
970
970
  signal: AbortSignal.timeout(this.timeout_ms),
971
971
  ...this.fetchOptions,
972
972
  });
@@ -2853,14 +2853,14 @@ class Client {
2853
2853
  ...(example.split && { split: example.split }),
2854
2854
  };
2855
2855
  // Add main example data
2856
- const stringifiedExample = (0, index_js_2.stringify)(exampleBody);
2856
+ const stringifiedExample = (0, index_js_2.serialize)(exampleBody);
2857
2857
  const exampleBlob = new Blob([stringifiedExample], {
2858
2858
  type: "application/json",
2859
2859
  });
2860
2860
  formData.append(exampleId, exampleBlob);
2861
2861
  // Add inputs
2862
2862
  if (example.inputs) {
2863
- const stringifiedInputs = (0, index_js_2.stringify)(example.inputs);
2863
+ const stringifiedInputs = (0, index_js_2.serialize)(example.inputs);
2864
2864
  const inputsBlob = new Blob([stringifiedInputs], {
2865
2865
  type: "application/json",
2866
2866
  });
@@ -2868,7 +2868,7 @@ class Client {
2868
2868
  }
2869
2869
  // Add outputs if present
2870
2870
  if (example.outputs) {
2871
- const stringifiedOutputs = (0, index_js_2.stringify)(example.outputs);
2871
+ const stringifiedOutputs = (0, index_js_2.serialize)(example.outputs);
2872
2872
  const outputsBlob = new Blob([stringifiedOutputs], {
2873
2873
  type: "application/json",
2874
2874
  });
@@ -2893,7 +2893,7 @@ class Client {
2893
2893
  }
2894
2894
  }
2895
2895
  if (example.attachments_operations) {
2896
- const stringifiedAttachmentsOperations = (0, index_js_2.stringify)(example.attachments_operations);
2896
+ const stringifiedAttachmentsOperations = (0, index_js_2.serialize)(example.attachments_operations);
2897
2897
  const attachmentsOperationsBlob = new Blob([stringifiedAttachmentsOperations], {
2898
2898
  type: "application/json",
2899
2899
  });
@@ -2927,20 +2927,20 @@ class Client {
2927
2927
  ...(example.split && { split: example.split }),
2928
2928
  };
2929
2929
  // Add main example data
2930
- const stringifiedExample = (0, index_js_2.stringify)(exampleBody);
2930
+ const stringifiedExample = (0, index_js_2.serialize)(exampleBody);
2931
2931
  const exampleBlob = new Blob([stringifiedExample], {
2932
2932
  type: "application/json",
2933
2933
  });
2934
2934
  formData.append(exampleId, exampleBlob);
2935
2935
  // Add inputs
2936
- const stringifiedInputs = (0, index_js_2.stringify)(example.inputs);
2936
+ const stringifiedInputs = (0, index_js_2.serialize)(example.inputs);
2937
2937
  const inputsBlob = new Blob([stringifiedInputs], {
2938
2938
  type: "application/json",
2939
2939
  });
2940
2940
  formData.append(`${exampleId}.inputs`, inputsBlob);
2941
2941
  // Add outputs if present
2942
2942
  if (example.outputs) {
2943
- const stringifiedOutputs = (0, index_js_2.stringify)(example.outputs);
2943
+ const stringifiedOutputs = (0, index_js_2.serialize)(example.outputs);
2944
2944
  const outputsBlob = new Blob([stringifiedOutputs], {
2945
2945
  type: "application/json",
2946
2946
  });
package/dist/client.js CHANGED
@@ -8,7 +8,7 @@ import { warnOnce } from "./utils/warn.js";
8
8
  import { parsePromptIdentifier } from "./utils/prompts.js";
9
9
  import { raiseForStatus } from "./utils/error.js";
10
10
  import { _getFetchImplementation } from "./singletons/fetch.js";
11
- import { stringify as stringifyForTracing } from "./utils/fast-safe-stringify/index.js";
11
+ import { serialize as serializePayloadForTracing } from "./utils/fast-safe-stringify/index.js";
12
12
  export function mergeRuntimeEnvIntoRunCreate(run) {
13
13
  const runtimeEnv = getRuntimeEnvironment();
14
14
  const envVars = getLangChainEnvVarsMetadata();
@@ -100,7 +100,7 @@ export class AutoBatchQueue {
100
100
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise
101
101
  itemPromiseResolve = resolve;
102
102
  });
103
- const size = stringifyForTracing(item.item).length;
103
+ const size = serializePayloadForTracing(item.item).length;
104
104
  this.items.push({
105
105
  action: item.action,
106
106
  payload: item.item,
@@ -655,7 +655,7 @@ export class Client {
655
655
  const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs`, {
656
656
  method: "POST",
657
657
  headers,
658
- body: stringifyForTracing(mergedRunCreateParam),
658
+ body: serializePayloadForTracing(mergedRunCreateParam),
659
659
  signal: AbortSignal.timeout(this.timeout_ms),
660
660
  ...this.fetchOptions,
661
661
  });
@@ -715,7 +715,7 @@ export class Client {
715
715
  }
716
716
  }
717
717
  if (batchChunks.post.length > 0 || batchChunks.patch.length > 0) {
718
- await this._postBatchIngestRuns(stringifyForTracing(batchChunks));
718
+ await this._postBatchIngestRuns(serializePayloadForTracing(batchChunks));
719
719
  }
720
720
  }
721
721
  async _postBatchIngestRuns(body) {
@@ -810,7 +810,7 @@ export class Client {
810
810
  const { inputs, outputs, events, attachments, ...payload } = originalPayload;
811
811
  const fields = { inputs, outputs, events };
812
812
  // encode the main run payload
813
- const stringifiedPayload = stringifyForTracing(payload);
813
+ const stringifiedPayload = serializePayloadForTracing(payload);
814
814
  accumulatedParts.push({
815
815
  name: `${method}.${payload.id}`,
816
816
  payload: new Blob([stringifiedPayload], {
@@ -822,7 +822,7 @@ export class Client {
822
822
  if (value === undefined) {
823
823
  continue;
824
824
  }
825
- const stringifiedValue = stringifyForTracing(value);
825
+ const stringifiedValue = serializePayloadForTracing(value);
826
826
  accumulatedParts.push({
827
827
  name: `${method}.${payload.id}.${key}`,
828
828
  payload: new Blob([stringifiedValue], {
@@ -938,7 +938,7 @@ export class Client {
938
938
  const response = await this.caller.call(_getFetchImplementation(), `${this.apiUrl}/runs/${runId}`, {
939
939
  method: "PATCH",
940
940
  headers,
941
- body: stringifyForTracing(run),
941
+ body: serializePayloadForTracing(run),
942
942
  signal: AbortSignal.timeout(this.timeout_ms),
943
943
  ...this.fetchOptions,
944
944
  });
@@ -2825,14 +2825,14 @@ export class Client {
2825
2825
  ...(example.split && { split: example.split }),
2826
2826
  };
2827
2827
  // Add main example data
2828
- const stringifiedExample = stringifyForTracing(exampleBody);
2828
+ const stringifiedExample = serializePayloadForTracing(exampleBody);
2829
2829
  const exampleBlob = new Blob([stringifiedExample], {
2830
2830
  type: "application/json",
2831
2831
  });
2832
2832
  formData.append(exampleId, exampleBlob);
2833
2833
  // Add inputs
2834
2834
  if (example.inputs) {
2835
- const stringifiedInputs = stringifyForTracing(example.inputs);
2835
+ const stringifiedInputs = serializePayloadForTracing(example.inputs);
2836
2836
  const inputsBlob = new Blob([stringifiedInputs], {
2837
2837
  type: "application/json",
2838
2838
  });
@@ -2840,7 +2840,7 @@ export class Client {
2840
2840
  }
2841
2841
  // Add outputs if present
2842
2842
  if (example.outputs) {
2843
- const stringifiedOutputs = stringifyForTracing(example.outputs);
2843
+ const stringifiedOutputs = serializePayloadForTracing(example.outputs);
2844
2844
  const outputsBlob = new Blob([stringifiedOutputs], {
2845
2845
  type: "application/json",
2846
2846
  });
@@ -2865,7 +2865,7 @@ export class Client {
2865
2865
  }
2866
2866
  }
2867
2867
  if (example.attachments_operations) {
2868
- const stringifiedAttachmentsOperations = stringifyForTracing(example.attachments_operations);
2868
+ const stringifiedAttachmentsOperations = serializePayloadForTracing(example.attachments_operations);
2869
2869
  const attachmentsOperationsBlob = new Blob([stringifiedAttachmentsOperations], {
2870
2870
  type: "application/json",
2871
2871
  });
@@ -2899,20 +2899,20 @@ export class Client {
2899
2899
  ...(example.split && { split: example.split }),
2900
2900
  };
2901
2901
  // Add main example data
2902
- const stringifiedExample = stringifyForTracing(exampleBody);
2902
+ const stringifiedExample = serializePayloadForTracing(exampleBody);
2903
2903
  const exampleBlob = new Blob([stringifiedExample], {
2904
2904
  type: "application/json",
2905
2905
  });
2906
2906
  formData.append(exampleId, exampleBlob);
2907
2907
  // Add inputs
2908
- const stringifiedInputs = stringifyForTracing(example.inputs);
2908
+ const stringifiedInputs = serializePayloadForTracing(example.inputs);
2909
2909
  const inputsBlob = new Blob([stringifiedInputs], {
2910
2910
  type: "application/json",
2911
2911
  });
2912
2912
  formData.append(`${exampleId}.inputs`, inputsBlob);
2913
2913
  // Add outputs if present
2914
2914
  if (example.outputs) {
2915
- const stringifiedOutputs = stringifyForTracing(example.outputs);
2915
+ const stringifiedOutputs = serializePayloadForTracing(example.outputs);
2916
2916
  const outputsBlob = new Blob([stringifiedOutputs], {
2917
2917
  type: "application/json",
2918
2918
  });
@@ -574,7 +574,6 @@ class _ExperimentManager {
574
574
  projectMetadata["revision_id"] = await (0, _git_js_1.getDefaultRevisionId)();
575
575
  }
576
576
  await this.client.updateProject(experiment.id, {
577
- endTime: new Date().toISOString(),
578
577
  metadata: projectMetadata,
579
578
  });
580
579
  }
@@ -570,7 +570,6 @@ export class _ExperimentManager {
570
570
  projectMetadata["revision_id"] = await getDefaultRevisionId();
571
571
  }
572
572
  await this.client.updateProject(experiment.id, {
573
- endTime: new Date().toISOString(),
574
573
  metadata: projectMetadata,
575
574
  });
576
575
  }
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.3.4";
11
+ exports.__version__ = "0.3.6";
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.3.4";
5
+ export declare const __version__ = "0.3.6";
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.3.4";
5
+ export const __version__ = "0.3.6";
@@ -16,12 +16,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
17
17
  };
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.wrapEvaluator = exports.logOutputs = exports.logFeedback = exports.toBeSemanticCloseTo = exports.toBeAbsoluteCloseTo = exports.toBeRelativeCloseTo = exports.expect = exports.describe = exports.it = exports.test = void 0;
19
+ exports.wrapEvaluator = exports.logOutputs = exports.logFeedback = exports.expect = exports.describe = exports.it = exports.test = void 0;
20
20
  const globals_1 = require("@jest/globals");
21
21
  const matchers_js_1 = require("../utils/jestlike/matchers.cjs");
22
- Object.defineProperty(exports, "toBeRelativeCloseTo", { enumerable: true, get: function () { return matchers_js_1.toBeRelativeCloseTo; } });
23
- Object.defineProperty(exports, "toBeAbsoluteCloseTo", { enumerable: true, get: function () { return matchers_js_1.toBeAbsoluteCloseTo; } });
24
- Object.defineProperty(exports, "toBeSemanticCloseTo", { enumerable: true, get: function () { return matchers_js_1.toBeSemanticCloseTo; } });
25
22
  const evaluatedBy_js_1 = require("../utils/jestlike/vendor/evaluatedBy.cjs");
26
23
  Object.defineProperty(exports, "wrapEvaluator", { enumerable: true, get: function () { return evaluatedBy_js_1.wrapEvaluator; } });
27
24
  const index_js_1 = require("../utils/jestlike/index.cjs");
@@ -1,5 +1,5 @@
1
1
  /// <reference types="jest" />
2
- import { toBeRelativeCloseTo, toBeAbsoluteCloseTo, toBeSemanticCloseTo, type AbsoluteCloseToMatcherOptions, type SemanticCloseToMatcherOptions, type RelativeCloseToMatcherOptions } from "../utils/jestlike/matchers.js";
2
+ import { type AbsoluteCloseToMatcherOptions, type SemanticCloseToMatcherOptions, type RelativeCloseToMatcherOptions } from "../utils/jestlike/matchers.js";
3
3
  import type { SimpleEvaluator } from "../utils/jestlike/vendor/evaluatedBy.js";
4
4
  import { wrapEvaluator } from "../utils/jestlike/vendor/evaluatedBy.js";
5
5
  import { logFeedback, logOutputs } from "../utils/jestlike/index.js";
@@ -128,9 +128,9 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
128
128
  inputs: I;
129
129
  referenceOutputs?: O | undefined;
130
130
  } & Record<string, any>) => unknown, timeout?: number | undefined) => void;
131
- }, describe: import("../utils/jestlike/types.js").LangSmithJestDescribeWrapper & {
132
- only: import("../utils/jestlike/types.js").LangSmithJestDescribeWrapper;
133
- skip: import("../utils/jestlike/types.js").LangSmithJestDescribeWrapper;
131
+ }, describe: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper & {
132
+ only: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
133
+ skip: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
134
134
  }, expect: jest.Expect;
135
135
  export {
136
136
  /**
@@ -324,12 +324,6 @@ describe,
324
324
  * ```
325
325
  */
326
326
  expect,
327
- /** Whether the actual string value is close to the expected value in relative terms. */
328
- toBeRelativeCloseTo,
329
- /** Whether the actual string value is close to the expected value in absolute terms. */
330
- toBeAbsoluteCloseTo,
331
- /** Whether the actual string value is close to the expected value as scored by an embeddings model. */
332
- toBeSemanticCloseTo,
333
327
  /**
334
328
  * Log feedback associated with the current test, usually generated by some kind of
335
329
  * evaluator.
@@ -209,12 +209,6 @@ describe,
209
209
  * ```
210
210
  */
211
211
  expect,
212
- /** Whether the actual string value is close to the expected value in relative terms. */
213
- toBeRelativeCloseTo,
214
- /** Whether the actual string value is close to the expected value in absolute terms. */
215
- toBeAbsoluteCloseTo,
216
- /** Whether the actual string value is close to the expected value as scored by an embeddings model. */
217
- toBeSemanticCloseTo,
218
212
  /**
219
213
  * Log feedback associated with the current test, usually generated by some kind of
220
214
  * evaluator.
@@ -1,35 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stringify = void 0;
3
+ exports.serialize = void 0;
4
4
  /* eslint-disable */
5
5
  // @ts-nocheck
6
6
  var LIMIT_REPLACE_NODE = "[...]";
7
7
  var CIRCULAR_REPLACE_NODE = { result: "[Circular]" };
8
8
  var arr = [];
9
9
  var replacerStack = [];
10
+ const encoder = new TextEncoder();
10
11
  function defaultOptions() {
11
12
  return {
12
13
  depthLimit: Number.MAX_SAFE_INTEGER,
13
14
  edgesLimit: Number.MAX_SAFE_INTEGER,
14
15
  };
15
16
  }
17
+ function encodeString(str) {
18
+ return encoder.encode(str);
19
+ }
16
20
  // Regular stringify
17
- function stringify(obj, replacer, spacer, options) {
21
+ function serialize(obj, replacer, spacer, options) {
18
22
  try {
19
- return JSON.stringify(obj, replacer, spacer);
23
+ const str = JSON.stringify(obj, replacer, spacer);
24
+ return encodeString(str);
20
25
  }
21
26
  catch (e) {
22
27
  // Fall back to more complex stringify if circular reference
23
28
  if (!e.message?.includes("Converting circular structure to JSON")) {
24
29
  console.warn("[WARNING]: LangSmith received unserializable value.");
25
- return "[Unserializable]";
30
+ return encodeString("[Unserializable]");
26
31
  }
27
32
  console.warn("[WARNING]: LangSmith received circular JSON. This will decrease tracer performance.");
28
33
  if (typeof options === "undefined") {
29
34
  options = defaultOptions();
30
35
  }
31
36
  decirc(obj, "", 0, [], undefined, 0, options);
32
- var res;
37
+ let res;
33
38
  try {
34
39
  if (replacerStack.length === 0) {
35
40
  res = JSON.stringify(obj, replacer, spacer);
@@ -39,11 +44,11 @@ function stringify(obj, replacer, spacer, options) {
39
44
  }
40
45
  }
41
46
  catch (_) {
42
- return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]");
47
+ return encodeString("[unable to serialize, circular reference is too complex to analyze]");
43
48
  }
44
49
  finally {
45
50
  while (arr.length !== 0) {
46
- var part = arr.pop();
51
+ const part = arr.pop();
47
52
  if (part.length === 4) {
48
53
  Object.defineProperty(part[0], part[1], part[3]);
49
54
  }
@@ -52,10 +57,10 @@ function stringify(obj, replacer, spacer, options) {
52
57
  }
53
58
  }
54
59
  }
55
- return res;
60
+ return encodeString(res);
56
61
  }
57
62
  }
58
- exports.stringify = stringify;
63
+ exports.serialize = serialize;
59
64
  function setReplace(replace, val, k, parent) {
60
65
  var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
61
66
  if (propertyDescriptor.get !== undefined) {
@@ -1 +1 @@
1
- export declare function stringify(obj: any, replacer?: any, spacer?: any, options?: any): string;
1
+ export declare function serialize(obj: any, replacer?: any, spacer?: any, options?: any): Uint8Array;
@@ -4,29 +4,34 @@ var LIMIT_REPLACE_NODE = "[...]";
4
4
  var CIRCULAR_REPLACE_NODE = { result: "[Circular]" };
5
5
  var arr = [];
6
6
  var replacerStack = [];
7
+ const encoder = new TextEncoder();
7
8
  function defaultOptions() {
8
9
  return {
9
10
  depthLimit: Number.MAX_SAFE_INTEGER,
10
11
  edgesLimit: Number.MAX_SAFE_INTEGER,
11
12
  };
12
13
  }
14
+ function encodeString(str) {
15
+ return encoder.encode(str);
16
+ }
13
17
  // Regular stringify
14
- export function stringify(obj, replacer, spacer, options) {
18
+ export function serialize(obj, replacer, spacer, options) {
15
19
  try {
16
- return JSON.stringify(obj, replacer, spacer);
20
+ const str = JSON.stringify(obj, replacer, spacer);
21
+ return encodeString(str);
17
22
  }
18
23
  catch (e) {
19
24
  // Fall back to more complex stringify if circular reference
20
25
  if (!e.message?.includes("Converting circular structure to JSON")) {
21
26
  console.warn("[WARNING]: LangSmith received unserializable value.");
22
- return "[Unserializable]";
27
+ return encodeString("[Unserializable]");
23
28
  }
24
29
  console.warn("[WARNING]: LangSmith received circular JSON. This will decrease tracer performance.");
25
30
  if (typeof options === "undefined") {
26
31
  options = defaultOptions();
27
32
  }
28
33
  decirc(obj, "", 0, [], undefined, 0, options);
29
- var res;
34
+ let res;
30
35
  try {
31
36
  if (replacerStack.length === 0) {
32
37
  res = JSON.stringify(obj, replacer, spacer);
@@ -36,11 +41,11 @@ export function stringify(obj, replacer, spacer, options) {
36
41
  }
37
42
  }
38
43
  catch (_) {
39
- return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]");
44
+ return encodeString("[unable to serialize, circular reference is too complex to analyze]");
40
45
  }
41
46
  finally {
42
47
  while (arr.length !== 0) {
43
- var part = arr.pop();
48
+ const part = arr.pop();
44
49
  if (part.length === 4) {
45
50
  Object.defineProperty(part[0], part[1], part[3]);
46
51
  }
@@ -49,7 +54,7 @@ export function stringify(obj, replacer, spacer, options) {
49
54
  }
50
55
  }
51
56
  }
52
- return res;
57
+ return encodeString(res);
53
58
  }
54
59
  }
55
60
  function setReplace(replace, val, k, parent) {
@@ -40,6 +40,7 @@ const _random_name_js_1 = require("../../evaluation/_random_name.cjs");
40
40
  const matchers_js_1 = require("./matchers.cjs");
41
41
  const globals_js_1 = require("./globals.cjs");
42
42
  const chain_js_1 = require("./vendor/chain.cjs");
43
+ const env_js_1 = require("../env.cjs");
43
44
  const DEFAULT_TEST_TIMEOUT = 30_000;
44
45
  const UUID5_NAMESPACE = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
45
46
  // From https://stackoverflow.com/a/29497680
@@ -209,7 +210,7 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
209
210
  datasetId: dataset.id,
210
211
  });
211
212
  const experimentUrl = `${datasetUrl}/compare?selectedSessions=${project.id}`;
212
- console.log(`[LANGSMITH]: Experiment starting! View results at ${experimentUrl}`);
213
+ console.log(`[LANGSMITH]: Experiment starting for dataset "${datasetName}"!\n[LANGSMITH]: View results at ${experimentUrl}`);
213
214
  storageValue = {
214
215
  dataset,
215
216
  project,
@@ -220,22 +221,40 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
220
221
  return storageValue;
221
222
  }
222
223
  function wrapDescribeMethod(method) {
223
- return function (datasetName, fn, experimentConfig) {
224
+ return function (testSuiteName, fn, experimentConfig) {
224
225
  const client = experimentConfig?.client ?? globals_js_1.DEFAULT_TEST_CLIENT;
225
- return method(datasetName, () => {
226
+ const suiteName = experimentConfig?.testSuiteName ?? testSuiteName;
227
+ return method(suiteName, () => {
226
228
  const startTime = new Date();
227
229
  const suiteUuid = (0, uuid_1.v4)();
230
+ const environment = experimentConfig?.metadata?.ENVIRONMENT ??
231
+ (0, env_js_1.getEnvironmentVariable)("ENVIRONMENT");
232
+ const nodeEnv = experimentConfig?.metadata?.NODE_ENV ??
233
+ (0, env_js_1.getEnvironmentVariable)("NODE_ENV");
234
+ const langsmithEnvironment = experimentConfig?.metadata?.LANGSMITH_ENVIRONMENT ??
235
+ (0, env_js_1.getEnvironmentVariable)("LANGSMITH_ENVIRONMENT");
236
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
237
+ const metadata = {
238
+ ...experimentConfig?.metadata,
239
+ __ls_runner: testRunnerName,
240
+ };
241
+ if (environment !== undefined) {
242
+ metadata.ENVIRONMENT = environment;
243
+ }
244
+ if (nodeEnv !== undefined) {
245
+ metadata.NODE_ENV = nodeEnv;
246
+ }
247
+ if (langsmithEnvironment !== undefined) {
248
+ metadata.LANGSMITH_ENVIRONMENT = langsmithEnvironment;
249
+ }
228
250
  const context = {
229
251
  suiteUuid,
230
- suiteName: datasetName,
252
+ suiteName,
231
253
  client,
232
254
  createdAt: new Date().toISOString(),
233
255
  projectConfig: {
234
256
  ...experimentConfig,
235
- metadata: {
236
- ...experimentConfig?.metadata,
237
- __ls_runner: testRunnerName,
238
- },
257
+ metadata,
239
258
  },
240
259
  enableTestTracking: experimentConfig?.enableTestTracking,
241
260
  };
@@ -2,7 +2,7 @@
2
2
  import { KVMap } from "../../schemas.js";
3
3
  import { toBeRelativeCloseTo, toBeAbsoluteCloseTo, toBeSemanticCloseTo } from "./matchers.js";
4
4
  import { SimpleEvaluationResult } from "./types.js";
5
- import type { LangSmithJestlikeWrapperConfig, LangSmithJestlikeWrapperParams, LangSmithJestDescribeWrapper } from "./types.js";
5
+ import type { LangSmithJestlikeWrapperConfig, LangSmithJestlikeWrapperParams, LangSmithJestlikeDescribeWrapper } from "./types.js";
6
6
  export declare const STRIP_ANSI_REGEX: RegExp;
7
7
  export declare const TEST_ID_DELIMITER = ", test_id=";
8
8
  export declare function logFeedback(feedback: SimpleEvaluationResult, config?: {
@@ -83,9 +83,9 @@ export declare function generateWrapperFromJestlikeMethods(methods: Record<strin
83
83
  referenceOutputs?: O_1 | undefined;
84
84
  } & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
85
85
  };
86
- describe: LangSmithJestDescribeWrapper & {
87
- only: LangSmithJestDescribeWrapper;
88
- skip: LangSmithJestDescribeWrapper;
86
+ describe: LangSmithJestlikeDescribeWrapper & {
87
+ only: LangSmithJestlikeDescribeWrapper;
88
+ skip: LangSmithJestlikeDescribeWrapper;
89
89
  };
90
90
  expect: jest.Expect;
91
91
  toBeRelativeCloseTo: typeof toBeRelativeCloseTo;
@@ -11,6 +11,7 @@ import { randomName } from "../../evaluation/_random_name.js";
11
11
  import { toBeRelativeCloseTo, toBeAbsoluteCloseTo, toBeSemanticCloseTo, } from "./matchers.js";
12
12
  import { evaluatorLogFeedbackPromises, testWrapperAsyncLocalStorageInstance, _logTestFeedback, syncExamplePromises, trackingEnabled, DEFAULT_TEST_CLIENT, } from "./globals.js";
13
13
  import { wrapExpect } from "./vendor/chain.js";
14
+ import { getEnvironmentVariable } from "../env.js";
14
15
  const DEFAULT_TEST_TIMEOUT = 30_000;
15
16
  const UUID5_NAMESPACE = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
16
17
  // From https://stackoverflow.com/a/29497680
@@ -177,7 +178,7 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
177
178
  datasetId: dataset.id,
178
179
  });
179
180
  const experimentUrl = `${datasetUrl}/compare?selectedSessions=${project.id}`;
180
- console.log(`[LANGSMITH]: Experiment starting! View results at ${experimentUrl}`);
181
+ console.log(`[LANGSMITH]: Experiment starting for dataset "${datasetName}"!\n[LANGSMITH]: View results at ${experimentUrl}`);
181
182
  storageValue = {
182
183
  dataset,
183
184
  project,
@@ -188,22 +189,40 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
188
189
  return storageValue;
189
190
  }
190
191
  function wrapDescribeMethod(method) {
191
- return function (datasetName, fn, experimentConfig) {
192
+ return function (testSuiteName, fn, experimentConfig) {
192
193
  const client = experimentConfig?.client ?? DEFAULT_TEST_CLIENT;
193
- return method(datasetName, () => {
194
+ const suiteName = experimentConfig?.testSuiteName ?? testSuiteName;
195
+ return method(suiteName, () => {
194
196
  const startTime = new Date();
195
197
  const suiteUuid = v4();
198
+ const environment = experimentConfig?.metadata?.ENVIRONMENT ??
199
+ getEnvironmentVariable("ENVIRONMENT");
200
+ const nodeEnv = experimentConfig?.metadata?.NODE_ENV ??
201
+ getEnvironmentVariable("NODE_ENV");
202
+ const langsmithEnvironment = experimentConfig?.metadata?.LANGSMITH_ENVIRONMENT ??
203
+ getEnvironmentVariable("LANGSMITH_ENVIRONMENT");
204
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
205
+ const metadata = {
206
+ ...experimentConfig?.metadata,
207
+ __ls_runner: testRunnerName,
208
+ };
209
+ if (environment !== undefined) {
210
+ metadata.ENVIRONMENT = environment;
211
+ }
212
+ if (nodeEnv !== undefined) {
213
+ metadata.NODE_ENV = nodeEnv;
214
+ }
215
+ if (langsmithEnvironment !== undefined) {
216
+ metadata.LANGSMITH_ENVIRONMENT = langsmithEnvironment;
217
+ }
196
218
  const context = {
197
219
  suiteUuid,
198
- suiteName: datasetName,
220
+ suiteName,
199
221
  client,
200
222
  createdAt: new Date().toISOString(),
201
223
  projectConfig: {
202
224
  ...experimentConfig,
203
- metadata: {
204
- ...experimentConfig?.metadata,
205
- __ls_runner: testRunnerName,
206
- },
225
+ metadata,
207
226
  },
208
227
  enableTestTracking: experimentConfig?.enableTestTracking,
209
228
  };
@@ -1,4 +1,6 @@
1
+ import { CreateProjectParams } from "../../client.js";
1
2
  import { EvaluationResult } from "../../evaluation/evaluator.js";
3
+ import { Client } from "../../index.js";
2
4
  import type { RunTreeConfig } from "../../run_trees.js";
3
5
  import type { SimpleEvaluator } from "./vendor/evaluatedBy.js";
4
6
  export { type SimpleEvaluator };
@@ -11,7 +13,14 @@ export type LangSmithJestlikeWrapperParams<I, O> = {
11
13
  referenceOutputs: O;
12
14
  config?: LangSmithJestlikeWrapperConfig;
13
15
  };
14
- export type LangSmithJestDescribeWrapper = (name: string, fn: () => void | Promise<void>, config?: Partial<RunTreeConfig>) => void;
16
+ export type LangSmithJestlikeDescribeWrapperConfig = {
17
+ client?: Client;
18
+ enableTestTracking?: boolean;
19
+ testSuiteName?: string;
20
+ } & Partial<Omit<CreateProjectParams, "referenceDatasetId">>;
21
+ export type LangSmithJestlikeDescribeWrapper = (name: string, fn: () => void | Promise<void>, config?: LangSmithJestlikeDescribeWrapperConfig) => void;
22
+ /** @deprecated Import as `LangSmithJestlikeDescribeWrapper` instead. */
23
+ export type LangSmithJestDescribeWrapper = LangSmithJestlikeDescribeWrapper;
15
24
  export type SimpleEvaluationResult = {
16
25
  key: EvaluationResult["key"];
17
26
  score: NonNullable<EvaluationResult["score"]>;
@@ -16,12 +16,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
17
17
  };
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.wrapEvaluator = exports.logOutputs = exports.logFeedback = exports.toBeSemanticCloseTo = exports.toBeAbsoluteCloseTo = exports.toBeRelativeCloseTo = exports.expect = exports.describe = exports.it = exports.test = void 0;
19
+ exports.wrapEvaluator = exports.logOutputs = exports.logFeedback = exports.expect = exports.describe = exports.it = exports.test = void 0;
20
20
  const vitest_1 = require("vitest");
21
21
  const matchers_js_1 = require("../utils/jestlike/matchers.cjs");
22
- Object.defineProperty(exports, "toBeRelativeCloseTo", { enumerable: true, get: function () { return matchers_js_1.toBeRelativeCloseTo; } });
23
- Object.defineProperty(exports, "toBeAbsoluteCloseTo", { enumerable: true, get: function () { return matchers_js_1.toBeAbsoluteCloseTo; } });
24
- Object.defineProperty(exports, "toBeSemanticCloseTo", { enumerable: true, get: function () { return matchers_js_1.toBeSemanticCloseTo; } });
25
22
  const evaluatedBy_js_1 = require("../utils/jestlike/vendor/evaluatedBy.cjs");
26
23
  Object.defineProperty(exports, "wrapEvaluator", { enumerable: true, get: function () { return evaluatedBy_js_1.wrapEvaluator; } });
27
24
  const index_js_1 = require("../utils/jestlike/index.cjs");
@@ -1,6 +1,6 @@
1
1
  /// <reference types="jest" />
2
2
  import { Assertion } from "vitest";
3
- import { toBeRelativeCloseTo, toBeAbsoluteCloseTo, toBeSemanticCloseTo, type AbsoluteCloseToMatcherOptions, type SemanticCloseToMatcherOptions, type RelativeCloseToMatcherOptions } from "../utils/jestlike/matchers.js";
3
+ import { type AbsoluteCloseToMatcherOptions, type SemanticCloseToMatcherOptions, type RelativeCloseToMatcherOptions } from "../utils/jestlike/matchers.js";
4
4
  import type { SimpleEvaluator } from "../utils/jestlike/vendor/evaluatedBy.js";
5
5
  import { wrapEvaluator } from "../utils/jestlike/vendor/evaluatedBy.js";
6
6
  import { logFeedback, logOutputs } from "../utils/jestlike/index.js";
@@ -126,9 +126,9 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
126
126
  inputs: I;
127
127
  referenceOutputs?: O | undefined;
128
128
  } & Record<string, any>) => unknown, timeout?: number | undefined) => void;
129
- }, describe: import("../utils/jestlike/types.js").LangSmithJestDescribeWrapper & {
130
- only: import("../utils/jestlike/types.js").LangSmithJestDescribeWrapper;
131
- skip: import("../utils/jestlike/types.js").LangSmithJestDescribeWrapper;
129
+ }, describe: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper & {
130
+ only: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
131
+ skip: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
132
132
  }, expect: jest.Expect;
133
133
  export {
134
134
  /**
@@ -322,12 +322,6 @@ describe,
322
322
  * ```
323
323
  */
324
324
  expect,
325
- /** Whether the actual string value is close to the expected value in relative terms. */
326
- toBeRelativeCloseTo,
327
- /** Whether the actual string value is close to the expected value in absolute terms. */
328
- toBeAbsoluteCloseTo,
329
- /** Whether the actual string value is close to the expected value as scored by an embeddings model. */
330
- toBeSemanticCloseTo,
331
325
  /**
332
326
  * Log feedback associated with the current test, usually generated by some kind of
333
327
  * evaluator.
@@ -209,12 +209,6 @@ describe,
209
209
  * ```
210
210
  */
211
211
  expect,
212
- /** Whether the actual string value is close to the expected value in relative terms. */
213
- toBeRelativeCloseTo,
214
- /** Whether the actual string value is close to the expected value in absolute terms. */
215
- toBeAbsoluteCloseTo,
216
- /** Whether the actual string value is close to the expected value as scored by an embeddings model. */
217
- toBeSemanticCloseTo,
218
212
  /**
219
213
  * Log feedback associated with the current test, usually generated by some kind of
220
214
  * evaluator.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.",
5
5
  "packageManager": "yarn@1.22.19",
6
6
  "files": [