langsmith 0.3.53 → 0.3.55

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_IS_ROOT = exports.LANGSMITH_TRACEABLE = 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;
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_TRACEABLE_PARENT_OTEL_SPAN_ID = exports.LANGSMITH_IS_ROOT = exports.LANGSMITH_TRACEABLE = 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";
@@ -45,6 +45,7 @@ exports.LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
45
45
  exports.LANGSMITH_REFERENCE_EXAMPLE_ID = "langsmith.reference_example_id";
46
46
  exports.LANGSMITH_TRACEABLE = "langsmith.traceable";
47
47
  exports.LANGSMITH_IS_ROOT = "langsmith.is_root";
48
+ exports.LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID = "langsmith.traceable_parent_otel_span_id";
48
49
  // GenAI event names
49
50
  exports.GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
50
51
  exports.GEN_AI_USER_MESSAGE = "gen_ai.user.message";
@@ -40,6 +40,7 @@ export declare const LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
40
40
  export declare const LANGSMITH_REFERENCE_EXAMPLE_ID = "langsmith.reference_example_id";
41
41
  export declare const LANGSMITH_TRACEABLE = "langsmith.traceable";
42
42
  export declare const LANGSMITH_IS_ROOT = "langsmith.is_root";
43
+ export declare const LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID = "langsmith.traceable_parent_otel_span_id";
43
44
  export declare const GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
44
45
  export declare const GEN_AI_USER_MESSAGE = "gen_ai.user.message";
45
46
  export declare const GEN_AI_ASSISTANT_MESSAGE = "gen_ai.assistant.message";
@@ -42,6 +42,7 @@ export const LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
42
42
  export const LANGSMITH_REFERENCE_EXAMPLE_ID = "langsmith.reference_example_id";
43
43
  export const LANGSMITH_TRACEABLE = "langsmith.traceable";
44
44
  export const LANGSMITH_IS_ROOT = "langsmith.is_root";
45
+ export const LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID = "langsmith.traceable_parent_otel_span_id";
45
46
  // GenAI event names
46
47
  export const GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
47
48
  export const GEN_AI_USER_MESSAGE = "gen_ai.user.message";
