langsmith 0.3.40 → 0.3.41

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AI_SDK_TOOL_OPERATIONS = exports.AI_SDK_LLM_OPERATIONS = exports.GEN_AI_CHOICE = exports.GEN_AI_ASSISTANT_MESSAGE = exports.GEN_AI_USER_MESSAGE = exports.GEN_AI_SYSTEM_MESSAGE = exports.LANGSMITH_USAGE_METADATA = exports.LANGSMITH_PARENT_RUN_ID = exports.LANGSMITH_DOTTED_ORDER = exports.LANGSMITH_TRACE_ID = exports.LANGSMITH_RUN_ID = exports.LANGSMITH_REQUEST_HEADERS = exports.LANGSMITH_REQUEST_STREAMING = exports.LANGSMITH_RUNTIME = exports.LANGSMITH_TAGS = exports.LANGSMITH_METADATA = exports.LANGSMITH_NAME = exports.LANGSMITH_RUN_TYPE = exports.LANGSMITH_SESSION_NAME = exports.LANGSMITH_SESSION_ID = exports.GEN_AI_USAGE_OUTPUT_TOKEN_DETAILS = exports.GEN_AI_USAGE_INPUT_TOKEN_DETAILS = exports.GEN_AI_RESPONSE_SYSTEM_FINGERPRINT = exports.GEN_AI_RESPONSE_SERVICE_TIER = exports.GEN_AI_RESPONSE_ID = exports.GEN_AI_SERIALIZED_DOC = exports.GEN_AI_SERIALIZED_SIGNATURE = exports.GEN_AI_SERIALIZED_NAME = exports.GEN_AI_REQUEST_EXTRA_BODY = exports.GEN_AI_REQUEST_EXTRA_QUERY = exports.GENAI_COMPLETION = exports.GENAI_PROMPT = exports.GEN_AI_RESPONSE_FINISH_REASONS = exports.GEN_AI_REQUEST_PRESENCE_PENALTY = exports.GEN_AI_REQUEST_FREQUENCY_PENALTY = exports.GEN_AI_REQUEST_TOP_P = exports.GEN_AI_REQUEST_TEMPERATURE = exports.GEN_AI_REQUEST_MAX_TOKENS = exports.GEN_AI_USAGE_TOTAL_TOKENS = exports.GEN_AI_USAGE_OUTPUT_TOKENS = exports.GEN_AI_USAGE_INPUT_TOKENS = exports.GEN_AI_RESPONSE_MODEL = exports.GEN_AI_REQUEST_MODEL = exports.GEN_AI_SYSTEM = exports.GEN_AI_OPERATION_NAME = void 0;
3
+ exports.AI_SDK_TOOL_OPERATIONS = exports.AI_SDK_LLM_OPERATIONS = exports.GEN_AI_CHOICE = exports.GEN_AI_ASSISTANT_MESSAGE = exports.GEN_AI_USER_MESSAGE = exports.GEN_AI_SYSTEM_MESSAGE = exports.LANGSMITH_REFERENCE_EXAMPLE_ID = exports.LANGSMITH_USAGE_METADATA = exports.LANGSMITH_PARENT_RUN_ID = exports.LANGSMITH_DOTTED_ORDER = exports.LANGSMITH_TRACE_ID = exports.LANGSMITH_RUN_ID = exports.LANGSMITH_REQUEST_HEADERS = exports.LANGSMITH_REQUEST_STREAMING = exports.LANGSMITH_RUNTIME = exports.LANGSMITH_TAGS = exports.LANGSMITH_METADATA = exports.LANGSMITH_NAME = exports.LANGSMITH_RUN_TYPE = exports.LANGSMITH_SESSION_NAME = exports.LANGSMITH_SESSION_ID = exports.GEN_AI_USAGE_OUTPUT_TOKEN_DETAILS = exports.GEN_AI_USAGE_INPUT_TOKEN_DETAILS = exports.GEN_AI_RESPONSE_SYSTEM_FINGERPRINT = exports.GEN_AI_RESPONSE_SERVICE_TIER = exports.GEN_AI_RESPONSE_ID = exports.GEN_AI_SERIALIZED_DOC = exports.GEN_AI_SERIALIZED_SIGNATURE = exports.GEN_AI_SERIALIZED_NAME = exports.GEN_AI_REQUEST_EXTRA_BODY = exports.GEN_AI_REQUEST_EXTRA_QUERY = exports.GENAI_COMPLETION = exports.GENAI_PROMPT = exports.GEN_AI_RESPONSE_FINISH_REASONS = exports.GEN_AI_REQUEST_PRESENCE_PENALTY = exports.GEN_AI_REQUEST_FREQUENCY_PENALTY = exports.GEN_AI_REQUEST_TOP_P = exports.GEN_AI_REQUEST_TEMPERATURE = exports.GEN_AI_REQUEST_MAX_TOKENS = exports.GEN_AI_USAGE_TOTAL_TOKENS = exports.GEN_AI_USAGE_OUTPUT_TOKENS = exports.GEN_AI_USAGE_INPUT_TOKENS = exports.GEN_AI_RESPONSE_MODEL = exports.GEN_AI_REQUEST_MODEL = exports.GEN_AI_SYSTEM = exports.GEN_AI_OPERATION_NAME = void 0;
4
4
  // OpenTelemetry GenAI semantic convention attribute names
