@latitude-data/telemetry 2.0.4 → 3.0.0-alpha.1
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/LICENSE +157 -0
- package/README.md +455 -31
- package/dist/index.cjs +489 -2089
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +169 -0
- package/dist/index.d.ts +144 -314
- package/dist/index.js +458 -2062
- package/dist/index.js.map +1 -1
- package/package.json +39 -47
- package/LICENSE.md +0 -21
package/dist/index.cjs
CHANGED
|
@@ -1,2113 +1,513 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ExportFilterSpanProcessor: () => ExportFilterSpanProcessor,
|
|
24
|
+
LatitudeSpanProcessor: () => LatitudeSpanProcessor,
|
|
25
|
+
RedactSpanProcessor: () => RedactSpanProcessor,
|
|
26
|
+
RedactThenExportSpanProcessor: () => RedactThenExportSpanProcessor,
|
|
27
|
+
buildShouldExportSpan: () => buildShouldExportSpan,
|
|
28
|
+
buildShouldExportSpanFromFields: () => buildShouldExportSpanFromFields,
|
|
29
|
+
capture: () => capture,
|
|
30
|
+
initLatitude: () => initLatitude,
|
|
31
|
+
isDefaultExportSpan: () => isDefaultExportSpan,
|
|
32
|
+
isGenAiOrLlmAttributeSpan: () => isGenAiOrLlmAttributeSpan,
|
|
33
|
+
isLatitudeInstrumentationSpan: () => isLatitudeInstrumentationSpan,
|
|
34
|
+
registerLatitudeInstrumentations: () => registerLatitudeInstrumentations
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
|
|
38
|
+
// src/sdk/context.ts
|
|
39
|
+
var import_api = require("@opentelemetry/api");
|
|
40
|
+
var LATITUDE_CONTEXT_KEY = (0, import_api.createContextKey)("latitude-internal-context");
|
|
41
|
+
var CAPTURE_TRACER_NAME = "so.latitude.instrumentation.capture";
|
|
42
|
+
function getLatitudeContext(ctx) {
|
|
43
|
+
return ctx.getValue(LATITUDE_CONTEXT_KEY);
|
|
40
44
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
constructor(options) {
|
|
47
|
-
this.options = options;
|
|
48
|
-
if (!options.mask) {
|
|
49
|
-
this.options.mask = (_attribute, _value) => '******';
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
onStart(_span, _context) {
|
|
53
|
-
// Noop
|
|
54
|
-
}
|
|
55
|
-
onEnd(span) {
|
|
56
|
-
Object.assign(span.attributes, this.redactAttributes(span.attributes));
|
|
57
|
-
for (const event of span.events) {
|
|
58
|
-
if (!event.attributes)
|
|
59
|
-
continue;
|
|
60
|
-
Object.assign(event.attributes, this.redactAttributes(event.attributes));
|
|
61
|
-
}
|
|
62
|
-
for (const link of span.links) {
|
|
63
|
-
if (!link.attributes)
|
|
64
|
-
continue;
|
|
65
|
-
Object.assign(link.attributes, this.redactAttributes(link.attributes));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
forceFlush() {
|
|
69
|
-
return Promise.resolve();
|
|
70
|
-
}
|
|
71
|
-
shutdown() {
|
|
72
|
-
return Promise.resolve();
|
|
73
|
-
}
|
|
74
|
-
shouldRedact(attribute) {
|
|
75
|
-
return this.options.attributes.some((pattern) => {
|
|
76
|
-
if (typeof pattern === 'string') {
|
|
77
|
-
return attribute === pattern;
|
|
78
|
-
}
|
|
79
|
-
else if (pattern instanceof RegExp) {
|
|
80
|
-
return pattern.test(attribute);
|
|
81
|
-
}
|
|
82
|
-
return false;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
redactAttributes(attributes) {
|
|
86
|
-
const redacted = {};
|
|
87
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
88
|
-
if (this.shouldRedact(key)) {
|
|
89
|
-
redacted[key] = this.options.mask(key, value);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return redacted;
|
|
93
|
-
}
|
|
45
|
+
function mergeArrays(a, b) {
|
|
46
|
+
if (!a && !b) return void 0;
|
|
47
|
+
if (!a) return b;
|
|
48
|
+
if (!b) return a;
|
|
49
|
+
return [.../* @__PURE__ */ new Set([...a, ...b])];
|
|
94
50
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}["production"];
|
|
128
|
-
function GET_GATEWAY_BASE_URL() {
|
|
129
|
-
if (process.env.GATEWAY_BASE_URL) {
|
|
130
|
-
return process.env.GATEWAY_BASE_URL;
|
|
131
|
-
}
|
|
132
|
-
if (!process.env.GATEWAY_HOSTNAME) {
|
|
133
|
-
return DEFAULT_GATEWAY_BASE_URL;
|
|
51
|
+
function capture(name, fn, options = {}) {
|
|
52
|
+
const currentContext = import_api.context.active();
|
|
53
|
+
const existingData = getLatitudeContext(currentContext);
|
|
54
|
+
const mergedData = {
|
|
55
|
+
name: options.name ?? name,
|
|
56
|
+
tags: mergeArrays(existingData?.tags, options.tags),
|
|
57
|
+
metadata: { ...existingData?.metadata, ...options.metadata },
|
|
58
|
+
sessionId: options.sessionId ?? existingData?.sessionId,
|
|
59
|
+
userId: options.userId ?? existingData?.userId
|
|
60
|
+
};
|
|
61
|
+
const newContext = currentContext.setValue(LATITUDE_CONTEXT_KEY, mergedData);
|
|
62
|
+
const existingSpan = import_api.trace.getSpan(currentContext);
|
|
63
|
+
if (existingSpan) {
|
|
64
|
+
return import_api.context.with(newContext, fn);
|
|
65
|
+
}
|
|
66
|
+
const tracer = import_api.trace.getTracer(CAPTURE_TRACER_NAME);
|
|
67
|
+
return tracer.startActiveSpan(name, { attributes: { "latitude.capture.root": true } }, newContext, (span) => {
|
|
68
|
+
let result;
|
|
69
|
+
try {
|
|
70
|
+
result = fn();
|
|
71
|
+
} catch (error) {
|
|
72
|
+
span.recordException(error);
|
|
73
|
+
span.end();
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
if (result instanceof Promise) {
|
|
77
|
+
return result.catch((error) => {
|
|
78
|
+
span.recordException(error);
|
|
79
|
+
throw error;
|
|
80
|
+
}).finally(() => {
|
|
81
|
+
span.end();
|
|
82
|
+
});
|
|
134
83
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return `${protocol}://${hostname}:${port}`;
|
|
84
|
+
span.end();
|
|
85
|
+
return result;
|
|
86
|
+
});
|
|
139
87
|
}
|
|
140
|
-
const env = { GATEWAY_BASE_URL: GET_GATEWAY_BASE_URL() };
|
|
141
88
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
89
|
+
// src/sdk/init.ts
|
|
90
|
+
var import_api2 = require("@opentelemetry/api");
|
|
91
|
+
var import_context_async_hooks = require("@opentelemetry/context-async-hooks");
|
|
92
|
+
var import_core = require("@opentelemetry/core");
|
|
93
|
+
var import_resources = require("@opentelemetry/resources");
|
|
94
|
+
var import_sdk_trace_node2 = require("@opentelemetry/sdk-trace-node");
|
|
95
|
+
var import_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
96
|
+
|
|
97
|
+
// src/sdk/instrumentations.ts
|
|
98
|
+
var import_instrumentation = require("@opentelemetry/instrumentation");
|
|
99
|
+
var import_instrumentation_anthropic = require("@traceloop/instrumentation-anthropic");
|
|
100
|
+
var import_instrumentation_bedrock = require("@traceloop/instrumentation-bedrock");
|
|
101
|
+
var import_instrumentation_cohere = require("@traceloop/instrumentation-cohere");
|
|
102
|
+
var import_instrumentation_langchain = require("@traceloop/instrumentation-langchain");
|
|
103
|
+
var import_instrumentation_llamaindex = require("@traceloop/instrumentation-llamaindex");
|
|
104
|
+
var import_instrumentation_openai = require("@traceloop/instrumentation-openai");
|
|
105
|
+
var import_instrumentation_together = require("@traceloop/instrumentation-together");
|
|
106
|
+
var import_instrumentation_vertexai = require("@traceloop/instrumentation-vertexai");
|
|
107
|
+
var INSTRUMENTATION_MAP = {
|
|
108
|
+
openai: { ctor: import_instrumentation_openai.OpenAIInstrumentation, moduleName: "openai", defaultEnrichTokens: true },
|
|
109
|
+
anthropic: { ctor: import_instrumentation_anthropic.AnthropicInstrumentation, moduleName: "@anthropic-ai/sdk" },
|
|
110
|
+
bedrock: { ctor: import_instrumentation_bedrock.BedrockInstrumentation, moduleName: "@aws-sdk/client-bedrock-runtime" },
|
|
111
|
+
cohere: { ctor: import_instrumentation_cohere.CohereInstrumentation, moduleName: "cohere-ai" },
|
|
112
|
+
langchain: { ctor: import_instrumentation_langchain.LangChainInstrumentation, moduleName: "langchain" },
|
|
113
|
+
llamaindex: { ctor: import_instrumentation_llamaindex.LlamaIndexInstrumentation, moduleName: "llamaindex" },
|
|
114
|
+
togetherai: { ctor: import_instrumentation_together.TogetherInstrumentation, moduleName: "together-ai", defaultEnrichTokens: false },
|
|
115
|
+
vertexai: { ctor: import_instrumentation_vertexai.VertexAIInstrumentation, moduleName: "@google-cloud/vertexai" },
|
|
116
|
+
aiplatform: { ctor: import_instrumentation_vertexai.AIPlatformInstrumentation, moduleName: "@google-cloud/aiplatform" }
|
|
117
|
+
};
|
|
118
|
+
async function createLatitudeInstrumentations(options) {
|
|
119
|
+
const result = [];
|
|
120
|
+
for (const type of options.instrumentations) {
|
|
121
|
+
const config = INSTRUMENTATION_MAP[type];
|
|
122
|
+
if (!config) {
|
|
123
|
+
console.warn(`[Latitude] Unknown instrumentation type: ${type}`);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const enrichTokens = options.enrichTokens?.[type] ?? config.defaultEnrichTokens;
|
|
127
|
+
const inst = new config.ctor(enrichTokens !== void 0 ? { enrichTokens } : void 0);
|
|
128
|
+
const moduleRef = options.modules?.[type] ?? await tryRequire(config.moduleName);
|
|
129
|
+
if (!moduleRef) {
|
|
130
|
+
console.warn(
|
|
131
|
+
`[Latitude] Module not found for ${type}: ${config.moduleName}. Install it or pass it explicitly in 'modules'.`
|
|
132
|
+
);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
inst.manuallyInstrument?.(moduleRef);
|
|
136
|
+
result.push(inst);
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
149
139
|
}
|
|
150
|
-
function
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
140
|
+
async function tryRequire(moduleName) {
|
|
141
|
+
try {
|
|
142
|
+
return require(moduleName);
|
|
143
|
+
} catch {
|
|
144
|
+
try {
|
|
145
|
+
const mod = await import(moduleName);
|
|
146
|
+
return mod.default ?? mod;
|
|
147
|
+
} catch {
|
|
148
|
+
return void 0;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function registerLatitudeInstrumentations(options) {
|
|
153
|
+
const instrumentations = await createLatitudeInstrumentations(options);
|
|
154
|
+
(0, import_instrumentation.registerInstrumentations)({
|
|
155
|
+
instrumentations,
|
|
156
|
+
tracerProvider: options.tracerProvider
|
|
157
|
+
});
|
|
157
158
|
}
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
});
|
|
171
|
-
zod.z.object({
|
|
172
|
-
inputTokens: zod.z.number(),
|
|
173
|
-
outputTokens: zod.z.number(),
|
|
174
|
-
promptTokens: zod.z.number(),
|
|
175
|
-
completionTokens: zod.z.number(),
|
|
176
|
-
totalTokens: zod.z.number(),
|
|
177
|
-
reasoningTokens: zod.z.number(),
|
|
178
|
-
cachedInputTokens: zod.z.number(),
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
var ParameterType;
|
|
182
|
-
(function (ParameterType) {
|
|
183
|
-
ParameterType["Text"] = "text";
|
|
184
|
-
ParameterType["Image"] = "image";
|
|
185
|
-
ParameterType["File"] = "file";
|
|
186
|
-
})(ParameterType || (ParameterType = {}));
|
|
187
|
-
var LatitudeTool;
|
|
188
|
-
(function (LatitudeTool) {
|
|
189
|
-
LatitudeTool["RunCode"] = "code";
|
|
190
|
-
LatitudeTool["WebSearch"] = "search";
|
|
191
|
-
LatitudeTool["WebExtract"] = "extract";
|
|
192
|
-
LatitudeTool["Think"] = "think";
|
|
193
|
-
LatitudeTool["TODO"] = "todo";
|
|
194
|
-
})(LatitudeTool || (LatitudeTool = {}));
|
|
195
|
-
var LatitudeToolInternalName;
|
|
196
|
-
(function (LatitudeToolInternalName) {
|
|
197
|
-
LatitudeToolInternalName["RunCode"] = "lat_tool_run_code";
|
|
198
|
-
LatitudeToolInternalName["WebSearch"] = "lat_tool_web_search";
|
|
199
|
-
LatitudeToolInternalName["WebExtract"] = "lat_tool_web_extract";
|
|
200
|
-
LatitudeToolInternalName["Think"] = "think";
|
|
201
|
-
LatitudeToolInternalName["TODO"] = "todo_write";
|
|
202
|
-
})(LatitudeToolInternalName || (LatitudeToolInternalName = {}));
|
|
203
|
-
[
|
|
204
|
-
LatitudeTool.Think,
|
|
205
|
-
LatitudeTool.TODO,
|
|
206
|
-
];
|
|
207
|
-
|
|
208
|
-
const actualOutputConfiguration = zod.z.object({
|
|
209
|
-
messageSelection: zod.z.enum(['last', 'all']), // Which assistant messages to select
|
|
210
|
-
contentFilter: zod.z
|
|
211
|
-
.enum(['text', 'reasoning', 'image', 'file', 'tool_call'])
|
|
212
|
-
.optional(),
|
|
213
|
-
parsingFormat: zod.z.enum(['string', 'json']),
|
|
214
|
-
fieldAccessor: zod.z.string().optional(), // Field accessor to get the output from if it's a key-value format
|
|
215
|
-
});
|
|
216
|
-
const expectedOutputConfiguration = zod.z.object({
|
|
217
|
-
parsingFormat: zod.z.enum(['string', 'json']),
|
|
218
|
-
fieldAccessor: zod.z.string().optional(), // Field accessor to get the output from if it's a key-value format
|
|
219
|
-
});
|
|
220
|
-
const EVALUATION_TRIGGER_TARGETS = ['first', 'every', 'last'];
|
|
221
|
-
const LAST_INTERACTION_DEBOUNCE_MIN_SECONDS = 30;
|
|
222
|
-
const LAST_INTERACTION_DEBOUNCE_MAX_SECONDS = 60 * 60 * 24; // 1 day
|
|
223
|
-
const MIN_EVALUATION_SAMPLE_RATE = 0; // 0%
|
|
224
|
-
const MAX_EVALUATION_SAMPLE_RATE = 100; // 100%
|
|
225
|
-
const triggerConfiguration = zod.z.object({
|
|
226
|
-
target: zod.z.enum(EVALUATION_TRIGGER_TARGETS),
|
|
227
|
-
lastInteractionDebounce: zod.z
|
|
228
|
-
.number()
|
|
229
|
-
.min(LAST_INTERACTION_DEBOUNCE_MIN_SECONDS)
|
|
230
|
-
.max(LAST_INTERACTION_DEBOUNCE_MAX_SECONDS)
|
|
231
|
-
.optional(),
|
|
232
|
-
sampleRate: zod.z
|
|
233
|
-
.number()
|
|
234
|
-
.int()
|
|
235
|
-
.min(MIN_EVALUATION_SAMPLE_RATE)
|
|
236
|
-
.max(MAX_EVALUATION_SAMPLE_RATE)
|
|
237
|
-
.optional(),
|
|
238
|
-
});
|
|
239
|
-
const baseEvaluationConfiguration = zod.z.object({
|
|
240
|
-
reverseScale: zod.z.boolean(), // If true, lower is better, otherwise, higher is better
|
|
241
|
-
actualOutput: actualOutputConfiguration,
|
|
242
|
-
expectedOutput: expectedOutputConfiguration.optional(),
|
|
243
|
-
trigger: triggerConfiguration.optional(),
|
|
244
|
-
});
|
|
245
|
-
const baseEvaluationResultMetadata = zod.z.object({
|
|
246
|
-
// configuration: Configuration snapshot is defined in every metric specification
|
|
247
|
-
actualOutput: zod.z.string(),
|
|
248
|
-
expectedOutput: zod.z.string().optional(),
|
|
249
|
-
datasetLabel: zod.z.string().optional(),
|
|
250
|
-
});
|
|
251
|
-
const baseEvaluationResultError = zod.z.object({
|
|
252
|
-
message: zod.z.string(),
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
const compositeEvaluationConfiguration = baseEvaluationConfiguration.extend({
|
|
256
|
-
evaluationUuids: zod.z.array(zod.z.string()),
|
|
257
|
-
minThreshold: zod.z.number().optional(), // Threshold percentage
|
|
258
|
-
maxThreshold: zod.z.number().optional(), // Threshold percentage
|
|
259
|
-
});
|
|
260
|
-
const compositeEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
|
|
261
|
-
results: zod.z.record(zod.z.string(), // Evaluation uuid
|
|
262
|
-
zod.z.object({
|
|
263
|
-
uuid: zod.z.string(), // Result uuid (for side effects)
|
|
264
|
-
name: zod.z.string(), // Evaluation name
|
|
265
|
-
score: zod.z.number(), // Normalized score
|
|
266
|
-
reason: zod.z.string(),
|
|
267
|
-
passed: zod.z.boolean(),
|
|
268
|
-
tokens: zod.z.number().optional(), // Optional llm evaluation usage
|
|
269
|
-
})),
|
|
270
|
-
});
|
|
271
|
-
const compositeEvaluationResultError = baseEvaluationResultError.extend({
|
|
272
|
-
errors: zod.z
|
|
273
|
-
.record(zod.z.string(), // Evaluation uuid
|
|
274
|
-
zod.z.object({
|
|
275
|
-
uuid: zod.z.string(), // Result uuid (for side effects)
|
|
276
|
-
name: zod.z.string(), // Evaluation name
|
|
277
|
-
message: zod.z.string(),
|
|
278
|
-
}))
|
|
279
|
-
.optional(),
|
|
280
|
-
});
|
|
281
|
-
// AVERAGE
|
|
282
|
-
const compositeEvaluationAverageConfiguration = compositeEvaluationConfiguration.extend({});
|
|
283
|
-
compositeEvaluationResultMetadata.extend({
|
|
284
|
-
configuration: compositeEvaluationAverageConfiguration,
|
|
285
|
-
});
|
|
286
|
-
compositeEvaluationResultError.extend({});
|
|
287
|
-
const CompositeEvaluationAverageSpecification = {
|
|
288
|
-
};
|
|
289
|
-
// WEIGHTED
|
|
290
|
-
const compositeEvaluationWeightedConfiguration = compositeEvaluationConfiguration.extend({
|
|
291
|
-
weights: zod.z.record(zod.z.string(), // Evaluation uuid
|
|
292
|
-
zod.z.number()),
|
|
293
|
-
});
|
|
294
|
-
compositeEvaluationResultMetadata.extend({
|
|
295
|
-
configuration: compositeEvaluationWeightedConfiguration,
|
|
296
|
-
});
|
|
297
|
-
compositeEvaluationResultError.extend({});
|
|
298
|
-
const CompositeEvaluationWeightedSpecification = {
|
|
299
|
-
};
|
|
300
|
-
// CUSTOM
|
|
301
|
-
const compositeEvaluationCustomConfiguration = compositeEvaluationConfiguration.extend({
|
|
302
|
-
formula: zod.z.string(),
|
|
303
|
-
});
|
|
304
|
-
compositeEvaluationResultMetadata.extend({
|
|
305
|
-
configuration: compositeEvaluationCustomConfiguration,
|
|
306
|
-
});
|
|
307
|
-
compositeEvaluationResultError.extend({});
|
|
308
|
-
const CompositeEvaluationCustomSpecification = {
|
|
309
|
-
};
|
|
310
|
-
/* ------------------------------------------------------------------------- */
|
|
311
|
-
var CompositeEvaluationMetric;
|
|
312
|
-
(function (CompositeEvaluationMetric) {
|
|
313
|
-
CompositeEvaluationMetric["Average"] = "average";
|
|
314
|
-
CompositeEvaluationMetric["Weighted"] = "weighted";
|
|
315
|
-
CompositeEvaluationMetric["Custom"] = "custom";
|
|
316
|
-
})(CompositeEvaluationMetric || (CompositeEvaluationMetric = {}));
|
|
317
|
-
const CompositeEvaluationSpecification = {
|
|
318
|
-
// prettier-ignore
|
|
319
|
-
metrics: {
|
|
320
|
-
[CompositeEvaluationMetric.Average]: CompositeEvaluationAverageSpecification,
|
|
321
|
-
[CompositeEvaluationMetric.Weighted]: CompositeEvaluationWeightedSpecification,
|
|
322
|
-
[CompositeEvaluationMetric.Custom]: CompositeEvaluationCustomSpecification,
|
|
323
|
-
},
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const selectedContextSchema = zod.z.object({
|
|
327
|
-
messageIndex: zod.z.number().int().nonnegative(),
|
|
328
|
-
contentBlockIndex: zod.z.number().int().nonnegative(),
|
|
329
|
-
contentType: zod.z.enum([
|
|
330
|
-
'text',
|
|
331
|
-
'reasoning',
|
|
332
|
-
'image',
|
|
333
|
-
'file',
|
|
334
|
-
'tool-call',
|
|
335
|
-
'tool-result',
|
|
336
|
-
]),
|
|
337
|
-
textRange: zod.z
|
|
338
|
-
.object({
|
|
339
|
-
start: zod.z.number().int().nonnegative(),
|
|
340
|
-
end: zod.z.number().int().nonnegative(),
|
|
341
|
-
})
|
|
342
|
-
.optional(),
|
|
343
|
-
selectedText: zod.z.string().optional(),
|
|
344
|
-
toolCallId: zod.z.string().optional(),
|
|
345
|
-
});
|
|
346
|
-
const humanEvaluationConfiguration = baseEvaluationConfiguration.extend({
|
|
347
|
-
enableControls: zod.z.boolean().optional(), // UI annotation controls
|
|
348
|
-
criteria: zod.z.string().optional(),
|
|
349
|
-
});
|
|
350
|
-
const humanEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
|
|
351
|
-
reason: zod.z.string().optional(),
|
|
352
|
-
enrichedReason: zod.z.string().optional(),
|
|
353
|
-
selectedContexts: zod.z.array(selectedContextSchema).optional(),
|
|
354
|
-
});
|
|
355
|
-
const humanEvaluationResultError = baseEvaluationResultError.extend({});
|
|
356
|
-
// BINARY
|
|
357
|
-
const humanEvaluationBinaryConfiguration = humanEvaluationConfiguration.extend({
|
|
358
|
-
passDescription: zod.z.string().optional(),
|
|
359
|
-
failDescription: zod.z.string().optional(),
|
|
360
|
-
});
|
|
361
|
-
humanEvaluationResultMetadata.extend({
|
|
362
|
-
configuration: humanEvaluationBinaryConfiguration,
|
|
363
|
-
});
|
|
364
|
-
humanEvaluationResultError.extend({});
|
|
365
|
-
const HumanEvaluationBinarySpecification = {
|
|
366
|
-
};
|
|
367
|
-
// RATING
|
|
368
|
-
const humanEvaluationRatingConfiguration = humanEvaluationConfiguration.extend({
|
|
369
|
-
minRating: zod.z.number(),
|
|
370
|
-
minRatingDescription: zod.z.string().optional(),
|
|
371
|
-
maxRating: zod.z.number(),
|
|
372
|
-
maxRatingDescription: zod.z.string().optional(),
|
|
373
|
-
minThreshold: zod.z.number().optional(), // Threshold in rating range
|
|
374
|
-
maxThreshold: zod.z.number().optional(), // Threshold in rating range
|
|
375
|
-
});
|
|
376
|
-
humanEvaluationResultMetadata.extend({
|
|
377
|
-
configuration: humanEvaluationRatingConfiguration,
|
|
378
|
-
});
|
|
379
|
-
humanEvaluationResultError.extend({});
|
|
380
|
-
const HumanEvaluationRatingSpecification = {
|
|
381
|
-
};
|
|
382
|
-
/* ------------------------------------------------------------------------- */
|
|
383
|
-
var HumanEvaluationMetric;
|
|
384
|
-
(function (HumanEvaluationMetric) {
|
|
385
|
-
HumanEvaluationMetric["Binary"] = "binary";
|
|
386
|
-
HumanEvaluationMetric["Rating"] = "rating";
|
|
387
|
-
})(HumanEvaluationMetric || (HumanEvaluationMetric = {}));
|
|
388
|
-
const HumanEvaluationSpecification = {
|
|
389
|
-
// prettier-ignore
|
|
390
|
-
metrics: {
|
|
391
|
-
[HumanEvaluationMetric.Binary]: HumanEvaluationBinarySpecification,
|
|
392
|
-
[HumanEvaluationMetric.Rating]: HumanEvaluationRatingSpecification,
|
|
393
|
-
},
|
|
160
|
+
// src/sdk/processor.ts
|
|
161
|
+
var import_exporter_trace_otlp_http = require("@opentelemetry/exporter-trace-otlp-http");
|
|
162
|
+
var import_sdk_trace_node = require("@opentelemetry/sdk-trace-node");
|
|
163
|
+
|
|
164
|
+
// src/constants/attributes.ts
|
|
165
|
+
var ATTRIBUTES = {
|
|
166
|
+
name: "latitude.capture.name",
|
|
167
|
+
tags: "latitude.tags",
|
|
168
|
+
metadata: "latitude.metadata",
|
|
169
|
+
sessionId: "session.id",
|
|
170
|
+
userId: "user.id"
|
|
394
171
|
};
|
|
395
172
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
})
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
llmEvaluationResultMetadata.extend({
|
|
461
|
-
configuration: llmEvaluationCustomConfiguration,
|
|
462
|
-
});
|
|
463
|
-
llmEvaluationResultError.extend({});
|
|
464
|
-
const LlmEvaluationCustomSpecification = {
|
|
465
|
-
};
|
|
466
|
-
// CUSTOM LABELED
|
|
467
|
-
const LlmEvaluationCustomLabeledSpecification = {
|
|
468
|
-
};
|
|
469
|
-
/* ------------------------------------------------------------------------- */
|
|
470
|
-
var LlmEvaluationMetric;
|
|
471
|
-
(function (LlmEvaluationMetric) {
|
|
472
|
-
LlmEvaluationMetric["Binary"] = "binary";
|
|
473
|
-
LlmEvaluationMetric["Rating"] = "rating";
|
|
474
|
-
LlmEvaluationMetric["Comparison"] = "comparison";
|
|
475
|
-
LlmEvaluationMetric["Custom"] = "custom";
|
|
476
|
-
LlmEvaluationMetric["CustomLabeled"] = "custom_labeled";
|
|
477
|
-
})(LlmEvaluationMetric || (LlmEvaluationMetric = {}));
|
|
478
|
-
const LlmEvaluationSpecification = {
|
|
479
|
-
// prettier-ignore
|
|
480
|
-
metrics: {
|
|
481
|
-
[LlmEvaluationMetric.Binary]: LlmEvaluationBinarySpecification,
|
|
482
|
-
[LlmEvaluationMetric.Rating]: LlmEvaluationRatingSpecification,
|
|
483
|
-
[LlmEvaluationMetric.Comparison]: LlmEvaluationComparisonSpecification,
|
|
484
|
-
[LlmEvaluationMetric.Custom]: LlmEvaluationCustomSpecification,
|
|
485
|
-
[LlmEvaluationMetric.CustomLabeled]: LlmEvaluationCustomLabeledSpecification,
|
|
486
|
-
},
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
const ruleEvaluationConfiguration = baseEvaluationConfiguration.extend({});
|
|
490
|
-
const ruleEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
|
|
491
|
-
reason: zod.z.string().optional(),
|
|
492
|
-
});
|
|
493
|
-
const ruleEvaluationResultError = baseEvaluationResultError.extend({});
|
|
494
|
-
// EXACT MATCH
|
|
495
|
-
const ruleEvaluationExactMatchConfiguration = ruleEvaluationConfiguration.extend({
|
|
496
|
-
caseInsensitive: zod.z.boolean(),
|
|
497
|
-
});
|
|
498
|
-
ruleEvaluationResultMetadata.extend({
|
|
499
|
-
configuration: ruleEvaluationExactMatchConfiguration,
|
|
500
|
-
});
|
|
501
|
-
ruleEvaluationResultError.extend({});
|
|
502
|
-
const RuleEvaluationExactMatchSpecification = {
|
|
503
|
-
};
|
|
504
|
-
// REGULAR EXPRESSION
|
|
505
|
-
const ruleEvaluationRegularExpressionConfiguration = ruleEvaluationConfiguration.extend({
|
|
506
|
-
pattern: zod.z.string(),
|
|
507
|
-
});
|
|
508
|
-
ruleEvaluationResultMetadata.extend({
|
|
509
|
-
configuration: ruleEvaluationRegularExpressionConfiguration,
|
|
510
|
-
});
|
|
511
|
-
ruleEvaluationResultError.extend({});
|
|
512
|
-
const RuleEvaluationRegularExpressionSpecification = {
|
|
513
|
-
};
|
|
514
|
-
// SCHEMA VALIDATION
|
|
515
|
-
const ruleEvaluationSchemaValidationConfiguration = ruleEvaluationConfiguration.extend({
|
|
516
|
-
format: zod.z.enum(['json']),
|
|
517
|
-
schema: zod.z.string(),
|
|
518
|
-
});
|
|
519
|
-
ruleEvaluationResultMetadata.extend({
|
|
520
|
-
configuration: ruleEvaluationSchemaValidationConfiguration,
|
|
521
|
-
});
|
|
522
|
-
ruleEvaluationResultError.extend({});
|
|
523
|
-
const RuleEvaluationSchemaValidationSpecification = {
|
|
524
|
-
};
|
|
525
|
-
// LENGTH COUNT
|
|
526
|
-
const ruleEvaluationLengthCountConfiguration = ruleEvaluationConfiguration.extend({
|
|
527
|
-
algorithm: zod.z.enum(['character', 'word', 'sentence']),
|
|
528
|
-
minLength: zod.z.number().optional(),
|
|
529
|
-
maxLength: zod.z.number().optional(),
|
|
530
|
-
});
|
|
531
|
-
ruleEvaluationResultMetadata.extend({
|
|
532
|
-
configuration: ruleEvaluationLengthCountConfiguration,
|
|
533
|
-
});
|
|
534
|
-
ruleEvaluationResultError.extend({});
|
|
535
|
-
const RuleEvaluationLengthCountSpecification = {
|
|
536
|
-
};
|
|
537
|
-
// LEXICAL OVERLAP
|
|
538
|
-
const ruleEvaluationLexicalOverlapConfiguration = ruleEvaluationConfiguration.extend({
|
|
539
|
-
algorithm: zod.z.enum(['substring', 'levenshtein_distance', 'rouge']),
|
|
540
|
-
minOverlap: zod.z.number().optional(), // Percentage of overlap
|
|
541
|
-
maxOverlap: zod.z.number().optional(), // Percentage of overlap
|
|
542
|
-
});
|
|
543
|
-
ruleEvaluationResultMetadata.extend({
|
|
544
|
-
configuration: ruleEvaluationLexicalOverlapConfiguration,
|
|
545
|
-
});
|
|
546
|
-
ruleEvaluationResultError.extend({});
|
|
547
|
-
const RuleEvaluationLexicalOverlapSpecification = {
|
|
548
|
-
};
|
|
549
|
-
// SEMANTIC SIMILARITY
|
|
550
|
-
const ruleEvaluationSemanticSimilarityConfiguration = ruleEvaluationConfiguration.extend({
|
|
551
|
-
algorithm: zod.z.enum(['cosine_distance']),
|
|
552
|
-
minSimilarity: zod.z.number().optional(), // Percentage of similarity
|
|
553
|
-
maxSimilarity: zod.z.number().optional(), // Percentage of similarity
|
|
554
|
-
});
|
|
555
|
-
ruleEvaluationResultMetadata.extend({
|
|
556
|
-
configuration: ruleEvaluationSemanticSimilarityConfiguration,
|
|
557
|
-
});
|
|
558
|
-
ruleEvaluationResultError.extend({});
|
|
559
|
-
const RuleEvaluationSemanticSimilaritySpecification = {
|
|
560
|
-
};
|
|
561
|
-
// NUMERIC SIMILARITY
|
|
562
|
-
const ruleEvaluationNumericSimilarityConfiguration = ruleEvaluationConfiguration.extend({
|
|
563
|
-
algorithm: zod.z.enum(['relative_difference']),
|
|
564
|
-
minSimilarity: zod.z.number().optional(), // Percentage of similarity
|
|
565
|
-
maxSimilarity: zod.z.number().optional(), // Percentage of similarity
|
|
566
|
-
});
|
|
567
|
-
ruleEvaluationResultMetadata.extend({
|
|
568
|
-
configuration: ruleEvaluationNumericSimilarityConfiguration,
|
|
569
|
-
});
|
|
570
|
-
ruleEvaluationResultError.extend({});
|
|
571
|
-
const RuleEvaluationNumericSimilaritySpecification = {
|
|
572
|
-
};
|
|
573
|
-
/* ------------------------------------------------------------------------- */
|
|
574
|
-
var RuleEvaluationMetric;
|
|
575
|
-
(function (RuleEvaluationMetric) {
|
|
576
|
-
RuleEvaluationMetric["ExactMatch"] = "exact_match";
|
|
577
|
-
RuleEvaluationMetric["RegularExpression"] = "regular_expression";
|
|
578
|
-
RuleEvaluationMetric["SchemaValidation"] = "schema_validation";
|
|
579
|
-
RuleEvaluationMetric["LengthCount"] = "length_count";
|
|
580
|
-
RuleEvaluationMetric["LexicalOverlap"] = "lexical_overlap";
|
|
581
|
-
RuleEvaluationMetric["SemanticSimilarity"] = "semantic_similarity";
|
|
582
|
-
RuleEvaluationMetric["NumericSimilarity"] = "numeric_similarity";
|
|
583
|
-
})(RuleEvaluationMetric || (RuleEvaluationMetric = {}));
|
|
584
|
-
const RuleEvaluationSpecification = {
|
|
585
|
-
// prettier-ignore
|
|
586
|
-
metrics: {
|
|
587
|
-
[RuleEvaluationMetric.ExactMatch]: RuleEvaluationExactMatchSpecification,
|
|
588
|
-
[RuleEvaluationMetric.RegularExpression]: RuleEvaluationRegularExpressionSpecification,
|
|
589
|
-
[RuleEvaluationMetric.SchemaValidation]: RuleEvaluationSchemaValidationSpecification,
|
|
590
|
-
[RuleEvaluationMetric.LengthCount]: RuleEvaluationLengthCountSpecification,
|
|
591
|
-
[RuleEvaluationMetric.LexicalOverlap]: RuleEvaluationLexicalOverlapSpecification,
|
|
592
|
-
[RuleEvaluationMetric.SemanticSimilarity]: RuleEvaluationSemanticSimilaritySpecification,
|
|
593
|
-
[RuleEvaluationMetric.NumericSimilarity]: RuleEvaluationNumericSimilaritySpecification,
|
|
594
|
-
},
|
|
173
|
+
// src/constants/scope.ts
|
|
174
|
+
var SCOPE_LATITUDE = "so.latitude.instrumentation";
|
|
175
|
+
|
|
176
|
+
// src/env/env.ts
|
|
177
|
+
var DEFAULT_EXPORTER_URL = {
|
|
178
|
+
production: "https://ingest.latitude.so",
|
|
179
|
+
development: "http://localhost:3002",
|
|
180
|
+
test: "http://localhost:3002"
|
|
181
|
+
}[process.env.NODE_ENV ?? "development"] ?? "http://localhost:3002";
|
|
182
|
+
function getExporterUrl() {
|
|
183
|
+
if (process.env.LATITUDE_TELEMETRY_URL) {
|
|
184
|
+
return process.env.LATITUDE_TELEMETRY_URL;
|
|
185
|
+
}
|
|
186
|
+
return DEFAULT_EXPORTER_URL;
|
|
187
|
+
}
|
|
188
|
+
var env = { EXPORTER_URL: getExporterUrl() };
|
|
189
|
+
|
|
190
|
+
// src/sdk/redact.ts
|
|
191
|
+
var RedactSpanProcessor = class {
|
|
192
|
+
options;
|
|
193
|
+
constructor(options) {
|
|
194
|
+
this.options = options;
|
|
195
|
+
if (!options.mask) {
|
|
196
|
+
this.options.mask = (_attribute, _value) => "******";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
onStart(_span, _context) {
|
|
200
|
+
}
|
|
201
|
+
onEnd(span) {
|
|
202
|
+
Object.assign(span.attributes, this.redactAttributes(span.attributes));
|
|
203
|
+
for (const event of span.events) {
|
|
204
|
+
if (!event.attributes) continue;
|
|
205
|
+
Object.assign(event.attributes, this.redactAttributes(event.attributes));
|
|
206
|
+
}
|
|
207
|
+
for (const link of span.links) {
|
|
208
|
+
if (!link.attributes) continue;
|
|
209
|
+
Object.assign(link.attributes, this.redactAttributes(link.attributes));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
forceFlush() {
|
|
213
|
+
return Promise.resolve();
|
|
214
|
+
}
|
|
215
|
+
shutdown() {
|
|
216
|
+
return Promise.resolve();
|
|
217
|
+
}
|
|
218
|
+
shouldRedact(attribute) {
|
|
219
|
+
return this.options.attributes.some((pattern) => {
|
|
220
|
+
if (typeof pattern === "string") {
|
|
221
|
+
return attribute === pattern;
|
|
222
|
+
} else if (pattern instanceof RegExp) {
|
|
223
|
+
return pattern.test(attribute);
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
redactAttributes(attributes) {
|
|
229
|
+
const redacted = {};
|
|
230
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
231
|
+
if (this.shouldRedact(key)) {
|
|
232
|
+
redacted[key] = this.options.mask?.(key, value);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return redacted;
|
|
236
|
+
}
|
|
595
237
|
};
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
var ChainEventTypes;
|
|
634
|
-
(function (ChainEventTypes) {
|
|
635
|
-
ChainEventTypes["ChainCompleted"] = "chain-completed";
|
|
636
|
-
ChainEventTypes["ChainError"] = "chain-error";
|
|
637
|
-
ChainEventTypes["ChainStarted"] = "chain-started";
|
|
638
|
-
ChainEventTypes["IntegrationWakingUp"] = "integration-waking-up";
|
|
639
|
-
ChainEventTypes["ProviderCompleted"] = "provider-completed";
|
|
640
|
-
ChainEventTypes["ProviderStarted"] = "provider-started";
|
|
641
|
-
ChainEventTypes["StepCompleted"] = "step-completed";
|
|
642
|
-
ChainEventTypes["StepStarted"] = "step-started";
|
|
643
|
-
ChainEventTypes["ToolCompleted"] = "tool-completed";
|
|
644
|
-
ChainEventTypes["ToolResult"] = "tool-result";
|
|
645
|
-
ChainEventTypes["ToolsStarted"] = "tools-started";
|
|
646
|
-
})(ChainEventTypes || (ChainEventTypes = {}));
|
|
647
|
-
|
|
648
|
-
zod.z.object({
|
|
649
|
-
name: zod.z.string(),
|
|
650
|
-
provider: zod.z.string(),
|
|
651
|
-
model: zod.z.string(),
|
|
652
|
-
temperature: zod.z.number(),
|
|
653
|
-
});
|
|
654
|
-
// Experiment ran from a dataset
|
|
655
|
-
const experimentDatasetSourceSchema = zod.z.object({
|
|
656
|
-
source: zod.z.literal('dataset'),
|
|
657
|
-
datasetId: zod.z.number(),
|
|
658
|
-
fromRow: zod.z.number(),
|
|
659
|
-
toRow: zod.z.number(),
|
|
660
|
-
datasetLabels: zod.z.record(zod.z.string(), zod.z.string()),
|
|
661
|
-
parametersMap: zod.z.record(zod.z.string(), zod.z.number()),
|
|
662
|
-
});
|
|
663
|
-
// Experiment ran from last logs (from commit and creation time of experiment)
|
|
664
|
-
const experimentLogsSourceSchema = zod.z.object({
|
|
665
|
-
source: zod.z.literal('logs'),
|
|
666
|
-
count: zod.z.number(),
|
|
667
|
-
});
|
|
668
|
-
// Experiment ran with manual parameters (currently only used for prompts with no parameters)
|
|
669
|
-
const experimentManualSourceSchema = zod.z.object({
|
|
670
|
-
source: zod.z.literal('manual'),
|
|
671
|
-
count: zod.z.number(),
|
|
672
|
-
parametersMap: zod.z.record(zod.z.string(), zod.z.number()),
|
|
673
|
-
});
|
|
674
|
-
zod.z.discriminatedUnion('source', [
|
|
675
|
-
experimentDatasetSourceSchema,
|
|
676
|
-
experimentLogsSourceSchema,
|
|
677
|
-
experimentManualSourceSchema,
|
|
678
|
-
]);
|
|
679
|
-
|
|
680
|
-
var QuotaType;
|
|
681
|
-
(function (QuotaType) {
|
|
682
|
-
QuotaType["Seats"] = "seats";
|
|
683
|
-
QuotaType["Runs"] = "runs";
|
|
684
|
-
QuotaType["Credits"] = "credits";
|
|
685
|
-
})(QuotaType || (QuotaType = {}));
|
|
686
|
-
var GrantSource;
|
|
687
|
-
(function (GrantSource) {
|
|
688
|
-
GrantSource["System"] = "system";
|
|
689
|
-
GrantSource["Subscription"] = "subscription";
|
|
690
|
-
GrantSource["Purchase"] = "purchase";
|
|
691
|
-
GrantSource["Reward"] = "reward";
|
|
692
|
-
GrantSource["Promocode"] = "promocode";
|
|
693
|
-
})(GrantSource || (GrantSource = {}));
|
|
694
|
-
|
|
695
|
-
var ModifiedDocumentType;
|
|
696
|
-
(function (ModifiedDocumentType) {
|
|
697
|
-
ModifiedDocumentType["Created"] = "created";
|
|
698
|
-
ModifiedDocumentType["Updated"] = "updated";
|
|
699
|
-
ModifiedDocumentType["UpdatedPath"] = "updated_path";
|
|
700
|
-
ModifiedDocumentType["Deleted"] = "deleted";
|
|
701
|
-
})(ModifiedDocumentType || (ModifiedDocumentType = {}));
|
|
702
|
-
|
|
703
|
-
var IntegrationType;
|
|
704
|
-
(function (IntegrationType) {
|
|
705
|
-
IntegrationType["Latitude"] = "latitude";
|
|
706
|
-
IntegrationType["ExternalMCP"] = "custom_mcp";
|
|
707
|
-
IntegrationType["Pipedream"] = "pipedream";
|
|
708
|
-
IntegrationType["HostedMCP"] = "mcp_server";
|
|
709
|
-
})(IntegrationType || (IntegrationType = {}));
|
|
710
|
-
var HostedIntegrationType;
|
|
711
|
-
(function (HostedIntegrationType) {
|
|
712
|
-
HostedIntegrationType["Stripe"] = "stripe";
|
|
713
|
-
HostedIntegrationType["Slack"] = "slack";
|
|
714
|
-
HostedIntegrationType["Github"] = "github";
|
|
715
|
-
HostedIntegrationType["Notion"] = "notion";
|
|
716
|
-
HostedIntegrationType["Twitter"] = "twitter";
|
|
717
|
-
HostedIntegrationType["Airtable"] = "airtable";
|
|
718
|
-
HostedIntegrationType["Linear"] = "linear";
|
|
719
|
-
HostedIntegrationType["YoutubeCaptions"] = "youtube_captions";
|
|
720
|
-
HostedIntegrationType["Reddit"] = "reddit";
|
|
721
|
-
HostedIntegrationType["Telegram"] = "telegram";
|
|
722
|
-
HostedIntegrationType["Tinybird"] = "tinybird";
|
|
723
|
-
HostedIntegrationType["Perplexity"] = "perplexity";
|
|
724
|
-
HostedIntegrationType["AwsKbRetrieval"] = "aws_kb_retrieval";
|
|
725
|
-
HostedIntegrationType["BraveSearch"] = "brave_search";
|
|
726
|
-
HostedIntegrationType["EverArt"] = "ever_art";
|
|
727
|
-
HostedIntegrationType["Fetch"] = "fetch";
|
|
728
|
-
HostedIntegrationType["GitLab"] = "gitlab";
|
|
729
|
-
HostedIntegrationType["GoogleMaps"] = "google_maps";
|
|
730
|
-
HostedIntegrationType["Sentry"] = "sentry";
|
|
731
|
-
HostedIntegrationType["Puppeteer"] = "puppeteer";
|
|
732
|
-
HostedIntegrationType["Time"] = "time";
|
|
733
|
-
HostedIntegrationType["browserbase"] = "browserbase";
|
|
734
|
-
HostedIntegrationType["Neon"] = "neon";
|
|
735
|
-
HostedIntegrationType["Postgres"] = "postgres";
|
|
736
|
-
HostedIntegrationType["Supabase"] = "supabase";
|
|
737
|
-
HostedIntegrationType["Redis"] = "redis";
|
|
738
|
-
HostedIntegrationType["Jira"] = "jira";
|
|
739
|
-
HostedIntegrationType["Attio"] = "attio";
|
|
740
|
-
HostedIntegrationType["Ghost"] = "ghost";
|
|
741
|
-
HostedIntegrationType["Figma"] = "figma";
|
|
742
|
-
HostedIntegrationType["Hyperbrowser"] = "hyperbrowser";
|
|
743
|
-
HostedIntegrationType["Audiense"] = "audiense";
|
|
744
|
-
HostedIntegrationType["Apify"] = "apify";
|
|
745
|
-
HostedIntegrationType["Exa"] = "exa";
|
|
746
|
-
HostedIntegrationType["YepCode"] = "yepcode";
|
|
747
|
-
HostedIntegrationType["Monday"] = "monday";
|
|
748
|
-
HostedIntegrationType["AgentQL"] = "agentql";
|
|
749
|
-
HostedIntegrationType["AgentRPC"] = "agentrpc";
|
|
750
|
-
HostedIntegrationType["AstraDB"] = "astra_db";
|
|
751
|
-
HostedIntegrationType["Bankless"] = "bankless";
|
|
752
|
-
HostedIntegrationType["Bicscan"] = "bicscan";
|
|
753
|
-
HostedIntegrationType["Chargebee"] = "chargebee";
|
|
754
|
-
HostedIntegrationType["Chronulus"] = "chronulus";
|
|
755
|
-
HostedIntegrationType["CircleCI"] = "circleci";
|
|
756
|
-
HostedIntegrationType["Codacy"] = "codacy";
|
|
757
|
-
HostedIntegrationType["CodeLogic"] = "codelogic";
|
|
758
|
-
HostedIntegrationType["Convex"] = "convex";
|
|
759
|
-
HostedIntegrationType["Dart"] = "dart";
|
|
760
|
-
HostedIntegrationType["DevHubCMS"] = "devhub_cms";
|
|
761
|
-
HostedIntegrationType["Elasticsearch"] = "elasticsearch";
|
|
762
|
-
HostedIntegrationType["ESignatures"] = "esignatures";
|
|
763
|
-
HostedIntegrationType["Fewsats"] = "fewsats";
|
|
764
|
-
HostedIntegrationType["Firecrawl"] = "firecrawl";
|
|
765
|
-
HostedIntegrationType["Graphlit"] = "graphlit";
|
|
766
|
-
HostedIntegrationType["Heroku"] = "heroku";
|
|
767
|
-
HostedIntegrationType["IntegrationAppHubspot"] = "integration_app_hubspot";
|
|
768
|
-
HostedIntegrationType["LaraTranslate"] = "lara_translate";
|
|
769
|
-
HostedIntegrationType["Logfire"] = "logfire";
|
|
770
|
-
HostedIntegrationType["Langfuse"] = "langfuse";
|
|
771
|
-
HostedIntegrationType["LingoSupabase"] = "lingo_supabase";
|
|
772
|
-
HostedIntegrationType["Make"] = "make";
|
|
773
|
-
HostedIntegrationType["Meilisearch"] = "meilisearch";
|
|
774
|
-
HostedIntegrationType["Momento"] = "momento";
|
|
775
|
-
HostedIntegrationType["Neo4jAura"] = "neo4j_aura";
|
|
776
|
-
HostedIntegrationType["Octagon"] = "octagon";
|
|
777
|
-
HostedIntegrationType["Paddle"] = "paddle";
|
|
778
|
-
HostedIntegrationType["PayPal"] = "paypal";
|
|
779
|
-
HostedIntegrationType["Qdrant"] = "qdrant";
|
|
780
|
-
HostedIntegrationType["Raygun"] = "raygun";
|
|
781
|
-
HostedIntegrationType["Rember"] = "rember";
|
|
782
|
-
HostedIntegrationType["Riza"] = "riza";
|
|
783
|
-
HostedIntegrationType["Search1API"] = "search1api";
|
|
784
|
-
HostedIntegrationType["Semgrep"] = "semgrep";
|
|
785
|
-
HostedIntegrationType["Tavily"] = "tavily";
|
|
786
|
-
HostedIntegrationType["Unstructured"] = "unstructured";
|
|
787
|
-
HostedIntegrationType["Vectorize"] = "vectorize";
|
|
788
|
-
HostedIntegrationType["Xero"] = "xero";
|
|
789
|
-
HostedIntegrationType["Readwise"] = "readwise";
|
|
790
|
-
HostedIntegrationType["Airbnb"] = "airbnb";
|
|
791
|
-
HostedIntegrationType["Mintlify"] = "mintlify";
|
|
792
|
-
// Require all auth file :point_down:
|
|
793
|
-
// Gmail = 'google_drive',
|
|
794
|
-
// GoogleCalendar = 'google_drive',
|
|
795
|
-
// GoogleDrive = 'google_drive',
|
|
796
|
-
// GoogleWorkspace = 'google_workspace', // env vars not supported (?)
|
|
797
|
-
// TODO: implement these
|
|
798
|
-
// Wordpress = 'wordpress', // Not on OpenTools
|
|
799
|
-
// Discord = 'discord', // Not on OpenTools
|
|
800
|
-
// Intercom = 'intercom', // Not on OpenTools
|
|
801
|
-
// Hubspot = 'hubspot', // Docker based
|
|
802
|
-
// Loops = 'loops', // Does not exist
|
|
803
|
-
})(HostedIntegrationType || (HostedIntegrationType = {}));
|
|
804
|
-
|
|
805
|
-
var LogSources;
|
|
806
|
-
(function (LogSources) {
|
|
807
|
-
LogSources["API"] = "api";
|
|
808
|
-
LogSources["AgentAsTool"] = "agent_as_tool";
|
|
809
|
-
LogSources["Copilot"] = "copilot";
|
|
810
|
-
LogSources["EmailTrigger"] = "email_trigger";
|
|
811
|
-
LogSources["Evaluation"] = "evaluation";
|
|
812
|
-
LogSources["Experiment"] = "experiment";
|
|
813
|
-
LogSources["IntegrationTrigger"] = "integration_trigger";
|
|
814
|
-
LogSources["Playground"] = "playground";
|
|
815
|
-
LogSources["ScheduledTrigger"] = "scheduled_trigger";
|
|
816
|
-
LogSources["SharedPrompt"] = "shared_prompt";
|
|
817
|
-
LogSources["ShadowTest"] = "shadow_test";
|
|
818
|
-
LogSources["ABTestChallenger"] = "ab_test_challenger";
|
|
819
|
-
LogSources["User"] = "user";
|
|
820
|
-
LogSources["Optimization"] = "optimization";
|
|
821
|
-
})(LogSources || (LogSources = {}));
|
|
822
|
-
|
|
823
|
-
var RunSourceGroup;
|
|
824
|
-
(function (RunSourceGroup) {
|
|
825
|
-
RunSourceGroup["Production"] = "production";
|
|
826
|
-
RunSourceGroup["Playground"] = "playground";
|
|
827
|
-
})(RunSourceGroup || (RunSourceGroup = {}));
|
|
828
|
-
({
|
|
829
|
-
[RunSourceGroup.Production]: [
|
|
830
|
-
LogSources.API,
|
|
831
|
-
LogSources.ShadowTest,
|
|
832
|
-
LogSources.ABTestChallenger,
|
|
833
|
-
LogSources.EmailTrigger,
|
|
834
|
-
LogSources.IntegrationTrigger,
|
|
835
|
-
LogSources.ScheduledTrigger,
|
|
836
|
-
LogSources.SharedPrompt,
|
|
837
|
-
LogSources.User,
|
|
838
|
-
],
|
|
839
|
-
[RunSourceGroup.Playground]: [LogSources.Playground, LogSources.Experiment],
|
|
840
|
-
});
|
|
841
|
-
|
|
842
|
-
var SpanKind;
|
|
843
|
-
(function (SpanKind) {
|
|
844
|
-
SpanKind["Internal"] = "internal";
|
|
845
|
-
SpanKind["Server"] = "server";
|
|
846
|
-
SpanKind["Client"] = "client";
|
|
847
|
-
SpanKind["Producer"] = "producer";
|
|
848
|
-
SpanKind["Consumer"] = "consumer";
|
|
849
|
-
})(SpanKind || (SpanKind = {}));
|
|
850
|
-
// Note: loosely based on OpenTelemetry GenAI semantic conventions
|
|
851
|
-
var SpanType;
|
|
852
|
-
(function (SpanType) {
|
|
853
|
-
// Latitude wrappers
|
|
854
|
-
SpanType["Prompt"] = "prompt";
|
|
855
|
-
SpanType["Chat"] = "chat";
|
|
856
|
-
SpanType["External"] = "external";
|
|
857
|
-
SpanType["UnresolvedExternal"] = "unresolved_external";
|
|
858
|
-
// Added a HTTP span to capture raw HTTP requests and responses when running from Latitude
|
|
859
|
-
SpanType["Http"] = "http";
|
|
860
|
-
// Any known span from supported specifications will be grouped into one of these types
|
|
861
|
-
SpanType["Completion"] = "completion";
|
|
862
|
-
SpanType["Tool"] = "tool";
|
|
863
|
-
SpanType["Embedding"] = "embedding";
|
|
864
|
-
SpanType["Unknown"] = "unknown";
|
|
865
|
-
})(SpanType || (SpanType = {}));
|
|
866
|
-
[
|
|
867
|
-
SpanType.Prompt,
|
|
868
|
-
SpanType.External,
|
|
869
|
-
SpanType.Chat,
|
|
238
|
+
var DEFAULT_REDACT_SPAN_PROCESSOR = () => new RedactSpanProcessor({
|
|
239
|
+
attributes: [
|
|
240
|
+
// HTTP security headers
|
|
241
|
+
/^http\.request\.header\.authorization$/i,
|
|
242
|
+
/^http\.request\.header\.cookie$/i,
|
|
243
|
+
/^http\.request\.header\.x[-_]api[-_]key$/i,
|
|
244
|
+
// Database statements may contain sensitive data
|
|
245
|
+
/^db\.statement$/i
|
|
246
|
+
]
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// src/sdk/span-filter.ts
|
|
250
|
+
var GEN_AI_PREFIX = "gen_ai.";
|
|
251
|
+
var LLM_PREFIX = "llm.";
|
|
252
|
+
var OPENINFERENCE_KIND = "openinference.span.kind";
|
|
253
|
+
var OTEL_LLM_INSTRUMENTATION_SCOPE_PREFIXES = [
|
|
254
|
+
"opentelemetry.instrumentation.alephalpha",
|
|
255
|
+
"opentelemetry.instrumentation.anthropic",
|
|
256
|
+
"opentelemetry.instrumentation.bedrock",
|
|
257
|
+
"opentelemetry.instrumentation.cohere",
|
|
258
|
+
"opentelemetry.instrumentation.crewai",
|
|
259
|
+
"opentelemetry.instrumentation.google_generativeai",
|
|
260
|
+
"opentelemetry.instrumentation.groq",
|
|
261
|
+
"opentelemetry.instrumentation.haystack",
|
|
262
|
+
"opentelemetry.instrumentation.langchain",
|
|
263
|
+
"opentelemetry.instrumentation.llamaindex",
|
|
264
|
+
"opentelemetry.instrumentation.mistralai",
|
|
265
|
+
"opentelemetry.instrumentation.ollama",
|
|
266
|
+
"opentelemetry.instrumentation.openai",
|
|
267
|
+
"opentelemetry.instrumentation.replicate",
|
|
268
|
+
"opentelemetry.instrumentation.sagemaker",
|
|
269
|
+
"opentelemetry.instrumentation.together",
|
|
270
|
+
"opentelemetry.instrumentation.transformers",
|
|
271
|
+
"opentelemetry.instrumentation.vertexai",
|
|
272
|
+
"opentelemetry.instrumentation.watsonx",
|
|
273
|
+
"openinference.instrumentation"
|
|
870
274
|
];
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
[SpanType.Chat]: {
|
|
879
|
-
name: 'Chat',
|
|
880
|
-
description: 'A chat continuation span',
|
|
881
|
-
isGenAI: false,
|
|
882
|
-
isHidden: false,
|
|
883
|
-
},
|
|
884
|
-
[SpanType.External]: {
|
|
885
|
-
name: 'External',
|
|
886
|
-
description: 'An external capture span',
|
|
887
|
-
isGenAI: false,
|
|
888
|
-
isHidden: false,
|
|
889
|
-
},
|
|
890
|
-
[SpanType.UnresolvedExternal]: {
|
|
891
|
-
name: 'Unresolved External',
|
|
892
|
-
description: 'An external span that needs path resolution before storage',
|
|
893
|
-
isGenAI: false,
|
|
894
|
-
isHidden: true,
|
|
895
|
-
},
|
|
896
|
-
[SpanType.Completion]: {
|
|
897
|
-
name: 'Completion',
|
|
898
|
-
description: 'A completion call',
|
|
899
|
-
isGenAI: true,
|
|
900
|
-
isHidden: false,
|
|
901
|
-
},
|
|
902
|
-
[SpanType.Embedding]: {
|
|
903
|
-
name: 'Embedding',
|
|
904
|
-
description: 'An embedding call',
|
|
905
|
-
isGenAI: true,
|
|
906
|
-
isHidden: false,
|
|
907
|
-
},
|
|
908
|
-
[SpanType.Tool]: {
|
|
909
|
-
name: 'Tool',
|
|
910
|
-
description: 'A tool call',
|
|
911
|
-
isGenAI: true,
|
|
912
|
-
isHidden: false,
|
|
913
|
-
},
|
|
914
|
-
[SpanType.Http]: {
|
|
915
|
-
name: 'HTTP',
|
|
916
|
-
description: 'An HTTP request',
|
|
917
|
-
isGenAI: false,
|
|
918
|
-
isHidden: true,
|
|
919
|
-
},
|
|
920
|
-
[SpanType.Unknown]: {
|
|
921
|
-
name: 'Unknown',
|
|
922
|
-
description: 'An unknown span',
|
|
923
|
-
isGenAI: false,
|
|
924
|
-
isHidden: true,
|
|
925
|
-
},
|
|
926
|
-
};
|
|
927
|
-
var SpanStatus;
|
|
928
|
-
(function (SpanStatus) {
|
|
929
|
-
SpanStatus["Unset"] = "unset";
|
|
930
|
-
SpanStatus["Ok"] = "ok";
|
|
931
|
-
SpanStatus["Error"] = "error";
|
|
932
|
-
})(SpanStatus || (SpanStatus = {}));
|
|
933
|
-
new Set([
|
|
934
|
-
SpanType.Prompt,
|
|
935
|
-
SpanType.Chat,
|
|
936
|
-
SpanType.External,
|
|
937
|
-
]);
|
|
938
|
-
|
|
939
|
-
// Note: Traces are unmaterialized but this context is used to propagate the trace
|
|
940
|
-
// See www.w3.org/TR/trace-context and w3c.github.io/baggage
|
|
941
|
-
zod.z.object({
|
|
942
|
-
traceparent: zod.z.string(), // <version>-<trace-id>-<span-id>-<trace-flags>
|
|
943
|
-
tracestate: zod.z.string().optional(), // <key>=urlencoded(<value>)[,<key>=urlencoded(<value>)]*
|
|
944
|
-
baggage: zod.z.string().optional(), // <key>=urlencoded(<value>)[,<key>=urlencoded(<value>)]*
|
|
945
|
-
});
|
|
946
|
-
|
|
947
|
-
const ATTRIBUTES = {
|
|
948
|
-
// Custom attributes added and used by Latitude spans (Prompt / External / Chat)
|
|
949
|
-
LATITUDE: {
|
|
950
|
-
type: 'latitude.type',
|
|
951
|
-
documentUuid: 'latitude.document_uuid',
|
|
952
|
-
promptPath: 'latitude.prompt_path',
|
|
953
|
-
commitUuid: 'latitude.commit_uuid',
|
|
954
|
-
documentLogUuid: 'latitude.document_log_uuid',
|
|
955
|
-
projectId: 'latitude.project_id',
|
|
956
|
-
experimentUuid: 'latitude.experiment_uuid',
|
|
957
|
-
source: 'latitude.source',
|
|
958
|
-
externalId: 'latitude.external_id',
|
|
959
|
-
testDeploymentId: 'latitude.test_deployment_id',
|
|
960
|
-
previousTraceId: 'latitude.previous_trace_id',
|
|
961
|
-
// Custom additions to the GenAI semantic conventions (deprecated)
|
|
962
|
-
request: {
|
|
963
|
-
_root: 'gen_ai.request',
|
|
964
|
-
configuration: 'gen_ai.request.configuration',
|
|
965
|
-
template: 'gen_ai.request.template',
|
|
966
|
-
parameters: 'gen_ai.request.parameters'},
|
|
967
|
-
response: {
|
|
968
|
-
_root: 'gen_ai.response'},
|
|
969
|
-
usage: {
|
|
970
|
-
promptTokens: 'gen_ai.usage.prompt_tokens',
|
|
971
|
-
cachedTokens: 'gen_ai.usage.cached_tokens',
|
|
972
|
-
reasoningTokens: 'gen_ai.usage.reasoning_tokens',
|
|
973
|
-
completionTokens: 'gen_ai.usage.completion_tokens',
|
|
974
|
-
},
|
|
975
|
-
},
|
|
976
|
-
// Official OpenTelemetry semantic conventions
|
|
977
|
-
OPENTELEMETRY: {
|
|
978
|
-
HTTP: {
|
|
979
|
-
request: {
|
|
980
|
-
url: 'http.request.url',
|
|
981
|
-
body: 'http.request.body',
|
|
982
|
-
header: 'http.request.header',
|
|
983
|
-
method: semanticConventions.ATTR_HTTP_REQUEST_METHOD,
|
|
984
|
-
},
|
|
985
|
-
response: {
|
|
986
|
-
body: 'http.response.body',
|
|
987
|
-
header: 'http.response.header',
|
|
988
|
-
statusCode: semanticConventions.ATTR_HTTP_RESPONSE_STATUS_CODE,
|
|
989
|
-
},
|
|
990
|
-
},
|
|
991
|
-
// GenAI semantic conventions
|
|
992
|
-
// https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/
|
|
993
|
-
GEN_AI: {
|
|
994
|
-
operation: incubating.ATTR_GEN_AI_OPERATION_NAME,
|
|
995
|
-
response: {
|
|
996
|
-
model: incubating.ATTR_GEN_AI_RESPONSE_MODEL,
|
|
997
|
-
finishReasons: incubating.ATTR_GEN_AI_RESPONSE_FINISH_REASONS,
|
|
998
|
-
},
|
|
999
|
-
usage: {
|
|
1000
|
-
inputTokens: incubating.ATTR_GEN_AI_USAGE_INPUT_TOKENS,
|
|
1001
|
-
outputTokens: incubating.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,
|
|
1002
|
-
},
|
|
1003
|
-
systemInstructions: 'gen_ai.system.instructions', // Contains the PARTS of the "system message"
|
|
1004
|
-
tool: {
|
|
1005
|
-
call: {
|
|
1006
|
-
id: incubating.ATTR_GEN_AI_TOOL_CALL_ID,
|
|
1007
|
-
arguments: 'gen_ai.tool.call.arguments'}},
|
|
1008
|
-
input: {
|
|
1009
|
-
messages: 'gen_ai.input.messages',
|
|
1010
|
-
},
|
|
1011
|
-
output: {
|
|
1012
|
-
messages: 'gen_ai.output.messages',
|
|
1013
|
-
},
|
|
1014
|
-
_deprecated: {
|
|
1015
|
-
system: incubating.ATTR_GEN_AI_SYSTEM,
|
|
1016
|
-
tool: {
|
|
1017
|
-
name: incubating.ATTR_GEN_AI_TOOL_NAME,
|
|
1018
|
-
type: incubating.ATTR_GEN_AI_TOOL_TYPE,
|
|
1019
|
-
result: {
|
|
1020
|
-
value: 'gen_ai.tool.result.value',
|
|
1021
|
-
isError: 'gen_ai.tool.result.is_error',
|
|
1022
|
-
},
|
|
1023
|
-
}},
|
|
1024
|
-
},
|
|
1025
|
-
}};
|
|
1026
|
-
const VALUES = {
|
|
1027
|
-
OPENTELEMETRY: {
|
|
1028
|
-
GEN_AI: {
|
|
1029
|
-
response: {
|
|
1030
|
-
finishReasons: {
|
|
1031
|
-
stop: 'stop',
|
|
1032
|
-
toolCalls: 'tool_calls'},
|
|
1033
|
-
},
|
|
1034
|
-
tool: {
|
|
1035
|
-
type: {
|
|
1036
|
-
function: 'function',
|
|
1037
|
-
},
|
|
1038
|
-
}},
|
|
1039
|
-
}};
|
|
1040
|
-
|
|
1041
|
-
/* Note: Instrumentation scopes from all language SDKs */
|
|
1042
|
-
const SCOPE_LATITUDE = 'so.latitude.instrumentation';
|
|
1043
|
-
var InstrumentationScope;
|
|
1044
|
-
(function (InstrumentationScope) {
|
|
1045
|
-
InstrumentationScope["Manual"] = "manual";
|
|
1046
|
-
InstrumentationScope["Latitude"] = "latitude";
|
|
1047
|
-
InstrumentationScope["OpenAI"] = "openai";
|
|
1048
|
-
InstrumentationScope["Anthropic"] = "anthropic";
|
|
1049
|
-
InstrumentationScope["AzureOpenAI"] = "azure";
|
|
1050
|
-
InstrumentationScope["VercelAI"] = "vercelai";
|
|
1051
|
-
InstrumentationScope["VertexAI"] = "vertexai";
|
|
1052
|
-
InstrumentationScope["AIPlatform"] = "aiplatform";
|
|
1053
|
-
InstrumentationScope["MistralAI"] = "mistralai";
|
|
1054
|
-
InstrumentationScope["Bedrock"] = "bedrock";
|
|
1055
|
-
InstrumentationScope["Sagemaker"] = "sagemaker";
|
|
1056
|
-
InstrumentationScope["TogetherAI"] = "togetherai";
|
|
1057
|
-
InstrumentationScope["Replicate"] = "replicate";
|
|
1058
|
-
InstrumentationScope["Groq"] = "groq";
|
|
1059
|
-
InstrumentationScope["Cohere"] = "cohere";
|
|
1060
|
-
InstrumentationScope["LiteLLM"] = "litellm";
|
|
1061
|
-
InstrumentationScope["Langchain"] = "langchain";
|
|
1062
|
-
InstrumentationScope["LlamaIndex"] = "llamaindex";
|
|
1063
|
-
InstrumentationScope["DSPy"] = "dspy";
|
|
1064
|
-
InstrumentationScope["Haystack"] = "haystack";
|
|
1065
|
-
InstrumentationScope["Ollama"] = "ollama";
|
|
1066
|
-
InstrumentationScope["Transformers"] = "transformers";
|
|
1067
|
-
InstrumentationScope["AlephAlpha"] = "alephalpha";
|
|
1068
|
-
})(InstrumentationScope || (InstrumentationScope = {}));
|
|
1069
|
-
/* Note: Schemas for span ingestion following OpenTelemetry service request specification */
|
|
1070
|
-
var Otlp;
|
|
1071
|
-
(function (Otlp) {
|
|
1072
|
-
Otlp.attributeValueSchema = zod.z.object({
|
|
1073
|
-
stringValue: zod.z.string().optional(),
|
|
1074
|
-
intValue: zod.z.number().optional(),
|
|
1075
|
-
boolValue: zod.z.boolean().optional(),
|
|
1076
|
-
arrayValue: zod.z
|
|
1077
|
-
.object({
|
|
1078
|
-
values: zod.z.array(zod.z.object({
|
|
1079
|
-
stringValue: zod.z.string().optional(),
|
|
1080
|
-
intValue: zod.z.number().optional(),
|
|
1081
|
-
boolValue: zod.z.boolean().optional(),
|
|
1082
|
-
})),
|
|
1083
|
-
})
|
|
1084
|
-
.optional(),
|
|
1085
|
-
});
|
|
1086
|
-
Otlp.attributeSchema = zod.z.object({
|
|
1087
|
-
key: zod.z.string(),
|
|
1088
|
-
value: Otlp.attributeValueSchema,
|
|
1089
|
-
});
|
|
1090
|
-
Otlp.eventSchema = zod.z.object({
|
|
1091
|
-
name: zod.z.string(),
|
|
1092
|
-
timeUnixNano: zod.z.string(),
|
|
1093
|
-
attributes: zod.z.array(Otlp.attributeSchema).optional(),
|
|
1094
|
-
});
|
|
1095
|
-
Otlp.linkSchema = zod.z.object({
|
|
1096
|
-
traceId: zod.z.string(),
|
|
1097
|
-
spanId: zod.z.string(),
|
|
1098
|
-
attributes: zod.z.array(Otlp.attributeSchema).optional(),
|
|
1099
|
-
});
|
|
1100
|
-
(function (StatusCode) {
|
|
1101
|
-
StatusCode[StatusCode["Unset"] = 0] = "Unset";
|
|
1102
|
-
StatusCode[StatusCode["Ok"] = 1] = "Ok";
|
|
1103
|
-
StatusCode[StatusCode["Error"] = 2] = "Error";
|
|
1104
|
-
})(Otlp.StatusCode || (Otlp.StatusCode = {}));
|
|
1105
|
-
Otlp.statusSchema = zod.z.object({
|
|
1106
|
-
code: zod.z.number(),
|
|
1107
|
-
message: zod.z.string().optional(),
|
|
1108
|
-
});
|
|
1109
|
-
(function (SpanKind) {
|
|
1110
|
-
SpanKind[SpanKind["Internal"] = 0] = "Internal";
|
|
1111
|
-
SpanKind[SpanKind["Server"] = 1] = "Server";
|
|
1112
|
-
SpanKind[SpanKind["Client"] = 2] = "Client";
|
|
1113
|
-
SpanKind[SpanKind["Producer"] = 3] = "Producer";
|
|
1114
|
-
SpanKind[SpanKind["Consumer"] = 4] = "Consumer";
|
|
1115
|
-
})(Otlp.SpanKind || (Otlp.SpanKind = {}));
|
|
1116
|
-
Otlp.spanSchema = zod.z.object({
|
|
1117
|
-
traceId: zod.z.string(),
|
|
1118
|
-
spanId: zod.z.string(),
|
|
1119
|
-
parentSpanId: zod.z.string().optional(),
|
|
1120
|
-
name: zod.z.string(),
|
|
1121
|
-
kind: zod.z.number(),
|
|
1122
|
-
startTimeUnixNano: zod.z.string(),
|
|
1123
|
-
endTimeUnixNano: zod.z.string(),
|
|
1124
|
-
status: Otlp.statusSchema.optional(),
|
|
1125
|
-
events: zod.z.array(Otlp.eventSchema).optional(),
|
|
1126
|
-
links: zod.z.array(Otlp.linkSchema).optional(),
|
|
1127
|
-
attributes: zod.z.array(Otlp.attributeSchema).optional(),
|
|
1128
|
-
});
|
|
1129
|
-
Otlp.scopeSchema = zod.z.object({
|
|
1130
|
-
name: zod.z.string(),
|
|
1131
|
-
version: zod.z.string().optional(),
|
|
1132
|
-
});
|
|
1133
|
-
Otlp.scopeSpanSchema = zod.z.object({
|
|
1134
|
-
scope: Otlp.scopeSchema,
|
|
1135
|
-
spans: zod.z.array(Otlp.spanSchema),
|
|
1136
|
-
});
|
|
1137
|
-
Otlp.resourceSchema = zod.z.object({
|
|
1138
|
-
attributes: zod.z.array(Otlp.attributeSchema),
|
|
1139
|
-
});
|
|
1140
|
-
Otlp.resourceSpanSchema = zod.z.object({
|
|
1141
|
-
resource: Otlp.resourceSchema,
|
|
1142
|
-
scopeSpans: zod.z.array(Otlp.scopeSpanSchema),
|
|
1143
|
-
});
|
|
1144
|
-
Otlp.serviceRequestSchema = zod.z.object({
|
|
1145
|
-
resourceSpans: zod.z.array(Otlp.resourceSpanSchema),
|
|
1146
|
-
});
|
|
1147
|
-
})(Otlp || (Otlp = {}));
|
|
1148
|
-
|
|
1149
|
-
const MAX_SIMULATION_TURNS = 10;
|
|
1150
|
-
const globalGoalSourceSchema = zod.z.object({
|
|
1151
|
-
type: zod.z.literal('global'),
|
|
1152
|
-
value: zod.z.string(),
|
|
1153
|
-
});
|
|
1154
|
-
const columnGoalSourceSchema = zod.z.object({
|
|
1155
|
-
type: zod.z.literal('column'),
|
|
1156
|
-
columnIndex: zod.z.number(),
|
|
1157
|
-
});
|
|
1158
|
-
const simulatedUserGoalSourceSchema = zod.z.discriminatedUnion('type', [
|
|
1159
|
-
globalGoalSourceSchema,
|
|
1160
|
-
columnGoalSourceSchema,
|
|
1161
|
-
]);
|
|
1162
|
-
const SimulationSettingsSchema = zod.z.object({
|
|
1163
|
-
simulateToolResponses: zod.z.boolean().optional(),
|
|
1164
|
-
simulatedTools: zod.z.array(zod.z.string()).optional(), // Empty array means all tools are simulated (if simulateToolResponses is true).
|
|
1165
|
-
toolSimulationInstructions: zod.z.string().optional(), // A prompt used to guide and generate the simulation result
|
|
1166
|
-
maxTurns: zod.z.number().min(1).max(MAX_SIMULATION_TURNS).optional(), // The maximum number of turns to simulate. Default is 1, and any greater value will add a new user message to the simulated conversation.
|
|
1167
|
-
simulatedUserGoal: zod.z.string().optional(), // Deprecated: Use simulatedUserGoalSource instead. Kept for backward compatibility.
|
|
1168
|
-
simulatedUserGoalSource: simulatedUserGoalSourceSchema.optional(), // The source for the simulated user goal (global text or dataset column).
|
|
1169
|
-
});
|
|
1170
|
-
|
|
1171
|
-
var OptimizationEngine;
|
|
1172
|
-
(function (OptimizationEngine) {
|
|
1173
|
-
OptimizationEngine["Identity"] = "identity";
|
|
1174
|
-
OptimizationEngine["Gepa"] = "gepa";
|
|
1175
|
-
})(OptimizationEngine || (OptimizationEngine = {}));
|
|
1176
|
-
const OptimizationBudgetSchema = zod.z.object({
|
|
1177
|
-
time: zod.z.number().min(0).optional(),
|
|
1178
|
-
tokens: zod.z.number().min(0).optional(),
|
|
1179
|
-
});
|
|
1180
|
-
zod.z.object({
|
|
1181
|
-
dataset: zod.z
|
|
1182
|
-
.object({
|
|
1183
|
-
target: zod.z.number().min(0).optional(), // Note: number of rows to curate when not provided by the user
|
|
1184
|
-
label: zod.z.string().optional(), // Note: expected output column when using a labeled evaluation
|
|
1185
|
-
})
|
|
1186
|
-
.optional(),
|
|
1187
|
-
parameters: zod.z
|
|
1188
|
-
.record(zod.z.string(), zod.z.object({
|
|
1189
|
-
column: zod.z.string().optional(), // Note: corresponding column in the user-provided trainset and testset
|
|
1190
|
-
isPii: zod.z.boolean().optional(),
|
|
1191
|
-
}))
|
|
1192
|
-
.optional(),
|
|
1193
|
-
simulation: SimulationSettingsSchema.optional(),
|
|
1194
|
-
scope: zod.z
|
|
1195
|
-
.object({
|
|
1196
|
-
configuration: zod.z.boolean().optional(),
|
|
1197
|
-
instructions: zod.z.boolean().optional(),
|
|
1198
|
-
})
|
|
1199
|
-
.optional(),
|
|
1200
|
-
budget: OptimizationBudgetSchema.optional(),
|
|
1201
|
-
});
|
|
1202
|
-
|
|
1203
|
-
// TODO(tracing): deprecated
|
|
1204
|
-
const HEAD_COMMIT = 'live';
|
|
1205
|
-
var Providers;
|
|
1206
|
-
(function (Providers) {
|
|
1207
|
-
Providers["OpenAI"] = "openai";
|
|
1208
|
-
Providers["Anthropic"] = "anthropic";
|
|
1209
|
-
Providers["Groq"] = "groq";
|
|
1210
|
-
Providers["Mistral"] = "mistral";
|
|
1211
|
-
Providers["Azure"] = "azure";
|
|
1212
|
-
Providers["Google"] = "google";
|
|
1213
|
-
Providers["GoogleVertex"] = "google_vertex";
|
|
1214
|
-
Providers["AnthropicVertex"] = "anthropic_vertex";
|
|
1215
|
-
Providers["Custom"] = "custom";
|
|
1216
|
-
Providers["XAI"] = "xai";
|
|
1217
|
-
Providers["AmazonBedrock"] = "amazon_bedrock";
|
|
1218
|
-
Providers["DeepSeek"] = "deepseek";
|
|
1219
|
-
Providers["Perplexity"] = "perplexity";
|
|
1220
|
-
})(Providers || (Providers = {}));
|
|
1221
|
-
var DocumentType;
|
|
1222
|
-
(function (DocumentType) {
|
|
1223
|
-
DocumentType["Prompt"] = "prompt";
|
|
1224
|
-
DocumentType["Agent"] = "agent";
|
|
1225
|
-
})(DocumentType || (DocumentType = {}));
|
|
1226
|
-
var DocumentTriggerType;
|
|
1227
|
-
(function (DocumentTriggerType) {
|
|
1228
|
-
DocumentTriggerType["Email"] = "email";
|
|
1229
|
-
DocumentTriggerType["Scheduled"] = "scheduled";
|
|
1230
|
-
DocumentTriggerType["Integration"] = "integration";
|
|
1231
|
-
})(DocumentTriggerType || (DocumentTriggerType = {}));
|
|
1232
|
-
var DocumentTriggerStatus;
|
|
1233
|
-
(function (DocumentTriggerStatus) {
|
|
1234
|
-
DocumentTriggerStatus["Pending"] = "pending";
|
|
1235
|
-
DocumentTriggerStatus["Deployed"] = "deployed";
|
|
1236
|
-
DocumentTriggerStatus["Deprecated"] = "deprecated";
|
|
1237
|
-
})(DocumentTriggerStatus || (DocumentTriggerStatus = {}));
|
|
1238
|
-
var DocumentTriggerParameters;
|
|
1239
|
-
(function (DocumentTriggerParameters) {
|
|
1240
|
-
DocumentTriggerParameters["SenderEmail"] = "senderEmail";
|
|
1241
|
-
DocumentTriggerParameters["SenderName"] = "senderName";
|
|
1242
|
-
DocumentTriggerParameters["Subject"] = "subject";
|
|
1243
|
-
DocumentTriggerParameters["Body"] = "body";
|
|
1244
|
-
DocumentTriggerParameters["Attachments"] = "attachments";
|
|
1245
|
-
})(DocumentTriggerParameters || (DocumentTriggerParameters = {}));
|
|
1246
|
-
const DOCUMENT_PATH_REGEXP = /^([\w-]+\/)*([\w-.])+$/;
|
|
1247
|
-
|
|
1248
|
-
const translator = new rosettaAi.Translator({
|
|
1249
|
-
filterEmptyMessages: true,
|
|
1250
|
-
providerMetadata: 'preserve',
|
|
1251
|
-
});
|
|
1252
|
-
class ManualInstrumentation {
|
|
1253
|
-
enabled;
|
|
1254
|
-
tracer;
|
|
1255
|
-
options;
|
|
1256
|
-
constructor(tracer, options) {
|
|
1257
|
-
this.enabled = false;
|
|
1258
|
-
this.tracer = tracer;
|
|
1259
|
-
this.options = options ?? {};
|
|
1260
|
-
}
|
|
1261
|
-
isEnabled() {
|
|
1262
|
-
return this.enabled;
|
|
1263
|
-
}
|
|
1264
|
-
enable() {
|
|
1265
|
-
this.enabled = true;
|
|
1266
|
-
}
|
|
1267
|
-
disable() {
|
|
1268
|
-
this.enabled = false;
|
|
1269
|
-
}
|
|
1270
|
-
resume(ctx) {
|
|
1271
|
-
const parts = ctx.traceparent.split('-');
|
|
1272
|
-
if (parts.length !== 4) {
|
|
1273
|
-
return otel__namespace.ROOT_CONTEXT;
|
|
1274
|
-
}
|
|
1275
|
-
const [, traceId, spanId, flags] = parts;
|
|
1276
|
-
if (!traceId || !spanId) {
|
|
1277
|
-
return otel__namespace.ROOT_CONTEXT;
|
|
1278
|
-
}
|
|
1279
|
-
const spanContext = {
|
|
1280
|
-
traceId,
|
|
1281
|
-
spanId,
|
|
1282
|
-
traceFlags: parseInt(flags ?? '01', 16),
|
|
1283
|
-
isRemote: true,
|
|
1284
|
-
};
|
|
1285
|
-
let context = otel.trace.setSpanContext(otel__namespace.ROOT_CONTEXT, spanContext);
|
|
1286
|
-
if (ctx.baggage) {
|
|
1287
|
-
const baggageEntries = {};
|
|
1288
|
-
for (const pair of ctx.baggage.split(',')) {
|
|
1289
|
-
const [key, value] = pair.split('=');
|
|
1290
|
-
if (key && value) {
|
|
1291
|
-
baggageEntries[key] = { value: decodeURIComponent(value) };
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
const baggage = otel.propagation.createBaggage(baggageEntries);
|
|
1295
|
-
context = otel.propagation.setBaggage(context, baggage);
|
|
1296
|
-
}
|
|
1297
|
-
return context;
|
|
1298
|
-
}
|
|
1299
|
-
error(span, error, options) {
|
|
1300
|
-
options = options || {};
|
|
1301
|
-
span.recordException(error);
|
|
1302
|
-
span.setAttributes(options.attributes || {});
|
|
1303
|
-
span.setStatus({
|
|
1304
|
-
code: otel__namespace.SpanStatusCode.ERROR,
|
|
1305
|
-
message: error.message || undefined,
|
|
1306
|
-
});
|
|
1307
|
-
span.end();
|
|
1308
|
-
}
|
|
1309
|
-
span(ctx, name, type, options) {
|
|
1310
|
-
if (!this.enabled) {
|
|
1311
|
-
return {
|
|
1312
|
-
context: ctx,
|
|
1313
|
-
end: (_options) => { },
|
|
1314
|
-
fail: (_error, _options) => { },
|
|
1315
|
-
};
|
|
1316
|
-
}
|
|
1317
|
-
const start = options || {};
|
|
1318
|
-
let operation = undefined;
|
|
1319
|
-
if (SPAN_SPECIFICATIONS[type].isGenAI) {
|
|
1320
|
-
operation = type;
|
|
1321
|
-
}
|
|
1322
|
-
const span = this.tracer.startSpan(name, {
|
|
1323
|
-
attributes: {
|
|
1324
|
-
[ATTRIBUTES.LATITUDE.type]: type,
|
|
1325
|
-
...(operation && {
|
|
1326
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.operation]: operation,
|
|
1327
|
-
}),
|
|
1328
|
-
...(start.attributes || {}),
|
|
1329
|
-
},
|
|
1330
|
-
kind: otel__namespace.SpanKind.CLIENT,
|
|
1331
|
-
}, ctx);
|
|
1332
|
-
const newCtx = otel.trace.setSpan(ctx, span);
|
|
1333
|
-
return {
|
|
1334
|
-
context: newCtx,
|
|
1335
|
-
end: (options) => {
|
|
1336
|
-
const end = options || {};
|
|
1337
|
-
span.setAttributes(end.attributes || {});
|
|
1338
|
-
span.setStatus({ code: otel__namespace.SpanStatusCode.OK });
|
|
1339
|
-
span.end();
|
|
1340
|
-
},
|
|
1341
|
-
fail: (error, options) => {
|
|
1342
|
-
this.error(span, error, options);
|
|
1343
|
-
},
|
|
1344
|
-
};
|
|
1345
|
-
}
|
|
1346
|
-
unknown(ctx, options) {
|
|
1347
|
-
return this.span(ctx, options?.name || SPAN_SPECIFICATIONS[SpanType.Unknown].name, SpanType.Unknown, options);
|
|
1348
|
-
}
|
|
1349
|
-
tool(ctx, options) {
|
|
1350
|
-
const start = options;
|
|
1351
|
-
let jsonArguments = '';
|
|
1352
|
-
try {
|
|
1353
|
-
jsonArguments = JSON.stringify(start.call.arguments);
|
|
1354
|
-
}
|
|
1355
|
-
catch (_error) {
|
|
1356
|
-
jsonArguments = '{}';
|
|
1357
|
-
}
|
|
1358
|
-
const span = this.span(ctx, start.name, SpanType.Tool, {
|
|
1359
|
-
attributes: {
|
|
1360
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.name]: start.name,
|
|
1361
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.type]: VALUES.OPENTELEMETRY.GEN_AI.tool.type.function,
|
|
1362
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.tool.call.id]: start.call.id,
|
|
1363
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.tool.call.arguments]: jsonArguments,
|
|
1364
|
-
...(start.attributes || {}),
|
|
1365
|
-
},
|
|
1366
|
-
});
|
|
1367
|
-
return {
|
|
1368
|
-
...span,
|
|
1369
|
-
end: (options) => {
|
|
1370
|
-
const end = options;
|
|
1371
|
-
let stringResult = '';
|
|
1372
|
-
if (typeof end.result.value !== 'string') {
|
|
1373
|
-
try {
|
|
1374
|
-
stringResult = JSON.stringify(end.result.value);
|
|
1375
|
-
}
|
|
1376
|
-
catch (_error) {
|
|
1377
|
-
stringResult = '{}';
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
else {
|
|
1381
|
-
stringResult = end.result.value;
|
|
1382
|
-
}
|
|
1383
|
-
span.end({
|
|
1384
|
-
attributes: {
|
|
1385
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.result.value]: stringResult,
|
|
1386
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.result.isError]: end.result.isError,
|
|
1387
|
-
...(end.attributes || {}),
|
|
1388
|
-
},
|
|
1389
|
-
});
|
|
1390
|
-
},
|
|
1391
|
-
};
|
|
1392
|
-
}
|
|
1393
|
-
attribifyConfiguration(direction, configuration) {
|
|
1394
|
-
const prefix = direction === 'input'
|
|
1395
|
-
? ATTRIBUTES.LATITUDE.request._root
|
|
1396
|
-
: ATTRIBUTES.LATITUDE.response._root;
|
|
1397
|
-
const attributes = {};
|
|
1398
|
-
for (const key in configuration) {
|
|
1399
|
-
const field = toSnakeCase(key);
|
|
1400
|
-
let value = configuration[key];
|
|
1401
|
-
if (value === null || value === undefined)
|
|
1402
|
-
continue;
|
|
1403
|
-
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
1404
|
-
try {
|
|
1405
|
-
value = JSON.stringify(value);
|
|
1406
|
-
}
|
|
1407
|
-
catch (_error) {
|
|
1408
|
-
value = '{}';
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
attributes[`${prefix}.${field}`] = value;
|
|
1412
|
-
}
|
|
1413
|
-
return attributes;
|
|
1414
|
-
}
|
|
1415
|
-
completion(ctx, options) {
|
|
1416
|
-
const start = options;
|
|
1417
|
-
const configuration = {
|
|
1418
|
-
...(start.configuration ?? {}),
|
|
1419
|
-
model: start.model,
|
|
1420
|
-
};
|
|
1421
|
-
let jsonConfiguration = '';
|
|
1422
|
-
try {
|
|
1423
|
-
jsonConfiguration = JSON.stringify(configuration);
|
|
1424
|
-
}
|
|
1425
|
-
catch (_error) {
|
|
1426
|
-
jsonConfiguration = '{}';
|
|
1427
|
-
}
|
|
1428
|
-
const attrConfiguration = this.attribifyConfiguration('input', configuration);
|
|
1429
|
-
const input = start.input ?? [];
|
|
1430
|
-
let jsonSystem = '';
|
|
1431
|
-
let jsonInput = '';
|
|
1432
|
-
try {
|
|
1433
|
-
const translated = translator.translate(input, {
|
|
1434
|
-
from: this.options.provider,
|
|
1435
|
-
to: rosettaAi.Provider.GenAI,
|
|
1436
|
-
direction: 'input',
|
|
1437
|
-
});
|
|
1438
|
-
jsonSystem = JSON.stringify(translated.system ?? []);
|
|
1439
|
-
jsonInput = JSON.stringify(translated.messages ?? []);
|
|
1440
|
-
}
|
|
1441
|
-
catch (_error) {
|
|
1442
|
-
jsonSystem = '[]';
|
|
1443
|
-
jsonInput = '[]';
|
|
1444
|
-
}
|
|
1445
|
-
const span = this.span(ctx, start.name || `${start.provider} / ${start.model}`, SpanType.Completion, {
|
|
1446
|
-
attributes: {
|
|
1447
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.system]: start.provider,
|
|
1448
|
-
[ATTRIBUTES.LATITUDE.request.configuration]: jsonConfiguration,
|
|
1449
|
-
...attrConfiguration,
|
|
1450
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.systemInstructions]: jsonSystem,
|
|
1451
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.input.messages]: jsonInput,
|
|
1452
|
-
...(start.attributes || {}),
|
|
1453
|
-
[ATTRIBUTES.LATITUDE.commitUuid]: start.versionUuid,
|
|
1454
|
-
[ATTRIBUTES.LATITUDE.documentUuid]: start.promptUuid,
|
|
1455
|
-
[ATTRIBUTES.LATITUDE.experimentUuid]: start.experimentUuid,
|
|
1456
|
-
},
|
|
1457
|
-
});
|
|
1458
|
-
return {
|
|
1459
|
-
...span,
|
|
1460
|
-
end: (options) => {
|
|
1461
|
-
const end = options ?? {};
|
|
1462
|
-
const output = end.output ?? [];
|
|
1463
|
-
let jsonOutput = '';
|
|
1464
|
-
try {
|
|
1465
|
-
const translated = translator.translate(output, {
|
|
1466
|
-
from: this.options.provider,
|
|
1467
|
-
to: rosettaAi.Provider.GenAI,
|
|
1468
|
-
direction: 'output',
|
|
1469
|
-
});
|
|
1470
|
-
jsonOutput = JSON.stringify(translated.messages ?? []);
|
|
1471
|
-
}
|
|
1472
|
-
catch (_error) {
|
|
1473
|
-
jsonOutput = '[]';
|
|
1474
|
-
}
|
|
1475
|
-
const tokens = {
|
|
1476
|
-
prompt: end.tokens?.prompt ?? 0,
|
|
1477
|
-
cached: end.tokens?.cached ?? 0,
|
|
1478
|
-
reasoning: end.tokens?.reasoning ?? 0,
|
|
1479
|
-
completion: end.tokens?.completion ?? 0,
|
|
1480
|
-
};
|
|
1481
|
-
const inputTokens = tokens.prompt + tokens.cached;
|
|
1482
|
-
const outputTokens = tokens.reasoning + tokens.completion;
|
|
1483
|
-
const finishReason = end.finishReason ?? '';
|
|
1484
|
-
span.end({
|
|
1485
|
-
attributes: {
|
|
1486
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.output.messages]: jsonOutput,
|
|
1487
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.usage.inputTokens]: inputTokens,
|
|
1488
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.usage.outputTokens]: outputTokens,
|
|
1489
|
-
[ATTRIBUTES.LATITUDE.usage.promptTokens]: tokens.prompt,
|
|
1490
|
-
[ATTRIBUTES.LATITUDE.usage.cachedTokens]: tokens.cached,
|
|
1491
|
-
[ATTRIBUTES.LATITUDE.usage.reasoningTokens]: tokens.reasoning,
|
|
1492
|
-
[ATTRIBUTES.LATITUDE.usage.completionTokens]: tokens.completion,
|
|
1493
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.response.model]: start.model,
|
|
1494
|
-
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.response.finishReasons]: [
|
|
1495
|
-
finishReason,
|
|
1496
|
-
],
|
|
1497
|
-
...(end.attributes || {}),
|
|
1498
|
-
},
|
|
1499
|
-
});
|
|
1500
|
-
},
|
|
1501
|
-
};
|
|
1502
|
-
}
|
|
1503
|
-
embedding(ctx, options) {
|
|
1504
|
-
return this.span(ctx, options?.name || SPAN_SPECIFICATIONS[SpanType.Embedding].name, SpanType.Embedding, options);
|
|
1505
|
-
}
|
|
1506
|
-
attribifyHeaders(direction, headers) {
|
|
1507
|
-
const prefix = direction === 'request'
|
|
1508
|
-
? ATTRIBUTES.OPENTELEMETRY.HTTP.request.header
|
|
1509
|
-
: ATTRIBUTES.OPENTELEMETRY.HTTP.response.header;
|
|
1510
|
-
const attributes = {};
|
|
1511
|
-
for (const key in headers) {
|
|
1512
|
-
const field = toKebabCase(key);
|
|
1513
|
-
const value = headers[key];
|
|
1514
|
-
if (value === null || value === undefined)
|
|
1515
|
-
continue;
|
|
1516
|
-
attributes[`${prefix}.${field}`] = value;
|
|
1517
|
-
}
|
|
1518
|
-
return attributes;
|
|
1519
|
-
}
|
|
1520
|
-
http(ctx, options) {
|
|
1521
|
-
const start = options;
|
|
1522
|
-
const method = start.request.method.toUpperCase();
|
|
1523
|
-
// Note: do not serialize headers as a single attribute because fields won't be redacted
|
|
1524
|
-
const attrHeaders = this.attribifyHeaders('request', start.request.headers);
|
|
1525
|
-
let finalBody = '';
|
|
1526
|
-
if (typeof start.request.body === 'string') {
|
|
1527
|
-
finalBody = start.request.body;
|
|
1528
|
-
}
|
|
1529
|
-
else {
|
|
1530
|
-
try {
|
|
1531
|
-
finalBody = JSON.stringify(start.request.body);
|
|
1532
|
-
}
|
|
1533
|
-
catch (_error) {
|
|
1534
|
-
finalBody = '{}';
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
const span = this.span(ctx, start.name || `${method} ${start.request.url}`, SpanType.Http, {
|
|
1538
|
-
attributes: {
|
|
1539
|
-
[ATTRIBUTES.OPENTELEMETRY.HTTP.request.method]: method,
|
|
1540
|
-
[ATTRIBUTES.OPENTELEMETRY.HTTP.request.url]: start.request.url,
|
|
1541
|
-
...attrHeaders,
|
|
1542
|
-
[ATTRIBUTES.OPENTELEMETRY.HTTP.request.body]: finalBody,
|
|
1543
|
-
...(start.attributes || {}),
|
|
1544
|
-
},
|
|
1545
|
-
});
|
|
1546
|
-
return {
|
|
1547
|
-
...span,
|
|
1548
|
-
end: (options) => {
|
|
1549
|
-
const end = options;
|
|
1550
|
-
// Note: do not serialize headers as a single attribute because fields won't be redacted
|
|
1551
|
-
const attrHeaders = this.attribifyHeaders('response', end.response.headers);
|
|
1552
|
-
let finalBody = '';
|
|
1553
|
-
if (typeof end.response.body === 'string') {
|
|
1554
|
-
finalBody = end.response.body;
|
|
1555
|
-
}
|
|
1556
|
-
else {
|
|
1557
|
-
try {
|
|
1558
|
-
finalBody = JSON.stringify(end.response.body);
|
|
1559
|
-
}
|
|
1560
|
-
catch (_error) {
|
|
1561
|
-
finalBody = '{}';
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
span.end({
|
|
1565
|
-
attributes: {
|
|
1566
|
-
[ATTRIBUTES.OPENTELEMETRY.HTTP.response.statusCode]: end.response.status,
|
|
1567
|
-
...attrHeaders,
|
|
1568
|
-
[ATTRIBUTES.OPENTELEMETRY.HTTP.response.body]: finalBody,
|
|
1569
|
-
...(end.attributes || {}),
|
|
1570
|
-
},
|
|
1571
|
-
});
|
|
1572
|
-
},
|
|
1573
|
-
};
|
|
1574
|
-
}
|
|
1575
|
-
prompt(ctx, { documentLogUuid, versionUuid, promptUuid, projectId, experimentUuid, testDeploymentId, externalId, template, parameters, name, source, ...rest }) {
|
|
1576
|
-
let jsonParameters = '';
|
|
1577
|
-
try {
|
|
1578
|
-
jsonParameters = JSON.stringify(parameters || {});
|
|
1579
|
-
}
|
|
1580
|
-
catch (_error) {
|
|
1581
|
-
jsonParameters = '{}';
|
|
1582
|
-
}
|
|
1583
|
-
const attributes = {
|
|
1584
|
-
[ATTRIBUTES.LATITUDE.request.template]: template,
|
|
1585
|
-
[ATTRIBUTES.LATITUDE.request.parameters]: jsonParameters,
|
|
1586
|
-
[ATTRIBUTES.LATITUDE.commitUuid]: versionUuid || HEAD_COMMIT,
|
|
1587
|
-
[ATTRIBUTES.LATITUDE.documentUuid]: promptUuid,
|
|
1588
|
-
[ATTRIBUTES.LATITUDE.projectId]: projectId,
|
|
1589
|
-
[ATTRIBUTES.LATITUDE.documentLogUuid]: documentLogUuid,
|
|
1590
|
-
...(experimentUuid && {
|
|
1591
|
-
[ATTRIBUTES.LATITUDE.experimentUuid]: experimentUuid,
|
|
1592
|
-
}),
|
|
1593
|
-
...(testDeploymentId && {
|
|
1594
|
-
[ATTRIBUTES.LATITUDE.testDeploymentId]: testDeploymentId,
|
|
1595
|
-
}),
|
|
1596
|
-
...(externalId && { [ATTRIBUTES.LATITUDE.externalId]: externalId }),
|
|
1597
|
-
...(source && { [ATTRIBUTES.LATITUDE.source]: source }),
|
|
1598
|
-
...(rest.attributes || {}),
|
|
1599
|
-
};
|
|
1600
|
-
return this.span(ctx, name || `prompt-${promptUuid}`, SpanType.Prompt, {
|
|
1601
|
-
attributes,
|
|
1602
|
-
});
|
|
1603
|
-
}
|
|
1604
|
-
chat(ctx, { documentLogUuid, previousTraceId, source, name, versionUuid, promptUuid, ...rest }) {
|
|
1605
|
-
const attributes = {
|
|
1606
|
-
[ATTRIBUTES.LATITUDE.documentLogUuid]: documentLogUuid,
|
|
1607
|
-
[ATTRIBUTES.LATITUDE.previousTraceId]: previousTraceId,
|
|
1608
|
-
...(versionUuid && { [ATTRIBUTES.LATITUDE.commitUuid]: versionUuid }),
|
|
1609
|
-
...(promptUuid && { [ATTRIBUTES.LATITUDE.documentUuid]: promptUuid }),
|
|
1610
|
-
...(source && { [ATTRIBUTES.LATITUDE.source]: source }),
|
|
1611
|
-
...(rest.attributes || {}),
|
|
1612
|
-
};
|
|
1613
|
-
return this.span(ctx, name || `chat-${documentLogUuid}`, SpanType.Chat, {
|
|
1614
|
-
attributes,
|
|
1615
|
-
});
|
|
1616
|
-
}
|
|
1617
|
-
external(ctx, { promptUuid, documentLogUuid, source, versionUuid, externalId, name, ...rest }) {
|
|
1618
|
-
const attributes = {
|
|
1619
|
-
[ATTRIBUTES.LATITUDE.documentUuid]: promptUuid,
|
|
1620
|
-
[ATTRIBUTES.LATITUDE.documentLogUuid]: documentLogUuid,
|
|
1621
|
-
[ATTRIBUTES.LATITUDE.source]: source ?? LogSources.API,
|
|
1622
|
-
...(versionUuid && { [ATTRIBUTES.LATITUDE.commitUuid]: versionUuid }),
|
|
1623
|
-
...(externalId && { [ATTRIBUTES.LATITUDE.externalId]: externalId }),
|
|
1624
|
-
...(rest.attributes || {}),
|
|
1625
|
-
};
|
|
1626
|
-
return this.span(ctx, name || `external-${promptUuid}`, SpanType.External, {
|
|
1627
|
-
attributes,
|
|
1628
|
-
});
|
|
1629
|
-
}
|
|
1630
|
-
// TODO(tracing): deprecate
|
|
1631
|
-
unresolvedExternal(ctx, { path, projectId, versionUuid, conversationUuid, name, ...rest }) {
|
|
1632
|
-
const attributes = {
|
|
1633
|
-
[ATTRIBUTES.LATITUDE.promptPath]: path,
|
|
1634
|
-
[ATTRIBUTES.LATITUDE.projectId]: projectId,
|
|
1635
|
-
...(versionUuid && { [ATTRIBUTES.LATITUDE.commitUuid]: versionUuid }),
|
|
1636
|
-
...(conversationUuid && {
|
|
1637
|
-
[ATTRIBUTES.LATITUDE.documentLogUuid]: conversationUuid,
|
|
1638
|
-
}),
|
|
1639
|
-
...(rest.attributes || {}),
|
|
1640
|
-
};
|
|
1641
|
-
return this.span(ctx, name || `capture-${path}`, SpanType.UnresolvedExternal, { attributes });
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
class LatitudeInstrumentation {
|
|
1646
|
-
options;
|
|
1647
|
-
manualTelemetry;
|
|
1648
|
-
constructor(tracer, options) {
|
|
1649
|
-
this.manualTelemetry = new ManualInstrumentation(tracer);
|
|
1650
|
-
this.options = options;
|
|
1651
|
-
}
|
|
1652
|
-
isEnabled() {
|
|
1653
|
-
return this.manualTelemetry.isEnabled();
|
|
1654
|
-
}
|
|
1655
|
-
enable() {
|
|
1656
|
-
this.manualTelemetry.enable();
|
|
1657
|
-
this.options.module.instrument(this);
|
|
1658
|
-
}
|
|
1659
|
-
disable() {
|
|
1660
|
-
this.manualTelemetry.disable();
|
|
1661
|
-
this.options.module.uninstrument();
|
|
1662
|
-
}
|
|
1663
|
-
countTokens(messages) {
|
|
1664
|
-
let length = 0;
|
|
1665
|
-
for (const message of messages) {
|
|
1666
|
-
if (!('content' in message))
|
|
1667
|
-
continue;
|
|
1668
|
-
if (typeof message.content === 'string') {
|
|
1669
|
-
length += message.content.length;
|
|
1670
|
-
}
|
|
1671
|
-
else if (Array.isArray(message.content)) {
|
|
1672
|
-
for (const content of message.content) {
|
|
1673
|
-
if (content.type === 'text') {
|
|
1674
|
-
length += content.text.length;
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
}
|
|
1679
|
-
// Note: this is an estimation to not bundle a tokenizer
|
|
1680
|
-
return Math.ceil(length / 4);
|
|
1681
|
-
}
|
|
1682
|
-
async wrapRenderChain(fn, ...args) {
|
|
1683
|
-
const { prompt, parameters } = args[0];
|
|
1684
|
-
const $prompt = this.manualTelemetry.prompt(otel.context.active(), {
|
|
1685
|
-
documentLogUuid: uuid.v4(),
|
|
1686
|
-
versionUuid: prompt.versionUuid,
|
|
1687
|
-
promptUuid: prompt.uuid,
|
|
1688
|
-
template: prompt.content,
|
|
1689
|
-
parameters: parameters,
|
|
1690
|
-
});
|
|
1691
|
-
let result;
|
|
1692
|
-
try {
|
|
1693
|
-
result = await otel.context.with($prompt.context, async () => await fn(...args));
|
|
1694
|
-
}
|
|
1695
|
-
catch (error) {
|
|
1696
|
-
$prompt.fail(error);
|
|
1697
|
-
throw error;
|
|
1698
|
-
}
|
|
1699
|
-
$prompt.end();
|
|
1700
|
-
return result;
|
|
1701
|
-
}
|
|
1702
|
-
async wrapRenderCompletion(fn, ...args) {
|
|
1703
|
-
if (!this.options.completions) {
|
|
1704
|
-
return await fn(...args);
|
|
1705
|
-
}
|
|
1706
|
-
const { provider, config, messages } = args[0];
|
|
1707
|
-
const model = config.model || 'unknown';
|
|
1708
|
-
const $completion = this.manualTelemetry.completion(otel.context.active(), {
|
|
1709
|
-
name: `${provider} / ${model}`,
|
|
1710
|
-
provider: provider,
|
|
1711
|
-
model: model,
|
|
1712
|
-
configuration: config,
|
|
1713
|
-
input: messages,
|
|
1714
|
-
});
|
|
1715
|
-
let result;
|
|
1716
|
-
try {
|
|
1717
|
-
result = await otel.context.with($completion.context, async () => await fn(...args));
|
|
1718
|
-
}
|
|
1719
|
-
catch (error) {
|
|
1720
|
-
$completion.fail(error);
|
|
1721
|
-
throw error;
|
|
1722
|
-
}
|
|
1723
|
-
// Note: enhance, this is just an estimation
|
|
1724
|
-
const promptTokens = this.countTokens(messages);
|
|
1725
|
-
const completionTokens = this.countTokens(result.messages);
|
|
1726
|
-
$completion.end({
|
|
1727
|
-
output: result.messages,
|
|
1728
|
-
tokens: {
|
|
1729
|
-
prompt: promptTokens,
|
|
1730
|
-
cached: 0,
|
|
1731
|
-
reasoning: 0,
|
|
1732
|
-
completion: completionTokens,
|
|
1733
|
-
},
|
|
1734
|
-
finishReason: result.toolRequests.length > 0
|
|
1735
|
-
? VALUES.OPENTELEMETRY.GEN_AI.response.finishReasons.toolCalls
|
|
1736
|
-
: VALUES.OPENTELEMETRY.GEN_AI.response.finishReasons.stop,
|
|
1737
|
-
});
|
|
1738
|
-
return result;
|
|
1739
|
-
}
|
|
1740
|
-
async wrapRenderTool(fn, ...args) {
|
|
1741
|
-
const { toolRequest } = args[0];
|
|
1742
|
-
const $tool = this.manualTelemetry.tool(otel.context.active(), {
|
|
1743
|
-
name: toolRequest.toolName,
|
|
1744
|
-
call: {
|
|
1745
|
-
id: toolRequest.toolCallId,
|
|
1746
|
-
arguments: toolRequest.toolArguments,
|
|
1747
|
-
},
|
|
1748
|
-
});
|
|
1749
|
-
let result;
|
|
1750
|
-
try {
|
|
1751
|
-
result = await otel.context.with($tool.context, async () => await fn(...args));
|
|
1752
|
-
}
|
|
1753
|
-
catch (error) {
|
|
1754
|
-
$tool.fail(error);
|
|
1755
|
-
throw error;
|
|
1756
|
-
}
|
|
1757
|
-
$tool.end({
|
|
1758
|
-
result: {
|
|
1759
|
-
value: result.result,
|
|
1760
|
-
isError: result.isError,
|
|
1761
|
-
},
|
|
1762
|
-
});
|
|
1763
|
-
return result;
|
|
1764
|
-
}
|
|
275
|
+
var LLM_SCOPE_SUBSTRINGS = ["openinference", "traceloop", "langsmith", "litellm"];
|
|
276
|
+
function buildShouldExportSpanFromFields(fields) {
|
|
277
|
+
return buildShouldExportSpan({
|
|
278
|
+
...fields.disableSmartFilter !== void 0 ? { disableSmartFilter: fields.disableSmartFilter } : {},
|
|
279
|
+
...fields.shouldExportSpan !== void 0 ? { shouldExportSpan: fields.shouldExportSpan } : {},
|
|
280
|
+
...fields.blockedInstrumentationScopes !== void 0 ? { blockedInstrumentationScopes: fields.blockedInstrumentationScopes } : {}
|
|
281
|
+
});
|
|
1765
282
|
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
(
|
|
1769
|
-
|
|
1770
|
-
LatitudeErrorCodes["OverloadedError"] = "OverloadedError";
|
|
1771
|
-
LatitudeErrorCodes["RateLimitError"] = "RateLimitError";
|
|
1772
|
-
LatitudeErrorCodes["UnauthorizedError"] = "UnauthorizedError";
|
|
1773
|
-
LatitudeErrorCodes["ForbiddenError"] = "ForbiddenError";
|
|
1774
|
-
LatitudeErrorCodes["BadRequestError"] = "BadRequestError";
|
|
1775
|
-
LatitudeErrorCodes["NotFoundError"] = "NotFoundError";
|
|
1776
|
-
LatitudeErrorCodes["ConflictError"] = "ConflictError";
|
|
1777
|
-
LatitudeErrorCodes["UnprocessableEntityError"] = "UnprocessableEntityError";
|
|
1778
|
-
LatitudeErrorCodes["NotImplementedError"] = "NotImplementedError";
|
|
1779
|
-
LatitudeErrorCodes["PaymentRequiredError"] = "PaymentRequiredError";
|
|
1780
|
-
LatitudeErrorCodes["AbortedError"] = "AbortedError";
|
|
1781
|
-
LatitudeErrorCodes["BillingError"] = "BillingError";
|
|
1782
|
-
})(LatitudeErrorCodes || (LatitudeErrorCodes = {}));
|
|
1783
|
-
// NOTE: If you add a new error code, please add it to the pg enum in models/runErrors.ts
|
|
1784
|
-
var RunErrorCodes;
|
|
1785
|
-
(function (RunErrorCodes) {
|
|
1786
|
-
RunErrorCodes["AIProviderConfigError"] = "ai_provider_config_error";
|
|
1787
|
-
RunErrorCodes["AIRunError"] = "ai_run_error";
|
|
1788
|
-
RunErrorCodes["ChainCompileError"] = "chain_compile_error";
|
|
1789
|
-
RunErrorCodes["DefaultProviderExceededQuota"] = "default_provider_exceeded_quota_error";
|
|
1790
|
-
RunErrorCodes["DefaultProviderInvalidModel"] = "default_provider_invalid_model_error";
|
|
1791
|
-
RunErrorCodes["DocumentConfigError"] = "document_config_error";
|
|
1792
|
-
RunErrorCodes["ErrorGeneratingMockToolResult"] = "error_generating_mock_tool_result";
|
|
1793
|
-
RunErrorCodes["FailedToWakeUpIntegrationError"] = "failed_to_wake_up_integration_error";
|
|
1794
|
-
RunErrorCodes["InvalidResponseFormatError"] = "invalid_response_format_error";
|
|
1795
|
-
RunErrorCodes["MaxStepCountExceededError"] = "max_step_count_exceeded_error";
|
|
1796
|
-
RunErrorCodes["MissingProvider"] = "missing_provider_error";
|
|
1797
|
-
RunErrorCodes["RateLimit"] = "rate_limit_error";
|
|
1798
|
-
RunErrorCodes["Unknown"] = "unknown_error";
|
|
1799
|
-
RunErrorCodes["UnsupportedProviderResponseTypeError"] = "unsupported_provider_response_type_error";
|
|
1800
|
-
RunErrorCodes["PaymentRequiredError"] = "payment_required_error";
|
|
1801
|
-
RunErrorCodes["AbortError"] = "abort_error";
|
|
1802
|
-
// DEPRECATED, but do not delete
|
|
1803
|
-
RunErrorCodes["EvaluationRunMissingProviderLogError"] = "ev_run_missing_provider_log_error";
|
|
1804
|
-
RunErrorCodes["EvaluationRunMissingWorkspaceError"] = "ev_run_missing_workspace_error";
|
|
1805
|
-
RunErrorCodes["EvaluationRunResponseJsonFormatError"] = "ev_run_response_json_format_error";
|
|
1806
|
-
RunErrorCodes["EvaluationRunUnsupportedResultTypeError"] = "ev_run_unsupported_result_type_error";
|
|
1807
|
-
})(RunErrorCodes || (RunErrorCodes = {}));
|
|
1808
|
-
var ApiErrorCodes;
|
|
1809
|
-
(function (ApiErrorCodes) {
|
|
1810
|
-
ApiErrorCodes["HTTPException"] = "http_exception";
|
|
1811
|
-
ApiErrorCodes["InternalServerError"] = "internal_server_error";
|
|
1812
|
-
})(ApiErrorCodes || (ApiErrorCodes = {}));
|
|
1813
|
-
|
|
1814
|
-
class LatitudeError extends Error {
|
|
1815
|
-
statusCode = 500;
|
|
1816
|
-
name = LatitudeErrorCodes.UnexpectedError;
|
|
1817
|
-
headers = {};
|
|
1818
|
-
details;
|
|
1819
|
-
constructor(message, details, status, name) {
|
|
1820
|
-
super(message);
|
|
1821
|
-
this.details = details ?? {};
|
|
1822
|
-
this.statusCode = status ?? this.statusCode;
|
|
1823
|
-
this.name = name ?? this.constructor.name;
|
|
1824
|
-
}
|
|
1825
|
-
serialize() {
|
|
1826
|
-
return {
|
|
1827
|
-
name: this.name,
|
|
1828
|
-
code: this.name,
|
|
1829
|
-
status: this.statusCode,
|
|
1830
|
-
message: this.message,
|
|
1831
|
-
details: this.details,
|
|
1832
|
-
};
|
|
1833
|
-
}
|
|
1834
|
-
static deserialize(json) {
|
|
1835
|
-
return new LatitudeError(json.message, json.details, json.status, json.name);
|
|
1836
|
-
}
|
|
283
|
+
function attributeKeys(span) {
|
|
284
|
+
const attrs = span.attributes;
|
|
285
|
+
if (!attrs || typeof attrs !== "object") return [];
|
|
286
|
+
return Object.keys(attrs);
|
|
1837
287
|
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
name = LatitudeErrorCodes.BadRequestError;
|
|
288
|
+
function instrumentationScopeName(span) {
|
|
289
|
+
return span.instrumentationLibrary?.name ?? "";
|
|
1841
290
|
}
|
|
1842
|
-
|
|
1843
|
-
const
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
this.telemetry = telemetry;
|
|
1851
|
-
}
|
|
1852
|
-
span(options, ctx) {
|
|
1853
|
-
return this.telemetry.unknown(ctx ?? otel.context.active(), options);
|
|
1854
|
-
}
|
|
1855
|
-
tool(options, ctx) {
|
|
1856
|
-
return this.telemetry.tool(ctx ?? otel.context.active(), options);
|
|
1857
|
-
}
|
|
1858
|
-
completion(options, ctx) {
|
|
1859
|
-
return this.telemetry.completion(ctx ?? otel.context.active(), options);
|
|
1860
|
-
}
|
|
1861
|
-
embedding(options, ctx) {
|
|
1862
|
-
return this.telemetry.embedding(ctx ?? otel.context.active(), options);
|
|
1863
|
-
}
|
|
1864
|
-
http(options, ctx) {
|
|
1865
|
-
return this.telemetry.http(ctx ?? otel.context.active(), options);
|
|
1866
|
-
}
|
|
1867
|
-
prompt(options, ctx) {
|
|
1868
|
-
return this.telemetry.prompt(ctx ?? otel.context.active(), options);
|
|
1869
|
-
}
|
|
1870
|
-
chat(options, ctx) {
|
|
1871
|
-
return this.telemetry.chat(ctx ?? otel.context.active(), options);
|
|
1872
|
-
}
|
|
1873
|
-
external(options, ctx) {
|
|
1874
|
-
return this.telemetry.external(ctx ?? otel.context.active(), options);
|
|
1875
|
-
}
|
|
291
|
+
function isGenAiOrLlmAttributeSpan(span) {
|
|
292
|
+
for (const key of attributeKeys(span)) {
|
|
293
|
+
if (key.startsWith(GEN_AI_PREFIX) || key.startsWith(LLM_PREFIX)) return true;
|
|
294
|
+
if (key === OPENINFERENCE_KIND || key.startsWith("openinference.")) return true;
|
|
295
|
+
if (key.startsWith("ai.")) return true;
|
|
296
|
+
if (key.startsWith("latitude.")) return true;
|
|
297
|
+
}
|
|
298
|
+
return false;
|
|
1876
299
|
}
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
this.telemetry = telemetry;
|
|
1881
|
-
}
|
|
1882
|
-
resume(ctx) {
|
|
1883
|
-
return this.telemetry.resume(ctx);
|
|
1884
|
-
}
|
|
1885
|
-
active() {
|
|
1886
|
-
return otel.context.active();
|
|
1887
|
-
}
|
|
1888
|
-
with(ctx, fn, thisArg, ...args) {
|
|
1889
|
-
return otel.context.with(ctx, fn, thisArg, ...args);
|
|
1890
|
-
}
|
|
300
|
+
function isLatitudeInstrumentationSpan(span) {
|
|
301
|
+
const name = instrumentationScopeName(span);
|
|
302
|
+
return name === SCOPE_LATITUDE || name.startsWith(`${SCOPE_LATITUDE}.`);
|
|
1891
303
|
}
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
}
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
disable() {
|
|
1904
|
-
this.instrumentations.forEach((instrumentation) => {
|
|
1905
|
-
if (instrumentation.isEnabled())
|
|
1906
|
-
instrumentation.disable();
|
|
1907
|
-
});
|
|
1908
|
-
}
|
|
304
|
+
function isKnownLlmInstrumentationScope(span) {
|
|
305
|
+
const name = instrumentationScopeName(span);
|
|
306
|
+
if (!name) return false;
|
|
307
|
+
for (const prefix of OTEL_LLM_INSTRUMENTATION_SCOPE_PREFIXES) {
|
|
308
|
+
if (name === prefix || name.startsWith(`${prefix}.`)) return true;
|
|
309
|
+
}
|
|
310
|
+
const lower = name.toLowerCase();
|
|
311
|
+
for (const part of LLM_SCOPE_SUBSTRINGS) {
|
|
312
|
+
if (lower.includes(part)) return true;
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
1909
315
|
}
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
this.scopeVersion = scopeVersion;
|
|
1916
|
-
}
|
|
1917
|
-
get(scope) {
|
|
1918
|
-
return this.provider(scope).getTracer('');
|
|
1919
|
-
}
|
|
1920
|
-
provider(scope) {
|
|
1921
|
-
return new ScopedTracerProvider(`${SCOPE_LATITUDE}.${scope}`, this.scopeVersion, this.nodeProvider);
|
|
1922
|
-
}
|
|
316
|
+
function isDefaultExportSpan(span) {
|
|
317
|
+
if (isLatitudeInstrumentationSpan(span)) return true;
|
|
318
|
+
if (isGenAiOrLlmAttributeSpan(span)) return true;
|
|
319
|
+
if (isKnownLlmInstrumentationScope(span)) return true;
|
|
320
|
+
return false;
|
|
1923
321
|
}
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
}
|
|
322
|
+
function buildShouldExportSpan(options) {
|
|
323
|
+
if (options.disableSmartFilter) return () => true;
|
|
324
|
+
const blocked = new Set(options.blockedInstrumentationScopes ?? []);
|
|
325
|
+
const extra = options.shouldExportSpan;
|
|
326
|
+
return (span) => {
|
|
327
|
+
const scope = instrumentationScopeName(span);
|
|
328
|
+
if (blocked.has(scope)) return false;
|
|
329
|
+
if (isDefaultExportSpan(span)) return true;
|
|
330
|
+
if (extra?.(span)) return true;
|
|
331
|
+
return false;
|
|
332
|
+
};
|
|
1936
333
|
}
|
|
1937
|
-
class
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
334
|
+
var ExportFilterSpanProcessor = class {
|
|
335
|
+
shouldExport;
|
|
336
|
+
inner;
|
|
337
|
+
constructor(shouldExport, inner) {
|
|
338
|
+
this.shouldExport = shouldExport;
|
|
339
|
+
this.inner = inner;
|
|
340
|
+
}
|
|
341
|
+
onStart(span, parentContext) {
|
|
342
|
+
this.inner.onStart(span, parentContext);
|
|
343
|
+
}
|
|
344
|
+
onEnd(span) {
|
|
345
|
+
if (!this.shouldExport(span)) return;
|
|
346
|
+
this.inner.onEnd(span);
|
|
347
|
+
}
|
|
348
|
+
forceFlush() {
|
|
349
|
+
return this.inner.forceFlush();
|
|
350
|
+
}
|
|
351
|
+
shutdown() {
|
|
352
|
+
return this.inner.shutdown();
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
var RedactThenExportSpanProcessor = class {
|
|
356
|
+
redact;
|
|
357
|
+
exportProcessor;
|
|
358
|
+
constructor(redact, exportProcessor) {
|
|
359
|
+
this.redact = redact;
|
|
360
|
+
this.exportProcessor = exportProcessor;
|
|
361
|
+
}
|
|
362
|
+
onStart(span, parentContext) {
|
|
363
|
+
this.redact?.onStart(span, parentContext);
|
|
364
|
+
this.exportProcessor.onStart(span, parentContext);
|
|
365
|
+
}
|
|
366
|
+
onEnd(span) {
|
|
367
|
+
this.redact?.onEnd(span);
|
|
368
|
+
this.exportProcessor.onEnd(span);
|
|
369
|
+
}
|
|
370
|
+
forceFlush() {
|
|
371
|
+
return this.exportProcessor.forceFlush();
|
|
372
|
+
}
|
|
373
|
+
shutdown() {
|
|
374
|
+
return this.exportProcessor.shutdown();
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
// src/sdk/processor.ts
|
|
379
|
+
var LatitudeSpanProcessor = class {
|
|
380
|
+
tail;
|
|
381
|
+
constructor(apiKey, projectSlug, options) {
|
|
382
|
+
if (!apiKey || apiKey.trim() === "") {
|
|
383
|
+
throw new Error("[Latitude] apiKey is required and cannot be empty");
|
|
1947
384
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
await this.nodeProvider.shutdown();
|
|
1951
|
-
await this.exporter.shutdown?.();
|
|
385
|
+
if (!projectSlug || projectSlug.trim() === "") {
|
|
386
|
+
throw new Error("[Latitude] projectSlug is required and cannot be empty");
|
|
1952
387
|
}
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
headers: {
|
|
388
|
+
const exporter = options?.exporter ?? new import_exporter_trace_otlp_http.OTLPTraceExporter({
|
|
389
|
+
url: `${env.EXPORTER_URL}/v1/traces`,
|
|
390
|
+
headers: {
|
|
1957
391
|
Authorization: `Bearer ${apiKey}`,
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
(
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
this.options.processors.forEach((processor) => {
|
|
2008
|
-
this.nodeProvider.addSpanProcessor(processor);
|
|
2009
|
-
});
|
|
2010
|
-
}
|
|
2011
|
-
else {
|
|
2012
|
-
this.nodeProvider.addSpanProcessor(DEFAULT_REDACT_SPAN_PROCESSOR());
|
|
2013
|
-
}
|
|
2014
|
-
if (this.options.disableBatch) {
|
|
2015
|
-
this.nodeProvider.addSpanProcessor(new sdkTraceNode.SimpleSpanProcessor(this.options.exporter));
|
|
2016
|
-
}
|
|
2017
|
-
else {
|
|
2018
|
-
this.nodeProvider.addSpanProcessor(new sdkTraceNode.BatchSpanProcessor(this.options.exporter));
|
|
2019
|
-
}
|
|
2020
|
-
this.nodeProvider.register();
|
|
2021
|
-
process.on('SIGTERM', async () => this.shutdown);
|
|
2022
|
-
process.on('SIGINT', async () => this.shutdown);
|
|
2023
|
-
this.manualInstrumentation = null;
|
|
2024
|
-
this.instrumentationsList = [];
|
|
2025
|
-
this.tracer = new TracerManager(this.nodeProvider, SCOPE_VERSION);
|
|
2026
|
-
this.initInstrumentations();
|
|
2027
|
-
this.instrumentation = new InstrumentationManager(this.instrumentationsList);
|
|
2028
|
-
this.instrumentation.enable();
|
|
2029
|
-
this.span = new SpanFactory(this.manualInstrumentation);
|
|
2030
|
-
this.context = new ContextManager(this.manualInstrumentation);
|
|
2031
|
-
}
|
|
2032
|
-
async flush() {
|
|
2033
|
-
await this.lifecycle.flush();
|
|
2034
|
-
}
|
|
2035
|
-
async shutdown() {
|
|
2036
|
-
await this.lifecycle.shutdown();
|
|
2037
|
-
}
|
|
2038
|
-
// TODO(tracing): auto instrument outgoing HTTP requests
|
|
2039
|
-
initInstrumentations() {
|
|
2040
|
-
this.instrumentationsList = [];
|
|
2041
|
-
const tracer = this.tracer.get(exports.Instrumentation.Manual);
|
|
2042
|
-
this.manualInstrumentation = new ManualInstrumentation(tracer, this.options.instrumentations?.manual);
|
|
2043
|
-
this.instrumentationsList.push(this.manualInstrumentation);
|
|
2044
|
-
const latitude = this.options.instrumentations?.latitude;
|
|
2045
|
-
if (latitude) {
|
|
2046
|
-
const tracer = this.tracer.get(exports.Instrumentation.Latitude);
|
|
2047
|
-
const instrumentation = new LatitudeInstrumentation(tracer, typeof latitude === 'object' ? latitude : { module: latitude });
|
|
2048
|
-
this.instrumentationsList.push(instrumentation);
|
|
2049
|
-
}
|
|
2050
|
-
const configureInstrumentation = (instrumentationType, InstrumentationConstructor, instrumentationOptions) => {
|
|
2051
|
-
const providerPkg = this.options.instrumentations?.[instrumentationType];
|
|
2052
|
-
if (!providerPkg)
|
|
2053
|
-
return;
|
|
2054
|
-
const provider = this.tracer.provider(instrumentationType);
|
|
2055
|
-
const instrumentation$1 = new InstrumentationConstructor(instrumentationOptions); // prettier-ignore
|
|
2056
|
-
instrumentation$1.setTracerProvider(provider);
|
|
2057
|
-
instrumentation$1.manuallyInstrument(providerPkg);
|
|
2058
|
-
instrumentation.registerInstrumentations({
|
|
2059
|
-
instrumentations: [instrumentation$1],
|
|
2060
|
-
tracerProvider: provider,
|
|
2061
|
-
});
|
|
2062
|
-
this.instrumentationsList.push(instrumentation$1);
|
|
2063
|
-
};
|
|
2064
|
-
configureInstrumentation(exports.Instrumentation.Anthropic, instrumentationAnthropic.AnthropicInstrumentation); // prettier-ignore
|
|
2065
|
-
configureInstrumentation(exports.Instrumentation.AIPlatform, instrumentationVertexai.AIPlatformInstrumentation); // prettier-ignore
|
|
2066
|
-
configureInstrumentation(exports.Instrumentation.Bedrock, instrumentationBedrock.BedrockInstrumentation); // prettier-ignore
|
|
2067
|
-
configureInstrumentation(exports.Instrumentation.Cohere, instrumentationCohere.CohereInstrumentation); // prettier-ignore
|
|
2068
|
-
configureInstrumentation(exports.Instrumentation.Langchain, instrumentationLangchain.LangChainInstrumentation); // prettier-ignore
|
|
2069
|
-
configureInstrumentation(exports.Instrumentation.LlamaIndex, instrumentationLlamaindex.LlamaIndexInstrumentation); // prettier-ignore
|
|
2070
|
-
// NOTE: `stream: true` in OpenAI make enrichTokens fail, so disabling.
|
|
2071
|
-
configureInstrumentation(exports.Instrumentation.OpenAI, instrumentationOpenai.OpenAIInstrumentation, { enrichTokens: false }); // prettier-ignore
|
|
2072
|
-
configureInstrumentation(exports.Instrumentation.TogetherAI, instrumentationTogether.TogetherInstrumentation, { enrichTokens: false }); // prettier-ignore
|
|
2073
|
-
configureInstrumentation(exports.Instrumentation.VertexAI, instrumentationVertexai.VertexAIInstrumentation); // prettier-ignore
|
|
2074
|
-
}
|
|
2075
|
-
async capture(options, fn) {
|
|
2076
|
-
if (!DOCUMENT_PATH_REGEXP.test(options.path)) {
|
|
2077
|
-
throw new BadRequestError("Invalid path, no spaces. Only letters, numbers, '.', '-' and '_'");
|
|
2078
|
-
}
|
|
2079
|
-
const captureBaggageEntries = {
|
|
2080
|
-
[ATTRIBUTES.LATITUDE.promptPath]: { value: options.path },
|
|
2081
|
-
[ATTRIBUTES.LATITUDE.projectId]: { value: String(options.projectId) },
|
|
2082
|
-
};
|
|
2083
|
-
if (options.versionUuid) {
|
|
2084
|
-
captureBaggageEntries[ATTRIBUTES.LATITUDE.commitUuid] = {
|
|
2085
|
-
value: options.versionUuid,
|
|
2086
|
-
};
|
|
2087
|
-
}
|
|
2088
|
-
if (options.conversationUuid) {
|
|
2089
|
-
captureBaggageEntries[ATTRIBUTES.LATITUDE.documentLogUuid] = {
|
|
2090
|
-
value: options.conversationUuid,
|
|
2091
|
-
};
|
|
2092
|
-
}
|
|
2093
|
-
const captureContext = otel.propagation.setBaggage(BACKGROUND(), otel.propagation.createBaggage(captureBaggageEntries));
|
|
2094
|
-
const span = this.manualInstrumentation.unresolvedExternal(captureContext, options);
|
|
2095
|
-
let result;
|
|
2096
|
-
try {
|
|
2097
|
-
result = await otel.context.with(span.context, async () => await fn(span.context));
|
|
2098
|
-
}
|
|
2099
|
-
catch (error) {
|
|
2100
|
-
span.fail(error);
|
|
2101
|
-
throw error;
|
|
2102
|
-
}
|
|
2103
|
-
span.end();
|
|
2104
|
-
return result;
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
392
|
+
"Content-Type": "application/json",
|
|
393
|
+
"X-Latitude-Project": projectSlug
|
|
394
|
+
},
|
|
395
|
+
timeoutMillis: 3e4
|
|
396
|
+
});
|
|
397
|
+
const redact = options?.disableRedact ? null : options?.redact ? new RedactSpanProcessor(options.redact) : DEFAULT_REDACT_SPAN_PROCESSOR();
|
|
398
|
+
const batchOrSimple = options?.disableBatch ? new import_sdk_trace_node.SimpleSpanProcessor(exporter) : new import_sdk_trace_node.BatchSpanProcessor(exporter);
|
|
399
|
+
const shouldExport = buildShouldExportSpanFromFields({
|
|
400
|
+
disableSmartFilter: options?.disableSmartFilter,
|
|
401
|
+
shouldExportSpan: options?.shouldExportSpan,
|
|
402
|
+
blockedInstrumentationScopes: options?.blockedInstrumentationScopes
|
|
403
|
+
});
|
|
404
|
+
const redactThenExport = new RedactThenExportSpanProcessor(redact, batchOrSimple);
|
|
405
|
+
this.tail = new ExportFilterSpanProcessor(shouldExport, redactThenExport);
|
|
406
|
+
}
|
|
407
|
+
onStart(span, parentContext) {
|
|
408
|
+
const latitudeData = getLatitudeContext(parentContext);
|
|
409
|
+
if (latitudeData) {
|
|
410
|
+
if (latitudeData.name) {
|
|
411
|
+
span.setAttribute(ATTRIBUTES.name, latitudeData.name);
|
|
412
|
+
if (span.attributes["latitude.capture.root"]) {
|
|
413
|
+
span.updateName(latitudeData.name);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (latitudeData.tags && latitudeData.tags.length > 0) {
|
|
417
|
+
span.setAttribute(ATTRIBUTES.tags, JSON.stringify(latitudeData.tags));
|
|
418
|
+
}
|
|
419
|
+
if (latitudeData.metadata && Object.keys(latitudeData.metadata).length > 0) {
|
|
420
|
+
span.setAttribute(ATTRIBUTES.metadata, JSON.stringify(latitudeData.metadata));
|
|
421
|
+
}
|
|
422
|
+
if (latitudeData.sessionId) {
|
|
423
|
+
span.setAttribute(ATTRIBUTES.sessionId, latitudeData.sessionId);
|
|
424
|
+
}
|
|
425
|
+
if (latitudeData.userId) {
|
|
426
|
+
span.setAttribute(ATTRIBUTES.userId, latitudeData.userId);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
this.tail.onStart(span, parentContext);
|
|
430
|
+
}
|
|
431
|
+
onEnd(span) {
|
|
432
|
+
this.tail.onEnd(span);
|
|
433
|
+
}
|
|
434
|
+
async forceFlush() {
|
|
435
|
+
await this.tail.forceFlush();
|
|
436
|
+
}
|
|
437
|
+
async shutdown() {
|
|
438
|
+
await this.tail.shutdown();
|
|
439
|
+
}
|
|
440
|
+
};
|
|
2107
441
|
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
442
|
+
// src/sdk/init.ts
|
|
443
|
+
var SERVICE_NAME = process.env.npm_package_name || "unknown";
|
|
444
|
+
var shutdownHandlersRegistered = false;
|
|
445
|
+
function initLatitude(options) {
|
|
446
|
+
const { apiKey, projectSlug, instrumentations = [], ...processorOptions } = options;
|
|
447
|
+
if (!apiKey || apiKey.trim() === "") {
|
|
448
|
+
throw new Error("[Latitude] apiKey is required and cannot be empty");
|
|
449
|
+
}
|
|
450
|
+
if (!projectSlug || projectSlug.trim() === "") {
|
|
451
|
+
throw new Error("[Latitude] projectSlug is required and cannot be empty");
|
|
452
|
+
}
|
|
453
|
+
const contextManager = new import_context_async_hooks.AsyncLocalStorageContextManager();
|
|
454
|
+
contextManager.enable();
|
|
455
|
+
const propagator = new import_core.CompositePropagator({
|
|
456
|
+
propagators: [new import_core.W3CTraceContextPropagator(), new import_core.W3CBaggagePropagator()]
|
|
457
|
+
});
|
|
458
|
+
import_api2.context.setGlobalContextManager(contextManager);
|
|
459
|
+
import_api2.propagation.setGlobalPropagator(propagator);
|
|
460
|
+
const provider = new import_sdk_trace_node2.NodeTracerProvider({
|
|
461
|
+
resource: new import_resources.Resource({
|
|
462
|
+
[import_semantic_conventions.ATTR_SERVICE_NAME]: SERVICE_NAME
|
|
463
|
+
}),
|
|
464
|
+
spanProcessors: [new LatitudeSpanProcessor(apiKey, projectSlug, processorOptions)]
|
|
465
|
+
});
|
|
466
|
+
provider.register();
|
|
467
|
+
const ready = registerLatitudeInstrumentations({
|
|
468
|
+
instrumentations,
|
|
469
|
+
tracerProvider: provider
|
|
470
|
+
}).catch((err) => {
|
|
471
|
+
console.warn("[Latitude] Failed to register instrumentations:", err);
|
|
472
|
+
});
|
|
473
|
+
const shutdown = async () => {
|
|
474
|
+
await provider.shutdown();
|
|
475
|
+
};
|
|
476
|
+
const flush = async () => {
|
|
477
|
+
await provider.forceFlush();
|
|
478
|
+
};
|
|
479
|
+
const handleShutdown = async () => {
|
|
480
|
+
try {
|
|
481
|
+
await shutdown();
|
|
482
|
+
} catch (err) {
|
|
483
|
+
console.error("Error during Latitude Telemetry shutdown:", err);
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
if (!shutdownHandlersRegistered) {
|
|
487
|
+
process.once("SIGTERM", handleShutdown);
|
|
488
|
+
process.once("SIGINT", handleShutdown);
|
|
489
|
+
shutdownHandlersRegistered = true;
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
provider,
|
|
493
|
+
flush,
|
|
494
|
+
shutdown,
|
|
495
|
+
ready
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
499
|
+
0 && (module.exports = {
|
|
500
|
+
ExportFilterSpanProcessor,
|
|
501
|
+
LatitudeSpanProcessor,
|
|
502
|
+
RedactSpanProcessor,
|
|
503
|
+
RedactThenExportSpanProcessor,
|
|
504
|
+
buildShouldExportSpan,
|
|
505
|
+
buildShouldExportSpanFromFields,
|
|
506
|
+
capture,
|
|
507
|
+
initLatitude,
|
|
508
|
+
isDefaultExportSpan,
|
|
509
|
+
isGenAiOrLlmAttributeSpan,
|
|
510
|
+
isLatitudeInstrumentationSpan,
|
|
511
|
+
registerLatitudeInstrumentations
|
|
512
|
+
});
|
|
513
|
+
//# sourceMappingURL=index.cjs.map
|