@@ -59,6 +59,8 @@ class LangSmithOTLPSpanProcessor extends sdk_trace_base_1.BatchSpanProcessor {
59
59
  else {
60
60
  span.attributes[constants_js_1.LANGSMITH_PARENT_RUN_ID] =
61
61
  (0, utils_js_1.getUuidFromOtelSpanId)(traceableParentId);
62
+ span.attributes[constants_js_1.LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID] =
63
+ traceableParentId;
62
64
  }
63
65
  if (isTraceable) {
64
66
  super.onStart(span, parentContext);
@@ -1,5 +1,5 @@
1
1
  import { BatchSpanProcessor, } from "@opentelemetry/sdk-trace-base";
2
- import { LANGSMITH_IS_ROOT, LANGSMITH_PARENT_RUN_ID, LANGSMITH_TRACEABLE, } from "./constants.js";
2
+ import { LANGSMITH_IS_ROOT, LANGSMITH_PARENT_RUN_ID, LANGSMITH_TRACEABLE, LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID, } from "./constants.js";
3
3
  import { getUuidFromOtelSpanId } from "./utils.js";
4
4
  import { RunTree } from "../../run_trees.js";
5
5
  export function isTraceableSpan(span) {
@@ -55,6 +55,8 @@ export class LangSmithOTLPSpanProcessor extends BatchSpanProcessor {
55
55
  else {
56
56
  span.attributes[LANGSMITH_PARENT_RUN_ID] =
57
57
  getUuidFromOtelSpanId(traceableParentId);
58
+ span.attributes[LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID] =
59
+ traceableParentId;
58
60
  }
59
61
  if (isTraceable) {
60
62
  super.onStart(span, parentContext);
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.53";
13
+ exports.__version__ = "0.3.55";
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.53";
6
+ export declare const __version__ = "0.3.55";
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.53";
6
+ export const __version__ = "0.3.55";
package/dist/vercel.cjs CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AISDKExporter = void 0;
3
+ exports.AISDKExporter = exports.parseStrippedIsoTime = void 0;
4
4
  const vercel_js_1 = require("./utils/vercel.cjs");
5
5
  const index_js_1 = require("./index.cjs");
6
6
  const uuid_1 = require("uuid");
7
7
  const traceable_js_1 = require("./singletons/traceable.cjs");
8
8
  const env_js_1 = require("./utils/env.cjs");
9
9
  const env_js_2 = require("./env.cjs");
10
+ const constants_js_1 = require("./experimental/otel/constants.cjs");
10
11
  // Attempt to convert CoreMessage to a LangChain-compatible format
11
12
  // which allows us to render messages more nicely in LangSmith
12
13
  function convertCoreToSmith(message) {
@@ -18,19 +19,22 @@ function convertCoreToSmith(message) {
18
19
  return {
19
20
  type: "text",
20
21
  text: part.text,
21
- // @ts-expect-error Backcompat for AI SDK 4
22
+ // Backcompat for AI SDK 4
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
24
  ...part.experimental_providerMetadata,
23
25
  };
24
26
  }
25
27
  if (part.type === "tool-call") {
26
- // @ts-expect-error Backcompat for AI SDK 4
28
+ // Backcompat for AI SDK 4
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
30
  const legacyToolCallInput = part.args;
28
31
  return {
29
32
  type: "tool_use",
30
33
  name: part.toolName,
31
34
  id: part.toolCallId,
32
35
  input: legacyToolCallInput ?? part.input,
33
- // @ts-expect-error Backcompat for AI SDK 4
36
+ // Backcompat for AI SDK 4
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
38
  ...part.experimental_providerMetadata,
35
39
  };
36
40
  }
@@ -40,7 +44,8 @@ function convertCoreToSmith(message) {
40
44
  if (toolCalls.length > 0) {
41
45
  data.additional_kwargs ??= {};
42
46
  data.additional_kwargs.tool_calls = toolCalls.map((part) => {
43
- // @ts-expect-error Backcompat for AI SDK 4
47
+ // Backcompat for AI SDK 4
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
49
  const legacyToolCallInput = part.args;
45
50
  return {
46
51
  id: part.toolCallId,
@@ -64,7 +69,8 @@ function convertCoreToSmith(message) {
64
69
  return {
65
70
  type: "text",
66
71
  text: part.text,
67
- // @ts-expect-error Backcompat for AI SDK 4
72
+ // Backcompat for AI SDK 4
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
74
  ...part.experimental_providerMetadata,
69
75
  };
70
76
  }
@@ -99,7 +105,8 @@ function convertCoreToSmith(message) {
99
105
  return {
100
106
  type: "image_url",
101
107
  image_url: imageUrl,
102
- // @ts-expect-error Backcompat for AI SDK 4
108
+ // Backcompat for AI SDK 4
109
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
110
  ...part.experimental_providerMetadata,
104
111
  };
105
112
  }
@@ -113,7 +120,8 @@ function convertCoreToSmith(message) {
113
120
  }
114
121
  if (message.role === "tool") {
115
122
  const res = message.content.map((toolCall) => {
116
- // @ts-expect-error Backcompat for AI SDK 4
123
+ // Backcompat for AI SDK 4
124
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
125
  const legacyToolCallResult = toolCall.result;
118
126
  return {
119
127
  type: "tool",
@@ -172,6 +180,22 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
172
180
  return dotOrder;
173
181
  return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
174
182
  }
183
+ // Helper function to convert dotted order version of start time to ISO string
184
+ const parseStrippedIsoTime = (stripped) => {
185
+ const year = stripped.slice(0, 4);
186
+ const month = stripped.slice(4, 6);
187
+ const day = stripped.slice(6, 8);
188
+ const hour = stripped.slice(9, 11); // Skip 'T'
189
+ const minute = stripped.slice(11, 13);
190
+ const second = stripped.slice(13, 15);
191
+ const ms = stripped.slice(15, 18); // milliseconds
192
+ const us = stripped.length >= 21 ? stripped.slice(18, 21) : "000"; // microseconds
193
+ // Create ISO string with microsecond precision only if microseconds are present
194
+ return us !== "000"
195
+ ? `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}${us}Z`
196
+ : `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`;
197
+ };
198
+ exports.parseStrippedIsoTime = parseStrippedIsoTime;
175
199
  function getMutableRunCreate(dotOrder) {
176
200
  const segments = dotOrder.split(".").map((i) => {
177
201
  const [startTime, runId] = i.split("Z");
@@ -180,12 +204,14 @@ function getMutableRunCreate(dotOrder) {
180
204
  const traceId = segments[0].runId;
181
205
  const parentRunId = segments.at(-2)?.runId;
182
206
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
183
- const runId = segments.at(-1).runId;
207
+ const lastSegment = segments.at(-1);
208
+ const startTime = (0, exports.parseStrippedIsoTime)(lastSegment.startTime);
184
209
  return {
185
- id: runId,
210
+ id: lastSegment.runId,
186
211
  trace_id: traceId,
187
212
  dotted_order: dotOrder,
188
213
  parent_run_id: parentRunId,
214
+ start_time: startTime,
189
215
  };
190
216
  }
191
217
  function convertToTimestamp([seconds, nanoseconds]) {
@@ -667,6 +693,14 @@ class AISDKExporter {
667
693
  const { traceId, spanId } = span.spanContext();
668
694
  const runId = (0, uuid_1.v5)(spanId, RUN_ID_NAMESPACE);
669
695
  let parentId = getParentSpanId(span);
696
+ if (constants_js_1.LANGSMITH_IS_ROOT in span.attributes) {
697
+ parentId = undefined;
698
+ }
699
+ else if (constants_js_1.LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID in span.attributes &&
700
+ typeof span.attributes[constants_js_1.LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID] ===
701
+ "string") {
702
+ parentId = span.attributes[constants_js_1.LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID];
703
+ }
670
704
  let parentRunId = parentId
671
705
  ? (0, uuid_1.v5)(parentId, RUN_ID_NAMESPACE)
672
706
  : undefined;
package/dist/vercel.d.ts CHANGED
@@ -7,6 +7,7 @@ export interface TelemetrySettings extends AITelemetrySettings {
7
7
  /** Name of the run sent to LangSmith */
8
8
  runName?: string;
9
9
  }
10
+ export declare const parseStrippedIsoTime: (stripped: string) => string;
10
11
  /**
11
12
  * OpenTelemetry trace exporter for Vercel AI SDK.
12
13
  *
package/dist/vercel.js CHANGED
@@ -4,6 +4,7 @@ import { v5 as uuid5 } from "uuid";
4
4
  import { getCurrentRunTree } from "./singletons/traceable.js";
5
5
  import { getLangSmithEnvironmentVariable, getEnvironmentVariable, } from "./utils/env.js";
6
6
  import { isTracingEnabled } from "./env.js";
7
+ import { LANGSMITH_IS_ROOT, LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID, } from "./experimental/otel/constants.js";
7
8
  // Attempt to convert CoreMessage to a LangChain-compatible format
8
9
  // which allows us to render messages more nicely in LangSmith
9
10
  function convertCoreToSmith(message) {
@@ -15,19 +16,22 @@ function convertCoreToSmith(message) {
15
16
  return {
16
17
  type: "text",
17
18
  text: part.text,
18
- // @ts-expect-error Backcompat for AI SDK 4
19
+ // Backcompat for AI SDK 4
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
21
  ...part.experimental_providerMetadata,
20
22
  };
21
23
  }
22
24
  if (part.type === "tool-call") {
23
- // @ts-expect-error Backcompat for AI SDK 4
25
+ // Backcompat for AI SDK 4
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
27
  const legacyToolCallInput = part.args;
25
28
  return {
26
29
  type: "tool_use",
27
30
  name: part.toolName,
28
31
  id: part.toolCallId,
29
32
  input: legacyToolCallInput ?? part.input,
30
- // @ts-expect-error Backcompat for AI SDK 4
33
+ // Backcompat for AI SDK 4
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
35
  ...part.experimental_providerMetadata,
32
36
  };
33
37
  }
@@ -37,7 +41,8 @@ function convertCoreToSmith(message) {
37
41
  if (toolCalls.length > 0) {
38
42
  data.additional_kwargs ??= {};
39
43
  data.additional_kwargs.tool_calls = toolCalls.map((part) => {
40
- // @ts-expect-error Backcompat for AI SDK 4
44
+ // Backcompat for AI SDK 4
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
46
  const legacyToolCallInput = part.args;
42
47
  return {
43
48
  id: part.toolCallId,
@@ -61,7 +66,8 @@ function convertCoreToSmith(message) {
61
66
  return {
62
67
  type: "text",
63
68
  text: part.text,
64
- // @ts-expect-error Backcompat for AI SDK 4
69
+ // Backcompat for AI SDK 4
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
71
  ...part.experimental_providerMetadata,
66
72
  };
67
73
  }
@@ -96,7 +102,8 @@ function convertCoreToSmith(message) {
96
102
  return {
97
103
  type: "image_url",
98
104
  image_url: imageUrl,
99
- // @ts-expect-error Backcompat for AI SDK 4
105
+ // Backcompat for AI SDK 4
106
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
107
  ...part.experimental_providerMetadata,
101
108
  };
102
109
  }
@@ -110,7 +117,8 @@ function convertCoreToSmith(message) {
110
117
  }
111
118
  if (message.role === "tool") {
112
119
  const res = message.content.map((toolCall) => {
113
- // @ts-expect-error Backcompat for AI SDK 4
120
+ // Backcompat for AI SDK 4
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
122
  const legacyToolCallResult = toolCall.result;
115
123
  return {
116
124
  type: "tool",
@@ -169,6 +177,21 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
169
177
  return dotOrder;
170
178
  return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
171
179
  }
180
+ // Helper function to convert dotted order version of start time to ISO string
181
+ export const parseStrippedIsoTime = (stripped) => {
182
+ const year = stripped.slice(0, 4);
183
+ const month = stripped.slice(4, 6);
184
+ const day = stripped.slice(6, 8);
185
+ const hour = stripped.slice(9, 11); // Skip 'T'
186
+ const minute = stripped.slice(11, 13);
187
+ const second = stripped.slice(13, 15);
188
+ const ms = stripped.slice(15, 18); // milliseconds
189
+ const us = stripped.length >= 21 ? stripped.slice(18, 21) : "000"; // microseconds
190
+ // Create ISO string with microsecond precision only if microseconds are present
191
+ return us !== "000"
192
+ ? `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}${us}Z`
193
+ : `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`;
194
+ };
172
195
  function getMutableRunCreate(dotOrder) {
173
196
  const segments = dotOrder.split(".").map((i) => {
174
197
  const [startTime, runId] = i.split("Z");
@@ -177,12 +200,14 @@ function getMutableRunCreate(dotOrder) {
177
200
  const traceId = segments[0].runId;
178
201
  const parentRunId = segments.at(-2)?.runId;
179
202
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
180
- const runId = segments.at(-1).runId;
203
+ const lastSegment = segments.at(-1);
204
+ const startTime = parseStrippedIsoTime(lastSegment.startTime);
181
205
  return {
182
- id: runId,
206
+ id: lastSegment.runId,
183
207
  trace_id: traceId,
184
208
  dotted_order: dotOrder,
185
209
  parent_run_id: parentRunId,
210
+ start_time: startTime,
186
211
  };
187
212
  }
188
213
  function convertToTimestamp([seconds, nanoseconds]) {
@@ -664,6 +689,14 @@ export class AISDKExporter {
664
689
  const { traceId, spanId } = span.spanContext();
665
690
  const runId = uuid5(spanId, RUN_ID_NAMESPACE);
666
691
  let parentId = getParentSpanId(span);
692
+ if (LANGSMITH_IS_ROOT in span.attributes) {
693
+ parentId = undefined;
694
+ }
695
+ else if (LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID in span.attributes &&
696
+ typeof span.attributes[LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID] ===
697
+ "string") {
698
+ parentId = span.attributes[LANGSMITH_TRACEABLE_PARENT_OTEL_SPAN_ID];
699
+ }
667
700
  let parentRunId = parentId
668
701
  ? uuid5(parentId, RUN_ID_NAMESPACE)
669
702
  : undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.3.53",
3
+ "version": "0.3.55",
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": [