@latitude-data/telemetry 1.0.2 → 1.0.4

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
@@ -3,7 +3,6 @@ import * as otel from '@opentelemetry/api';
3
3
  import { propagation, trace, context } from '@opentelemetry/api';
4
4
  import { ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
5
5
  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';
6
- import { v4 } from 'uuid';
7
6
  import { BaggageSpanProcessor, ALLOW_ALL_BAGGAGE_KEYS } from '@opentelemetry/baggage-span-processor';
8
7
  import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';
9
8
  import { CompositePropagator, W3CTraceContextPropagator, W3CBaggagePropagator } from '@opentelemetry/core';
@@ -12,14 +11,13 @@ import { registerInstrumentations } from '@opentelemetry/instrumentation';
12
11
  import { Resource } from '@opentelemetry/resources';
13
12
  import { NodeTracerProvider, SimpleSpanProcessor, BatchSpanProcessor } from '@opentelemetry/sdk-trace-node';
14
13
  import { AnthropicInstrumentation } from '@traceloop/instrumentation-anthropic';
15
- import { AzureOpenAIInstrumentation } from '@traceloop/instrumentation-azure';
16
14
  import { BedrockInstrumentation } from '@traceloop/instrumentation-bedrock';
17
15
  import { CohereInstrumentation } from '@traceloop/instrumentation-cohere';
18
16
  import { LangChainInstrumentation } from '@traceloop/instrumentation-langchain';
19
17
  import { LlamaIndexInstrumentation } from '@traceloop/instrumentation-llamaindex';
20
18
  import { OpenAIInstrumentation } from '@traceloop/instrumentation-openai';
21
19
  import { TogetherInstrumentation } from '@traceloop/instrumentation-together';
22
- import { VertexAIInstrumentation, AIPlatformInstrumentation } from '@traceloop/instrumentation-vertexai';
20
+ import { AIPlatformInstrumentation, VertexAIInstrumentation } from '@traceloop/instrumentation-vertexai';
23
21
 
24
22
  class RedactSpanProcessor {
25
23
  options;
@@ -76,6 +74,7 @@ const DEFAULT_REDACT_SPAN_PROCESSOR = () => new RedactSpanProcessor({
76
74
  attributes: [
77
75
  /^.*auth.*$/i,
78
76
  /^.*authorization.*$/i,
77
+ /^(?!ai\.).*usage.*$/i,
79
78
  /^(?!gen_ai\.).*token.*$/i,
80
79
  /^.*secret.*$/i,
81
80
  /^.*key.*$/i,
@@ -118,289 +117,6 @@ function GET_GATEWAY_BASE_URL() {
118
117
  }
119
118
  const env = { GATEWAY_BASE_URL: GET_GATEWAY_BASE_URL() };
120
119
 
121
- var SegmentSource;
122
- (function (SegmentSource) {
123
- SegmentSource["API"] = "api";
124
- SegmentSource["AgentAsTool"] = "agent_as_tool";
125
- SegmentSource["Copilot"] = "copilot";
126
- SegmentSource["EmailTrigger"] = "email_trigger";
127
- SegmentSource["Evaluation"] = "evaluation";
128
- SegmentSource["Experiment"] = "experiment";
129
- SegmentSource["Playground"] = "playground";
130
- SegmentSource["ScheduledTrigger"] = "scheduled_trigger";
131
- SegmentSource["IntegrationTrigger"] = "integration_trigger";
132
- SegmentSource["SharedPrompt"] = "shared_prompt";
133
- SegmentSource["User"] = "user";
134
- })(SegmentSource || (SegmentSource = {}));
135
- var SegmentType;
136
- (function (SegmentType) {
137
- SegmentType["Document"] = "document";
138
- SegmentType["Step"] = "step";
139
- })(SegmentType || (SegmentType = {}));
140
- const SEGMENT_SPECIFICATIONS = {
141
- [SegmentType.Document]: {
142
- name: 'Prompt',
143
- description: 'A prompt',
144
- },
145
- [SegmentType.Step]: {
146
- name: 'Step',
147
- description: 'A step in a prompt',
148
- },
149
- };
150
- const baseSegmentBaggageSchema = z.object({
151
- id: z.string(),
152
- parentId: z.string().optional(),
153
- source: z.nativeEnum(SegmentSource),
154
- });
155
- z.discriminatedUnion('type', [
156
- baseSegmentBaggageSchema.extend({
157
- type: z.literal(SegmentType.Document),
158
- data: z.object({
159
- logUuid: z.string().optional(), // TODO(tracing): temporal related log, remove when observability is ready
160
- commitUuid: z.string(),
161
- documentUuid: z.string(),
162
- experimentUuid: z.string().optional(),
163
- externalId: z.string().optional(),
164
- }),
165
- }),
166
- baseSegmentBaggageSchema.extend({
167
- type: z.literal(SegmentType.Step),
168
- data: z.undefined().optional(),
169
- }),
170
- ]);
171
-
172
- var SpanKind;
173
- (function (SpanKind) {
174
- SpanKind["Internal"] = "internal";
175
- SpanKind["Server"] = "server";
176
- SpanKind["Client"] = "client";
177
- SpanKind["Producer"] = "producer";
178
- SpanKind["Consumer"] = "consumer";
179
- })(SpanKind || (SpanKind = {}));
180
- // Note: loosely based on OpenTelemetry GenAI semantic conventions
181
- var SpanType;
182
- (function (SpanType) {
183
- SpanType["Tool"] = "tool";
184
- SpanType["Completion"] = "completion";
185
- SpanType["Embedding"] = "embedding";
186
- SpanType["Retrieval"] = "retrieval";
187
- SpanType["Reranking"] = "reranking";
188
- SpanType["Http"] = "http";
189
- SpanType["Segment"] = "segment";
190
- SpanType["Unknown"] = "unknown";
191
- })(SpanType || (SpanType = {}));
192
- const SPAN_SPECIFICATIONS = {
193
- [SpanType.Tool]: {
194
- name: 'Tool',
195
- description: 'A tool call',
196
- isGenAI: true,
197
- isHidden: false,
198
- },
199
- [SpanType.Completion]: {
200
- name: 'Completion',
201
- description: 'A completion call',
202
- isGenAI: true,
203
- isHidden: false,
204
- },
205
- [SpanType.Embedding]: {
206
- name: 'Embedding',
207
- description: 'An embedding call',
208
- isGenAI: true,
209
- isHidden: false,
210
- },
211
- [SpanType.Retrieval]: {
212
- name: 'Retrieval',
213
- description: 'A retrieval call',
214
- isGenAI: true,
215
- isHidden: false,
216
- },
217
- [SpanType.Reranking]: {
218
- name: 'Reranking',
219
- description: 'A reranking call',
220
- isGenAI: true,
221
- isHidden: false,
222
- },
223
- [SpanType.Http]: {
224
- name: 'HTTP',
225
- description: 'An HTTP request',
226
- isGenAI: false,
227
- isHidden: true,
228
- },
229
- [SpanType.Segment]: {
230
- name: 'Segment',
231
- description: 'A (partial) segment of a trace',
232
- isGenAI: false,
233
- isHidden: false,
234
- },
235
- [SpanType.Unknown]: {
236
- name: 'Unknown',
237
- description: 'An unknown span',
238
- isGenAI: false,
239
- isHidden: true,
240
- },
241
- };
242
- var SpanStatus;
243
- (function (SpanStatus) {
244
- SpanStatus["Unset"] = "unset";
245
- SpanStatus["Ok"] = "ok";
246
- SpanStatus["Error"] = "error";
247
- })(SpanStatus || (SpanStatus = {}));
248
-
249
- // Note: Traces are unmaterialized but this context is used to propagate the trace
250
- // See www.w3.org/TR/trace-context and w3c.github.io/baggage
251
- z.object({
252
- traceparent: z.string(), // <version>-<trace-id>-<span-id>-<trace-flags>
253
- tracestate: z.string().optional(), // <key>=urlencoded(<value>)[,<key>=urlencoded(<value>)]*
254
- baggage: z.string().optional(), // <key>=urlencoded(<value>)[,<key>=urlencoded(<value>)]*
255
- });
256
-
257
- /* Note: Instrumentation scopes from all language SDKs */
258
- const SCOPE_LATITUDE = 'so.latitude.instrumentation';
259
- var InstrumentationScope;
260
- (function (InstrumentationScope) {
261
- InstrumentationScope["Manual"] = "manual";
262
- InstrumentationScope["Latitude"] = "latitude";
263
- InstrumentationScope["OpenAI"] = "openai";
264
- InstrumentationScope["Anthropic"] = "anthropic";
265
- InstrumentationScope["AzureOpenAI"] = "azure";
266
- InstrumentationScope["VercelAI"] = "vercelai";
267
- InstrumentationScope["VertexAI"] = "vertexai";
268
- InstrumentationScope["AIPlatform"] = "aiplatform";
269
- InstrumentationScope["MistralAI"] = "mistralai";
270
- InstrumentationScope["Bedrock"] = "bedrock";
271
- InstrumentationScope["Sagemaker"] = "sagemaker";
272
- InstrumentationScope["TogetherAI"] = "togetherai";
273
- InstrumentationScope["Replicate"] = "replicate";
274
- InstrumentationScope["Groq"] = "groq";
275
- InstrumentationScope["Cohere"] = "cohere";
276
- InstrumentationScope["LiteLLM"] = "litellm";
277
- InstrumentationScope["Langchain"] = "langchain";
278
- InstrumentationScope["LlamaIndex"] = "llamaindex";
279
- InstrumentationScope["DSPy"] = "dspy";
280
- InstrumentationScope["Haystack"] = "haystack";
281
- InstrumentationScope["Ollama"] = "ollama";
282
- InstrumentationScope["Transformers"] = "transformers";
283
- InstrumentationScope["AlephAlpha"] = "alephalpha";
284
- })(InstrumentationScope || (InstrumentationScope = {}));
285
- /* Note: non-standard OpenTelemetry semantic conventions used in Latitude */
286
- const ATTR_LATITUDE = 'latitude';
287
- const ATTR_LATITUDE_TYPE = `${ATTR_LATITUDE}.type`;
288
- const ATTR_LATITUDE_SEGMENT_ID = `${ATTR_LATITUDE}.segment.id`;
289
- const ATTR_LATITUDE_SEGMENT_PARENT_ID = `${ATTR_LATITUDE}.segment.parent_id`;
290
- const ATTR_LATITUDE_SEGMENTS = `${ATTR_LATITUDE}.segments`;
291
- const GEN_AI_TOOL_TYPE_VALUE_FUNCTION = 'function';
292
- const ATTR_GEN_AI_TOOL_CALL_ARGUMENTS = 'gen_ai.tool.call.arguments';
293
- const ATTR_GEN_AI_TOOL_RESULT_VALUE = 'gen_ai.tool.result.value';
294
- const ATTR_GEN_AI_TOOL_RESULT_IS_ERROR = 'gen_ai.tool.result.is_error';
295
- const ATTR_GEN_AI_REQUEST = 'gen_ai.request';
296
- const ATTR_GEN_AI_REQUEST_CONFIGURATION = 'gen_ai.request.configuration';
297
- const ATTR_GEN_AI_REQUEST_TEMPLATE = 'gen_ai.request.template';
298
- const ATTR_GEN_AI_REQUEST_PARAMETERS = 'gen_ai.request.parameters';
299
- const ATTR_GEN_AI_REQUEST_MESSAGES = 'gen_ai.request.messages';
300
- const ATTR_GEN_AI_RESPONSE = 'gen_ai.response';
301
- const ATTR_GEN_AI_RESPONSE_MESSAGES = 'gen_ai.response.messages';
302
- const ATTR_GEN_AI_USAGE_PROMPT_TOKENS = 'gen_ai.usage.prompt_tokens';
303
- const ATTR_GEN_AI_USAGE_CACHED_TOKENS = 'gen_ai.usage.cached_tokens';
304
- const ATTR_GEN_AI_USAGE_REASONING_TOKENS = 'gen_ai.usage.reasoning_tokens'; // prettier-ignore
305
- const ATTR_GEN_AI_USAGE_COMPLETION_TOKENS = 'gen_ai.usage.completion_tokens'; // prettier-ignore
306
- const ATTR_GEN_AI_PROMPTS = 'gen_ai.prompt'; // gen_ai.prompt.{index}.{role/content/...}
307
- const ATTR_GEN_AI_COMPLETIONS = 'gen_ai.completion'; // gen_ai.completion.{index}.{role/content/...}
308
- const ATTR_GEN_AI_MESSAGE_ROLE = 'role';
309
- const ATTR_GEN_AI_MESSAGE_CONTENT = 'content'; // string or object
310
- const ATTR_GEN_AI_MESSAGE_TOOL_NAME = 'tool_name';
311
- const ATTR_GEN_AI_MESSAGE_TOOL_CALL_ID = 'tool_call_id';
312
- const ATTR_GEN_AI_MESSAGE_TOOL_RESULT_IS_ERROR = 'is_error';
313
- const ATTR_GEN_AI_MESSAGE_TOOL_CALLS = 'tool_calls'; // gen_ai.completion.{index}.tool_calls.{index}.{id/name/arguments}
314
- const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_ID = 'id';
315
- const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_NAME = 'name';
316
- const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_ARGUMENTS = 'arguments';
317
- const GEN_AI_RESPONSE_FINISH_REASON_VALUE_STOP = 'stop';
318
- const GEN_AI_RESPONSE_FINISH_REASON_VALUE_TOOL_CALLS = 'tool_calls';
319
- const ATTR_HTTP_REQUEST_URL = 'http.request.url';
320
- const ATTR_HTTP_REQUEST_BODY = 'http.request.body';
321
- const ATTR_HTTP_REQUEST_HEADER = 'http.request.header';
322
- const ATTR_HTTP_RESPONSE_BODY = 'http.response.body';
323
- const ATTR_HTTP_RESPONSE_HEADER = 'http.response.header';
324
- /* Note: Schemas for span ingestion following OpenTelemetry service request specification */
325
- var Otlp;
326
- (function (Otlp) {
327
- Otlp.attributeValueSchema = z.object({
328
- stringValue: z.string().optional(),
329
- intValue: z.number().optional(),
330
- boolValue: z.boolean().optional(),
331
- arrayValue: z
332
- .object({
333
- values: z.array(z.object({
334
- stringValue: z.string().optional(),
335
- intValue: z.number().optional(),
336
- boolValue: z.boolean().optional(),
337
- })),
338
- })
339
- .optional(),
340
- });
341
- Otlp.attributeSchema = z.object({
342
- key: z.string(),
343
- value: Otlp.attributeValueSchema,
344
- });
345
- Otlp.eventSchema = z.object({
346
- name: z.string(),
347
- timeUnixNano: z.string(),
348
- attributes: z.array(Otlp.attributeSchema).optional(),
349
- });
350
- Otlp.linkSchema = z.object({
351
- traceId: z.string(),
352
- spanId: z.string(),
353
- attributes: z.array(Otlp.attributeSchema).optional(),
354
- });
355
- (function (StatusCode) {
356
- StatusCode[StatusCode["Unset"] = 0] = "Unset";
357
- StatusCode[StatusCode["Ok"] = 1] = "Ok";
358
- StatusCode[StatusCode["Error"] = 2] = "Error";
359
- })(Otlp.StatusCode || (Otlp.StatusCode = {}));
360
- Otlp.statusSchema = z.object({
361
- code: z.number(),
362
- message: z.string().optional(),
363
- });
364
- (function (SpanKind) {
365
- SpanKind[SpanKind["Internal"] = 0] = "Internal";
366
- SpanKind[SpanKind["Server"] = 1] = "Server";
367
- SpanKind[SpanKind["Client"] = 2] = "Client";
368
- SpanKind[SpanKind["Producer"] = 3] = "Producer";
369
- SpanKind[SpanKind["Consumer"] = 4] = "Consumer";
370
- })(Otlp.SpanKind || (Otlp.SpanKind = {}));
371
- Otlp.spanSchema = z.object({
372
- traceId: z.string(),
373
- spanId: z.string(),
374
- parentSpanId: z.string().optional(),
375
- name: z.string(),
376
- kind: z.number(),
377
- startTimeUnixNano: z.string(),
378
- endTimeUnixNano: z.string(),
379
- status: Otlp.statusSchema.optional(),
380
- events: z.array(Otlp.eventSchema).optional(),
381
- links: z.array(Otlp.linkSchema).optional(),
382
- attributes: z.array(Otlp.attributeSchema).optional(),
383
- });
384
- Otlp.scopeSchema = z.object({
385
- name: z.string(),
386
- version: z.string().optional(),
387
- });
388
- Otlp.scopeSpanSchema = z.object({
389
- scope: Otlp.scopeSchema,
390
- spans: z.array(Otlp.spanSchema),
391
- });
392
- Otlp.resourceSchema = z.object({
393
- attributes: z.array(Otlp.attributeSchema),
394
- });
395
- Otlp.resourceSpanSchema = z.object({
396
- resource: Otlp.resourceSchema,
397
- scopeSpans: z.array(Otlp.scopeSpanSchema),
398
- });
399
- Otlp.serviceRequestSchema = z.object({
400
- resourceSpans: z.array(Otlp.resourceSpanSchema),
401
- });
402
- })(Otlp || (Otlp = {}));
403
-
404
120
  var StreamEventTypes;
405
121
  (function (StreamEventTypes) {
406
122
  StreamEventTypes["Latitude"] = "latitude-event";
@@ -425,17 +141,27 @@ var LatitudeTool;
425
141
  LatitudeTool["RunCode"] = "code";
426
142
  LatitudeTool["WebSearch"] = "search";
427
143
  LatitudeTool["WebExtract"] = "extract";
144
+ LatitudeTool["Think"] = "think";
145
+ LatitudeTool["TODO"] = "todo";
428
146
  })(LatitudeTool || (LatitudeTool = {}));
429
147
  var LatitudeToolInternalName;
430
148
  (function (LatitudeToolInternalName) {
431
149
  LatitudeToolInternalName["RunCode"] = "lat_tool_run_code";
432
150
  LatitudeToolInternalName["WebSearch"] = "lat_tool_web_search";
433
151
  LatitudeToolInternalName["WebExtract"] = "lat_tool_web_extract";
152
+ LatitudeToolInternalName["Think"] = "think";
153
+ LatitudeToolInternalName["TODO"] = "todo_write";
434
154
  })(LatitudeToolInternalName || (LatitudeToolInternalName = {}));
155
+ [
156
+ LatitudeTool.Think,
157
+ LatitudeTool.TODO,
158
+ ];
435
159
 
436
160
  const actualOutputConfiguration = z.object({
437
161
  messageSelection: z.enum(['last', 'all']), // Which assistant messages to select
438
- contentFilter: z.enum(['text', 'image', 'file', 'tool_call']).optional(),
162
+ contentFilter: z
163
+ .enum(['text', 'reasoning', 'image', 'file', 'tool_call'])
164
+ .optional(),
439
165
  parsingFormat: z.enum(['string', 'json']),
440
166
  fieldAccessor: z.string().optional(), // Field accessor to get the output from if it's a key-value format
441
167
  });
@@ -445,11 +171,11 @@ const expectedOutputConfiguration = z.object({
445
171
  });
446
172
  const baseEvaluationConfiguration = z.object({
447
173
  reverseScale: z.boolean(), // If true, lower is better, otherwise, higher is better
448
- actualOutput: actualOutputConfiguration.optional(), // Optional for backwards compatibility
449
- expectedOutput: expectedOutputConfiguration.optional(), // Optional for backwards compatibility
174
+ actualOutput: actualOutputConfiguration,
175
+ expectedOutput: expectedOutputConfiguration.optional(),
450
176
  });
451
177
  const baseEvaluationResultMetadata = z.object({
452
- // Configuration snapshot is defined in every metric specification
178
+ // configuration: Configuration snapshot is defined in every metric specification
453
179
  actualOutput: z.string(),
454
180
  expectedOutput: z.string().optional(),
455
181
  datasetLabel: z.string().optional(),
@@ -458,7 +184,78 @@ const baseEvaluationResultError = z.object({
458
184
  message: z.string(),
459
185
  });
460
186
 
187
+ const compositeEvaluationConfiguration = baseEvaluationConfiguration.extend({
188
+ evaluationUuids: z.array(z.string()),
189
+ minThreshold: z.number().optional(), // Threshold percentage
190
+ maxThreshold: z.number().optional(), // Threshold percentage
191
+ });
192
+ const compositeEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
193
+ results: z.record(z.string(), // Evaluation uuid
194
+ z.object({
195
+ uuid: z.string(), // Result uuid (for side effects)
196
+ name: z.string(), // Evaluation name
197
+ score: z.number(), // Normalized score
198
+ reason: z.string(),
199
+ passed: z.boolean(),
200
+ })),
201
+ });
202
+ const compositeEvaluationResultError = baseEvaluationResultError.extend({
203
+ errors: z
204
+ .record(z.string(), // Evaluation uuid
205
+ z.object({
206
+ uuid: z.string(), // Result uuid (for side effects)
207
+ name: z.string(), // Evaluation name
208
+ message: z.string(),
209
+ }))
210
+ .optional(),
211
+ });
212
+ // AVERAGE
213
+ const compositeEvaluationAverageConfiguration = compositeEvaluationConfiguration.extend({});
214
+ compositeEvaluationResultMetadata.extend({
215
+ configuration: compositeEvaluationAverageConfiguration,
216
+ });
217
+ compositeEvaluationResultError.extend({});
218
+ const CompositeEvaluationAverageSpecification = {
219
+ };
220
+ // WEIGHTED
221
+ const compositeEvaluationWeightedConfiguration = compositeEvaluationConfiguration.extend({
222
+ weights: z.record(z.string(), // Evaluation uuid
223
+ z.number()),
224
+ });
225
+ compositeEvaluationResultMetadata.extend({
226
+ configuration: compositeEvaluationWeightedConfiguration,
227
+ });
228
+ compositeEvaluationResultError.extend({});
229
+ const CompositeEvaluationWeightedSpecification = {
230
+ };
231
+ // CUSTOM
232
+ const compositeEvaluationCustomConfiguration = compositeEvaluationConfiguration.extend({
233
+ formula: z.string(),
234
+ });
235
+ compositeEvaluationResultMetadata.extend({
236
+ configuration: compositeEvaluationCustomConfiguration,
237
+ });
238
+ compositeEvaluationResultError.extend({});
239
+ const CompositeEvaluationCustomSpecification = {
240
+ };
241
+ /* ------------------------------------------------------------------------- */
242
+ var CompositeEvaluationMetric;
243
+ (function (CompositeEvaluationMetric) {
244
+ CompositeEvaluationMetric["Average"] = "average";
245
+ CompositeEvaluationMetric["Weighted"] = "weighted";
246
+ CompositeEvaluationMetric["Custom"] = "custom";
247
+ })(CompositeEvaluationMetric || (CompositeEvaluationMetric = {}));
248
+ const CompositeEvaluationSpecification = {
249
+ // prettier-ignore
250
+ metrics: {
251
+ [CompositeEvaluationMetric.Average]: CompositeEvaluationAverageSpecification,
252
+ [CompositeEvaluationMetric.Weighted]: CompositeEvaluationWeightedSpecification,
253
+ [CompositeEvaluationMetric.Custom]: CompositeEvaluationCustomSpecification,
254
+ },
255
+ };
256
+
461
257
  const humanEvaluationConfiguration = baseEvaluationConfiguration.extend({
258
+ enableControls: z.boolean().optional(),
462
259
  criteria: z.string().optional(),
463
260
  });
464
261
  const humanEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
@@ -599,7 +396,9 @@ const LlmEvaluationSpecification = {
599
396
  };
600
397
 
601
398
  const ruleEvaluationConfiguration = baseEvaluationConfiguration.extend({});
602
- const ruleEvaluationResultMetadata = baseEvaluationResultMetadata.extend({});
399
+ const ruleEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
400
+ reason: z.string().optional(),
401
+ });
603
402
  const ruleEvaluationResultError = baseEvaluationResultError.extend({});
604
403
  // EXACT MATCH
605
404
  const ruleEvaluationExactMatchConfiguration = ruleEvaluationConfiguration.extend({
@@ -709,12 +508,14 @@ var EvaluationType;
709
508
  EvaluationType["Rule"] = "rule";
710
509
  EvaluationType["Llm"] = "llm";
711
510
  EvaluationType["Human"] = "human";
511
+ EvaluationType["Composite"] = "composite";
712
512
  })(EvaluationType || (EvaluationType = {}));
713
- const EvaluationTypeSchema = z.nativeEnum(EvaluationType);
513
+ const EvaluationTypeSchema = z.enum(EvaluationType);
714
514
  const EvaluationMetricSchema = z.union([
715
- z.nativeEnum(RuleEvaluationMetric),
716
- z.nativeEnum(LlmEvaluationMetric),
717
- z.nativeEnum(HumanEvaluationMetric),
515
+ z.enum(RuleEvaluationMetric),
516
+ z.enum(LlmEvaluationMetric),
517
+ z.enum(HumanEvaluationMetric),
518
+ z.enum(CompositeEvaluationMetric),
718
519
  ]);
719
520
  const EvaluationConfigurationSchema = z.custom();
720
521
  // prettier-ignore
@@ -725,6 +526,7 @@ z.custom();
725
526
  [EvaluationType.Rule]: RuleEvaluationSpecification,
726
527
  [EvaluationType.Llm]: LlmEvaluationSpecification,
727
528
  [EvaluationType.Human]: HumanEvaluationSpecification,
529
+ [EvaluationType.Composite]: CompositeEvaluationSpecification,
728
530
  });
729
531
  z.object({
730
532
  name: z.string(),
@@ -738,7 +540,6 @@ z.object({
738
540
  enableSuggestions: z.boolean().nullable().optional(),
739
541
  autoApplySuggestions: z.boolean().nullable().optional(),
740
542
  });
741
- Object.values(SegmentSource).filter((source) => source !== SegmentSource.Evaluation && source !== SegmentSource.Experiment);
742
543
 
743
544
  var LegacyChainEventTypes;
744
545
  (function (LegacyChainEventTypes) {
@@ -759,17 +560,71 @@ var ChainEventTypes;
759
560
  ChainEventTypes["StepCompleted"] = "step-completed";
760
561
  ChainEventTypes["StepStarted"] = "step-started";
761
562
  ChainEventTypes["ToolCompleted"] = "tool-completed";
762
- ChainEventTypes["ToolsRequested"] = "tools-requested";
763
563
  ChainEventTypes["ToolResult"] = "tool-result";
764
564
  ChainEventTypes["ToolsStarted"] = "tools-started";
765
565
  })(ChainEventTypes || (ChainEventTypes = {}));
766
566
 
567
+ z.object({
568
+ name: z.string(),
569
+ provider: z.string(),
570
+ model: z.string(),
571
+ temperature: z.number(),
572
+ });
573
+ // Experiment ran from a dataset
574
+ const experimentDatasetSourceSchema = z.object({
575
+ source: z.literal('dataset'),
576
+ datasetId: z.number(),
577
+ fromRow: z.number(),
578
+ toRow: z.number(),
579
+ datasetLabels: z.record(z.string(), z.string()),
580
+ parametersMap: z.record(z.string(), z.number()),
581
+ });
582
+ // Experiment ran from last logs (from commit and creation time of experiment)
583
+ const experimentLogsSourceSchema = z.object({
584
+ source: z.literal('logs'),
585
+ count: z.number(),
586
+ });
587
+ // Experiment ran with manual parameters (currently only used for prompts with no parameters)
588
+ const experimentManualSourceSchema = z.object({
589
+ source: z.literal('manual'),
590
+ count: z.number(),
591
+ parametersMap: z.record(z.string(), z.number()),
592
+ });
593
+ z.discriminatedUnion('source', [
594
+ experimentDatasetSourceSchema,
595
+ experimentLogsSourceSchema,
596
+ experimentManualSourceSchema,
597
+ ]);
598
+
599
+ var QuotaType;
600
+ (function (QuotaType) {
601
+ QuotaType["Seats"] = "seats";
602
+ QuotaType["Runs"] = "runs";
603
+ QuotaType["Credits"] = "credits";
604
+ })(QuotaType || (QuotaType = {}));
605
+ var GrantSource;
606
+ (function (GrantSource) {
607
+ GrantSource["System"] = "system";
608
+ GrantSource["Subscription"] = "subscription";
609
+ GrantSource["Purchase"] = "purchase";
610
+ GrantSource["Reward"] = "reward";
611
+ GrantSource["Promocode"] = "promocode";
612
+ })(GrantSource || (GrantSource = {}));
613
+
614
+ var ModifiedDocumentType;
615
+ (function (ModifiedDocumentType) {
616
+ ModifiedDocumentType["Created"] = "created";
617
+ ModifiedDocumentType["Updated"] = "updated";
618
+ ModifiedDocumentType["UpdatedPath"] = "updated_path";
619
+ ModifiedDocumentType["Deleted"] = "deleted";
620
+ })(ModifiedDocumentType || (ModifiedDocumentType = {}));
621
+
767
622
  var IntegrationType;
768
623
  (function (IntegrationType) {
769
624
  IntegrationType["Latitude"] = "latitude";
770
625
  IntegrationType["ExternalMCP"] = "custom_mcp";
771
- IntegrationType["HostedMCP"] = "mcp_server";
772
626
  IntegrationType["Pipedream"] = "pipedream";
627
+ IntegrationType["HostedMCP"] = "mcp_server";
773
628
  })(IntegrationType || (IntegrationType = {}));
774
629
  var HostedIntegrationType;
775
630
  (function (HostedIntegrationType) {
@@ -866,13 +721,40 @@ var HostedIntegrationType;
866
721
  // Loops = 'loops', // Does not exist
867
722
  })(HostedIntegrationType || (HostedIntegrationType = {}));
868
723
 
869
- // TODO(evalsv2): Remove
870
- var EvaluationResultableType;
871
- (function (EvaluationResultableType) {
872
- EvaluationResultableType["Boolean"] = "evaluation_resultable_booleans";
873
- EvaluationResultableType["Text"] = "evaluation_resultable_texts";
874
- EvaluationResultableType["Number"] = "evaluation_resultable_numbers";
875
- })(EvaluationResultableType || (EvaluationResultableType = {}));
724
+ var LogSources;
725
+ (function (LogSources) {
726
+ LogSources["API"] = "api";
727
+ LogSources["AgentAsTool"] = "agent_as_tool";
728
+ LogSources["Copilot"] = "copilot";
729
+ LogSources["EmailTrigger"] = "email_trigger";
730
+ LogSources["Evaluation"] = "evaluation";
731
+ LogSources["Experiment"] = "experiment";
732
+ LogSources["IntegrationTrigger"] = "integration_trigger";
733
+ LogSources["Playground"] = "playground";
734
+ LogSources["ScheduledTrigger"] = "scheduled_trigger";
735
+ LogSources["SharedPrompt"] = "shared_prompt";
736
+ LogSources["ShadowTest"] = "shadow_test";
737
+ LogSources["ABTestChallenger"] = "ab_test_challenger";
738
+ LogSources["User"] = "user";
739
+ })(LogSources || (LogSources = {}));
740
+
741
+ var RunSourceGroup;
742
+ (function (RunSourceGroup) {
743
+ RunSourceGroup["Production"] = "production";
744
+ RunSourceGroup["Playground"] = "playground";
745
+ })(RunSourceGroup || (RunSourceGroup = {}));
746
+ ({
747
+ [RunSourceGroup.Production]: [
748
+ LogSources.API,
749
+ LogSources.Copilot,
750
+ LogSources.EmailTrigger,
751
+ LogSources.IntegrationTrigger,
752
+ LogSources.ScheduledTrigger,
753
+ LogSources.SharedPrompt,
754
+ LogSources.User,
755
+ ],
756
+ [RunSourceGroup.Playground]: [LogSources.Playground, LogSources.Experiment],
757
+ });
876
758
 
877
759
  var MessageRole;
878
760
  (function (MessageRole) {
@@ -882,13 +764,242 @@ var MessageRole;
882
764
  MessageRole["tool"] = "tool";
883
765
  })(MessageRole || (MessageRole = {}));
884
766
 
885
- var ModifiedDocumentType;
886
- (function (ModifiedDocumentType) {
887
- ModifiedDocumentType["Created"] = "created";
888
- ModifiedDocumentType["Updated"] = "updated";
889
- ModifiedDocumentType["UpdatedPath"] = "updated_path";
890
- ModifiedDocumentType["Deleted"] = "deleted";
891
- })(ModifiedDocumentType || (ModifiedDocumentType = {}));
767
+ var SpanKind;
768
+ (function (SpanKind) {
769
+ SpanKind["Internal"] = "internal";
770
+ SpanKind["Server"] = "server";
771
+ SpanKind["Client"] = "client";
772
+ SpanKind["Producer"] = "producer";
773
+ SpanKind["Consumer"] = "consumer";
774
+ })(SpanKind || (SpanKind = {}));
775
+ // Note: loosely based on OpenTelemetry GenAI semantic conventions
776
+ var SpanType;
777
+ (function (SpanType) {
778
+ SpanType["Tool"] = "tool";
779
+ SpanType["Completion"] = "completion";
780
+ SpanType["Embedding"] = "embedding";
781
+ SpanType["Retrieval"] = "retrieval";
782
+ SpanType["Reranking"] = "reranking";
783
+ SpanType["Http"] = "http";
784
+ SpanType["Unknown"] = "unknown";
785
+ SpanType["Prompt"] = "prompt";
786
+ SpanType["Step"] = "step";
787
+ })(SpanType || (SpanType = {}));
788
+ const SPAN_SPECIFICATIONS = {
789
+ [SpanType.Tool]: {
790
+ name: 'Tool',
791
+ description: 'A tool call',
792
+ isGenAI: true,
793
+ isHidden: false,
794
+ },
795
+ [SpanType.Completion]: {
796
+ name: 'Completion',
797
+ description: 'A completion call',
798
+ isGenAI: true,
799
+ isHidden: false,
800
+ },
801
+ [SpanType.Embedding]: {
802
+ name: 'Embedding',
803
+ description: 'An embedding call',
804
+ isGenAI: true,
805
+ isHidden: false,
806
+ },
807
+ [SpanType.Retrieval]: {
808
+ name: 'Retrieval',
809
+ description: 'A retrieval call',
810
+ isGenAI: true,
811
+ isHidden: false,
812
+ },
813
+ [SpanType.Reranking]: {
814
+ name: 'Reranking',
815
+ description: 'A reranking call',
816
+ isGenAI: true,
817
+ isHidden: false,
818
+ },
819
+ [SpanType.Http]: {
820
+ name: 'HTTP',
821
+ description: 'An HTTP request',
822
+ isGenAI: false,
823
+ isHidden: true,
824
+ },
825
+ [SpanType.Unknown]: {
826
+ name: 'Unknown',
827
+ description: 'An unknown span',
828
+ isGenAI: false,
829
+ isHidden: true,
830
+ },
831
+ [SpanType.Prompt]: {
832
+ name: 'Prompt',
833
+ description: 'A prompt span',
834
+ isGenAI: false,
835
+ isHidden: false,
836
+ },
837
+ [SpanType.Step]: {
838
+ name: 'Step',
839
+ description: 'A step span',
840
+ isGenAI: false,
841
+ isHidden: false,
842
+ },
843
+ };
844
+ var SpanStatus;
845
+ (function (SpanStatus) {
846
+ SpanStatus["Unset"] = "unset";
847
+ SpanStatus["Ok"] = "ok";
848
+ SpanStatus["Error"] = "error";
849
+ })(SpanStatus || (SpanStatus = {}));
850
+
851
+ // Note: Traces are unmaterialized but this context is used to propagate the trace
852
+ // See www.w3.org/TR/trace-context and w3c.github.io/baggage
853
+ z.object({
854
+ traceparent: z.string(), // <version>-<trace-id>-<span-id>-<trace-flags>
855
+ tracestate: z.string().optional(), // <key>=urlencoded(<value>)[,<key>=urlencoded(<value>)]*
856
+ baggage: z.string().optional(), // <key>=urlencoded(<value>)[,<key>=urlencoded(<value>)]*
857
+ });
858
+
859
+ /* Note: Instrumentation scopes from all language SDKs */
860
+ const SCOPE_LATITUDE = 'so.latitude.instrumentation';
861
+ var InstrumentationScope;
862
+ (function (InstrumentationScope) {
863
+ InstrumentationScope["Manual"] = "manual";
864
+ InstrumentationScope["Latitude"] = "latitude";
865
+ InstrumentationScope["OpenAI"] = "openai";
866
+ InstrumentationScope["Anthropic"] = "anthropic";
867
+ InstrumentationScope["AzureOpenAI"] = "azure";
868
+ InstrumentationScope["VercelAI"] = "vercelai";
869
+ InstrumentationScope["VertexAI"] = "vertexai";
870
+ InstrumentationScope["AIPlatform"] = "aiplatform";
871
+ InstrumentationScope["MistralAI"] = "mistralai";
872
+ InstrumentationScope["Bedrock"] = "bedrock";
873
+ InstrumentationScope["Sagemaker"] = "sagemaker";
874
+ InstrumentationScope["TogetherAI"] = "togetherai";
875
+ InstrumentationScope["Replicate"] = "replicate";
876
+ InstrumentationScope["Groq"] = "groq";
877
+ InstrumentationScope["Cohere"] = "cohere";
878
+ InstrumentationScope["LiteLLM"] = "litellm";
879
+ InstrumentationScope["Langchain"] = "langchain";
880
+ InstrumentationScope["LlamaIndex"] = "llamaindex";
881
+ InstrumentationScope["DSPy"] = "dspy";
882
+ InstrumentationScope["Haystack"] = "haystack";
883
+ InstrumentationScope["Ollama"] = "ollama";
884
+ InstrumentationScope["Transformers"] = "transformers";
885
+ InstrumentationScope["AlephAlpha"] = "alephalpha";
886
+ })(InstrumentationScope || (InstrumentationScope = {}));
887
+ /* Note: non-standard OpenTelemetry semantic conventions used in Latitude */
888
+ const ATTR_LATITUDE = 'latitude';
889
+ const ATTR_LATITUDE_TYPE = `${ATTR_LATITUDE}.type`;
890
+ const ATTR_LATITUDE_TEST_DEPLOYMENT_ID = `${ATTR_LATITUDE}.test_deployment_id`;
891
+ const GEN_AI_TOOL_TYPE_VALUE_FUNCTION = 'function';
892
+ const ATTR_GEN_AI_TOOL_CALL_ARGUMENTS = 'gen_ai.tool.call.arguments';
893
+ const ATTR_GEN_AI_TOOL_RESULT_VALUE = 'gen_ai.tool.result.value';
894
+ const ATTR_GEN_AI_TOOL_RESULT_IS_ERROR = 'gen_ai.tool.result.is_error';
895
+ const ATTR_GEN_AI_REQUEST = 'gen_ai.request';
896
+ const ATTR_GEN_AI_REQUEST_CONFIGURATION = 'gen_ai.request.configuration';
897
+ const ATTR_GEN_AI_REQUEST_TEMPLATE = 'gen_ai.request.template';
898
+ const ATTR_GEN_AI_REQUEST_PARAMETERS = 'gen_ai.request.parameters';
899
+ const ATTR_GEN_AI_REQUEST_MESSAGES = 'gen_ai.request.messages';
900
+ const ATTR_GEN_AI_RESPONSE = 'gen_ai.response';
901
+ const ATTR_GEN_AI_RESPONSE_MESSAGES = 'gen_ai.response.messages';
902
+ const ATTR_GEN_AI_USAGE_PROMPT_TOKENS = 'gen_ai.usage.prompt_tokens';
903
+ const ATTR_GEN_AI_USAGE_CACHED_TOKENS = 'gen_ai.usage.cached_tokens';
904
+ const ATTR_GEN_AI_USAGE_REASONING_TOKENS = 'gen_ai.usage.reasoning_tokens'; // prettier-ignore
905
+ const ATTR_GEN_AI_USAGE_COMPLETION_TOKENS = 'gen_ai.usage.completion_tokens'; // prettier-ignore
906
+ const ATTR_GEN_AI_PROMPTS = 'gen_ai.prompt'; // gen_ai.prompt.{index}.{role/content/...}
907
+ const ATTR_GEN_AI_COMPLETIONS = 'gen_ai.completion'; // gen_ai.completion.{index}.{role/content/...}
908
+ const ATTR_GEN_AI_MESSAGE_ROLE = 'role';
909
+ const ATTR_GEN_AI_MESSAGE_CONTENT = 'content'; // string or object
910
+ const ATTR_GEN_AI_MESSAGE_TOOL_NAME = 'tool_name';
911
+ const ATTR_GEN_AI_MESSAGE_TOOL_CALL_ID = 'tool_call_id';
912
+ const ATTR_GEN_AI_MESSAGE_TOOL_RESULT_IS_ERROR = 'is_error';
913
+ const ATTR_GEN_AI_MESSAGE_TOOL_CALLS = 'tool_calls'; // gen_ai.completion.{index}.tool_calls.{index}.{id/name/arguments}
914
+ const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_ID = 'id';
915
+ const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_NAME = 'name';
916
+ const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_ARGUMENTS = 'arguments';
917
+ const GEN_AI_RESPONSE_FINISH_REASON_VALUE_STOP = 'stop';
918
+ const GEN_AI_RESPONSE_FINISH_REASON_VALUE_TOOL_CALLS = 'tool_calls';
919
+ const ATTR_HTTP_REQUEST_URL = 'http.request.url';
920
+ const ATTR_HTTP_REQUEST_BODY = 'http.request.body';
921
+ const ATTR_HTTP_REQUEST_HEADER = 'http.request.header';
922
+ const ATTR_HTTP_RESPONSE_BODY = 'http.response.body';
923
+ const ATTR_HTTP_RESPONSE_HEADER = 'http.response.header';
924
+ /* Note: Schemas for span ingestion following OpenTelemetry service request specification */
925
+ var Otlp;
926
+ (function (Otlp) {
927
+ Otlp.attributeValueSchema = z.object({
928
+ stringValue: z.string().optional(),
929
+ intValue: z.number().optional(),
930
+ boolValue: z.boolean().optional(),
931
+ arrayValue: z
932
+ .object({
933
+ values: z.array(z.object({
934
+ stringValue: z.string().optional(),
935
+ intValue: z.number().optional(),
936
+ boolValue: z.boolean().optional(),
937
+ })),
938
+ })
939
+ .optional(),
940
+ });
941
+ Otlp.attributeSchema = z.object({
942
+ key: z.string(),
943
+ value: Otlp.attributeValueSchema,
944
+ });
945
+ Otlp.eventSchema = z.object({
946
+ name: z.string(),
947
+ timeUnixNano: z.string(),
948
+ attributes: z.array(Otlp.attributeSchema).optional(),
949
+ });
950
+ Otlp.linkSchema = z.object({
951
+ traceId: z.string(),
952
+ spanId: z.string(),
953
+ attributes: z.array(Otlp.attributeSchema).optional(),
954
+ });
955
+ (function (StatusCode) {
956
+ StatusCode[StatusCode["Unset"] = 0] = "Unset";
957
+ StatusCode[StatusCode["Ok"] = 1] = "Ok";
958
+ StatusCode[StatusCode["Error"] = 2] = "Error";
959
+ })(Otlp.StatusCode || (Otlp.StatusCode = {}));
960
+ Otlp.statusSchema = z.object({
961
+ code: z.number(),
962
+ message: z.string().optional(),
963
+ });
964
+ (function (SpanKind) {
965
+ SpanKind[SpanKind["Internal"] = 0] = "Internal";
966
+ SpanKind[SpanKind["Server"] = 1] = "Server";
967
+ SpanKind[SpanKind["Client"] = 2] = "Client";
968
+ SpanKind[SpanKind["Producer"] = 3] = "Producer";
969
+ SpanKind[SpanKind["Consumer"] = 4] = "Consumer";
970
+ })(Otlp.SpanKind || (Otlp.SpanKind = {}));
971
+ Otlp.spanSchema = z.object({
972
+ traceId: z.string(),
973
+ spanId: z.string(),
974
+ parentSpanId: z.string().optional(),
975
+ name: z.string(),
976
+ kind: z.number(),
977
+ startTimeUnixNano: z.string(),
978
+ endTimeUnixNano: z.string(),
979
+ status: Otlp.statusSchema.optional(),
980
+ events: z.array(Otlp.eventSchema).optional(),
981
+ links: z.array(Otlp.linkSchema).optional(),
982
+ attributes: z.array(Otlp.attributeSchema).optional(),
983
+ });
984
+ Otlp.scopeSchema = z.object({
985
+ name: z.string(),
986
+ version: z.string().optional(),
987
+ });
988
+ Otlp.scopeSpanSchema = z.object({
989
+ scope: Otlp.scopeSchema,
990
+ spans: z.array(Otlp.spanSchema),
991
+ });
992
+ Otlp.resourceSchema = z.object({
993
+ attributes: z.array(Otlp.attributeSchema),
994
+ });
995
+ Otlp.resourceSpanSchema = z.object({
996
+ resource: Otlp.resourceSchema,
997
+ scopeSpans: z.array(Otlp.scopeSpanSchema),
998
+ });
999
+ Otlp.serviceRequestSchema = z.object({
1000
+ resourceSpans: z.array(Otlp.resourceSpanSchema),
1001
+ });
1002
+ })(Otlp || (Otlp = {}));
892
1003
 
893
1004
  // TODO(tracing): deprecated
894
1005
  const HEAD_COMMIT = 'live';
@@ -919,6 +1030,12 @@ var DocumentTriggerType;
919
1030
  DocumentTriggerType["Scheduled"] = "scheduled";
920
1031
  DocumentTriggerType["Integration"] = "integration";
921
1032
  })(DocumentTriggerType || (DocumentTriggerType = {}));
1033
+ var DocumentTriggerStatus;
1034
+ (function (DocumentTriggerStatus) {
1035
+ DocumentTriggerStatus["Pending"] = "pending";
1036
+ DocumentTriggerStatus["Deployed"] = "deployed";
1037
+ DocumentTriggerStatus["Deprecated"] = "deprecated";
1038
+ })(DocumentTriggerStatus || (DocumentTriggerStatus = {}));
922
1039
  var DocumentTriggerParameters;
923
1040
  (function (DocumentTriggerParameters) {
924
1041
  DocumentTriggerParameters["SenderEmail"] = "senderEmail";
@@ -930,11 +1047,9 @@ var DocumentTriggerParameters;
930
1047
 
931
1048
  class ManualInstrumentation {
932
1049
  enabled;
933
- source;
934
1050
  tracer;
935
- constructor(source, tracer) {
1051
+ constructor(tracer) {
936
1052
  this.enabled = false;
937
- this.source = source;
938
1053
  this.tracer = tracer;
939
1054
  }
940
1055
  isEnabled() {
@@ -946,96 +1061,9 @@ class ManualInstrumentation {
946
1061
  disable() {
947
1062
  this.enabled = false;
948
1063
  }
949
- baggage(ctx) {
950
- if ('traceparent' in ctx) {
951
- ctx = propagation.extract(otel.ROOT_CONTEXT, ctx);
952
- }
953
- const baggage = Object.fromEntries(propagation.getBaggage(ctx)?.getAllEntries() || []);
954
- if (!(ATTR_LATITUDE_SEGMENT_ID in baggage) ||
955
- !(ATTR_LATITUDE_SEGMENTS in baggage)) {
956
- return undefined;
957
- }
958
- const segment = {
959
- id: baggage[ATTR_LATITUDE_SEGMENT_ID].value,
960
- parentId: baggage[ATTR_LATITUDE_SEGMENT_PARENT_ID]?.value,
961
- };
962
- let segments = [];
963
- try {
964
- segments = JSON.parse(baggage[ATTR_LATITUDE_SEGMENTS].value);
965
- }
966
- catch (error) {
967
- return undefined;
968
- }
969
- if (segments.length < 1) {
970
- return undefined;
971
- }
972
- return { segment, segments };
973
- }
974
- setBaggage(ctx, baggage, extra) {
975
- let parent = Object.fromEntries(propagation.getBaggage(ctx)?.getAllEntries() || []);
976
- parent = Object.fromEntries(Object.entries(parent).filter(([attribute]) => attribute !== ATTR_LATITUDE_SEGMENT_ID &&
977
- attribute !== ATTR_LATITUDE_SEGMENT_PARENT_ID &&
978
- attribute !== ATTR_LATITUDE_SEGMENTS));
979
- if (!baggage) {
980
- const payload = propagation.createBaggage({ ...parent, ...(extra || {}) });
981
- return propagation.setBaggage(ctx, payload);
982
- }
983
- let jsonSegments = '';
984
- try {
985
- jsonSegments = JSON.stringify(baggage.segments);
986
- }
987
- catch (error) {
988
- jsonSegments = '[]';
989
- }
990
- const payload = propagation.createBaggage({
991
- ...parent,
992
- [ATTR_LATITUDE_SEGMENT_ID]: { value: baggage.segment.id },
993
- ...(baggage.segment.parentId && {
994
- [ATTR_LATITUDE_SEGMENT_PARENT_ID]: { value: baggage.segment.parentId },
995
- }),
996
- [ATTR_LATITUDE_SEGMENTS]: { value: jsonSegments },
997
- ...(extra || {}),
998
- });
999
- return propagation.setBaggage(ctx, payload);
1000
- }
1001
- pause(ctx) {
1002
- const baggage = this.baggage(ctx);
1003
- if (baggage) {
1004
- baggage.segments.at(-1).paused = true;
1005
- }
1006
- ctx = this.setBaggage(ctx, baggage);
1007
- let carrier = {};
1008
- propagation.inject(ctx, carrier);
1009
- return carrier;
1010
- }
1011
1064
  resume(ctx) {
1012
1065
  return propagation.extract(otel.ROOT_CONTEXT, ctx);
1013
1066
  }
1014
- restored(ctx) {
1015
- const baggage = this.baggage(ctx);
1016
- return !baggage?.segments.some((segment) => segment.paused);
1017
- }
1018
- restore(ctx) {
1019
- let baggage = this.baggage(ctx);
1020
- if (!baggage)
1021
- return ctx;
1022
- const segments = baggage.segments;
1023
- while (segments.at(-1)?.paused)
1024
- segments.pop();
1025
- const segment = segments.at(-1);
1026
- if (!segment)
1027
- return otel.ROOT_CONTEXT;
1028
- baggage = {
1029
- segment: { id: segment.id, parentId: segment.parentId },
1030
- segments: segments,
1031
- };
1032
- ctx = this.setBaggage(ctx, baggage);
1033
- let carrier = {};
1034
- propagation.inject(ctx, carrier);
1035
- carrier.traceparent = segment.traceparent;
1036
- carrier.tracestate = segment.tracestate;
1037
- return this.resume(carrier);
1038
- }
1039
1067
  capitalize(str) {
1040
1068
  if (str.length === 0)
1041
1069
  return str;
@@ -1368,6 +1396,9 @@ class ManualInstrumentation {
1368
1396
  [ATTR_GEN_AI_REQUEST_MESSAGES]: jsonInput,
1369
1397
  ...attrInput,
1370
1398
  ...(start.attributes || {}),
1399
+ ['latitude.commitUuid']: start.versionUuid,
1400
+ ['latitude.documentUuid']: start.promptUuid,
1401
+ ['latitude.experimentUuid']: start.experimentUuid,
1371
1402
  },
1372
1403
  });
1373
1404
  return {
@@ -1482,49 +1513,7 @@ class ManualInstrumentation {
1482
1513
  fail: span.fail,
1483
1514
  };
1484
1515
  }
1485
- segment(ctx, type, data, options) {
1486
- options = options || {};
1487
- let baggage = this.baggage(ctx);
1488
- const parent = baggage?.segments.at(-1);
1489
- const segments = baggage?.segments || [];
1490
- segments.push({
1491
- ...{
1492
- id: options._internal?.id || v4(),
1493
- ...(parent?.id && { parentId: parent.id }),
1494
- source: options._internal?.source || parent?.source || this.source,
1495
- type: type,
1496
- data: data,
1497
- },
1498
- traceparent: 'undefined',
1499
- tracestate: undefined,
1500
- });
1501
- const segment = segments.at(-1);
1502
- baggage = {
1503
- segment: { id: segment.id, parentId: segment.parentId },
1504
- segments: segments,
1505
- };
1506
- ctx = this.setBaggage(ctx, baggage, options.baggage);
1507
- // Dummy wrapper to force the same trace and carry on some segment attributes
1508
- const span = this.span(ctx, SEGMENT_SPECIFICATIONS[type].name, SpanType.Segment, { attributes: options.attributes });
1509
- let carrier = {};
1510
- propagation.inject(span.context, carrier);
1511
- baggage.segments.at(-1).traceparent = carrier.traceparent;
1512
- baggage.segments.at(-1).tracestate = carrier.tracestate;
1513
- // Fix current segment span segments attribute now that we know the trace
1514
- trace
1515
- .getSpan(span.context)
1516
- .setAttribute(ATTR_LATITUDE_SEGMENTS, JSON.stringify(baggage.segments));
1517
- ctx = this.setBaggage(span.context, baggage, options.baggage);
1518
- return { context: ctx, end: span.end, fail: span.fail };
1519
- }
1520
- prompt(ctx, { logUuid, versionUuid, promptUuid, experimentUuid, externalId, template, parameters, ...rest }) {
1521
- const baggage = {
1522
- ...(logUuid && { logUuid }), // TODO(tracing): temporal related log, remove when observability is ready
1523
- commitUuid: versionUuid || HEAD_COMMIT,
1524
- documentUuid: promptUuid,
1525
- ...(experimentUuid && { experimentUuid }),
1526
- ...(externalId && { externalId }),
1527
- };
1516
+ prompt(ctx, { documentLogUuid, versionUuid, promptUuid, projectId, experimentUuid, testDeploymentId, externalId, template, parameters, name, source, ...rest }) {
1528
1517
  let jsonParameters = '';
1529
1518
  try {
1530
1519
  jsonParameters = JSON.stringify(parameters || {});
@@ -1535,23 +1524,32 @@ class ManualInstrumentation {
1535
1524
  const attributes = {
1536
1525
  [ATTR_GEN_AI_REQUEST_TEMPLATE]: template,
1537
1526
  [ATTR_GEN_AI_REQUEST_PARAMETERS]: jsonParameters,
1527
+ ['latitude.commitUuid']: versionUuid || HEAD_COMMIT,
1528
+ ['latitude.documentUuid']: promptUuid,
1529
+ ['latitude.projectId']: projectId,
1530
+ ...(documentLogUuid && { ['latitude.documentLogUuid']: documentLogUuid }),
1531
+ ...(experimentUuid && { ['latitude.experimentUuid']: experimentUuid }),
1532
+ ...(testDeploymentId && {
1533
+ [ATTR_LATITUDE_TEST_DEPLOYMENT_ID]: testDeploymentId,
1534
+ }),
1535
+ ...(externalId && { ['latitude.externalId']: externalId }),
1536
+ ...(source && { ['latitude.source']: source }),
1538
1537
  ...(rest.attributes || {}),
1539
1538
  };
1540
- return this.segment(ctx, SegmentType.Document, baggage, {
1541
- ...rest,
1539
+ return this.span(ctx, name || `prompt-${promptUuid}`, SpanType.Prompt, {
1542
1540
  attributes,
1543
1541
  });
1544
1542
  }
1545
1543
  step(ctx, options) {
1546
- return this.segment(ctx, SegmentType.Step, undefined, options);
1544
+ return this.span(ctx, 'step', SpanType.Step, options);
1547
1545
  }
1548
1546
  }
1549
1547
 
1550
1548
  class LatitudeInstrumentation {
1551
1549
  options;
1552
1550
  telemetry;
1553
- constructor(source, tracer, options) {
1554
- this.telemetry = new ManualInstrumentation(source, tracer);
1551
+ constructor(tracer, options) {
1552
+ this.telemetry = new ManualInstrumentation(tracer);
1555
1553
  this.options = options;
1556
1554
  }
1557
1555
  isEnabled() {
@@ -1584,44 +1582,6 @@ class LatitudeInstrumentation {
1584
1582
  // Note: this is an estimation to not bundle a tokenizer
1585
1583
  return Math.ceil(length / 4);
1586
1584
  }
1587
- withTraceContext(ctx, fn) {
1588
- return context.with(this.telemetry.resume(ctx), fn);
1589
- }
1590
- async wrapToolHandler(fn, ...args) {
1591
- const toolArguments = args[0];
1592
- const { id, name } = args[1];
1593
- const $tool = this.telemetry.tool(context.active(), {
1594
- name,
1595
- call: {
1596
- id,
1597
- arguments: toolArguments,
1598
- },
1599
- });
1600
- let result;
1601
- try {
1602
- result = await context.with($tool.context, async () => await fn(...args));
1603
- }
1604
- catch (error) {
1605
- if (error.name === 'ToolExecutionPausedError') {
1606
- $tool.fail(error);
1607
- throw error;
1608
- }
1609
- $tool.end({
1610
- result: {
1611
- value: error.message,
1612
- isError: true,
1613
- },
1614
- });
1615
- throw error;
1616
- }
1617
- $tool.end({
1618
- result: {
1619
- value: result,
1620
- isError: false,
1621
- },
1622
- });
1623
- return result;
1624
- }
1625
1585
  async wrapRenderChain(fn, ...args) {
1626
1586
  const { prompt, parameters } = args[0];
1627
1587
  const $prompt = this.telemetry.prompt(context.active(), {
@@ -1711,8 +1671,8 @@ class LatitudeInstrumentation {
1711
1671
  }
1712
1672
  $tool.end({
1713
1673
  result: {
1714
- value: result,
1715
- isError: false, // Note: currently unknown
1674
+ value: result.result,
1675
+ isError: result.isError,
1716
1676
  },
1717
1677
  });
1718
1678
  return result;
@@ -1747,18 +1707,16 @@ const DEFAULT_SPAN_EXPORTER = (apiKey) => new OTLPTraceExporter({
1747
1707
  // Note: Only exporting typescript instrumentations
1748
1708
  var Instrumentation;
1749
1709
  (function (Instrumentation) {
1750
- Instrumentation["Latitude"] = "latitude";
1751
- Instrumentation["OpenAI"] = "openai";
1752
1710
  Instrumentation["Anthropic"] = "anthropic";
1753
- Instrumentation["AzureOpenAI"] = "azure";
1754
- Instrumentation["VercelAI"] = "vercelai";
1755
- Instrumentation["VertexAI"] = "vertexai";
1756
1711
  Instrumentation["AIPlatform"] = "aiplatform";
1757
1712
  Instrumentation["Bedrock"] = "bedrock";
1758
- Instrumentation["TogetherAI"] = "togetherai";
1759
1713
  Instrumentation["Cohere"] = "cohere";
1760
1714
  Instrumentation["Langchain"] = "langchain";
1715
+ Instrumentation["Latitude"] = "latitude";
1761
1716
  Instrumentation["LlamaIndex"] = "llamaindex";
1717
+ Instrumentation["OpenAI"] = "openai";
1718
+ Instrumentation["TogetherAI"] = "togetherai";
1719
+ Instrumentation["VertexAI"] = "vertexai";
1762
1720
  })(Instrumentation || (Instrumentation = {}));
1763
1721
  class LatitudeTelemetry {
1764
1722
  options;
@@ -1824,136 +1782,37 @@ class LatitudeTelemetry {
1824
1782
  initInstrumentations() {
1825
1783
  this.instrumentations = [];
1826
1784
  const tracer = this.tracer(InstrumentationScope.Manual);
1827
- this.telemetry = new ManualInstrumentation(SegmentSource.API, tracer);
1785
+ this.telemetry = new ManualInstrumentation(tracer);
1828
1786
  this.instrumentations.push(this.telemetry);
1829
1787
  const latitude = this.options.instrumentations?.latitude;
1830
1788
  if (latitude) {
1831
1789
  const tracer = this.tracer(Instrumentation.Latitude);
1832
- const instrumentation = new LatitudeInstrumentation(SegmentSource.API, tracer, typeof latitude === 'object' ? latitude : { module: latitude });
1833
- this.instrumentations.push(instrumentation);
1834
- }
1835
- const openai = this.options.instrumentations?.openai;
1836
- if (openai) {
1837
- const provider = this.tracerProvider(Instrumentation.OpenAI);
1838
- const instrumentation = new OpenAIInstrumentation({ enrichTokens: true });
1839
- instrumentation.setTracerProvider(provider);
1840
- instrumentation.manuallyInstrument(openai);
1841
- registerInstrumentations({
1842
- instrumentations: [instrumentation],
1843
- tracerProvider: provider,
1844
- });
1790
+ const instrumentation = new LatitudeInstrumentation(tracer, typeof latitude === 'object' ? latitude : { module: latitude });
1845
1791
  this.instrumentations.push(instrumentation);
1846
1792
  }
1847
- const anthropic = this.options.instrumentations?.anthropic;
1848
- if (anthropic) {
1849
- const provider = this.tracerProvider(Instrumentation.Anthropic);
1850
- const instrumentation = new AnthropicInstrumentation();
1793
+ const configureInstrumentation = (instrumentationType, InstrumentationConstructor, instrumentationOptions) => {
1794
+ const providerPkg = this.options.instrumentations?.[instrumentationType];
1795
+ const provider = this.tracerProvider(instrumentationType);
1796
+ const instrumentation = new InstrumentationConstructor(instrumentationOptions); // prettier-ignore
1851
1797
  instrumentation.setTracerProvider(provider);
1852
- instrumentation.manuallyInstrument(anthropic);
1853
- registerInstrumentations({
1854
- instrumentations: [instrumentation],
1855
- tracerProvider: provider,
1856
- });
1857
- this.instrumentations.push(instrumentation);
1858
- }
1859
- const azure = this.options.instrumentations?.azure;
1860
- if (azure) {
1861
- const provider = this.tracerProvider(Instrumentation.AzureOpenAI);
1862
- const instrumentation = new AzureOpenAIInstrumentation();
1863
- instrumentation.setTracerProvider(provider);
1864
- instrumentation.manuallyInstrument(azure);
1865
- registerInstrumentations({
1866
- instrumentations: [instrumentation],
1867
- tracerProvider: provider,
1868
- });
1869
- this.instrumentations.push(instrumentation);
1870
- }
1871
- const vertexai = this.options.instrumentations?.vertexai;
1872
- if (vertexai) {
1873
- const provider = this.tracerProvider(Instrumentation.VertexAI);
1874
- const instrumentation = new VertexAIInstrumentation();
1875
- instrumentation.setTracerProvider(provider);
1876
- instrumentation.manuallyInstrument(vertexai);
1877
- registerInstrumentations({
1878
- instrumentations: [instrumentation],
1879
- tracerProvider: provider,
1880
- });
1881
- this.instrumentations.push(instrumentation);
1882
- }
1883
- const aiplatform = this.options.instrumentations?.aiplatform;
1884
- if (aiplatform) {
1885
- const provider = this.tracerProvider(Instrumentation.AIPlatform);
1886
- const instrumentation = new AIPlatformInstrumentation();
1887
- instrumentation.setTracerProvider(provider);
1888
- instrumentation.manuallyInstrument(aiplatform);
1889
- registerInstrumentations({
1890
- instrumentations: [instrumentation],
1891
- tracerProvider: provider,
1892
- });
1893
- this.instrumentations.push(instrumentation);
1894
- }
1895
- const bedrock = this.options.instrumentations?.bedrock;
1896
- if (bedrock) {
1897
- const provider = this.tracerProvider(Instrumentation.Bedrock);
1898
- const instrumentation = new BedrockInstrumentation();
1899
- instrumentation.setTracerProvider(provider);
1900
- instrumentation.manuallyInstrument(bedrock);
1901
- registerInstrumentations({
1902
- instrumentations: [instrumentation],
1903
- tracerProvider: provider,
1904
- });
1905
- this.instrumentations.push(instrumentation);
1906
- }
1907
- const togetherai = this.options.instrumentations?.togetherai;
1908
- if (togetherai) {
1909
- const provider = this.tracerProvider(Instrumentation.TogetherAI);
1910
- const instrumentation = new TogetherInstrumentation({
1911
- enrichTokens: true,
1912
- });
1913
- instrumentation.setTracerProvider(provider);
1914
- instrumentation.manuallyInstrument(togetherai);
1915
- registerInstrumentations({
1916
- instrumentations: [instrumentation],
1917
- tracerProvider: provider,
1918
- });
1919
- this.instrumentations.push(instrumentation);
1920
- }
1921
- const cohere = this.options.instrumentations?.cohere;
1922
- if (cohere) {
1923
- const provider = this.tracerProvider(Instrumentation.Cohere);
1924
- const instrumentation = new CohereInstrumentation();
1925
- instrumentation.setTracerProvider(provider);
1926
- instrumentation.manuallyInstrument(cohere);
1927
- registerInstrumentations({
1928
- instrumentations: [instrumentation],
1929
- tracerProvider: provider,
1930
- });
1931
- this.instrumentations.push(instrumentation);
1932
- }
1933
- const langchain = this.options.instrumentations?.langchain;
1934
- if (langchain) {
1935
- const provider = this.tracerProvider(Instrumentation.Langchain);
1936
- const instrumentation = new LangChainInstrumentation();
1937
- instrumentation.setTracerProvider(provider);
1938
- instrumentation.manuallyInstrument(langchain);
1939
- registerInstrumentations({
1940
- instrumentations: [instrumentation],
1941
- tracerProvider: provider,
1942
- });
1943
- this.instrumentations.push(instrumentation);
1944
- }
1945
- const llamaindex = this.options.instrumentations?.llamaindex;
1946
- if (llamaindex) {
1947
- const provider = this.tracerProvider(Instrumentation.LlamaIndex);
1948
- const instrumentation = new LlamaIndexInstrumentation();
1949
- instrumentation.setTracerProvider(provider);
1950
- instrumentation.manuallyInstrument(llamaindex);
1798
+ if (providerPkg) {
1799
+ instrumentation.manuallyInstrument(providerPkg);
1800
+ }
1951
1801
  registerInstrumentations({
1952
1802
  instrumentations: [instrumentation],
1953
1803
  tracerProvider: provider,
1954
1804
  });
1955
1805
  this.instrumentations.push(instrumentation);
1956
- }
1806
+ };
1807
+ configureInstrumentation(Instrumentation.Anthropic, AnthropicInstrumentation); // prettier-ignore
1808
+ configureInstrumentation(Instrumentation.AIPlatform, AIPlatformInstrumentation); // prettier-ignore
1809
+ configureInstrumentation(Instrumentation.Bedrock, BedrockInstrumentation); // prettier-ignore
1810
+ configureInstrumentation(Instrumentation.Cohere, CohereInstrumentation); // prettier-ignore
1811
+ configureInstrumentation(Instrumentation.Langchain, LangChainInstrumentation); // prettier-ignore
1812
+ configureInstrumentation(Instrumentation.LlamaIndex, LlamaIndexInstrumentation); // prettier-ignore
1813
+ configureInstrumentation(Instrumentation.OpenAI, OpenAIInstrumentation, { enrichTokens: true }); // prettier-ignore
1814
+ configureInstrumentation(Instrumentation.TogetherAI, TogetherInstrumentation, { enrichTokens: true }); // prettier-ignore
1815
+ configureInstrumentation(Instrumentation.VertexAI, VertexAIInstrumentation); // prettier-ignore
1957
1816
  }
1958
1817
  instrument() {
1959
1818
  this.instrumentations.forEach((instrumentation) => {
@@ -1967,21 +1826,9 @@ class LatitudeTelemetry {
1967
1826
  instrumentation.disable();
1968
1827
  });
1969
1828
  }
1970
- baggage(ctx) {
1971
- return this.telemetry.baggage(ctx);
1972
- }
1973
- pause(ctx) {
1974
- return this.telemetry.pause(ctx);
1975
- }
1976
1829
  resume(ctx) {
1977
1830
  return this.telemetry.resume(ctx);
1978
1831
  }
1979
- restored(ctx) {
1980
- return this.telemetry.restored(ctx);
1981
- }
1982
- restore(ctx) {
1983
- return this.telemetry.restore(ctx);
1984
- }
1985
1832
  tool(ctx, options) {
1986
1833
  return this.telemetry.tool(ctx, options);
1987
1834
  }