@latitude-data/telemetry 1.0.4 → 1.1.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.cjs +343 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +194 -62
- package/dist/index.js +344 -103
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,7 @@ var zod = require('zod');
|
|
|
4
4
|
var otel = require('@opentelemetry/api');
|
|
5
5
|
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
6
6
|
var incubating = require('@opentelemetry/semantic-conventions/incubating');
|
|
7
|
+
var uuid = require('uuid');
|
|
7
8
|
var baggageSpanProcessor = require('@opentelemetry/baggage-span-processor');
|
|
8
9
|
var contextAsyncHooks = require('@opentelemetry/context-async-hooks');
|
|
9
10
|
var core = require('@opentelemetry/core');
|
|
@@ -94,7 +95,7 @@ const DEFAULT_REDACT_SPAN_PROCESSOR = () => new RedactSpanProcessor({
|
|
|
94
95
|
attributes: [
|
|
95
96
|
/^.*auth.*$/i,
|
|
96
97
|
/^.*authorization.*$/i,
|
|
97
|
-
/^(?!
|
|
98
|
+
/^(?!gen_ai\.).*usage.*$/i,
|
|
98
99
|
/^(?!gen_ai\.).*token.*$/i,
|
|
99
100
|
/^.*secret.*$/i,
|
|
100
101
|
/^.*key.*$/i,
|
|
@@ -208,6 +209,7 @@ const compositeEvaluationConfiguration = baseEvaluationConfiguration.extend({
|
|
|
208
209
|
evaluationUuids: zod.z.array(zod.z.string()),
|
|
209
210
|
minThreshold: zod.z.number().optional(), // Threshold percentage
|
|
210
211
|
maxThreshold: zod.z.number().optional(), // Threshold percentage
|
|
212
|
+
defaultTarget: zod.z.boolean().optional(), // Default for optimizations and distillations
|
|
211
213
|
});
|
|
212
214
|
const compositeEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
|
|
213
215
|
results: zod.z.record(zod.z.string(), // Evaluation uuid
|
|
@@ -275,7 +277,7 @@ const CompositeEvaluationSpecification = {
|
|
|
275
277
|
};
|
|
276
278
|
|
|
277
279
|
const humanEvaluationConfiguration = baseEvaluationConfiguration.extend({
|
|
278
|
-
enableControls: zod.z.boolean().optional(),
|
|
280
|
+
enableControls: zod.z.boolean().optional(), // UI annotation controls
|
|
279
281
|
criteria: zod.z.string().optional(),
|
|
280
282
|
});
|
|
281
283
|
const humanEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
|
|
@@ -803,6 +805,9 @@ var SpanType;
|
|
|
803
805
|
SpanType["Http"] = "http";
|
|
804
806
|
SpanType["Unknown"] = "unknown";
|
|
805
807
|
SpanType["Prompt"] = "prompt";
|
|
808
|
+
SpanType["Chat"] = "chat";
|
|
809
|
+
SpanType["External"] = "external";
|
|
810
|
+
SpanType["UnresolvedExternal"] = "unresolved_external";
|
|
806
811
|
SpanType["Step"] = "step";
|
|
807
812
|
})(SpanType || (SpanType = {}));
|
|
808
813
|
const SPAN_SPECIFICATIONS = {
|
|
@@ -854,6 +859,24 @@ const SPAN_SPECIFICATIONS = {
|
|
|
854
859
|
isGenAI: false,
|
|
855
860
|
isHidden: false,
|
|
856
861
|
},
|
|
862
|
+
[SpanType.Chat]: {
|
|
863
|
+
name: 'Chat',
|
|
864
|
+
description: 'A chat continuation span',
|
|
865
|
+
isGenAI: false,
|
|
866
|
+
isHidden: false,
|
|
867
|
+
},
|
|
868
|
+
[SpanType.External]: {
|
|
869
|
+
name: 'External',
|
|
870
|
+
description: 'An external capture span',
|
|
871
|
+
isGenAI: false,
|
|
872
|
+
isHidden: false,
|
|
873
|
+
},
|
|
874
|
+
[SpanType.UnresolvedExternal]: {
|
|
875
|
+
name: 'Unresolved External',
|
|
876
|
+
description: 'An external span that needs path resolution before storage',
|
|
877
|
+
isGenAI: false,
|
|
878
|
+
isHidden: true,
|
|
879
|
+
},
|
|
857
880
|
[SpanType.Step]: {
|
|
858
881
|
name: 'Step',
|
|
859
882
|
description: 'A step span',
|
|
@@ -907,7 +930,16 @@ var InstrumentationScope;
|
|
|
907
930
|
/* Note: non-standard OpenTelemetry semantic conventions used in Latitude */
|
|
908
931
|
const ATTR_LATITUDE = 'latitude';
|
|
909
932
|
const ATTR_LATITUDE_TYPE = `${ATTR_LATITUDE}.type`;
|
|
933
|
+
const ATTR_LATITUDE_DOCUMENT_UUID = `${ATTR_LATITUDE}.document_uuid`;
|
|
934
|
+
const ATTR_LATITUDE_PROMPT_PATH = `${ATTR_LATITUDE}.prompt_path`;
|
|
935
|
+
const ATTR_LATITUDE_COMMIT_UUID = `${ATTR_LATITUDE}.commit_uuid`;
|
|
936
|
+
const ATTR_LATITUDE_DOCUMENT_LOG_UUID = `${ATTR_LATITUDE}.document_log_uuid`;
|
|
937
|
+
const ATTR_LATITUDE_PROJECT_ID = `${ATTR_LATITUDE}.project_id`;
|
|
938
|
+
const ATTR_LATITUDE_EXPERIMENT_UUID = `${ATTR_LATITUDE}.experiment_uuid`;
|
|
939
|
+
const ATTR_LATITUDE_SOURCE = `${ATTR_LATITUDE}.source`;
|
|
940
|
+
const ATTR_LATITUDE_EXTERNAL_ID = `${ATTR_LATITUDE}.external_id`;
|
|
910
941
|
const ATTR_LATITUDE_TEST_DEPLOYMENT_ID = `${ATTR_LATITUDE}.test_deployment_id`;
|
|
942
|
+
const ATTR_LATITUDE_PREVIOUS_TRACE_ID = `${ATTR_LATITUDE}.previous_trace_id`;
|
|
911
943
|
const GEN_AI_TOOL_TYPE_VALUE_FUNCTION = 'function';
|
|
912
944
|
const ATTR_GEN_AI_TOOL_CALL_ARGUMENTS = 'gen_ai.tool.call.arguments';
|
|
913
945
|
const ATTR_GEN_AI_TOOL_RESULT_VALUE = 'gen_ai.tool.result.value';
|
|
@@ -1064,6 +1096,7 @@ var DocumentTriggerParameters;
|
|
|
1064
1096
|
DocumentTriggerParameters["Body"] = "body";
|
|
1065
1097
|
DocumentTriggerParameters["Attachments"] = "attachments";
|
|
1066
1098
|
})(DocumentTriggerParameters || (DocumentTriggerParameters = {}));
|
|
1099
|
+
const DOCUMENT_PATH_REGEXP = /^([\w-]+\/)*([\w-.])+$/;
|
|
1067
1100
|
|
|
1068
1101
|
class ManualInstrumentation {
|
|
1069
1102
|
enabled;
|
|
@@ -1082,7 +1115,33 @@ class ManualInstrumentation {
|
|
|
1082
1115
|
this.enabled = false;
|
|
1083
1116
|
}
|
|
1084
1117
|
resume(ctx) {
|
|
1085
|
-
|
|
1118
|
+
const parts = ctx.traceparent.split('-');
|
|
1119
|
+
if (parts.length !== 4) {
|
|
1120
|
+
return otel__namespace.ROOT_CONTEXT;
|
|
1121
|
+
}
|
|
1122
|
+
const [, traceId, spanId, flags] = parts;
|
|
1123
|
+
if (!traceId || !spanId) {
|
|
1124
|
+
return otel__namespace.ROOT_CONTEXT;
|
|
1125
|
+
}
|
|
1126
|
+
const spanContext = {
|
|
1127
|
+
traceId,
|
|
1128
|
+
spanId,
|
|
1129
|
+
traceFlags: parseInt(flags ?? '01', 16),
|
|
1130
|
+
isRemote: true,
|
|
1131
|
+
};
|
|
1132
|
+
let context = otel.trace.setSpanContext(otel__namespace.ROOT_CONTEXT, spanContext);
|
|
1133
|
+
if (ctx.baggage) {
|
|
1134
|
+
const baggageEntries = {};
|
|
1135
|
+
for (const pair of ctx.baggage.split(',')) {
|
|
1136
|
+
const [key, value] = pair.split('=');
|
|
1137
|
+
if (key && value) {
|
|
1138
|
+
baggageEntries[key] = { value: decodeURIComponent(value) };
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
const baggage = otel.propagation.createBaggage(baggageEntries);
|
|
1142
|
+
context = otel.propagation.setBaggage(context, baggage);
|
|
1143
|
+
}
|
|
1144
|
+
return context;
|
|
1086
1145
|
}
|
|
1087
1146
|
capitalize(str) {
|
|
1088
1147
|
if (str.length === 0)
|
|
@@ -1389,7 +1448,7 @@ class ManualInstrumentation {
|
|
|
1389
1448
|
completion(ctx, options) {
|
|
1390
1449
|
const start = options;
|
|
1391
1450
|
const configuration = {
|
|
1392
|
-
...start.configuration,
|
|
1451
|
+
...(start.configuration ?? {}),
|
|
1393
1452
|
model: start.model,
|
|
1394
1453
|
};
|
|
1395
1454
|
let jsonConfiguration = '';
|
|
@@ -1400,14 +1459,15 @@ class ManualInstrumentation {
|
|
|
1400
1459
|
jsonConfiguration = '{}';
|
|
1401
1460
|
}
|
|
1402
1461
|
const attrConfiguration = this.attribifyConfiguration('input', configuration);
|
|
1462
|
+
const input = start.input ?? [];
|
|
1403
1463
|
let jsonInput = '';
|
|
1404
1464
|
try {
|
|
1405
|
-
jsonInput = JSON.stringify(
|
|
1465
|
+
jsonInput = JSON.stringify(input);
|
|
1406
1466
|
}
|
|
1407
1467
|
catch (error) {
|
|
1408
1468
|
jsonInput = '[]';
|
|
1409
1469
|
}
|
|
1410
|
-
const attrInput = this.attribifyMessages('input',
|
|
1470
|
+
const attrInput = this.attribifyMessages('input', input);
|
|
1411
1471
|
const span = this.span(ctx, start.name || `${start.provider} / ${start.model}`, SpanType.Completion, {
|
|
1412
1472
|
attributes: {
|
|
1413
1473
|
[incubating.ATTR_GEN_AI_SYSTEM]: start.provider,
|
|
@@ -1416,37 +1476,45 @@ class ManualInstrumentation {
|
|
|
1416
1476
|
[ATTR_GEN_AI_REQUEST_MESSAGES]: jsonInput,
|
|
1417
1477
|
...attrInput,
|
|
1418
1478
|
...(start.attributes || {}),
|
|
1419
|
-
[
|
|
1420
|
-
[
|
|
1421
|
-
[
|
|
1479
|
+
[ATTR_LATITUDE_COMMIT_UUID]: start.versionUuid,
|
|
1480
|
+
[ATTR_LATITUDE_DOCUMENT_UUID]: start.promptUuid,
|
|
1481
|
+
[ATTR_LATITUDE_EXPERIMENT_UUID]: start.experimentUuid,
|
|
1422
1482
|
},
|
|
1423
1483
|
});
|
|
1424
1484
|
return {
|
|
1425
1485
|
context: span.context,
|
|
1426
1486
|
end: (options) => {
|
|
1427
|
-
const end = options;
|
|
1487
|
+
const end = options ?? {};
|
|
1488
|
+
const output = end.output ?? [];
|
|
1428
1489
|
let jsonOutput = '';
|
|
1429
1490
|
try {
|
|
1430
|
-
jsonOutput = JSON.stringify(
|
|
1491
|
+
jsonOutput = JSON.stringify(output);
|
|
1431
1492
|
}
|
|
1432
1493
|
catch (error) {
|
|
1433
1494
|
jsonOutput = '[]';
|
|
1434
1495
|
}
|
|
1435
|
-
const attrOutput = this.attribifyMessages('output',
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1496
|
+
const attrOutput = this.attribifyMessages('output', output);
|
|
1497
|
+
const tokens = {
|
|
1498
|
+
prompt: end.tokens?.prompt ?? 0,
|
|
1499
|
+
cached: end.tokens?.cached ?? 0,
|
|
1500
|
+
reasoning: end.tokens?.reasoning ?? 0,
|
|
1501
|
+
completion: end.tokens?.completion ?? 0,
|
|
1502
|
+
};
|
|
1503
|
+
const inputTokens = tokens.prompt + tokens.cached;
|
|
1504
|
+
const outputTokens = tokens.reasoning + tokens.completion;
|
|
1505
|
+
const finishReason = end.finishReason ?? '';
|
|
1438
1506
|
span.end({
|
|
1439
1507
|
attributes: {
|
|
1440
1508
|
[ATTR_GEN_AI_RESPONSE_MESSAGES]: jsonOutput,
|
|
1441
1509
|
...attrOutput,
|
|
1442
1510
|
[incubating.ATTR_GEN_AI_USAGE_INPUT_TOKENS]: inputTokens,
|
|
1443
|
-
[ATTR_GEN_AI_USAGE_PROMPT_TOKENS]:
|
|
1444
|
-
[ATTR_GEN_AI_USAGE_CACHED_TOKENS]:
|
|
1445
|
-
[ATTR_GEN_AI_USAGE_REASONING_TOKENS]:
|
|
1446
|
-
[ATTR_GEN_AI_USAGE_COMPLETION_TOKENS]:
|
|
1511
|
+
[ATTR_GEN_AI_USAGE_PROMPT_TOKENS]: tokens.prompt,
|
|
1512
|
+
[ATTR_GEN_AI_USAGE_CACHED_TOKENS]: tokens.cached,
|
|
1513
|
+
[ATTR_GEN_AI_USAGE_REASONING_TOKENS]: tokens.reasoning,
|
|
1514
|
+
[ATTR_GEN_AI_USAGE_COMPLETION_TOKENS]: tokens.completion,
|
|
1447
1515
|
[incubating.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS]: outputTokens,
|
|
1448
1516
|
[incubating.ATTR_GEN_AI_RESPONSE_MODEL]: start.model,
|
|
1449
|
-
[incubating.ATTR_GEN_AI_RESPONSE_FINISH_REASONS]: [
|
|
1517
|
+
[incubating.ATTR_GEN_AI_RESPONSE_FINISH_REASONS]: [finishReason],
|
|
1450
1518
|
...(end.attributes || {}),
|
|
1451
1519
|
},
|
|
1452
1520
|
});
|
|
@@ -1544,16 +1612,18 @@ class ManualInstrumentation {
|
|
|
1544
1612
|
const attributes = {
|
|
1545
1613
|
[ATTR_GEN_AI_REQUEST_TEMPLATE]: template,
|
|
1546
1614
|
[ATTR_GEN_AI_REQUEST_PARAMETERS]: jsonParameters,
|
|
1547
|
-
[
|
|
1548
|
-
[
|
|
1549
|
-
[
|
|
1550
|
-
|
|
1551
|
-
...(experimentUuid && {
|
|
1615
|
+
[ATTR_LATITUDE_COMMIT_UUID]: versionUuid || HEAD_COMMIT,
|
|
1616
|
+
[ATTR_LATITUDE_DOCUMENT_UUID]: promptUuid,
|
|
1617
|
+
[ATTR_LATITUDE_PROJECT_ID]: projectId,
|
|
1618
|
+
[ATTR_LATITUDE_DOCUMENT_LOG_UUID]: documentLogUuid,
|
|
1619
|
+
...(experimentUuid && {
|
|
1620
|
+
[ATTR_LATITUDE_EXPERIMENT_UUID]: experimentUuid,
|
|
1621
|
+
}),
|
|
1552
1622
|
...(testDeploymentId && {
|
|
1553
1623
|
[ATTR_LATITUDE_TEST_DEPLOYMENT_ID]: testDeploymentId,
|
|
1554
1624
|
}),
|
|
1555
|
-
...(externalId && { [
|
|
1556
|
-
...(source && { [
|
|
1625
|
+
...(externalId && { [ATTR_LATITUDE_EXTERNAL_ID]: externalId }),
|
|
1626
|
+
...(source && { [ATTR_LATITUDE_SOURCE]: source }),
|
|
1557
1627
|
...(rest.attributes || {}),
|
|
1558
1628
|
};
|
|
1559
1629
|
return this.span(ctx, name || `prompt-${promptUuid}`, SpanType.Prompt, {
|
|
@@ -1563,24 +1633,58 @@ class ManualInstrumentation {
|
|
|
1563
1633
|
step(ctx, options) {
|
|
1564
1634
|
return this.span(ctx, 'step', SpanType.Step, options);
|
|
1565
1635
|
}
|
|
1636
|
+
chat(ctx, { documentLogUuid, previousTraceId, source, name, ...rest }) {
|
|
1637
|
+
const attributes = {
|
|
1638
|
+
[ATTR_LATITUDE_DOCUMENT_LOG_UUID]: documentLogUuid,
|
|
1639
|
+
[ATTR_LATITUDE_PREVIOUS_TRACE_ID]: previousTraceId,
|
|
1640
|
+
...(source && { [ATTR_LATITUDE_SOURCE]: source }),
|
|
1641
|
+
...(rest.attributes || {}),
|
|
1642
|
+
};
|
|
1643
|
+
return this.span(ctx, name || 'chat', SpanType.Chat, { attributes });
|
|
1644
|
+
}
|
|
1645
|
+
external(ctx, { promptUuid, documentLogUuid, source, versionUuid, externalId, name, ...rest }) {
|
|
1646
|
+
const attributes = {
|
|
1647
|
+
[ATTR_LATITUDE_DOCUMENT_UUID]: promptUuid,
|
|
1648
|
+
[ATTR_LATITUDE_DOCUMENT_LOG_UUID]: documentLogUuid,
|
|
1649
|
+
[ATTR_LATITUDE_SOURCE]: source ?? LogSources.API,
|
|
1650
|
+
...(versionUuid && { [ATTR_LATITUDE_COMMIT_UUID]: versionUuid }),
|
|
1651
|
+
...(externalId && { [ATTR_LATITUDE_EXTERNAL_ID]: externalId }),
|
|
1652
|
+
...(rest.attributes || {}),
|
|
1653
|
+
};
|
|
1654
|
+
return this.span(ctx, name || `external-${promptUuid}`, SpanType.External, {
|
|
1655
|
+
attributes,
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
unresolvedExternal(ctx, { path, projectId, versionUuid, conversationUuid, name, ...rest }) {
|
|
1659
|
+
const attributes = {
|
|
1660
|
+
[ATTR_LATITUDE_PROMPT_PATH]: path,
|
|
1661
|
+
[ATTR_LATITUDE_PROJECT_ID]: projectId,
|
|
1662
|
+
...(versionUuid && { [ATTR_LATITUDE_COMMIT_UUID]: versionUuid }),
|
|
1663
|
+
...(conversationUuid && {
|
|
1664
|
+
[ATTR_LATITUDE_DOCUMENT_LOG_UUID]: conversationUuid,
|
|
1665
|
+
}),
|
|
1666
|
+
...(rest.attributes || {}),
|
|
1667
|
+
};
|
|
1668
|
+
return this.span(ctx, name || `capture-${path}`, SpanType.UnresolvedExternal, { attributes });
|
|
1669
|
+
}
|
|
1566
1670
|
}
|
|
1567
1671
|
|
|
1568
1672
|
class LatitudeInstrumentation {
|
|
1569
1673
|
options;
|
|
1570
|
-
|
|
1674
|
+
manualTelemetry;
|
|
1571
1675
|
constructor(tracer, options) {
|
|
1572
|
-
this.
|
|
1676
|
+
this.manualTelemetry = new ManualInstrumentation(tracer);
|
|
1573
1677
|
this.options = options;
|
|
1574
1678
|
}
|
|
1575
1679
|
isEnabled() {
|
|
1576
|
-
return this.
|
|
1680
|
+
return this.manualTelemetry.isEnabled();
|
|
1577
1681
|
}
|
|
1578
1682
|
enable() {
|
|
1579
1683
|
this.options.module.instrument(this);
|
|
1580
|
-
this.
|
|
1684
|
+
this.manualTelemetry.enable();
|
|
1581
1685
|
}
|
|
1582
1686
|
disable() {
|
|
1583
|
-
this.
|
|
1687
|
+
this.manualTelemetry.disable();
|
|
1584
1688
|
this.options.module.uninstrument();
|
|
1585
1689
|
}
|
|
1586
1690
|
countTokens(messages) {
|
|
@@ -1604,7 +1708,8 @@ class LatitudeInstrumentation {
|
|
|
1604
1708
|
}
|
|
1605
1709
|
async wrapRenderChain(fn, ...args) {
|
|
1606
1710
|
const { prompt, parameters } = args[0];
|
|
1607
|
-
const $prompt = this.
|
|
1711
|
+
const $prompt = this.manualTelemetry.prompt(otel.context.active(), {
|
|
1712
|
+
documentLogUuid: uuid.v4(),
|
|
1608
1713
|
versionUuid: prompt.versionUuid,
|
|
1609
1714
|
promptUuid: prompt.uuid,
|
|
1610
1715
|
template: prompt.content,
|
|
@@ -1622,7 +1727,7 @@ class LatitudeInstrumentation {
|
|
|
1622
1727
|
return result;
|
|
1623
1728
|
}
|
|
1624
1729
|
async wrapRenderStep(fn, ...args) {
|
|
1625
|
-
const $step = this.
|
|
1730
|
+
const $step = this.manualTelemetry.step(otel.context.active());
|
|
1626
1731
|
let result;
|
|
1627
1732
|
try {
|
|
1628
1733
|
result = await otel.context.with($step.context, async () => await fn(...args));
|
|
@@ -1640,7 +1745,7 @@ class LatitudeInstrumentation {
|
|
|
1640
1745
|
}
|
|
1641
1746
|
const { provider, config, messages } = args[0];
|
|
1642
1747
|
const model = config.model || 'unknown';
|
|
1643
|
-
const $completion = this.
|
|
1748
|
+
const $completion = this.manualTelemetry.completion(otel.context.active(), {
|
|
1644
1749
|
name: `${provider} / ${model}`,
|
|
1645
1750
|
provider: provider,
|
|
1646
1751
|
model: model,
|
|
@@ -1674,7 +1779,7 @@ class LatitudeInstrumentation {
|
|
|
1674
1779
|
}
|
|
1675
1780
|
async wrapRenderTool(fn, ...args) {
|
|
1676
1781
|
const { toolRequest } = args[0];
|
|
1677
|
-
const $tool = this.
|
|
1782
|
+
const $tool = this.manualTelemetry.tool(otel.context.active(), {
|
|
1678
1783
|
name: toolRequest.toolName,
|
|
1679
1784
|
call: {
|
|
1680
1785
|
id: toolRequest.toolCallId,
|
|
@@ -1699,10 +1804,165 @@ class LatitudeInstrumentation {
|
|
|
1699
1804
|
}
|
|
1700
1805
|
}
|
|
1701
1806
|
|
|
1807
|
+
var LatitudeErrorCodes;
|
|
1808
|
+
(function (LatitudeErrorCodes) {
|
|
1809
|
+
LatitudeErrorCodes["UnexpectedError"] = "UnexpectedError";
|
|
1810
|
+
LatitudeErrorCodes["OverloadedError"] = "OverloadedError";
|
|
1811
|
+
LatitudeErrorCodes["RateLimitError"] = "RateLimitError";
|
|
1812
|
+
LatitudeErrorCodes["UnauthorizedError"] = "UnauthorizedError";
|
|
1813
|
+
LatitudeErrorCodes["ForbiddenError"] = "ForbiddenError";
|
|
1814
|
+
LatitudeErrorCodes["BadRequestError"] = "BadRequestError";
|
|
1815
|
+
LatitudeErrorCodes["NotFoundError"] = "NotFoundError";
|
|
1816
|
+
LatitudeErrorCodes["ConflictError"] = "ConflictError";
|
|
1817
|
+
LatitudeErrorCodes["UnprocessableEntityError"] = "UnprocessableEntityError";
|
|
1818
|
+
LatitudeErrorCodes["NotImplementedError"] = "NotImplementedError";
|
|
1819
|
+
LatitudeErrorCodes["PaymentRequiredError"] = "PaymentRequiredError";
|
|
1820
|
+
LatitudeErrorCodes["AbortedError"] = "AbortedError";
|
|
1821
|
+
})(LatitudeErrorCodes || (LatitudeErrorCodes = {}));
|
|
1822
|
+
// NOTE: If you add a new error code, please add it to the pg enum in models/runErrors.ts
|
|
1823
|
+
var RunErrorCodes;
|
|
1824
|
+
(function (RunErrorCodes) {
|
|
1825
|
+
RunErrorCodes["AIProviderConfigError"] = "ai_provider_config_error";
|
|
1826
|
+
RunErrorCodes["AIRunError"] = "ai_run_error";
|
|
1827
|
+
RunErrorCodes["ChainCompileError"] = "chain_compile_error";
|
|
1828
|
+
RunErrorCodes["DefaultProviderExceededQuota"] = "default_provider_exceeded_quota_error";
|
|
1829
|
+
RunErrorCodes["DefaultProviderInvalidModel"] = "default_provider_invalid_model_error";
|
|
1830
|
+
RunErrorCodes["DocumentConfigError"] = "document_config_error";
|
|
1831
|
+
RunErrorCodes["ErrorGeneratingMockToolResult"] = "error_generating_mock_tool_result";
|
|
1832
|
+
RunErrorCodes["FailedToWakeUpIntegrationError"] = "failed_to_wake_up_integration_error";
|
|
1833
|
+
RunErrorCodes["InvalidResponseFormatError"] = "invalid_response_format_error";
|
|
1834
|
+
RunErrorCodes["MaxStepCountExceededError"] = "max_step_count_exceeded_error";
|
|
1835
|
+
RunErrorCodes["MissingProvider"] = "missing_provider_error";
|
|
1836
|
+
RunErrorCodes["RateLimit"] = "rate_limit_error";
|
|
1837
|
+
RunErrorCodes["Unknown"] = "unknown_error";
|
|
1838
|
+
RunErrorCodes["UnsupportedProviderResponseTypeError"] = "unsupported_provider_response_type_error";
|
|
1839
|
+
RunErrorCodes["PaymentRequiredError"] = "payment_required_error";
|
|
1840
|
+
RunErrorCodes["AbortError"] = "abort_error";
|
|
1841
|
+
// DEPRECATED, but do not delete
|
|
1842
|
+
RunErrorCodes["EvaluationRunMissingProviderLogError"] = "ev_run_missing_provider_log_error";
|
|
1843
|
+
RunErrorCodes["EvaluationRunMissingWorkspaceError"] = "ev_run_missing_workspace_error";
|
|
1844
|
+
RunErrorCodes["EvaluationRunResponseJsonFormatError"] = "ev_run_response_json_format_error";
|
|
1845
|
+
RunErrorCodes["EvaluationRunUnsupportedResultTypeError"] = "ev_run_unsupported_result_type_error";
|
|
1846
|
+
})(RunErrorCodes || (RunErrorCodes = {}));
|
|
1847
|
+
var ApiErrorCodes;
|
|
1848
|
+
(function (ApiErrorCodes) {
|
|
1849
|
+
ApiErrorCodes["HTTPException"] = "http_exception";
|
|
1850
|
+
ApiErrorCodes["InternalServerError"] = "internal_server_error";
|
|
1851
|
+
})(ApiErrorCodes || (ApiErrorCodes = {}));
|
|
1852
|
+
|
|
1853
|
+
class LatitudeError extends Error {
|
|
1854
|
+
statusCode = 500;
|
|
1855
|
+
name = LatitudeErrorCodes.UnexpectedError;
|
|
1856
|
+
headers = {};
|
|
1857
|
+
details;
|
|
1858
|
+
constructor(message, details, status, name) {
|
|
1859
|
+
super(message);
|
|
1860
|
+
this.details = details ?? {};
|
|
1861
|
+
this.statusCode = status ?? this.statusCode;
|
|
1862
|
+
this.name = name ?? this.constructor.name;
|
|
1863
|
+
}
|
|
1864
|
+
serialize() {
|
|
1865
|
+
return {
|
|
1866
|
+
name: this.name,
|
|
1867
|
+
code: this.name,
|
|
1868
|
+
status: this.statusCode,
|
|
1869
|
+
message: this.message,
|
|
1870
|
+
details: this.details,
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
static deserialize(json) {
|
|
1874
|
+
return new LatitudeError(json.message, json.details, json.status, json.name);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
class BadRequestError extends LatitudeError {
|
|
1878
|
+
statusCode = 400;
|
|
1879
|
+
name = LatitudeErrorCodes.BadRequestError;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1702
1882
|
const TRACES_URL = `${env.GATEWAY_BASE_URL}/api/v3/traces`;
|
|
1703
1883
|
const SERVICE_NAME = process.env.npm_package_name || 'unknown';
|
|
1704
1884
|
const SCOPE_VERSION = process.env.npm_package_version || 'unknown';
|
|
1705
1885
|
const BACKGROUND = () => otel__namespace.ROOT_CONTEXT;
|
|
1886
|
+
class SpanFactory {
|
|
1887
|
+
telemetry;
|
|
1888
|
+
constructor(telemetry) {
|
|
1889
|
+
this.telemetry = telemetry;
|
|
1890
|
+
}
|
|
1891
|
+
tool(options, ctx) {
|
|
1892
|
+
return this.telemetry.tool(ctx ?? otel.context.active(), options);
|
|
1893
|
+
}
|
|
1894
|
+
completion(options, ctx) {
|
|
1895
|
+
return this.telemetry.completion(ctx ?? otel.context.active(), options);
|
|
1896
|
+
}
|
|
1897
|
+
embedding(options, ctx) {
|
|
1898
|
+
return this.telemetry.embedding(ctx ?? otel.context.active(), options);
|
|
1899
|
+
}
|
|
1900
|
+
retrieval(options, ctx) {
|
|
1901
|
+
return this.telemetry.retrieval(ctx ?? otel.context.active(), options);
|
|
1902
|
+
}
|
|
1903
|
+
reranking(options, ctx) {
|
|
1904
|
+
return this.telemetry.reranking(ctx ?? otel.context.active(), options);
|
|
1905
|
+
}
|
|
1906
|
+
http(options, ctx) {
|
|
1907
|
+
return this.telemetry.http(ctx ?? otel.context.active(), options);
|
|
1908
|
+
}
|
|
1909
|
+
prompt(options, ctx) {
|
|
1910
|
+
return this.telemetry.prompt(ctx ?? otel.context.active(), options);
|
|
1911
|
+
}
|
|
1912
|
+
step(options, ctx) {
|
|
1913
|
+
return this.telemetry.step(ctx ?? otel.context.active(), options);
|
|
1914
|
+
}
|
|
1915
|
+
chat(options, ctx) {
|
|
1916
|
+
return this.telemetry.chat(ctx ?? otel.context.active(), options);
|
|
1917
|
+
}
|
|
1918
|
+
external(options, ctx) {
|
|
1919
|
+
return this.telemetry.external(ctx ?? otel.context.active(), options);
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
class ContextManager {
|
|
1923
|
+
telemetry;
|
|
1924
|
+
constructor(telemetry) {
|
|
1925
|
+
this.telemetry = telemetry;
|
|
1926
|
+
}
|
|
1927
|
+
resume(ctx) {
|
|
1928
|
+
return this.telemetry.resume(ctx);
|
|
1929
|
+
}
|
|
1930
|
+
active() {
|
|
1931
|
+
return otel.context.active();
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
class InstrumentationManager {
|
|
1935
|
+
instrumentations;
|
|
1936
|
+
constructor(instrumentations) {
|
|
1937
|
+
this.instrumentations = instrumentations;
|
|
1938
|
+
}
|
|
1939
|
+
enable() {
|
|
1940
|
+
this.instrumentations.forEach((instrumentation) => {
|
|
1941
|
+
if (!instrumentation.isEnabled())
|
|
1942
|
+
instrumentation.enable();
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
disable() {
|
|
1946
|
+
this.instrumentations.forEach((instrumentation) => {
|
|
1947
|
+
if (instrumentation.isEnabled())
|
|
1948
|
+
instrumentation.disable();
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
class TracerManager {
|
|
1953
|
+
nodeProvider;
|
|
1954
|
+
scopeVersion;
|
|
1955
|
+
constructor(nodeProvider, scopeVersion) {
|
|
1956
|
+
this.nodeProvider = nodeProvider;
|
|
1957
|
+
this.scopeVersion = scopeVersion;
|
|
1958
|
+
}
|
|
1959
|
+
get(scope) {
|
|
1960
|
+
return this.provider(scope).getTracer('');
|
|
1961
|
+
}
|
|
1962
|
+
provider(scope) {
|
|
1963
|
+
return new ScopedTracerProvider(`${SCOPE_LATITUDE}.${scope}`, this.scopeVersion, this.nodeProvider);
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1706
1966
|
class ScopedTracerProvider {
|
|
1707
1967
|
scope;
|
|
1708
1968
|
version;
|
|
@@ -1740,9 +2000,13 @@ exports.Instrumentation = void 0;
|
|
|
1740
2000
|
})(exports.Instrumentation || (exports.Instrumentation = {}));
|
|
1741
2001
|
class LatitudeTelemetry {
|
|
1742
2002
|
options;
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
2003
|
+
nodeProvider;
|
|
2004
|
+
manualInstrumentation;
|
|
2005
|
+
instrumentationsList;
|
|
2006
|
+
span;
|
|
2007
|
+
context;
|
|
2008
|
+
instrumentation;
|
|
2009
|
+
tracer;
|
|
1746
2010
|
constructor(apiKey, options) {
|
|
1747
2011
|
this.options = options || {};
|
|
1748
2012
|
if (!this.options.exporter) {
|
|
@@ -1756,63 +2020,61 @@ class LatitudeTelemetry {
|
|
|
1756
2020
|
new core.W3CBaggagePropagator(),
|
|
1757
2021
|
],
|
|
1758
2022
|
}));
|
|
1759
|
-
this.
|
|
2023
|
+
this.nodeProvider = new sdkTraceNode.NodeTracerProvider({
|
|
1760
2024
|
resource: new resources.Resource({ [semanticConventions.ATTR_SERVICE_NAME]: SERVICE_NAME }),
|
|
1761
2025
|
});
|
|
1762
2026
|
// Note: important, must run before the exporter span processors
|
|
1763
|
-
this.
|
|
2027
|
+
this.nodeProvider.addSpanProcessor(new baggageSpanProcessor.BaggageSpanProcessor(baggageSpanProcessor.ALLOW_ALL_BAGGAGE_KEYS));
|
|
1764
2028
|
if (this.options.processors) {
|
|
1765
2029
|
this.options.processors.forEach((processor) => {
|
|
1766
|
-
this.
|
|
2030
|
+
this.nodeProvider.addSpanProcessor(processor);
|
|
1767
2031
|
});
|
|
1768
2032
|
}
|
|
1769
2033
|
else {
|
|
1770
|
-
this.
|
|
2034
|
+
this.nodeProvider.addSpanProcessor(DEFAULT_REDACT_SPAN_PROCESSOR());
|
|
1771
2035
|
}
|
|
1772
2036
|
if (this.options.disableBatch) {
|
|
1773
|
-
this.
|
|
2037
|
+
this.nodeProvider.addSpanProcessor(new sdkTraceNode.SimpleSpanProcessor(this.options.exporter));
|
|
1774
2038
|
}
|
|
1775
2039
|
else {
|
|
1776
|
-
this.
|
|
2040
|
+
this.nodeProvider.addSpanProcessor(new sdkTraceNode.BatchSpanProcessor(this.options.exporter));
|
|
1777
2041
|
}
|
|
1778
|
-
this.
|
|
2042
|
+
this.nodeProvider.register();
|
|
1779
2043
|
process.on('SIGTERM', async () => this.shutdown);
|
|
1780
2044
|
process.on('SIGINT', async () => this.shutdown);
|
|
1781
|
-
this.
|
|
1782
|
-
this.
|
|
2045
|
+
this.manualInstrumentation = null;
|
|
2046
|
+
this.instrumentationsList = [];
|
|
2047
|
+
this.tracer = new TracerManager(this.nodeProvider, SCOPE_VERSION);
|
|
1783
2048
|
this.initInstrumentations();
|
|
1784
|
-
this.
|
|
2049
|
+
this.instrumentation = new InstrumentationManager(this.instrumentationsList);
|
|
2050
|
+
this.instrumentation.enable();
|
|
2051
|
+
this.span = new SpanFactory(this.manualInstrumentation);
|
|
2052
|
+
this.context = new ContextManager(this.manualInstrumentation);
|
|
1785
2053
|
}
|
|
1786
2054
|
async flush() {
|
|
1787
|
-
await this.
|
|
2055
|
+
await this.nodeProvider.forceFlush();
|
|
1788
2056
|
await this.options.exporter.forceFlush?.();
|
|
1789
2057
|
}
|
|
1790
2058
|
async shutdown() {
|
|
1791
2059
|
await this.flush();
|
|
1792
|
-
await this.
|
|
2060
|
+
await this.nodeProvider.shutdown();
|
|
1793
2061
|
await this.options.exporter.shutdown?.();
|
|
1794
2062
|
}
|
|
1795
|
-
tracerProvider(instrumentation) {
|
|
1796
|
-
return new ScopedTracerProvider(`${SCOPE_LATITUDE}.${instrumentation}`, SCOPE_VERSION, this.provider);
|
|
1797
|
-
}
|
|
1798
|
-
tracer(instrumentation) {
|
|
1799
|
-
return this.tracerProvider(instrumentation).getTracer('');
|
|
1800
|
-
}
|
|
1801
2063
|
// TODO(tracing): auto instrument outgoing HTTP requests
|
|
1802
2064
|
initInstrumentations() {
|
|
1803
|
-
this.
|
|
1804
|
-
const tracer = this.tracer(InstrumentationScope.Manual);
|
|
1805
|
-
this.
|
|
1806
|
-
this.
|
|
2065
|
+
this.instrumentationsList = [];
|
|
2066
|
+
const tracer = this.tracer.get(InstrumentationScope.Manual);
|
|
2067
|
+
this.manualInstrumentation = new ManualInstrumentation(tracer);
|
|
2068
|
+
this.instrumentationsList.push(this.manualInstrumentation);
|
|
1807
2069
|
const latitude = this.options.instrumentations?.latitude;
|
|
1808
2070
|
if (latitude) {
|
|
1809
|
-
const tracer = this.tracer(exports.Instrumentation.Latitude);
|
|
2071
|
+
const tracer = this.tracer.get(exports.Instrumentation.Latitude);
|
|
1810
2072
|
const instrumentation = new LatitudeInstrumentation(tracer, typeof latitude === 'object' ? latitude : { module: latitude });
|
|
1811
|
-
this.
|
|
2073
|
+
this.instrumentationsList.push(instrumentation);
|
|
1812
2074
|
}
|
|
1813
2075
|
const configureInstrumentation = (instrumentationType, InstrumentationConstructor, instrumentationOptions) => {
|
|
1814
2076
|
const providerPkg = this.options.instrumentations?.[instrumentationType];
|
|
1815
|
-
const provider = this.
|
|
2077
|
+
const provider = this.tracer.provider(instrumentationType);
|
|
1816
2078
|
const instrumentation$1 = new InstrumentationConstructor(instrumentationOptions); // prettier-ignore
|
|
1817
2079
|
instrumentation$1.setTracerProvider(provider);
|
|
1818
2080
|
if (providerPkg) {
|
|
@@ -1822,7 +2084,7 @@ class LatitudeTelemetry {
|
|
|
1822
2084
|
instrumentations: [instrumentation$1],
|
|
1823
2085
|
tracerProvider: provider,
|
|
1824
2086
|
});
|
|
1825
|
-
this.
|
|
2087
|
+
this.instrumentationsList.push(instrumentation$1);
|
|
1826
2088
|
};
|
|
1827
2089
|
configureInstrumentation(exports.Instrumentation.Anthropic, instrumentationAnthropic.AnthropicInstrumentation); // prettier-ignore
|
|
1828
2090
|
configureInstrumentation(exports.Instrumentation.AIPlatform, instrumentationVertexai.AIPlatformInstrumentation); // prettier-ignore
|
|
@@ -1834,44 +2096,23 @@ class LatitudeTelemetry {
|
|
|
1834
2096
|
configureInstrumentation(exports.Instrumentation.TogetherAI, instrumentationTogether.TogetherInstrumentation, { enrichTokens: true }); // prettier-ignore
|
|
1835
2097
|
configureInstrumentation(exports.Instrumentation.VertexAI, instrumentationVertexai.VertexAIInstrumentation); // prettier-ignore
|
|
1836
2098
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
}
|
|
1855
|
-
completion(ctx, options) {
|
|
1856
|
-
return this.telemetry.completion(ctx, options);
|
|
1857
|
-
}
|
|
1858
|
-
embedding(ctx, options) {
|
|
1859
|
-
return this.telemetry.embedding(ctx, options);
|
|
1860
|
-
}
|
|
1861
|
-
retrieval(ctx, options) {
|
|
1862
|
-
return this.telemetry.retrieval(ctx, options);
|
|
1863
|
-
}
|
|
1864
|
-
reranking(ctx, options) {
|
|
1865
|
-
return this.telemetry.reranking(ctx, options);
|
|
1866
|
-
}
|
|
1867
|
-
http(ctx, options) {
|
|
1868
|
-
return this.telemetry.http(ctx, options);
|
|
1869
|
-
}
|
|
1870
|
-
prompt(ctx, options) {
|
|
1871
|
-
return this.telemetry.prompt(ctx, options);
|
|
1872
|
-
}
|
|
1873
|
-
step(ctx, options) {
|
|
1874
|
-
return this.telemetry.step(ctx, options);
|
|
2099
|
+
async capture(options, fn) {
|
|
2100
|
+
if (!DOCUMENT_PATH_REGEXP.test(options.path)) {
|
|
2101
|
+
throw new BadRequestError("Invalid path, no spaces. Only letters, numbers, '.', '-' and '_'");
|
|
2102
|
+
}
|
|
2103
|
+
const span = this.manualInstrumentation.unresolvedExternal(otel__namespace.ROOT_CONTEXT, options);
|
|
2104
|
+
try {
|
|
2105
|
+
const result = await otel.context.with(span.context, () => fn(span.context));
|
|
2106
|
+
span.end();
|
|
2107
|
+
return result;
|
|
2108
|
+
}
|
|
2109
|
+
catch (error) {
|
|
2110
|
+
span.fail(error);
|
|
2111
|
+
throw error;
|
|
2112
|
+
}
|
|
2113
|
+
finally {
|
|
2114
|
+
await this.flush();
|
|
2115
|
+
}
|
|
1875
2116
|
}
|
|
1876
2117
|
}
|
|
1877
2118
|
|