5
5
  exports.GEN_AI_OPERATION_NAME = "gen_ai.operation.name";
6
6
  exports.GEN_AI_SYSTEM = "gen_ai.system";
@@ -42,6 +42,7 @@ exports.LANGSMITH_TRACE_ID = "langsmith.trace.id";
42
42
  exports.LANGSMITH_DOTTED_ORDER = "langsmith.span.dotted_order";
43
43
  exports.LANGSMITH_PARENT_RUN_ID = "langsmith.span.parent_id";
44
44
  exports.LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
45
+ exports.LANGSMITH_REFERENCE_EXAMPLE_ID = "langsmith.reference_example_id";
45
46
  // GenAI event names
46
47
  exports.GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
47
48
  exports.GEN_AI_USER_MESSAGE = "gen_ai.user.message";
@@ -37,6 +37,7 @@ export declare const LANGSMITH_TRACE_ID = "langsmith.trace.id";
37
37
  export declare const LANGSMITH_DOTTED_ORDER = "langsmith.span.dotted_order";
38
38
  export declare const LANGSMITH_PARENT_RUN_ID = "langsmith.span.parent_id";
39
39
  export declare const LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
40
+ export declare const LANGSMITH_REFERENCE_EXAMPLE_ID = "langsmith.reference_example_id";
40
41
  export declare const GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
41
42
  export declare const GEN_AI_USER_MESSAGE = "gen_ai.user.message";
42
43
  export declare const GEN_AI_ASSISTANT_MESSAGE = "gen_ai.assistant.message";
@@ -39,6 +39,7 @@ export const LANGSMITH_TRACE_ID = "langsmith.trace.id";
39
39
  export const LANGSMITH_DOTTED_ORDER = "langsmith.span.dotted_order";
40
40
  export const LANGSMITH_PARENT_RUN_ID = "langsmith.span.parent_id";
41
41
  export const LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
42
+ export const LANGSMITH_REFERENCE_EXAMPLE_ID = "langsmith.reference_example_id";
42
43
  // GenAI event names
43
44
  export const GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
44
45
  export const GEN_AI_USER_MESSAGE = "gen_ai.user.message";
@@ -79,11 +79,11 @@ class LangSmithOTLPTraceExporter extends exporter_trace_otlp_proto_1.OTLPTraceEx
79
79
  // Configure headers with API key and project if available
80
80
  let defaultHeaderString = (0, env_js_2.getEnvironmentVariable)("OTEL_EXPORTER_OTLP_HEADERS") ?? "";
