langsmith 0.3.50 → 0.3.52
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 +3 -3
- package/dist/client.js +3 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/run_trees.cjs +51 -6
- package/dist/run_trees.js +51 -6
- package/dist/vercel.cjs +48 -4
- package/dist/vercel.d.ts +11 -0
- package/dist/vercel.js +45 -4
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -588,11 +588,11 @@ class Client {
|
|
|
588
588
|
if (patch) {
|
|
589
589
|
const sampled = [];
|
|
590
590
|
for (const run of runs) {
|
|
591
|
-
if (!this.filteredPostUuids.has(run.
|
|
591
|
+
if (!this.filteredPostUuids.has(run.trace_id)) {
|
|
592
592
|
sampled.push(run);
|
|
593
593
|
}
|
|
594
|
-
else {
|
|
595
|
-
this.filteredPostUuids.delete(run.
|
|
594
|
+
else if (run.id === run.trace_id) {
|
|
595
|
+
this.filteredPostUuids.delete(run.trace_id);
|
|
596
596
|
}
|
|
597
597
|
}
|
|
598
598
|
return sampled;
|
package/dist/client.js
CHANGED
|
@@ -550,11 +550,11 @@ export class Client {
|
|
|
550
550
|
if (patch) {
|
|
551
551
|
const sampled = [];
|
|
552
552
|
for (const run of runs) {
|
|
553
|
-
if (!this.filteredPostUuids.has(run.
|
|
553
|
+
if (!this.filteredPostUuids.has(run.trace_id)) {
|
|
554
554
|
sampled.push(run);
|
|
555
555
|
}
|
|
556
|
-
else {
|
|
557
|
-
this.filteredPostUuids.delete(run.
|
|
556
|
+
else if (run.id === run.trace_id) {
|
|
557
|
+
this.filteredPostUuids.delete(run.trace_id);
|
|
558
558
|
}
|
|
559
559
|
}
|
|
560
560
|
return sampled;
|
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.52";
|
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.52";
|
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.52";
|
package/dist/run_trees.cjs
CHANGED
|
@@ -776,17 +776,62 @@ function _getWriteReplicasFromEnv() {
|
|
|
776
776
|
return [];
|
|
777
777
|
try {
|
|
778
778
|
const parsed = JSON.parse(envVar);
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
779
|
+
if (Array.isArray(parsed)) {
|
|
780
|
+
const replicas = [];
|
|
781
|
+
for (const item of parsed) {
|
|
782
|
+
if (typeof item !== "object" || item === null) {
|
|
783
|
+
console.warn(`Invalid item type in LANGSMITH_RUNS_ENDPOINTS: ` +
|
|
784
|
+
`expected object, got ${typeof item}`);
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
if (typeof item.api_url !== "string") {
|
|
788
|
+
console.warn(`Invalid api_url type in LANGSMITH_RUNS_ENDPOINTS: ` +
|
|
789
|
+
`expected string, got ${typeof item.api_url}`);
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
if (typeof item.api_key !== "string") {
|
|
793
|
+
console.warn(`Invalid api_key type in LANGSMITH_RUNS_ENDPOINTS: ` +
|
|
794
|
+
`expected string, got ${typeof item.api_key}`);
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
replicas.push({
|
|
798
|
+
apiUrl: item.api_url.replace(/\/$/, ""),
|
|
799
|
+
apiKey: item.api_key,
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
return replicas;
|
|
803
|
+
}
|
|
804
|
+
else if (typeof parsed === "object" && parsed !== null) {
|
|
805
|
+
_checkEndpointEnvUnset(parsed);
|
|
806
|
+
const replicas = [];
|
|
807
|
+
for (const [url, key] of Object.entries(parsed)) {
|
|
808
|
+
const cleanUrl = url.replace(/\/$/, "");
|
|
809
|
+
if (typeof key === "string") {
|
|
810
|
+
replicas.push({
|
|
811
|
+
apiUrl: cleanUrl,
|
|
812
|
+
apiKey: key,
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
else {
|
|
816
|
+
console.warn(`Invalid value type in LANGSMITH_RUNS_ENDPOINTS for URL ${url}: ` +
|
|
817
|
+
`expected string, got ${typeof key}`);
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
return replicas;
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
console.warn("Invalid LANGSMITH_RUNS_ENDPOINTS – must be valid JSON array of " +
|
|
825
|
+
`objects with api_url and api_key properties, or object mapping url->apiKey, got ${typeof parsed}`);
|
|
826
|
+
return [];
|
|
827
|
+
}
|
|
784
828
|
}
|
|
785
829
|
catch (e) {
|
|
786
830
|
if ((0, error_js_1.isConflictingEndpointsError)(e)) {
|
|
787
831
|
throw e;
|
|
788
832
|
}
|
|
789
|
-
console.warn("Invalid LANGSMITH_RUNS_ENDPOINTS – must be valid JSON
|
|
833
|
+
console.warn("Invalid LANGSMITH_RUNS_ENDPOINTS – must be valid JSON array of " +
|
|
834
|
+
"objects with api_url and api_key properties, or object mapping url->apiKey");
|
|
790
835
|
return [];
|
|
791
836
|
}
|
|
792
837
|
}
|
package/dist/run_trees.js
CHANGED
|
@@ -735,17 +735,62 @@ function _getWriteReplicasFromEnv() {
|
|
|
735
735
|
return [];
|
|
736
736
|
try {
|
|
737
737
|
const parsed = JSON.parse(envVar);
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
738
|
+
if (Array.isArray(parsed)) {
|
|
739
|
+
const replicas = [];
|
|
740
|
+
for (const item of parsed) {
|
|
741
|
+
if (typeof item !== "object" || item === null) {
|
|
742
|
+
console.warn(`Invalid item type in LANGSMITH_RUNS_ENDPOINTS: ` +
|
|
743
|
+
`expected object, got ${typeof item}`);
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
if (typeof item.api_url !== "string") {
|
|
747
|
+
console.warn(`Invalid api_url type in LANGSMITH_RUNS_ENDPOINTS: ` +
|
|
748
|
+
`expected string, got ${typeof item.api_url}`);
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
if (typeof item.api_key !== "string") {
|
|
752
|
+
console.warn(`Invalid api_key type in LANGSMITH_RUNS_ENDPOINTS: ` +
|
|
753
|
+
`expected string, got ${typeof item.api_key}`);
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
replicas.push({
|
|
757
|
+
apiUrl: item.api_url.replace(/\/$/, ""),
|
|
758
|
+
apiKey: item.api_key,
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
return replicas;
|
|
762
|
+
}
|
|
763
|
+
else if (typeof parsed === "object" && parsed !== null) {
|
|
764
|
+
_checkEndpointEnvUnset(parsed);
|
|
765
|
+
const replicas = [];
|
|
766
|
+
for (const [url, key] of Object.entries(parsed)) {
|
|
767
|
+
const cleanUrl = url.replace(/\/$/, "");
|
|
768
|
+
if (typeof key === "string") {
|
|
769
|
+
replicas.push({
|
|
770
|
+
apiUrl: cleanUrl,
|
|
771
|
+
apiKey: key,
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
console.warn(`Invalid value type in LANGSMITH_RUNS_ENDPOINTS for URL ${url}: ` +
|
|
776
|
+
`expected string, got ${typeof key}`);
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
return replicas;
|
|
781
|
+
}
|
|
782
|
+
else {
|
|
783
|
+
console.warn("Invalid LANGSMITH_RUNS_ENDPOINTS – must be valid JSON array of " +
|
|
784
|
+
`objects with api_url and api_key properties, or object mapping url->apiKey, got ${typeof parsed}`);
|
|
785
|
+
return [];
|
|
786
|
+
}
|
|
743
787
|
}
|
|
744
788
|
catch (e) {
|
|
745
789
|
if (isConflictingEndpointsError(e)) {
|
|
746
790
|
throw e;
|
|
747
791
|
}
|
|
748
|
-
console.warn("Invalid LANGSMITH_RUNS_ENDPOINTS – must be valid JSON
|
|
792
|
+
console.warn("Invalid LANGSMITH_RUNS_ENDPOINTS – must be valid JSON array of " +
|
|
793
|
+
"objects with api_url and api_key properties, or object mapping url->apiKey");
|
|
749
794
|
return [];
|
|
750
795
|
}
|
|
751
796
|
}
|
package/dist/vercel.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AISDKExporter = void 0;
|
|
3
|
+
exports.AISDKExporter = exports.toStrippedIsoTime = exports.parseStrippedIsoTime = void 0;
|
|
4
|
+
exports.getMutableRunCreate = getMutableRunCreate;
|
|
4
5
|
const vercel_js_1 = require("./utils/vercel.cjs");
|
|
5
6
|
const index_js_1 = require("./index.cjs");
|
|
6
7
|
const uuid_1 = require("uuid");
|
|
@@ -172,20 +173,58 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
|
|
|
172
173
|
return dotOrder;
|
|
173
174
|
return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
|
|
174
175
|
}
|
|
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;
|
|
175
197
|
function getMutableRunCreate(dotOrder) {
|
|
176
198
|
const segments = dotOrder.split(".").map((i) => {
|
|
177
199
|
const [startTime, runId] = i.split("Z");
|
|
178
200
|
return { startTime, runId };
|
|
179
201
|
});
|
|
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(".");
|
|
180
216
|
const traceId = segments[0].runId;
|
|
181
217
|
const parentRunId = segments.at(-2)?.runId;
|
|
182
218
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
183
219
|
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);
|
|
184
222
|
return {
|
|
185
223
|
id: runId,
|
|
186
224
|
trace_id: traceId,
|
|
187
|
-
dotted_order:
|
|
225
|
+
dotted_order: updatedDotOrder,
|
|
188
226
|
parent_run_id: parentRunId,
|
|
227
|
+
start_time: lastSegmentTime.toISOString(),
|
|
189
228
|
};
|
|
190
229
|
}
|
|
191
230
|
function convertToTimestamp([seconds, nanoseconds]) {
|
|
@@ -777,10 +816,15 @@ class AISDKExporter {
|
|
|
777
816
|
}
|
|
778
817
|
this.seenSpanInfo[task.id].dotOrder = taskDotOrder;
|
|
779
818
|
if (!this.seenSpanInfo[task.id].sent) {
|
|
780
|
-
|
|
819
|
+
const updated = {
|
|
781
820
|
...task.run,
|
|
782
821
|
...getMutableRunCreate(taskDotOrder),
|
|
783
|
-
}
|
|
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);
|
|
784
828
|
}
|
|
785
829
|
this.seenSpanInfo[task.id].sent = true;
|
|
786
830
|
}
|
package/dist/vercel.d.ts
CHANGED
|
@@ -7,6 +7,16 @@ 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;
|
|
10
20
|
/**
|
|
11
21
|
* OpenTelemetry trace exporter for Vercel AI SDK.
|
|
12
22
|
*
|
|
@@ -81,3 +91,4 @@ export declare class AISDKExporter {
|
|
|
81
91
|
forceFlush(): Promise<void>;
|
|
82
92
|
protected logDebug(...args: Parameters<typeof console.debug>): void;
|
|
83
93
|
}
|
|
94
|
+
export {};
|
package/dist/vercel.js
CHANGED
|
@@ -169,20 +169,56 @@ function reparentDotOrder(dotOrder, sourceRunId, parentDotOrder) {
|
|
|
169
169
|
return dotOrder;
|
|
170
170
|
return joinDotOrder(...parentDotOrder.split("."), ...segments.slice(sourceIndex));
|
|
171
171
|
}
|
|
172
|
-
function
|
|
172
|
+
// Helper function to convert stripped ISO string back to parseable format
|
|
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) {
|
|
173
192
|
const segments = dotOrder.split(".").map((i) => {
|
|
174
193
|
const [startTime, runId] = i.split("Z");
|
|
175
194
|
return { startTime, runId };
|
|
176
195
|
});
|
|
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(".");
|
|
177
210
|
const traceId = segments[0].runId;
|
|
178
211
|
const parentRunId = segments.at(-2)?.runId;
|
|
179
212
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
180
213
|
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);
|
|
181
216
|
return {
|
|
182
217
|
id: runId,
|
|
183
218
|
trace_id: traceId,
|
|
184
|
-
dotted_order:
|
|
219
|
+
dotted_order: updatedDotOrder,
|
|
185
220
|
parent_run_id: parentRunId,
|
|
221
|
+
start_time: lastSegmentTime.toISOString(),
|
|
186
222
|
};
|
|
187
223
|
}
|
|
188
224
|
function convertToTimestamp([seconds, nanoseconds]) {
|
|
@@ -774,10 +810,15 @@ export class AISDKExporter {
|
|
|
774
810
|
}
|
|
775
811
|
this.seenSpanInfo[task.id].dotOrder = taskDotOrder;
|
|
776
812
|
if (!this.seenSpanInfo[task.id].sent) {
|
|
777
|
-
|
|
813
|
+
const updated = {
|
|
778
814
|
...task.run,
|
|
779
815
|
...getMutableRunCreate(taskDotOrder),
|
|
780
|
-
}
|
|
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);
|
|
781
822
|
}
|
|
782
823
|
this.seenSpanInfo[task.id].sent = true;
|
|
783
824
|
}
|