langsmith 0.3.52 → 0.3.53
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 +4 -48
- package/dist/vercel.d.ts +0 -11
- package/dist/vercel.js +4 -45
- 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.53";
|
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.53";
|
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.53";
|
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 =
|
|
4
|
-
exports.getMutableRunCreate = getMutableRunCreate;
|
|
3
|
+
exports.AISDKExporter = 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");
|
|
@@ -173,58 +172,20 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
|
|
|
173
172
|
return dotOrder;
|
|
174
173
|
return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
|
|
175
174
|
}
|
|
176
|
-
// Helper function to convert stripped ISO string back to parseable format
|
|
177
|
-
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
|
-
const year = stripped.slice(0, 4);
|
|
182
|
-
const month = stripped.slice(4, 6);
|
|
183
|
-
const day = stripped.slice(6, 8);
|
|
184
|
-
const hour = stripped.slice(9, 11); // Skip 'T'
|
|
185
|
-
const minute = stripped.slice(11, 13);
|
|
186
|
-
const second = stripped.slice(13, 15);
|
|
187
|
-
const ms = stripped.slice(15, 18); // Only use first 3 digits for milliseconds
|
|
188
|
-
// Ignore microseconds (18-21) as Date only has millisecond precision
|
|
189
|
-
return new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`);
|
|
190
|
-
};
|
|
191
|
-
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
175
|
function getMutableRunCreate(dotOrder) {
|
|
198
176
|
const segments = dotOrder.split(".").map((i) => {
|
|
199
177
|
const [startTime, runId] = i.split("Z");
|
|
200
178
|
return { startTime, runId };
|
|
201
179
|
});
|
|
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
180
|
const traceId = segments[0].runId;
|
|
217
181
|
const parentRunId = segments.at(-2)?.runId;
|
|
218
182
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
219
183
|
const runId = segments.at(-1).runId;
|
|
220
|
-
// If this is the last segment (current run), set start_time to its ISO timestamp
|
|
221
|
-
const lastSegmentTime = (0, exports.parseStrippedIsoTime)(segments.at(-1).startTime);
|
|
222
184
|
return {
|
|
223
185
|
id: runId,
|
|
224
186
|
trace_id: traceId,
|
|
225
|
-
dotted_order:
|
|
187
|
+
dotted_order: dotOrder,
|
|
226
188
|
parent_run_id: parentRunId,
|
|
227
|
-
start_time: lastSegmentTime.toISOString(),
|
|
228
189
|
};
|
|
229
190
|
}
|
|
230
191
|
function convertToTimestamp([seconds, nanoseconds]) {
|
|
@@ -816,15 +777,10 @@ class AISDKExporter {
|
|
|
816
777
|
}
|
|
817
778
|
this.seenSpanInfo[task.id].dotOrder = taskDotOrder;
|
|
818
779
|
if (!this.seenSpanInfo[task.id].sent) {
|
|
819
|
-
|
|
780
|
+
sampled.push({
|
|
820
781
|
...task.run,
|
|
821
782
|
...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);
|
|
783
|
+
});
|
|
828
784
|
}
|
|
829
785
|
this.seenSpanInfo[task.id].sent = true;
|
|
830
786
|
}
|
package/dist/vercel.d.ts
CHANGED
|
@@ -7,16 +7,6 @@ export interface TelemetrySettings extends AITelemetrySettings {
|
|
|
7
7
|
/** Name of the run sent to LangSmith */
|
|
8
8
|
runName?: string;
|
|
9
9
|
}
|
|
10
|
-
interface MutableRunCreate {
|
|
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;
|
|
20
10
|
/**
|
|
21
11
|
* OpenTelemetry trace exporter for Vercel AI SDK.
|
|
22
12
|
*
|
|
@@ -91,4 +81,3 @@ export declare class AISDKExporter {
|
|
|
91
81
|
forceFlush(): Promise<void>;
|
|
92
82
|
protected logDebug(...args: Parameters<typeof console.debug>): void;
|
|
93
83
|
}
|
|
94
|
-
export {};
|
package/dist/vercel.js
CHANGED
|
@@ -169,56 +169,20 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
|
|
|
169
169
|
return dotOrder;
|
|
170
170
|
return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
|
|
171
171
|
}
|
|
172
|
-
|
|
173
|
-
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
|
-
const year = stripped.slice(0, 4);
|
|
178
|
-
const month = stripped.slice(4, 6);
|
|
179
|
-
const day = stripped.slice(6, 8);
|
|
180
|
-
const hour = stripped.slice(9, 11); // Skip 'T'
|
|
181
|
-
const minute = stripped.slice(11, 13);
|
|
182
|
-
const second = stripped.slice(13, 15);
|
|
183
|
-
const ms = stripped.slice(15, 18); // Only use first 3 digits for milliseconds
|
|
184
|
-
// Ignore microseconds (18-21) as Date only has millisecond precision
|
|
185
|
-
return new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`);
|
|
186
|
-
};
|
|
187
|
-
// Helper function to convert Date back to stripped format
|
|
188
|
-
export const toStrippedIsoTime = (date) => {
|
|
189
|
-
return stripNonAlphanumeric(date.toISOString().slice(0, -1)) + "000";
|
|
190
|
-
};
|
|
191
|
-
export function getMutableRunCreate(dotOrder) {
|
|
172
|
+
function getMutableRunCreate(dotOrder) {
|
|
192
173
|
const segments = dotOrder.split(".").map((i) => {
|
|
193
174
|
const [startTime, runId] = i.split("Z");
|
|
194
175
|
return { startTime, runId };
|
|
195
176
|
});
|
|
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
177
|
const traceId = segments[0].runId;
|
|
211
178
|
const parentRunId = segments.at(-2)?.runId;
|
|
212
179
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
213
180
|
const runId = segments.at(-1).runId;
|
|
214
|
-
// If this is the last segment (current run), set start_time to its ISO timestamp
|
|
215
|
-
const lastSegmentTime = parseStrippedIsoTime(segments.at(-1).startTime);
|
|
216
181
|
return {
|
|
217
182
|
id: runId,
|
|
218
183
|
trace_id: traceId,
|
|
219
|
-
dotted_order:
|
|
184
|
+
dotted_order: dotOrder,
|
|
220
185
|
parent_run_id: parentRunId,
|
|
221
|
-
start_time: lastSegmentTime.toISOString(),
|
|
222
186
|
};
|
|
223
187
|
}
|
|
224
188
|
function convertToTimestamp([seconds, nanoseconds]) {
|
|
@@ -810,15 +774,10 @@ export class AISDKExporter {
|
|
|
810
774
|
}
|
|
811
775
|
this.seenSpanInfo[task.id].dotOrder = taskDotOrder;
|
|
812
776
|
if (!this.seenSpanInfo[task.id].sent) {
|
|
813
|
-
|
|
777
|
+
sampled.push({
|
|
814
778
|
...task.run,
|
|
815
779
|
...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);
|
|
780
|
+
});
|
|
822
781
|
}
|
|
823
782
|
this.seenSpanInfo[task.id].sent = true;
|
|
824
783
|
}
|