81
81
  if (!defaultHeaderString) {
82
- const apiKey = (0, env_js_2.getLangSmithEnvironmentVariable)("API_KEY");
82
+ const apiKey = config?.apiKey ?? (0, env_js_2.getLangSmithEnvironmentVariable)("API_KEY");
83
83
  if (apiKey) {
84
84
  defaultHeaderString = `x-api-key=${apiKey}`;
85
85
  }
86
- const project = (0, env_js_2.getLangSmithEnvironmentVariable)("PROJECT");
86
+ const project = config?.projectName ?? (0, env_js_2.getLangSmithEnvironmentVariable)("PROJECT");
87
87
  if (project) {
88
88
  defaultHeaderString += `,Langsmith-Project=${project}`;
89
89
  }
@@ -138,9 +138,16 @@ class LangSmithOTLPTraceExporter extends exporter_trace_otlp_proto_1.OTLPTraceEx
138
138
  // Iterate over all attributes starting with "ai.telemetry.metadata"
139
139
  for (const [key, value] of Object.entries(span.attributes)) {
140
140
  if (key.startsWith("ai.telemetry.metadata.")) {
141
- const metadataKey = key.replace("ai.telemetry.metadata.", "");
142
- span.attributes[`${constants.LANGSMITH_METADATA}.${metadataKey}`] =
143
- value;
141
+ if (key === "ai.telemetry.metadata.ls_project_name") {
142
+ span.attributes[constants.LANGSMITH_SESSION_NAME] = value;
143
+ }
144
+ else if (key === "ai.telemetry.metadata.ls_project_id") {
145
+ span.attributes[constants.LANGSMITH_SESSION_ID] = value;
146
+ }
147
+ else {
148
+ const metadataKey = key.replace("ai.telemetry.metadata.", "");
149
+ span.attributes[`${constants.LANGSMITH_METADATA}.${metadataKey}`] = value;
150
+ }
144
151
  delete span.attributes[key];
145
152
  }
146
153
  }
@@ -24,6 +24,14 @@ export type LangSmithOTLPTraceExporterConfig = ConstructorParameters<typeof OTLP
24
24
  * @returns A transformed version of the span.
25
25
  */
26
26
  transformExportedSpan?: (span: ReadableSpan) => ReadableSpan | Promise<ReadableSpan>;
27
+ /**
28
+ * The API key to use for the exporter.
29
+ */
30
+ apiKey?: string;
31
+ /**
32
+ * The name of the project to export traces to.
33
+ */
34
+ projectName?: string;
27
35
  };
