langsmith 0.3.52 → 0.3.54
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/experimental/otel/processor.cjs +4 -35
- package/dist/experimental/otel/processor.js +6 -37
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/run_trees.cjs +0 -1
- package/dist/run_trees.d.ts +0 -1
- package/dist/run_trees.js +1 -1
- package/dist/vercel.cjs +29 -48
- package/dist/vercel.d.ts +1 -11
- package/dist/vercel.js +29 -46
- package/package.json +1 -1
|
@@ -6,24 +6,10 @@ const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
|
|
6
6
|
const constants_js_1 = require("./constants.cjs");
|
|
7
7
|
const utils_js_1 = require("./utils.cjs");
|
|
8
8
|
const run_trees_js_1 = require("../../run_trees.cjs");
|
|
9
|
-
const NANOSECOND_DIGITS = 9;
|
|
10
|
-
const MICROSECOND_DIGITS = 6;
|
|
11
9
|
function isTraceableSpan(span) {
|
|
12
10
|
return (span.attributes[constants_js_1.LANGSMITH_TRACEABLE] === "true" ||
|
|
13
11
|
typeof span.attributes["ai.operationId"] === "string");
|
|
14
12
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Convert hrTime to timestamp, for example "2019-05-14T17:00:00.000123Z"
|
|
17
|
-
* @param time
|
|
18
|
-
*/
|
|
19
|
-
function hrTimeToTimeStamp(time) {
|
|
20
|
-
const precision = NANOSECOND_DIGITS;
|
|
21
|
-
const tmp = `${"0".repeat(precision)}${time[1]}Z`;
|
|
22
|
-
const nanoString = tmp.substring(tmp.length - precision - 1);
|
|
23
|
-
const date = new Date(time[0] * 1000).toISOString();
|
|
24
|
-
// We only need 6 digits of precision for the dotted order
|
|
25
|
-
return `${date.replace("000Z", nanoString.slice(0, MICROSECOND_DIGITS))}Z`;
|
|
26
|
-
}
|
|
27
13
|
function getParentSpanId(span) {
|
|
28
14
|
// Backcompat shim to support OTEL 1.x and 2.x
|
|
29
15
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -53,35 +39,20 @@ class LangSmithOTLPSpanProcessor extends sdk_trace_base_1.BatchSpanProcessor {
|
|
|
53
39
|
this.traceMap[span.spanContext().traceId].spanCount++;
|
|
54
40
|
const isTraceable = isTraceableSpan(span);
|
|
55
41
|
const parentSpanId = getParentSpanId(span);
|
|
42
|
+
this.traceMap[span.spanContext().traceId].spanInfo[span.spanContext().spanId] = {
|
|
43
|
+
isTraceable,
|
|
44
|
+
parentSpanId,
|
|
45
|
+
};
|
|
56
46
|
let currentCandidateParentSpanId = parentSpanId;
|
|
57
47
|
let traceableParentId;
|
|
58
|
-
let parentDottedOrder;
|
|
59
|
-
// LangSmith uses the first span's id as the trace id, NOT the actual OTEL trace id
|
|
60
|
-
// Default to the current span if no parent information is present
|
|
61
|
-
let lsTraceId = (0, utils_js_1.getUuidFromOtelSpanId)(span.spanContext().spanId);
|
|
62
48
|
while (currentCandidateParentSpanId) {
|
|
63
49
|
const currentSpanInfo = this.traceMap[span.spanContext().traceId].spanInfo[currentCandidateParentSpanId];
|
|
64
50
|
if (currentSpanInfo?.isTraceable) {
|
|
65
51
|
traceableParentId = currentCandidateParentSpanId;
|
|
66
|
-
parentDottedOrder = currentSpanInfo.dottedOrder;
|
|
67
|
-
lsTraceId = currentSpanInfo.lsTraceId;
|
|
68
52
|
break;
|
|
69
53
|
}
|
|
70
54
|
currentCandidateParentSpanId = currentSpanInfo?.parentSpanId;
|
|
71
55
|
}
|
|
72
|
-
const startTimestamp = hrTimeToTimeStamp(span.startTime);
|
|
73
|
-
const spanUuid = (0, utils_js_1.getUuidFromOtelSpanId)(span.spanContext().spanId);
|
|
74
|
-
const dottedOrderComponent = (0, run_trees_js_1.stripNonAlphanumeric)(startTimestamp) + spanUuid;
|
|
75
|
-
const currentDottedOrder = parentDottedOrder
|
|
76
|
-
? `${parentDottedOrder}.${dottedOrderComponent}`
|
|
77
|
-
: dottedOrderComponent;
|
|
78
|
-
this.traceMap[span.spanContext().traceId].spanInfo[span.spanContext().spanId] = {
|
|
79
|
-
isTraceable,
|
|
80
|
-
lsTraceId,
|
|
81
|
-
spanId: span.spanContext().spanId,
|
|
82
|
-
parentSpanId,
|
|
83
|
-
dottedOrder: currentDottedOrder,
|
|
84
|
-
};
|
|
85
56
|
if (!traceableParentId) {
|
|
86
57
|
span.attributes[constants_js_1.LANGSMITH_IS_ROOT] = true;
|
|
87
58
|
}
|
|
@@ -89,8 +60,6 @@ class LangSmithOTLPSpanProcessor extends sdk_trace_base_1.BatchSpanProcessor {
|
|
|
89
60
|
span.attributes[constants_js_1.LANGSMITH_PARENT_RUN_ID] =
|
|
90
61
|
(0, utils_js_1.getUuidFromOtelSpanId)(traceableParentId);
|
|
91
62
|
}
|
|
92
|
-
span.attributes[constants_js_1.LANGSMITH_DOTTED_ORDER] = currentDottedOrder;
|
|
93
|
-
span.attributes[constants_js_1.LANGSMITH_TRACE_ID] = lsTraceId;
|
|
94
63
|
if (isTraceable) {
|
|
95
64
|
super.onStart(span, parentContext);
|
|
96
65
|
}
|
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
import { BatchSpanProcessor, } from "@opentelemetry/sdk-trace-base";
|
|
2
|
-
import { LANGSMITH_IS_ROOT, LANGSMITH_PARENT_RUN_ID, LANGSMITH_TRACEABLE,
|
|
2
|
+
import { LANGSMITH_IS_ROOT, LANGSMITH_PARENT_RUN_ID, LANGSMITH_TRACEABLE, } from "./constants.js";
|
|
3
3
|
import { getUuidFromOtelSpanId } from "./utils.js";
|
|
4
|
-
import { RunTree
|
|
5
|
-
const NANOSECOND_DIGITS = 9;
|
|
6
|
-
const MICROSECOND_DIGITS = 6;
|
|
4
|
+
import { RunTree } from "../../run_trees.js";
|
|
7
5
|
export function isTraceableSpan(span) {
|
|
8
6
|
return (span.attributes[LANGSMITH_TRACEABLE] === "true" ||
|
|
9
7
|
typeof span.attributes["ai.operationId"] === "string");
|
|
10
8
|
}
|
|
11
|
-
/**
|
|
12
|
-
* Convert hrTime to timestamp, for example "2019-05-14T17:00:00.000123Z"
|
|
13
|
-
* @param time
|
|
14
|
-
*/
|
|
15
|
-
function hrTimeToTimeStamp(time) {
|
|
16
|
-
const precision = NANOSECOND_DIGITS;
|
|
17
|
-
const tmp = `${"0".repeat(precision)}${time[1]}Z`;
|
|
18
|
-
const nanoString = tmp.substring(tmp.length - precision - 1);
|
|
19
|
-
const date = new Date(time[0] * 1000).toISOString();
|
|
20
|
-
// We only need 6 digits of precision for the dotted order
|
|
21
|
-
return `${date.replace("000Z", nanoString.slice(0, MICROSECOND_DIGITS))}Z`;
|
|
22
|
-
}
|
|
23
9
|
function getParentSpanId(span) {
|
|
24
10
|
// Backcompat shim to support OTEL 1.x and 2.x
|
|
25
11
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -49,35 +35,20 @@ export class LangSmithOTLPSpanProcessor extends BatchSpanProcessor {
|
|
|
49
35
|
this.traceMap[span.spanContext().traceId].spanCount++;
|
|
50
36
|
const isTraceable = isTraceableSpan(span);
|
|
51
37
|
const parentSpanId = getParentSpanId(span);
|
|
38
|
+
this.traceMap[span.spanContext().traceId].spanInfo[span.spanContext().spanId] = {
|
|
39
|
+
isTraceable,
|
|
40
|
+
parentSpanId,
|
|
41
|
+
};
|
|
52
42
|
let currentCandidateParentSpanId = parentSpanId;
|
|
53
43
|
let traceableParentId;
|
|
54
|
-
let parentDottedOrder;
|
|
55
|
-
// LangSmith uses the first span's id as the trace id, NOT the actual OTEL trace id
|
|
56
|
-
// Default to the current span if no parent information is present
|
|
57
|
-
let lsTraceId = getUuidFromOtelSpanId(span.spanContext().spanId);
|
|
58
44
|
while (currentCandidateParentSpanId) {
|
|
59
45
|
const currentSpanInfo = this.traceMap[span.spanContext().traceId].spanInfo[currentCandidateParentSpanId];
|
|
60
46
|
if (currentSpanInfo?.isTraceable) {
|
|
61
47
|
traceableParentId = currentCandidateParentSpanId;
|
|
62
|
-
parentDottedOrder = currentSpanInfo.dottedOrder;
|
|
63
|
-
lsTraceId = currentSpanInfo.lsTraceId;
|
|
64
48
|
break;
|
|
65
49
|
}
|
|
66
50
|
currentCandidateParentSpanId = currentSpanInfo?.parentSpanId;
|
|
67
51
|
}
|
|
68
|
-
const startTimestamp = hrTimeToTimeStamp(span.startTime);
|
|
69
|
-
const spanUuid = getUuidFromOtelSpanId(span.spanContext().spanId);
|
|
70
|
-
const dottedOrderComponent = stripNonAlphanumeric(startTimestamp) + spanUuid;
|
|
71
|
-
const currentDottedOrder = parentDottedOrder
|
|
72
|
-
? `${parentDottedOrder}.${dottedOrderComponent}`
|
|
73
|
-
: dottedOrderComponent;
|
|
74
|
-
this.traceMap[span.spanContext().traceId].spanInfo[span.spanContext().spanId] = {
|
|
75
|
-
isTraceable,
|
|
76
|
-
lsTraceId,
|
|
77
|
-
spanId: span.spanContext().spanId,
|
|
78
|
-
parentSpanId,
|
|
79
|
-
dottedOrder: currentDottedOrder,
|
|
80
|
-
};
|
|
81
52
|
if (!traceableParentId) {
|
|
82
53
|
span.attributes[LANGSMITH_IS_ROOT] = true;
|
|
83
54
|
}
|
|
@@ -85,8 +56,6 @@ export class LangSmithOTLPSpanProcessor extends BatchSpanProcessor {
|
|
|
85
56
|
span.attributes[LANGSMITH_PARENT_RUN_ID] =
|
|
86
57
|
getUuidFromOtelSpanId(traceableParentId);
|
|
87
58
|
}
|
|
88
|
-
span.attributes[LANGSMITH_DOTTED_ORDER] = currentDottedOrder;
|
|
89
|
-
span.attributes[LANGSMITH_TRACE_ID] = lsTraceId;
|
|
90
59
|
if (isTraceable) {
|
|
91
60
|
super.onStart(span, parentContext);
|
|
92
61
|
}
|
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.
|
|
13
|
+
exports.__version__ = "0.3.54";
|
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.
|
|
6
|
+
export declare const __version__ = "0.3.54";
|
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.
|
|
6
|
+
export const __version__ = "0.3.54";
|
package/dist/run_trees.cjs
CHANGED
|
@@ -34,7 +34,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.RunTree = void 0;
|
|
37
|
-
exports.stripNonAlphanumeric = stripNonAlphanumeric;
|
|
38
37
|
exports.convertToDottedOrderFormat = convertToDottedOrderFormat;
|
|
39
38
|
exports.isRunTree = isRunTree;
|
|
40
39
|
exports.isRunnableConfigLike = isRunnableConfigLike;
|
package/dist/run_trees.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Client } from "./client.js";
|
|
2
2
|
import { Attachments, BaseRun, KVMap, RunCreate } from "./schemas.js";
|
|
3
|
-
export declare function stripNonAlphanumeric(input: string): string;
|
|
4
3
|
export declare function convertToDottedOrderFormat(epoch: number, runId: string, executionOrder?: number): {
|
|
5
4
|
dottedOrder: string;
|
|
6
5
|
microsecondPrecisionDatestring: string;
|
package/dist/run_trees.js
CHANGED
|
@@ -7,7 +7,7 @@ import { getEnvironmentVariable, getRuntimeEnvironment, } from "./utils/env.js";
|
|
|
7
7
|
import { getDefaultProjectName } from "./utils/project.js";
|
|
8
8
|
import { getLangSmithEnvironmentVariable } from "./utils/env.js";
|
|
9
9
|
import { warnOnce } from "./utils/warn.js";
|
|
10
|
-
|
|
10
|
+
function stripNonAlphanumeric(input) {
|
|
11
11
|
return input.replace(/[-:.]/g, "");
|
|
12
12
|
}
|
|
13
13
|
export function convertToDottedOrderFormat(epoch, runId, executionOrder = 1) {
|
package/dist/vercel.cjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AISDKExporter = exports.
|
|
4
|
-
exports.getMutableRunCreate = getMutableRunCreate;
|
|
3
|
+
exports.AISDKExporter = exports.parseStrippedIsoTime = void 0;
|
|
5
4
|
const vercel_js_1 = require("./utils/vercel.cjs");
|
|
6
5
|
const index_js_1 = require("./index.cjs");
|
|
7
6
|
const uuid_1 = require("uuid");
|
|
@@ -19,19 +18,22 @@ function convertCoreToSmith(message) {
|
|
|
19
18
|
return {
|
|
20
19
|
type: "text",
|
|
21
20
|
text: part.text,
|
|
22
|
-
//
|
|
21
|
+
// Backcompat for AI SDK 4
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
23
|
...part.experimental_providerMetadata,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
if (part.type === "tool-call") {
|
|
27
|
-
//
|
|
27
|
+
// Backcompat for AI SDK 4
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
29
|
const legacyToolCallInput = part.args;
|
|
29
30
|
return {
|
|
30
31
|
type: "tool_use",
|
|
31
32
|
name: part.toolName,
|
|
32
33
|
id: part.toolCallId,
|
|
33
34
|
input: legacyToolCallInput ?? part.input,
|
|
34
|
-
//
|
|
35
|
+
// Backcompat for AI SDK 4
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
37
|
...part.experimental_providerMetadata,
|
|
36
38
|
};
|
|
37
39
|
}
|
|
@@ -41,7 +43,8 @@ function convertCoreToSmith(message) {
|
|
|
41
43
|
if (toolCalls.length > 0) {
|
|
42
44
|
data.additional_kwargs ??= {};
|
|
43
45
|
data.additional_kwargs.tool_calls = toolCalls.map((part) => {
|
|
44
|
-
//
|
|
46
|
+
// Backcompat for AI SDK 4
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
48
|
const legacyToolCallInput = part.args;
|
|
46
49
|
return {
|
|
47
50
|
id: part.toolCallId,
|
|
@@ -65,7 +68,8 @@ function convertCoreToSmith(message) {
|
|
|
65
68
|
return {
|
|
66
69
|
type: "text",
|
|
67
70
|
text: part.text,
|
|
68
|
-
//
|
|
71
|
+
// Backcompat for AI SDK 4
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
73
|
...part.experimental_providerMetadata,
|
|
70
74
|
};
|
|
71
75
|
}
|
|
@@ -100,7 +104,8 @@ function convertCoreToSmith(message) {
|
|
|
100
104
|
return {
|
|
101
105
|
type: "image_url",
|
|
102
106
|
image_url: imageUrl,
|
|
103
|
-
//
|
|
107
|
+
// Backcompat for AI SDK 4
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
104
109
|
...part.experimental_providerMetadata,
|
|
105
110
|
};
|
|
106
111
|
}
|
|
@@ -114,7 +119,8 @@ function convertCoreToSmith(message) {
|
|
|
114
119
|
}
|
|
115
120
|
if (message.role === "tool") {
|
|
116
121
|
const res = message.content.map((toolCall) => {
|
|
117
|
-
//
|
|
122
|
+
// Backcompat for AI SDK 4
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
124
|
const legacyToolCallResult = toolCall.result;
|
|
119
125
|
return {
|
|
120
126
|
type: "tool",
|
|
@@ -173,58 +179,38 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
|
|
|
173
179
|
return dotOrder;
|
|
174
180
|
return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
|
|
175
181
|
}
|
|
176
|
-
// Helper function to convert
|
|
182
|
+
// Helper function to convert dotted order version of start time to ISO string
|
|
177
183
|
const parseStrippedIsoTime = (stripped) => {
|
|
178
|
-
// Insert back the removed characters: YYYYMMDDTHHMMSSSSSSSS -> YYYY-MM-DDTHH:MM:SS.SSSZ
|
|
179
|
-
// The stripped format is timestamp part only (no Z - that becomes the separator)
|
|
180
|
-
// Format includes microseconds: 20231201T120000000000 (milliseconds + microseconds)
|
|
181
184
|
const year = stripped.slice(0, 4);
|
|
182
185
|
const month = stripped.slice(4, 6);
|
|
183
186
|
const day = stripped.slice(6, 8);
|
|
184
187
|
const hour = stripped.slice(9, 11); // Skip 'T'
|
|
185
188
|
const minute = stripped.slice(11, 13);
|
|
186
189
|
const second = stripped.slice(13, 15);
|
|
187
|
-
const ms = stripped.slice(15, 18); //
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
const ms = stripped.slice(15, 18); // milliseconds
|
|
191
|
+
const us = stripped.length >= 21 ? stripped.slice(18, 21) : "000"; // microseconds
|
|
192
|
+
// Create ISO string with microsecond precision only if microseconds are present
|
|
193
|
+
return us !== "000"
|
|
194
|
+
? `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}${us}Z`
|
|
195
|
+
: `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`;
|
|
190
196
|
};
|
|
191
197
|
exports.parseStrippedIsoTime = parseStrippedIsoTime;
|
|
192
|
-
// Helper function to convert Date back to stripped format
|
|
193
|
-
const toStrippedIsoTime = (date) => {
|
|
194
|
-
return stripNonAlphanumeric(date.toISOString().slice(0, -1)) + "000";
|
|
195
|
-
};
|
|
196
|
-
exports.toStrippedIsoTime = toStrippedIsoTime;
|
|
197
198
|
function getMutableRunCreate(dotOrder) {
|
|
198
199
|
const segments = dotOrder.split(".").map((i) => {
|
|
199
200
|
const [startTime, runId] = i.split("Z");
|
|
200
201
|
return { startTime, runId };
|
|
201
202
|
});
|
|
202
|
-
// Iteratively check and fix timing to ensure each segment is greater than its parent
|
|
203
|
-
for (let i = 1; i < segments.length; i++) {
|
|
204
|
-
const parentTime = (0, exports.parseStrippedIsoTime)(segments[i - 1].startTime);
|
|
205
|
-
const currentTime = (0, exports.parseStrippedIsoTime)(segments[i].startTime);
|
|
206
|
-
if (currentTime.getTime() <= parentTime.getTime()) {
|
|
207
|
-
// Increment by 1 millisecond to make it greater than parent
|
|
208
|
-
const newTime = new Date(parentTime.getTime() + 1);
|
|
209
|
-
segments[i].startTime = (0, exports.toStrippedIsoTime)(newTime);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
// Reconstruct the dotted order with potentially updated timestamps
|
|
213
|
-
const updatedDotOrder = segments
|
|
214
|
-
.map((segment) => `${segment.startTime}Z${segment.runId}`)
|
|
215
|
-
.join(".");
|
|
216
203
|
const traceId = segments[0].runId;
|
|
217
204
|
const parentRunId = segments.at(-2)?.runId;
|
|
218
205
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
const lastSegmentTime = (0, exports.parseStrippedIsoTime)(segments.at(-1).startTime);
|
|
206
|
+
const lastSegment = segments.at(-1);
|
|
207
|
+
const startTime = (0, exports.parseStrippedIsoTime)(lastSegment.startTime);
|
|
222
208
|
return {
|
|
223
|
-
id: runId,
|
|
209
|
+
id: lastSegment.runId,
|
|
224
210
|
trace_id: traceId,
|
|
225
|
-
dotted_order:
|
|
211
|
+
dotted_order: dotOrder,
|
|
226
212
|
parent_run_id: parentRunId,
|
|
227
|
-
start_time:
|
|
213
|
+
start_time: startTime,
|
|
228
214
|
};
|
|
229
215
|
}
|
|
230
216
|
function convertToTimestamp([seconds, nanoseconds]) {
|
|
@@ -816,15 +802,10 @@ class AISDKExporter {
|
|
|
816
802
|
}
|
|
817
803
|
this.seenSpanInfo[task.id].dotOrder = taskDotOrder;
|
|
818
804
|
if (!this.seenSpanInfo[task.id].sent) {
|
|
819
|
-
|
|
805
|
+
sampled.push({
|
|
820
806
|
...task.run,
|
|
821
807
|
...getMutableRunCreate(taskDotOrder),
|
|
822
|
-
};
|
|
823
|
-
if (updated.end_time !== undefined &&
|
|
824
|
-
updated.end_time < updated.start_time) {
|
|
825
|
-
updated.end_time = new Date(new Date(updated.start_time).getTime() + 1).toISOString();
|
|
826
|
-
}
|
|
827
|
-
sampled.push(updated);
|
|
808
|
+
});
|
|
828
809
|
}
|
|
829
810
|
this.seenSpanInfo[task.id].sent = true;
|
|
830
811
|
}
|
package/dist/vercel.d.ts
CHANGED
|
@@ -7,16 +7,7 @@ export interface TelemetrySettings extends AITelemetrySettings {
|
|
|
7
7
|
/** Name of the run sent to LangSmith */
|
|
8
8
|
runName?: string;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
id: string;
|
|
12
|
-
trace_id: string;
|
|
13
|
-
dotted_order: string;
|
|
14
|
-
parent_run_id: string | undefined;
|
|
15
|
-
start_time: string;
|
|
16
|
-
}
|
|
17
|
-
export declare const parseStrippedIsoTime: (stripped: string) => Date;
|
|
18
|
-
export declare const toStrippedIsoTime: (date: Date) => string;
|
|
19
|
-
export declare function getMutableRunCreate(dotOrder: string): MutableRunCreate;
|
|
10
|
+
export declare const parseStrippedIsoTime: (stripped: string) => string;
|
|
20
11
|
/**
|
|
21
12
|
* OpenTelemetry trace exporter for Vercel AI SDK.
|
|
22
13
|
*
|
|
@@ -91,4 +82,3 @@ export declare class AISDKExporter {
|
|
|
91
82
|
forceFlush(): Promise<void>;
|
|
92
83
|
protected logDebug(...args: Parameters<typeof console.debug>): void;
|
|
93
84
|
}
|
|
94
|
-
export {};
|
package/dist/vercel.js
CHANGED
|
@@ -15,19 +15,22 @@ function convertCoreToSmith(message) {
|
|
|
15
15
|
return {
|
|
16
16
|
type: "text",
|
|
17
17
|
text: part.text,
|
|
18
|
-
//
|
|
18
|
+
// Backcompat for AI SDK 4
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
20
|
...part.experimental_providerMetadata,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
if (part.type === "tool-call") {
|
|
23
|
-
//
|
|
24
|
+
// Backcompat for AI SDK 4
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
26
|
const legacyToolCallInput = part.args;
|
|
25
27
|
return {
|
|
26
28
|
type: "tool_use",
|
|
27
29
|
name: part.toolName,
|
|
28
30
|
id: part.toolCallId,
|
|
29
31
|
input: legacyToolCallInput ?? part.input,
|
|
30
|
-
//
|
|
32
|
+
// Backcompat for AI SDK 4
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
34
|
...part.experimental_providerMetadata,
|
|
32
35
|
};
|
|
33
36
|
}
|
|
@@ -37,7 +40,8 @@ function convertCoreToSmith(message) {
|
|
|
37
40
|
if (toolCalls.length > 0) {
|
|
38
41
|
data.additional_kwargs ??= {};
|
|
39
42
|
data.additional_kwargs.tool_calls = toolCalls.map((part) => {
|
|
40
|
-
//
|
|
43
|
+
// Backcompat for AI SDK 4
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
45
|
const legacyToolCallInput = part.args;
|
|
42
46
|
return {
|
|
43
47
|
id: part.toolCallId,
|
|
@@ -61,7 +65,8 @@ function convertCoreToSmith(message) {
|
|
|
61
65
|
return {
|
|
62
66
|
type: "text",
|
|
63
67
|
text: part.text,
|
|
64
|
-
//
|
|
68
|
+
// Backcompat for AI SDK 4
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
70
|
...part.experimental_providerMetadata,
|
|
66
71
|
};
|
|
67
72
|
}
|
|
@@ -96,7 +101,8 @@ function convertCoreToSmith(message) {
|
|
|
96
101
|
return {
|
|
97
102
|
type: "image_url",
|
|
98
103
|
image_url: imageUrl,
|
|
99
|
-
//
|
|
104
|
+
// Backcompat for AI SDK 4
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
106
|
...part.experimental_providerMetadata,
|
|
101
107
|
};
|
|
102
108
|
}
|
|
@@ -110,7 +116,8 @@ function convertCoreToSmith(message) {
|
|
|
110
116
|
}
|
|
111
117
|
if (message.role === "tool") {
|
|
112
118
|
const res = message.content.map((toolCall) => {
|
|
113
|
-
//
|
|
119
|
+
// Backcompat for AI SDK 4
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
121
|
const legacyToolCallResult = toolCall.result;
|
|
115
122
|
return {
|
|
116
123
|
type: "tool",
|
|
@@ -169,56 +176,37 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
|
|
|
169
176
|
return dotOrder;
|
|
170
177
|
return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
|
|
171
178
|
}
|
|
172
|
-
// Helper function to convert
|
|
179
|
+
// Helper function to convert dotted order version of start time to ISO string
|
|
173
180
|
export const parseStrippedIsoTime = (stripped) => {
|
|
174
|
-
// Insert back the removed characters: YYYYMMDDTHHMMSSSSSSSS -> YYYY-MM-DDTHH:MM:SS.SSSZ
|
|
175
|
-
// The stripped format is timestamp part only (no Z - that becomes the separator)
|
|
176
|
-
// Format includes microseconds: 20231201T120000000000 (milliseconds + microseconds)
|
|
177
181
|
const year = stripped.slice(0, 4);
|
|
178
182
|
const month = stripped.slice(4, 6);
|
|
179
183
|
const day = stripped.slice(6, 8);
|
|
180
184
|
const hour = stripped.slice(9, 11); // Skip 'T'
|
|
181
185
|
const minute = stripped.slice(11, 13);
|
|
182
186
|
const second = stripped.slice(13, 15);
|
|
183
|
-
const ms = stripped.slice(15, 18); //
|
|
184
|
-
|
|
185
|
-
|
|
187
|
+
const ms = stripped.slice(15, 18); // milliseconds
|
|
188
|
+
const us = stripped.length >= 21 ? stripped.slice(18, 21) : "000"; // microseconds
|
|
189
|
+
// Create ISO string with microsecond precision only if microseconds are present
|
|
190
|
+
return us !== "000"
|
|
191
|
+
? `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}${us}Z`
|
|
192
|
+
: `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`;
|
|
186
193
|
};
|
|
187
|
-
|
|
188
|
-
export const toStrippedIsoTime = (date) => {
|
|
189
|
-
return stripNonAlphanumeric(date.toISOString().slice(0, -1)) + "000";
|
|
190
|
-
};
|
|
191
|
-
export function getMutableRunCreate(dotOrder) {
|
|
194
|
+
function getMutableRunCreate(dotOrder) {
|
|
192
195
|
const segments = dotOrder.split(".").map((i) => {
|
|
193
196
|
const [startTime, runId] = i.split("Z");
|
|
194
197
|
return { startTime, runId };
|
|
195
198
|
});
|
|
196
|
-
// Iteratively check and fix timing to ensure each segment is greater than its parent
|
|
197
|
-
for (let i = 1; i < segments.length; i++) {
|
|
198
|
-
const parentTime = parseStrippedIsoTime(segments[i - 1].startTime);
|
|
199
|
-
const currentTime = parseStrippedIsoTime(segments[i].startTime);
|
|
200
|
-
if (currentTime.getTime() <= parentTime.getTime()) {
|
|
201
|
-
// Increment by 1 millisecond to make it greater than parent
|
|
202
|
-
const newTime = new Date(parentTime.getTime() + 1);
|
|
203
|
-
segments[i].startTime = toStrippedIsoTime(newTime);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
// Reconstruct the dotted order with potentially updated timestamps
|
|
207
|
-
const updatedDotOrder = segments
|
|
208
|
-
.map((segment) => `${segment.startTime}Z${segment.runId}`)
|
|
209
|
-
.join(".");
|
|
210
199
|
const traceId = segments[0].runId;
|
|
211
200
|
const parentRunId = segments.at(-2)?.runId;
|
|
212
201
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
const lastSegmentTime = parseStrippedIsoTime(segments.at(-1).startTime);
|
|
202
|
+
const lastSegment = segments.at(-1);
|
|
203
|
+
const startTime = parseStrippedIsoTime(lastSegment.startTime);
|
|
216
204
|
return {
|
|
217
|
-
id: runId,
|
|
205
|
+
id: lastSegment.runId,
|
|
218
206
|
trace_id: traceId,
|
|
219
|
-
dotted_order:
|
|
207
|
+
dotted_order: dotOrder,
|
|
220
208
|
parent_run_id: parentRunId,
|
|
221
|
-
start_time:
|
|
209
|
+
start_time: startTime,
|
|
222
210
|
};
|
|
223
211
|
}
|
|
224
212
|
function convertToTimestamp([seconds, nanoseconds]) {
|
|
@@ -810,15 +798,10 @@ export class AISDKExporter {
|
|
|
810
798
|
}
|
|
811
799
|
this.seenSpanInfo[task.id].dotOrder = taskDotOrder;
|
|
812
800
|
if (!this.seenSpanInfo[task.id].sent) {
|
|
813
|
-
|
|
801
|
+
sampled.push({
|
|
814
802
|
...task.run,
|
|
815
803
|
...getMutableRunCreate(taskDotOrder),
|
|
816
|
-
};
|
|
817
|
-
if (updated.end_time !== undefined &&
|
|
818
|
-
updated.end_time < updated.start_time) {
|
|
819
|
-
updated.end_time = new Date(new Date(updated.start_time).getTime() + 1).toISOString();
|
|
820
|
-
}
|
|
821
|
-
sampled.push(updated);
|
|
804
|
+
});
|
|
822
805
|
}
|
|
823
806
|
this.seenSpanInfo[task.id].sent = true;
|
|
824
807
|
}
|