@latitude-data/telemetry 2.0.2 → 3.0.0-alpha.0

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