28
36
  /**
29
37
  * LangSmith OpenTelemetry trace exporter that extends the standard OTLP trace exporter
@@ -43,11 +43,11 @@ export class LangSmithOTLPTraceExporter extends OTLPTraceExporter {
43
43
  // Configure headers with API key and project if available
44
44
  let defaultHeaderString = getEnvironmentVariable("OTEL_EXPORTER_OTLP_HEADERS") ?? "";
45
45
  if (!defaultHeaderString) {
46
- const apiKey = getLangSmithEnvironmentVariable("API_KEY");
46
+ const apiKey = config?.apiKey ?? getLangSmithEnvironmentVariable("API_KEY");
47
47
  if (apiKey) {
48
48
  defaultHeaderString = `x-api-key=${apiKey}`;
49
49
  }
50
- const project = getLangSmithEnvironmentVariable("PROJECT");
50
+ const project = config?.projectName ?? getLangSmithEnvironmentVariable("PROJECT");
51
51
  if (project) {
52
52
  defaultHeaderString += `,Langsmith-Project=${project}`;
53
53
  }
@@ -102,9 +102,16 @@ export class LangSmithOTLPTraceExporter extends OTLPTraceExporter {
102
102
  // Iterate over all attributes starting with "ai.telemetry.metadata"
103
103
  for (const [key, value] of Object.entries(span.attributes)) {
104
104
  if (key.startsWith("ai.telemetry.metadata.")) {
105
- const metadataKey = key.replace("ai.telemetry.metadata.", "");
106
- span.attributes[`${constants.LANGSMITH_METADATA}.${metadataKey}`] =
107
- value;
105
+ if (key === "ai.telemetry.metadata.ls_project_name") {
106
+ span.attributes[constants.LANGSMITH_SESSION_NAME] = value;
107
+ }
108
+ else if (key === "ai.telemetry.metadata.ls_project_id") {
109
+ span.attributes[constants.LANGSMITH_SESSION_ID] = value;
110
+ }
111
+ else {
112
+ const metadataKey = key.replace("ai.telemetry.metadata.", "");
113
+ span.attributes[`${constants.LANGSMITH_METADATA}.${metadataKey}`] = value;
114
+ }
108
115
  delete span.attributes[key];
109
116
  }
110
117
  }
package/dist/index.cjs CHANGED
@@ -10,4 +10,4 @@ Object.defineProperty(exports, "overrideFetchImplementation", { enumerable: true
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
12
  // Update using yarn bump-version
13
- exports.__version__ = "0.3.40";
13
+ exports.__version__ = "0.3.41";
package/dist/index.d.ts CHANGED
@@ -3,4 +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 declare const __version__ = "0.3.40";
6
+ export declare const __version__ = "0.3.41";
package/dist/index.js CHANGED
@@ -3,4 +3,4 @@ export { RunTree } from "./run_trees.js";
3
3
  export { overrideFetchImplementation } from "./singletons/fetch.js";
4
4
  export { getDefaultProjectName } from "./utils/project.js";
5
5
  // Update using yarn bump-version
6
- export const __version__ = "0.3.40";
6
+ export const __version__ = "0.3.41";
@@ -12,6 +12,7 @@ const env_js_2 = require("./utils/env.cjs");
12
12
  const index_js_1 = require("./index.cjs");
13
13
  const otel_js_1 = require("./singletons/otel.cjs");
14
14
  const utils_js_1 = require("./experimental/otel/utils.cjs");
15
+ const constants_js_2 = require("./experimental/otel/constants.cjs");
15
16
  traceable_js_1.AsyncLocalStorageProviderSingleton.initializeGlobalInstance(new node_async_hooks_1.AsyncLocalStorage());
16
17
  /**
17
18
  * Create OpenTelemetry context manager from RunTree if OTEL is enabled.
@@ -29,10 +30,13 @@ function maybeCreateOtelContext(runTree, tracer
29
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
31
  return (fn) => {
31
32
  const resolvedTracer = tracer ?? otel_trace.getTracer("langsmith", index_js_1.__version__);
33
+ const attributes = {};
34
+ if (runTree.reference_example_id) {
35
+ attributes[constants_js_2.LANGSMITH_REFERENCE_EXAMPLE_ID] =
36
+ runTree.reference_example_id;
37
+ }
32
38
  return resolvedTracer.startActiveSpan(runTree.name, {
33
- attributes: {
34
- "langsmith.traceable": "true",
35
- },
39
+ attributes,
36
40
  }, () => {
37
41
  otel_trace.setSpanContext(otel_context.active(), spanContext);
38
42
  return fn();
package/dist/traceable.js CHANGED
@@ -8,6 +8,7 @@ import { getEnvironmentVariable } from "./utils/env.js";
8
8
  import { __version__ } from "./index.js";
9
9
  import { getOTELTrace, getOTELContext } from "./singletons/otel.js";
10
10
  import { createOtelSpanContextFromRun } from "./experimental/otel/utils.js";
11
+ import { LANGSMITH_REFERENCE_EXAMPLE_ID } from "./experimental/otel/constants.js";
11
12
  AsyncLocalStorageProviderSingleton.initializeGlobalInstance(new AsyncLocalStorage());
12
13
  /**
13
14
  * Create OpenTelemetry context manager from RunTree if OTEL is enabled.
@@ -25,10 +26,13 @@ function maybeCreateOtelContext(runTree, tracer
25
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
27
  return (fn) => {
27
28
  const resolvedTracer = tracer ?? otel_trace.getTracer("langsmith", __version__);
29
+ const attributes = {};
30
+ if (runTree.reference_example_id) {
31
+ attributes[LANGSMITH_REFERENCE_EXAMPLE_ID] =
32
+ runTree.reference_example_id;
33
+ }
28
34
  return resolvedTracer.startActiveSpan(runTree.name, {
29
- attributes: {
30
- "langsmith.traceable": "true",
31
- },
35
+ attributes,
32
36
  }, () => {
33
37
  otel_trace.setSpanContext(otel_context.active(), spanContext);
34
38
  return fn();
@@ -18,10 +18,52 @@ function defaultOptions() {
18
18
  function encodeString(str) {
19
19
  return encoder.encode(str);
20
20
  }
21
+ // Shared function to handle well-known types
22
+ function serializeWellKnownTypes(val) {
23
+ if (val && typeof val === "object" && val !== null) {
24
+ if (val instanceof Map) {
25
+ return Object.fromEntries(val);
26
+ }
27
+ else if (val instanceof Set) {
28
+ return Array.from(val);
29
+ }
30
+ else if (val instanceof Date) {
31
+ return val.toISOString();
32
+ }
33
+ else if (val instanceof RegExp) {
34
+ return val.toString();
35
+ }
36
+ else if (val instanceof Error) {
37
+ return {
38
+ name: val.name,
39
+ message: val.message,
40
+ };
41
+ }
42
+ }
43
+ else if (typeof val === "bigint") {
44
+ return val.toString();
45
+ }
46
+ return val;
47
+ }
48
+ // Default replacer function to handle well-known types
49
+ function createDefaultReplacer(userReplacer) {
50
+ return function (key, val) {
51
+ // Apply user replacer first if provided
52
+ if (userReplacer) {
53
+ const userResult = userReplacer.call(this, key, val);
54
+ // If user replacer returned undefined, fall back to our serialization
55
+ if (userResult !== undefined) {
56
+ return userResult;
57
+ }
58
+ }
59
+ // Fall back to our well-known type handling
60
+ return serializeWellKnownTypes(val);
61
+ };
62
+ }
21
63
  // Regular stringify
22
64
  function serialize(obj, errorContext, replacer, spacer, options) {
23
65
  try {
24
- const str = JSON.stringify(obj, replacer, spacer);
66
+ const str = JSON.stringify(obj, createDefaultReplacer(replacer), spacer);
25
67
  return encodeString(str);
26
68
  }
27
69
  catch (e) {
@@ -107,6 +149,8 @@ function decirc(val, k, edgeIndex, stack, parent, depth, options) {
107
149
  }
108
150
  }
109
151
  else {
152
+ // Handle well-known types before Object.keys iteration
153
+ val = serializeWellKnownTypes(val);
110
154
  var keys = Object.keys(val);
111
155
  for (i = 0; i < keys.length; i++) {
112
156
  var key = keys[i];
@@ -193,6 +237,8 @@ function deterministicDecirc(val, k, edgeIndex, stack, parent, depth, options) {
193
237
  }
194
238
  }
195
239
  else {
240
+ // Handle well-known types before Object.keys iteration
241
+ val = serializeWellKnownTypes(val);
196
242
  // Create a temporary object in the required way
197
243
  var tmp = {};
198
244
  var keys = Object.keys(val).sort(compareFunction);
@@ -15,10 +15,52 @@ function defaultOptions() {
15
15
  function encodeString(str) {
16
16
  return encoder.encode(str);
17
17
  }
18
+ // Shared function to handle well-known types
19
+ function serializeWellKnownTypes(val) {
20
+ if (val && typeof val === "object" && val !== null) {
21
+ if (val instanceof Map) {
22
+ return Object.fromEntries(val);
23
+ }
24
+ else if (val instanceof Set) {
25
+ return Array.from(val);
26
+ }
27
+ else if (val instanceof Date) {
28
+ return val.toISOString();
29
+ }
30
+ else if (val instanceof RegExp) {
31
+ return val.toString();
32
+ }
33
+ else if (val instanceof Error) {
34
+ return {
35
+ name: val.name,
36
+ message: val.message,
37
+ };
38
+ }
39
+ }
40
+ else if (typeof val === "bigint") {
41
+ return val.toString();
42
+ }
43
+ return val;
44
+ }
45
+ // Default replacer function to handle well-known types
46
+ function createDefaultReplacer(userReplacer) {
47
+ return function (key, val) {
48
+ // Apply user replacer first if provided
49
+ if (userReplacer) {
50
+ const userResult = userReplacer.call(this, key, val);
51
+ // If user replacer returned undefined, fall back to our serialization
52
+ if (userResult !== undefined) {
53
+ return userResult;
54
+ }
55
+ }
56
+ // Fall back to our well-known type handling
57
+ return serializeWellKnownTypes(val);
58
+ };
59
+ }
18
60
  // Regular stringify
19
61
  export function serialize(obj, errorContext, replacer, spacer, options) {
20
62
  try {
21
- const str = JSON.stringify(obj, replacer, spacer);
63
+ const str = JSON.stringify(obj, createDefaultReplacer(replacer), spacer);
22
64
  return encodeString(str);
23
65
  }
24
66
  catch (e) {
@@ -104,6 +146,8 @@ function decirc(val, k, edgeIndex, stack, parent, depth, options) {
104
146
  }
105
147
  }
106
148
  else {
149
+ // Handle well-known types before Object.keys iteration
150
+ val = serializeWellKnownTypes(val);
107
151
  var keys = Object.keys(val);
108
152
  for (i = 0; i < keys.length; i++) {
109
153
  var key = keys[i];
@@ -190,6 +234,8 @@ function deterministicDecirc(val, k, edgeIndex, stack, parent, depth, options) {
190
234
  }
191
235
  }
192
236
  else {
237
+ // Handle well-known types before Object.keys iteration
238
+ val = serializeWellKnownTypes(val);
193
239
  // Create a temporary object in the required way
194
240
  var tmp = {};
195
241
  var keys = Object.keys(val).sort(compareFunction);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.3.40",
3
+ "version": "0.3.41",
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": [