@latitude-data/telemetry 1.0.4 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +613 -261
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +170 -64
- package/dist/index.js +614 -262
- package/dist/index.js.map +1 -1
- package/package.json +11 -8
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var zod = require('zod');
|
|
4
|
-
var otel = require('@opentelemetry/api');
|
|
5
|
-
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
6
4
|
var incubating = require('@opentelemetry/semantic-conventions/incubating');
|
|
5
|
+
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
6
|
+
var otel = require('@opentelemetry/api');
|
|
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,
|
|
@@ -149,6 +150,15 @@ zod.z.object({
|
|
|
149
150
|
isError: zod.z.boolean().optional(),
|
|
150
151
|
text: zod.z.string().optional(),
|
|
151
152
|
});
|
|
153
|
+
zod.z.object({
|
|
154
|
+
inputTokens: zod.z.number(),
|
|
155
|
+
outputTokens: zod.z.number(),
|
|
156
|
+
promptTokens: zod.z.number(),
|
|
157
|
+
completionTokens: zod.z.number(),
|
|
158
|
+
totalTokens: zod.z.number(),
|
|
159
|
+
reasoningTokens: zod.z.number(),
|
|
160
|
+
cachedInputTokens: zod.z.number(),
|
|
161
|
+
});
|
|
152
162
|
|
|
153
163
|
var ParameterType;
|
|
154
164
|
(function (ParameterType) {
|
|
@@ -274,12 +284,34 @@ const CompositeEvaluationSpecification = {
|
|
|
274
284
|
},
|
|
275
285
|
};
|
|
276
286
|
|
|
287
|
+
const selectedContextSchema = zod.z.object({
|
|
288
|
+
messageIndex: zod.z.number().int().nonnegative(),
|
|
289
|
+
contentBlockIndex: zod.z.number().int().nonnegative(),
|
|
290
|
+
contentType: zod.z.enum([
|
|
291
|
+
'text',
|
|
292
|
+
'reasoning',
|
|
293
|
+
'image',
|
|
294
|
+
'file',
|
|
295
|
+
'tool-call',
|
|
296
|
+
'tool-result',
|
|
297
|
+
]),
|
|
298
|
+
textRange: zod.z
|
|
299
|
+
.object({
|
|
300
|
+
start: zod.z.number().int().nonnegative(),
|
|
301
|
+
end: zod.z.number().int().nonnegative(),
|
|
302
|
+
})
|
|
303
|
+
.optional(),
|
|
304
|
+
selectedText: zod.z.string().optional(),
|
|
305
|
+
toolCallId: zod.z.string().optional(),
|
|
306
|
+
});
|
|
277
307
|
const humanEvaluationConfiguration = baseEvaluationConfiguration.extend({
|
|
278
|
-
enableControls: zod.z.boolean().optional(),
|
|
308
|
+
enableControls: zod.z.boolean().optional(), // UI annotation controls
|
|
279
309
|
criteria: zod.z.string().optional(),
|
|
280
310
|
});
|
|
281
311
|
const humanEvaluationResultMetadata = baseEvaluationResultMetadata.extend({
|
|
282
312
|
reason: zod.z.string().optional(),
|
|
313
|
+
enrichedReason: zod.z.string().optional(),
|
|
314
|
+
selectedContexts: zod.z.array(selectedContextSchema).optional(),
|
|
283
315
|
});
|
|
284
316
|
const humanEvaluationResultError = baseEvaluationResultError.extend({});
|
|
285
317
|
// BINARY
|
|
@@ -557,8 +589,6 @@ zod.z.object({
|
|
|
557
589
|
});
|
|
558
590
|
zod.z.object({
|
|
559
591
|
evaluateLiveLogs: zod.z.boolean().nullable().optional(),
|
|
560
|
-
enableSuggestions: zod.z.boolean().nullable().optional(),
|
|
561
|
-
autoApplySuggestions: zod.z.boolean().nullable().optional(),
|
|
562
592
|
});
|
|
563
593
|
|
|
564
594
|
var LegacyChainEventTypes;
|
|
@@ -756,6 +786,7 @@ var LogSources;
|
|
|
756
786
|
LogSources["ShadowTest"] = "shadow_test";
|
|
757
787
|
LogSources["ABTestChallenger"] = "ab_test_challenger";
|
|
758
788
|
LogSources["User"] = "user";
|
|
789
|
+
LogSources["Optimization"] = "optimization";
|
|
759
790
|
})(LogSources || (LogSources = {}));
|
|
760
791
|
|
|
761
792
|
var RunSourceGroup;
|
|
@@ -766,7 +797,8 @@ var RunSourceGroup;
|
|
|
766
797
|
({
|
|
767
798
|
[RunSourceGroup.Production]: [
|
|
768
799
|
LogSources.API,
|
|
769
|
-
LogSources.
|
|
800
|
+
LogSources.ShadowTest,
|
|
801
|
+
LogSources.ABTestChallenger,
|
|
770
802
|
LogSources.EmailTrigger,
|
|
771
803
|
LogSources.IntegrationTrigger,
|
|
772
804
|
LogSources.ScheduledTrigger,
|
|
@@ -795,23 +827,49 @@ var SpanKind;
|
|
|
795
827
|
// Note: loosely based on OpenTelemetry GenAI semantic conventions
|
|
796
828
|
var SpanType;
|
|
797
829
|
(function (SpanType) {
|
|
798
|
-
|
|
830
|
+
// Latitude wrappers
|
|
831
|
+
SpanType["Prompt"] = "prompt";
|
|
832
|
+
SpanType["Chat"] = "chat";
|
|
833
|
+
SpanType["External"] = "external";
|
|
834
|
+
SpanType["UnresolvedExternal"] = "unresolved_external";
|
|
835
|
+
// Added a HTTP span to capture raw HTTP requests and responses when running from Latitude
|
|
836
|
+
SpanType["Http"] = "http";
|
|
837
|
+
// Any known span from supported specifications will be grouped into one of these types
|
|
799
838
|
SpanType["Completion"] = "completion";
|
|
839
|
+
SpanType["Tool"] = "tool";
|
|
800
840
|
SpanType["Embedding"] = "embedding";
|
|
801
|
-
SpanType["Retrieval"] = "retrieval";
|
|
802
|
-
SpanType["Reranking"] = "reranking";
|
|
803
|
-
SpanType["Http"] = "http";
|
|
804
841
|
SpanType["Unknown"] = "unknown";
|
|
805
|
-
SpanType["Prompt"] = "prompt";
|
|
806
|
-
SpanType["Step"] = "step";
|
|
807
842
|
})(SpanType || (SpanType = {}));
|
|
843
|
+
[
|
|
844
|
+
SpanType.Prompt,
|
|
845
|
+
SpanType.External,
|
|
846
|
+
SpanType.Chat,
|
|
847
|
+
];
|
|
808
848
|
const SPAN_SPECIFICATIONS = {
|
|
809
|
-
[SpanType.
|
|
810
|
-
name: '
|
|
811
|
-
description: 'A
|
|
812
|
-
isGenAI:
|
|
849
|
+
[SpanType.Prompt]: {
|
|
850
|
+
name: 'Prompt',
|
|
851
|
+
description: 'A prompt span',
|
|
852
|
+
isGenAI: false,
|
|
813
853
|
isHidden: false,
|
|
814
854
|
},
|
|
855
|
+
[SpanType.Chat]: {
|
|
856
|
+
name: 'Chat',
|
|
857
|
+
description: 'A chat continuation span',
|
|
858
|
+
isGenAI: false,
|
|
859
|
+
isHidden: false,
|
|
860
|
+
},
|
|
861
|
+
[SpanType.External]: {
|
|
862
|
+
name: 'External',
|
|
863
|
+
description: 'An external capture span',
|
|
864
|
+
isGenAI: false,
|
|
865
|
+
isHidden: false,
|
|
866
|
+
},
|
|
867
|
+
[SpanType.UnresolvedExternal]: {
|
|
868
|
+
name: 'Unresolved External',
|
|
869
|
+
description: 'An external span that needs path resolution before storage',
|
|
870
|
+
isGenAI: false,
|
|
871
|
+
isHidden: true,
|
|
872
|
+
},
|
|
815
873
|
[SpanType.Completion]: {
|
|
816
874
|
name: 'Completion',
|
|
817
875
|
description: 'A completion call',
|
|
@@ -824,15 +882,9 @@ const SPAN_SPECIFICATIONS = {
|
|
|
824
882
|
isGenAI: true,
|
|
825
883
|
isHidden: false,
|
|
826
884
|
},
|
|
827
|
-
[SpanType.
|
|
828
|
-
name: '
|
|
829
|
-
description: 'A
|
|
830
|
-
isGenAI: true,
|
|
831
|
-
isHidden: false,
|
|
832
|
-
},
|
|
833
|
-
[SpanType.Reranking]: {
|
|
834
|
-
name: 'Reranking',
|
|
835
|
-
description: 'A reranking call',
|
|
885
|
+
[SpanType.Tool]: {
|
|
886
|
+
name: 'Tool',
|
|
887
|
+
description: 'A tool call',
|
|
836
888
|
isGenAI: true,
|
|
837
889
|
isHidden: false,
|
|
838
890
|
},
|
|
@@ -848,18 +900,6 @@ const SPAN_SPECIFICATIONS = {
|
|
|
848
900
|
isGenAI: false,
|
|
849
901
|
isHidden: true,
|
|
850
902
|
},
|
|
851
|
-
[SpanType.Prompt]: {
|
|
852
|
-
name: 'Prompt',
|
|
853
|
-
description: 'A prompt span',
|
|
854
|
-
isGenAI: false,
|
|
855
|
-
isHidden: false,
|
|
856
|
-
},
|
|
857
|
-
[SpanType.Step]: {
|
|
858
|
-
name: 'Step',
|
|
859
|
-
description: 'A step span',
|
|
860
|
-
isGenAI: false,
|
|
861
|
-
isHidden: false,
|
|
862
|
-
},
|
|
863
903
|
};
|
|
864
904
|
var SpanStatus;
|
|
865
905
|
(function (SpanStatus) {
|
|
@@ -867,6 +907,11 @@ var SpanStatus;
|
|
|
867
907
|
SpanStatus["Ok"] = "ok";
|
|
868
908
|
SpanStatus["Error"] = "error";
|
|
869
909
|
})(SpanStatus || (SpanStatus = {}));
|
|
910
|
+
new Set([
|
|
911
|
+
SpanType.Prompt,
|
|
912
|
+
SpanType.Chat,
|
|
913
|
+
SpanType.External,
|
|
914
|
+
]);
|
|
870
915
|
|
|
871
916
|
// Note: Traces are unmaterialized but this context is used to propagate the trace
|
|
872
917
|
// See www.w3.org/TR/trace-context and w3c.github.io/baggage
|
|
@@ -876,6 +921,130 @@ zod.z.object({
|
|
|
876
921
|
baggage: zod.z.string().optional(), // <key>=urlencoded(<value>)[,<key>=urlencoded(<value>)]*
|
|
877
922
|
});
|
|
878
923
|
|
|
924
|
+
const ATTRIBUTES = {
|
|
925
|
+
// Custom attributes added and used by Latitude spans (Prompt / External / Chat)
|
|
926
|
+
LATITUDE: {
|
|
927
|
+
type: 'latitude.type',
|
|
928
|
+
documentUuid: 'latitude.document_uuid',
|
|
929
|
+
promptPath: 'latitude.prompt_path',
|
|
930
|
+
commitUuid: 'latitude.commit_uuid',
|
|
931
|
+
documentLogUuid: 'latitude.document_log_uuid',
|
|
932
|
+
projectId: 'latitude.project_id',
|
|
933
|
+
experimentUuid: 'latitude.experiment_uuid',
|
|
934
|
+
source: 'latitude.source',
|
|
935
|
+
externalId: 'latitude.external_id',
|
|
936
|
+
testDeploymentId: 'latitude.test_deployment_id',
|
|
937
|
+
previousTraceId: 'latitude.previous_trace_id',
|
|
938
|
+
// Custom additions to the GenAI semantic conventions (deprecated)
|
|
939
|
+
request: {
|
|
940
|
+
_root: 'gen_ai.request',
|
|
941
|
+
configuration: 'gen_ai.request.configuration',
|
|
942
|
+
template: 'gen_ai.request.template',
|
|
943
|
+
parameters: 'gen_ai.request.parameters',
|
|
944
|
+
messages: 'gen_ai.request.messages'},
|
|
945
|
+
response: {
|
|
946
|
+
_root: 'gen_ai.response',
|
|
947
|
+
messages: 'gen_ai.response.messages',
|
|
948
|
+
},
|
|
949
|
+
usage: {
|
|
950
|
+
promptTokens: 'gen_ai.usage.prompt_tokens',
|
|
951
|
+
cachedTokens: 'gen_ai.usage.cached_tokens',
|
|
952
|
+
reasoningTokens: 'gen_ai.usage.reasoning_tokens',
|
|
953
|
+
completionTokens: 'gen_ai.usage.completion_tokens',
|
|
954
|
+
},
|
|
955
|
+
},
|
|
956
|
+
// Official OpenTelemetry semantic conventions
|
|
957
|
+
OPENTELEMETRY: {
|
|
958
|
+
HTTP: {
|
|
959
|
+
request: {
|
|
960
|
+
url: 'http.request.url',
|
|
961
|
+
body: 'http.request.body',
|
|
962
|
+
header: 'http.request.header',
|
|
963
|
+
method: semanticConventions.ATTR_HTTP_REQUEST_METHOD,
|
|
964
|
+
},
|
|
965
|
+
response: {
|
|
966
|
+
body: 'http.response.body',
|
|
967
|
+
header: 'http.response.header',
|
|
968
|
+
statusCode: semanticConventions.ATTR_HTTP_RESPONSE_STATUS_CODE,
|
|
969
|
+
},
|
|
970
|
+
},
|
|
971
|
+
// GenAI semantic conventions
|
|
972
|
+
// https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/
|
|
973
|
+
GEN_AI: {
|
|
974
|
+
operation: incubating.ATTR_GEN_AI_OPERATION_NAME,
|
|
975
|
+
response: {
|
|
976
|
+
model: incubating.ATTR_GEN_AI_RESPONSE_MODEL,
|
|
977
|
+
finishReasons: incubating.ATTR_GEN_AI_RESPONSE_FINISH_REASONS,
|
|
978
|
+
},
|
|
979
|
+
usage: {
|
|
980
|
+
inputTokens: incubating.ATTR_GEN_AI_USAGE_INPUT_TOKENS,
|
|
981
|
+
outputTokens: incubating.ATTR_GEN_AI_USAGE_OUTPUT_TOKENS,
|
|
982
|
+
},
|
|
983
|
+
tool: {
|
|
984
|
+
call: {
|
|
985
|
+
id: incubating.ATTR_GEN_AI_TOOL_CALL_ID,
|
|
986
|
+
arguments: 'gen_ai.tool.call.arguments'}},
|
|
987
|
+
_deprecated: {
|
|
988
|
+
system: incubating.ATTR_GEN_AI_SYSTEM,
|
|
989
|
+
tool: {
|
|
990
|
+
name: incubating.ATTR_GEN_AI_TOOL_NAME,
|
|
991
|
+
type: incubating.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
|
+
prompt: {
|
|
998
|
+
_root: 'gen_ai.prompt',
|
|
999
|
+
index: (promptIndex) => ({
|
|
1000
|
+
role: `gen_ai.prompt.${promptIndex}.role`,
|
|
1001
|
+
content: `gen_ai.prompt.${promptIndex}.content`, // string or object
|
|
1002
|
+
toolCalls: (toolCallIndex) => ({
|
|
1003
|
+
id: `gen_ai.prompt.${promptIndex}.tool_calls.${toolCallIndex}.id`,
|
|
1004
|
+
name: `gen_ai.prompt.${promptIndex}.tool_calls.${toolCallIndex}.name`,
|
|
1005
|
+
arguments: `gen_ai.prompt.${promptIndex}.tool_calls.${toolCallIndex}.arguments`,
|
|
1006
|
+
}),
|
|
1007
|
+
tool: {
|
|
1008
|
+
callId: `gen_ai.prompt.${promptIndex}.tool_call_id`,
|
|
1009
|
+
toolName: `gen_ai.prompt.${promptIndex}.tool_name`,
|
|
1010
|
+
isError: `gen_ai.prompt.${promptIndex}.is_error`,
|
|
1011
|
+
},
|
|
1012
|
+
}),
|
|
1013
|
+
},
|
|
1014
|
+
completion: {
|
|
1015
|
+
_root: 'gen_ai.completion',
|
|
1016
|
+
index: (completionIndex) => ({
|
|
1017
|
+
role: `gen_ai.completion.${completionIndex}.role`,
|
|
1018
|
+
content: `gen_ai.completion.${completionIndex}.content`, // string or object
|
|
1019
|
+
toolCalls: (toolCallIndex) => ({
|
|
1020
|
+
id: `gen_ai.completion.${completionIndex}.tool_calls.${toolCallIndex}.id`,
|
|
1021
|
+
name: `gen_ai.completion.${completionIndex}.tool_calls.${toolCallIndex}.name`,
|
|
1022
|
+
arguments: `gen_ai.completion.${completionIndex}.tool_calls.${toolCallIndex}.arguments`,
|
|
1023
|
+
}),
|
|
1024
|
+
tool: {
|
|
1025
|
+
callId: `gen_ai.prompt.${completionIndex}.tool_call_id`,
|
|
1026
|
+
toolName: `gen_ai.prompt.${completionIndex}.tool_name`,
|
|
1027
|
+
isError: `gen_ai.prompt.${completionIndex}.is_error`,
|
|
1028
|
+
},
|
|
1029
|
+
}),
|
|
1030
|
+
}},
|
|
1031
|
+
},
|
|
1032
|
+
}};
|
|
1033
|
+
const VALUES = {
|
|
1034
|
+
OPENTELEMETRY: {
|
|
1035
|
+
GEN_AI: {
|
|
1036
|
+
response: {
|
|
1037
|
+
finishReasons: {
|
|
1038
|
+
stop: 'stop',
|
|
1039
|
+
toolCalls: 'tool_calls'},
|
|
1040
|
+
},
|
|
1041
|
+
tool: {
|
|
1042
|
+
type: {
|
|
1043
|
+
function: 'function',
|
|
1044
|
+
},
|
|
1045
|
+
}},
|
|
1046
|
+
}};
|
|
1047
|
+
|
|
879
1048
|
/* Note: Instrumentation scopes from all language SDKs */
|
|
880
1049
|
const SCOPE_LATITUDE = 'so.latitude.instrumentation';
|
|
881
1050
|
var InstrumentationScope;
|
|
@@ -904,43 +1073,6 @@ var InstrumentationScope;
|
|
|
904
1073
|
InstrumentationScope["Transformers"] = "transformers";
|
|
905
1074
|
InstrumentationScope["AlephAlpha"] = "alephalpha";
|
|
906
1075
|
})(InstrumentationScope || (InstrumentationScope = {}));
|
|
907
|
-
/* Note: non-standard OpenTelemetry semantic conventions used in Latitude */
|
|
908
|
-
const ATTR_LATITUDE = 'latitude';
|
|
909
|
-
const ATTR_LATITUDE_TYPE = `${ATTR_LATITUDE}.type`;
|
|
910
|
-
const ATTR_LATITUDE_TEST_DEPLOYMENT_ID = `${ATTR_LATITUDE}.test_deployment_id`;
|
|
911
|
-
const GEN_AI_TOOL_TYPE_VALUE_FUNCTION = 'function';
|
|
912
|
-
const ATTR_GEN_AI_TOOL_CALL_ARGUMENTS = 'gen_ai.tool.call.arguments';
|
|
913
|
-
const ATTR_GEN_AI_TOOL_RESULT_VALUE = 'gen_ai.tool.result.value';
|
|
914
|
-
const ATTR_GEN_AI_TOOL_RESULT_IS_ERROR = 'gen_ai.tool.result.is_error';
|
|
915
|
-
const ATTR_GEN_AI_REQUEST = 'gen_ai.request';
|
|
916
|
-
const ATTR_GEN_AI_REQUEST_CONFIGURATION = 'gen_ai.request.configuration';
|
|
917
|
-
const ATTR_GEN_AI_REQUEST_TEMPLATE = 'gen_ai.request.template';
|
|
918
|
-
const ATTR_GEN_AI_REQUEST_PARAMETERS = 'gen_ai.request.parameters';
|
|
919
|
-
const ATTR_GEN_AI_REQUEST_MESSAGES = 'gen_ai.request.messages';
|
|
920
|
-
const ATTR_GEN_AI_RESPONSE = 'gen_ai.response';
|
|
921
|
-
const ATTR_GEN_AI_RESPONSE_MESSAGES = 'gen_ai.response.messages';
|
|
922
|
-
const ATTR_GEN_AI_USAGE_PROMPT_TOKENS = 'gen_ai.usage.prompt_tokens';
|
|
923
|
-
const ATTR_GEN_AI_USAGE_CACHED_TOKENS = 'gen_ai.usage.cached_tokens';
|
|
924
|
-
const ATTR_GEN_AI_USAGE_REASONING_TOKENS = 'gen_ai.usage.reasoning_tokens'; // prettier-ignore
|
|
925
|
-
const ATTR_GEN_AI_USAGE_COMPLETION_TOKENS = 'gen_ai.usage.completion_tokens'; // prettier-ignore
|
|
926
|
-
const ATTR_GEN_AI_PROMPTS = 'gen_ai.prompt'; // gen_ai.prompt.{index}.{role/content/...}
|
|
927
|
-
const ATTR_GEN_AI_COMPLETIONS = 'gen_ai.completion'; // gen_ai.completion.{index}.{role/content/...}
|
|
928
|
-
const ATTR_GEN_AI_MESSAGE_ROLE = 'role';
|
|
929
|
-
const ATTR_GEN_AI_MESSAGE_CONTENT = 'content'; // string or object
|
|
930
|
-
const ATTR_GEN_AI_MESSAGE_TOOL_NAME = 'tool_name';
|
|
931
|
-
const ATTR_GEN_AI_MESSAGE_TOOL_CALL_ID = 'tool_call_id';
|
|
932
|
-
const ATTR_GEN_AI_MESSAGE_TOOL_RESULT_IS_ERROR = 'is_error';
|
|
933
|
-
const ATTR_GEN_AI_MESSAGE_TOOL_CALLS = 'tool_calls'; // gen_ai.completion.{index}.tool_calls.{index}.{id/name/arguments}
|
|
934
|
-
const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_ID = 'id';
|
|
935
|
-
const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_NAME = 'name';
|
|
936
|
-
const ATTR_GEN_AI_MESSAGE_TOOL_CALLS_ARGUMENTS = 'arguments';
|
|
937
|
-
const GEN_AI_RESPONSE_FINISH_REASON_VALUE_STOP = 'stop';
|
|
938
|
-
const GEN_AI_RESPONSE_FINISH_REASON_VALUE_TOOL_CALLS = 'tool_calls';
|
|
939
|
-
const ATTR_HTTP_REQUEST_URL = 'http.request.url';
|
|
940
|
-
const ATTR_HTTP_REQUEST_BODY = 'http.request.body';
|
|
941
|
-
const ATTR_HTTP_REQUEST_HEADER = 'http.request.header';
|
|
942
|
-
const ATTR_HTTP_RESPONSE_BODY = 'http.response.body';
|
|
943
|
-
const ATTR_HTTP_RESPONSE_HEADER = 'http.response.header';
|
|
944
1076
|
/* Note: Schemas for span ingestion following OpenTelemetry service request specification */
|
|
945
1077
|
var Otlp;
|
|
946
1078
|
(function (Otlp) {
|
|
@@ -1021,6 +1153,40 @@ var Otlp;
|
|
|
1021
1153
|
});
|
|
1022
1154
|
})(Otlp || (Otlp = {}));
|
|
1023
1155
|
|
|
1156
|
+
const MAX_SIMULATION_TURNS = 10;
|
|
1157
|
+
const SimulationSettingsSchema = zod.z.object({
|
|
1158
|
+
simulateToolResponses: zod.z.boolean().optional(),
|
|
1159
|
+
simulatedTools: zod.z.array(zod.z.string()).optional(), // Empty array means all tools are simulated (if simulateToolResponses is true).
|
|
1160
|
+
toolSimulationInstructions: zod.z.string().optional(), // A prompt used to guide and generate the simulation result
|
|
1161
|
+
maxTurns: zod.z.number().min(1).max(MAX_SIMULATION_TURNS).optional(), // The maximum number of turns to simulate. Default is 1, and any greater value will add a new user message to the simulated conversation.
|
|
1162
|
+
});
|
|
1163
|
+
|
|
1164
|
+
var OptimizationEngine;
|
|
1165
|
+
(function (OptimizationEngine) {
|
|
1166
|
+
OptimizationEngine["Identity"] = "identity";
|
|
1167
|
+
OptimizationEngine["Gepa"] = "gepa";
|
|
1168
|
+
})(OptimizationEngine || (OptimizationEngine = {}));
|
|
1169
|
+
const OptimizationBudgetSchema = zod.z.object({
|
|
1170
|
+
time: zod.z.number().min(0).optional(),
|
|
1171
|
+
tokens: zod.z.number().min(0).optional(),
|
|
1172
|
+
});
|
|
1173
|
+
zod.z.object({
|
|
1174
|
+
parameters: zod.z
|
|
1175
|
+
.record(zod.z.string(), zod.z.object({
|
|
1176
|
+
column: zod.z.string().optional(), // Note: corresponding column in the user-provided trainset and testset
|
|
1177
|
+
isPii: zod.z.boolean().optional(),
|
|
1178
|
+
}))
|
|
1179
|
+
.optional(),
|
|
1180
|
+
simulation: SimulationSettingsSchema.optional(),
|
|
1181
|
+
scope: zod.z
|
|
1182
|
+
.object({
|
|
1183
|
+
configuration: zod.z.boolean().optional(),
|
|
1184
|
+
instructions: zod.z.boolean().optional(),
|
|
1185
|
+
})
|
|
1186
|
+
.optional(),
|
|
1187
|
+
budget: OptimizationBudgetSchema.optional(),
|
|
1188
|
+
});
|
|
1189
|
+
|
|
1024
1190
|
// TODO(tracing): deprecated
|
|
1025
1191
|
const HEAD_COMMIT = 'live';
|
|
1026
1192
|
var Providers;
|
|
@@ -1064,6 +1230,7 @@ var DocumentTriggerParameters;
|
|
|
1064
1230
|
DocumentTriggerParameters["Body"] = "body";
|
|
1065
1231
|
DocumentTriggerParameters["Attachments"] = "attachments";
|
|
1066
1232
|
})(DocumentTriggerParameters || (DocumentTriggerParameters = {}));
|
|
1233
|
+
const DOCUMENT_PATH_REGEXP = /^([\w-]+\/)*([\w-.])+$/;
|
|
1067
1234
|
|
|
1068
1235
|
class ManualInstrumentation {
|
|
1069
1236
|
enabled;
|
|
@@ -1082,7 +1249,33 @@ class ManualInstrumentation {
|
|
|
1082
1249
|
this.enabled = false;
|
|
1083
1250
|
}
|
|
1084
1251
|
resume(ctx) {
|
|
1085
|
-
|
|
1252
|
+
const parts = ctx.traceparent.split('-');
|
|
1253
|
+
if (parts.length !== 4) {
|
|
1254
|
+
return otel__namespace.ROOT_CONTEXT;
|
|
1255
|
+
}
|
|
1256
|
+
const [, traceId, spanId, flags] = parts;
|
|
1257
|
+
if (!traceId || !spanId) {
|
|
1258
|
+
return otel__namespace.ROOT_CONTEXT;
|
|
1259
|
+
}
|
|
1260
|
+
const spanContext = {
|
|
1261
|
+
traceId,
|
|
1262
|
+
spanId,
|
|
1263
|
+
traceFlags: parseInt(flags ?? '01', 16),
|
|
1264
|
+
isRemote: true,
|
|
1265
|
+
};
|
|
1266
|
+
let context = otel.trace.setSpanContext(otel__namespace.ROOT_CONTEXT, spanContext);
|
|
1267
|
+
if (ctx.baggage) {
|
|
1268
|
+
const baggageEntries = {};
|
|
1269
|
+
for (const pair of ctx.baggage.split(',')) {
|
|
1270
|
+
const [key, value] = pair.split('=');
|
|
1271
|
+
if (key && value) {
|
|
1272
|
+
baggageEntries[key] = { value: decodeURIComponent(value) };
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
const baggage = otel.propagation.createBaggage(baggageEntries);
|
|
1276
|
+
context = otel.propagation.setBaggage(context, baggage);
|
|
1277
|
+
}
|
|
1278
|
+
return context;
|
|
1086
1279
|
}
|
|
1087
1280
|
capitalize(str) {
|
|
1088
1281
|
if (str.length === 0)
|
|
@@ -1139,9 +1332,9 @@ class ManualInstrumentation {
|
|
|
1139
1332
|
}
|
|
1140
1333
|
const span = this.tracer.startSpan(name, {
|
|
1141
1334
|
attributes: {
|
|
1142
|
-
[
|
|
1335
|
+
[ATTRIBUTES.LATITUDE.type]: type,
|
|
1143
1336
|
...(operation && {
|
|
1144
|
-
[
|
|
1337
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.operation]: operation,
|
|
1145
1338
|
}),
|
|
1146
1339
|
...(start.attributes || {}),
|
|
1147
1340
|
},
|
|
@@ -1167,15 +1360,15 @@ class ManualInstrumentation {
|
|
|
1167
1360
|
try {
|
|
1168
1361
|
jsonArguments = JSON.stringify(start.call.arguments);
|
|
1169
1362
|
}
|
|
1170
|
-
catch (
|
|
1363
|
+
catch (_error) {
|
|
1171
1364
|
jsonArguments = '{}';
|
|
1172
1365
|
}
|
|
1173
1366
|
const span = this.span(ctx, start.name, SpanType.Tool, {
|
|
1174
1367
|
attributes: {
|
|
1175
|
-
[
|
|
1176
|
-
[
|
|
1177
|
-
[
|
|
1178
|
-
[
|
|
1368
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.name]: start.name,
|
|
1369
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.type]: VALUES.OPENTELEMETRY.GEN_AI.tool.type.function,
|
|
1370
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.tool.call.id]: start.call.id,
|
|
1371
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.tool.call.arguments]: jsonArguments,
|
|
1179
1372
|
...(start.attributes || {}),
|
|
1180
1373
|
},
|
|
1181
1374
|
});
|
|
@@ -1188,7 +1381,7 @@ class ManualInstrumentation {
|
|
|
1188
1381
|
try {
|
|
1189
1382
|
stringResult = JSON.stringify(end.result.value);
|
|
1190
1383
|
}
|
|
1191
|
-
catch (
|
|
1384
|
+
catch (_error) {
|
|
1192
1385
|
stringResult = '{}';
|
|
1193
1386
|
}
|
|
1194
1387
|
}
|
|
@@ -1197,8 +1390,8 @@ class ManualInstrumentation {
|
|
|
1197
1390
|
}
|
|
1198
1391
|
span.end({
|
|
1199
1392
|
attributes: {
|
|
1200
|
-
[
|
|
1201
|
-
[
|
|
1393
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.result.value]: stringResult,
|
|
1394
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.tool.result.isError]: end.result.isError,
|
|
1202
1395
|
...(end.attributes || {}),
|
|
1203
1396
|
},
|
|
1204
1397
|
});
|
|
@@ -1206,12 +1399,12 @@ class ManualInstrumentation {
|
|
|
1206
1399
|
fail: span.fail,
|
|
1207
1400
|
};
|
|
1208
1401
|
}
|
|
1209
|
-
attribifyMessageToolCalls(
|
|
1402
|
+
attribifyMessageToolCalls(otelMessageField, toolCalls) {
|
|
1210
1403
|
const attributes = {};
|
|
1211
1404
|
for (let i = 0; i < toolCalls.length; i++) {
|
|
1212
1405
|
for (const key in toolCalls[i]) {
|
|
1213
1406
|
const field = this.toCamelCase(key);
|
|
1214
|
-
|
|
1407
|
+
const value = toolCalls[i][key];
|
|
1215
1408
|
if (value === null || value === undefined)
|
|
1216
1409
|
continue;
|
|
1217
1410
|
switch (field) {
|
|
@@ -1220,28 +1413,29 @@ class ManualInstrumentation {
|
|
|
1220
1413
|
case 'toolUseId': {
|
|
1221
1414
|
if (typeof value !== 'string')
|
|
1222
1415
|
continue;
|
|
1223
|
-
attributes[
|
|
1416
|
+
attributes[otelMessageField.toolCalls(i).id] = value;
|
|
1224
1417
|
break;
|
|
1225
1418
|
}
|
|
1226
1419
|
case 'name':
|
|
1227
1420
|
case 'toolName': {
|
|
1228
1421
|
if (typeof value !== 'string')
|
|
1229
1422
|
continue;
|
|
1230
|
-
attributes[
|
|
1423
|
+
attributes[otelMessageField.toolCalls(i).name] = value;
|
|
1231
1424
|
break;
|
|
1232
1425
|
}
|
|
1233
1426
|
case 'arguments':
|
|
1234
1427
|
case 'toolArguments':
|
|
1235
1428
|
case 'input': {
|
|
1236
1429
|
if (typeof value === 'string') {
|
|
1237
|
-
attributes[
|
|
1430
|
+
attributes[otelMessageField.toolCalls(i).arguments] = value;
|
|
1238
1431
|
}
|
|
1239
1432
|
else {
|
|
1240
1433
|
try {
|
|
1241
|
-
attributes[
|
|
1434
|
+
attributes[otelMessageField.toolCalls(i).arguments] =
|
|
1435
|
+
JSON.stringify(value);
|
|
1242
1436
|
}
|
|
1243
|
-
catch (
|
|
1244
|
-
attributes[
|
|
1437
|
+
catch (_error) {
|
|
1438
|
+
attributes[otelMessageField.toolCalls(i).arguments] = '{}';
|
|
1245
1439
|
}
|
|
1246
1440
|
}
|
|
1247
1441
|
break;
|
|
@@ -1258,8 +1452,9 @@ class ManualInstrumentation {
|
|
|
1258
1452
|
continue;
|
|
1259
1453
|
if (typeof value.arguments !== 'string')
|
|
1260
1454
|
continue;
|
|
1261
|
-
attributes[
|
|
1262
|
-
attributes[
|
|
1455
|
+
attributes[otelMessageField.toolCalls(i).name] = value.name;
|
|
1456
|
+
attributes[otelMessageField.toolCalls(i).arguments] =
|
|
1457
|
+
value.arguments;
|
|
1263
1458
|
break;
|
|
1264
1459
|
}
|
|
1265
1460
|
}
|
|
@@ -1267,18 +1462,16 @@ class ManualInstrumentation {
|
|
|
1267
1462
|
}
|
|
1268
1463
|
return attributes;
|
|
1269
1464
|
}
|
|
1270
|
-
attribifyMessageContent(
|
|
1465
|
+
attribifyMessageContent(otelMessageField, content) {
|
|
1271
1466
|
let attributes = {};
|
|
1272
1467
|
if (typeof content === 'string') {
|
|
1273
|
-
attributes[`${prefix}.${ATTR_GEN_AI_MESSAGE_CONTENT}`] = content;
|
|
1274
1468
|
return attributes;
|
|
1275
1469
|
}
|
|
1276
1470
|
try {
|
|
1277
|
-
attributes[
|
|
1278
|
-
JSON.stringify(content);
|
|
1471
|
+
attributes[otelMessageField.content] = JSON.stringify(content);
|
|
1279
1472
|
}
|
|
1280
|
-
catch (
|
|
1281
|
-
attributes[
|
|
1473
|
+
catch (_error) {
|
|
1474
|
+
attributes[otelMessageField.content] = '[]';
|
|
1282
1475
|
}
|
|
1283
1476
|
if (!Array.isArray(content))
|
|
1284
1477
|
return attributes;
|
|
@@ -1298,32 +1491,34 @@ class ManualInstrumentation {
|
|
|
1298
1491
|
if (toolCalls.length > 0) {
|
|
1299
1492
|
attributes = {
|
|
1300
1493
|
...attributes,
|
|
1301
|
-
...this.attribifyMessageToolCalls(
|
|
1494
|
+
...this.attribifyMessageToolCalls(otelMessageField, toolCalls),
|
|
1302
1495
|
};
|
|
1303
1496
|
}
|
|
1304
1497
|
return attributes;
|
|
1305
1498
|
}
|
|
1306
1499
|
attribifyMessages(direction, messages) {
|
|
1307
|
-
const
|
|
1500
|
+
const otelField = direction === 'input'
|
|
1501
|
+
? ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.prompt
|
|
1502
|
+
: ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.completion;
|
|
1308
1503
|
let attributes = {};
|
|
1309
1504
|
for (let i = 0; i < messages.length; i++) {
|
|
1310
1505
|
for (const key in messages[i]) {
|
|
1311
1506
|
const field = this.toCamelCase(key);
|
|
1312
|
-
|
|
1507
|
+
const value = messages[i][key];
|
|
1313
1508
|
if (value === null || value === undefined)
|
|
1314
1509
|
continue;
|
|
1315
1510
|
switch (field) {
|
|
1316
1511
|
case 'role': {
|
|
1317
1512
|
if (typeof value !== 'string')
|
|
1318
1513
|
continue;
|
|
1319
|
-
attributes[
|
|
1514
|
+
attributes[otelField.index(i).role] = value;
|
|
1320
1515
|
break;
|
|
1321
1516
|
}
|
|
1322
1517
|
/* Tool calls for Anthropic and PromptL are in the content */
|
|
1323
1518
|
case 'content': {
|
|
1324
1519
|
attributes = {
|
|
1325
1520
|
...attributes,
|
|
1326
|
-
...this.attribifyMessageContent(
|
|
1521
|
+
...this.attribifyMessageContent(otelField.index(i), value),
|
|
1327
1522
|
};
|
|
1328
1523
|
break;
|
|
1329
1524
|
}
|
|
@@ -1333,7 +1528,7 @@ class ManualInstrumentation {
|
|
|
1333
1528
|
continue;
|
|
1334
1529
|
attributes = {
|
|
1335
1530
|
...attributes,
|
|
1336
|
-
...this.attribifyMessageToolCalls(
|
|
1531
|
+
...this.attribifyMessageToolCalls(otelField.index(i), value),
|
|
1337
1532
|
};
|
|
1338
1533
|
break;
|
|
1339
1534
|
}
|
|
@@ -1343,22 +1538,20 @@ class ManualInstrumentation {
|
|
|
1343
1538
|
case 'toolUseId': {
|
|
1344
1539
|
if (typeof value !== 'string')
|
|
1345
1540
|
continue;
|
|
1346
|
-
attributes[
|
|
1347
|
-
value;
|
|
1541
|
+
attributes[otelField.index(i).tool.callId] = value;
|
|
1348
1542
|
break;
|
|
1349
1543
|
}
|
|
1350
1544
|
case 'toolName': {
|
|
1351
1545
|
if (typeof value !== 'string')
|
|
1352
1546
|
continue;
|
|
1353
|
-
attributes[
|
|
1354
|
-
value;
|
|
1547
|
+
attributes[otelField.index(i).tool.toolName] = value;
|
|
1355
1548
|
break;
|
|
1356
1549
|
}
|
|
1357
1550
|
// Note: 'toolResult' is 'content' itself
|
|
1358
1551
|
case 'isError': {
|
|
1359
1552
|
if (typeof value !== 'boolean')
|
|
1360
1553
|
continue;
|
|
1361
|
-
attributes[
|
|
1554
|
+
attributes[otelField.index(i).tool.isError] = value;
|
|
1362
1555
|
break;
|
|
1363
1556
|
}
|
|
1364
1557
|
}
|
|
@@ -1367,7 +1560,9 @@ class ManualInstrumentation {
|
|
|
1367
1560
|
return attributes;
|
|
1368
1561
|
}
|
|
1369
1562
|
attribifyConfiguration(direction, configuration) {
|
|
1370
|
-
const prefix = direction === 'input'
|
|
1563
|
+
const prefix = direction === 'input'
|
|
1564
|
+
? ATTRIBUTES.LATITUDE.request._root
|
|
1565
|
+
: ATTRIBUTES.LATITUDE.response._root;
|
|
1371
1566
|
const attributes = {};
|
|
1372
1567
|
for (const key in configuration) {
|
|
1373
1568
|
const field = this.toSnakeCase(key);
|
|
@@ -1378,7 +1573,7 @@ class ManualInstrumentation {
|
|
|
1378
1573
|
try {
|
|
1379
1574
|
value = JSON.stringify(value);
|
|
1380
1575
|
}
|
|
1381
|
-
catch (
|
|
1576
|
+
catch (_error) {
|
|
1382
1577
|
value = '{}';
|
|
1383
1578
|
}
|
|
1384
1579
|
}
|
|
@@ -1389,64 +1584,75 @@ class ManualInstrumentation {
|
|
|
1389
1584
|
completion(ctx, options) {
|
|
1390
1585
|
const start = options;
|
|
1391
1586
|
const configuration = {
|
|
1392
|
-
...start.configuration,
|
|
1587
|
+
...(start.configuration ?? {}),
|
|
1393
1588
|
model: start.model,
|
|
1394
1589
|
};
|
|
1395
1590
|
let jsonConfiguration = '';
|
|
1396
1591
|
try {
|
|
1397
1592
|
jsonConfiguration = JSON.stringify(configuration);
|
|
1398
1593
|
}
|
|
1399
|
-
catch (
|
|
1594
|
+
catch (_error) {
|
|
1400
1595
|
jsonConfiguration = '{}';
|
|
1401
1596
|
}
|
|
1402
1597
|
const attrConfiguration = this.attribifyConfiguration('input', configuration);
|
|
1598
|
+
const input = start.input ?? [];
|
|
1403
1599
|
let jsonInput = '';
|
|
1404
1600
|
try {
|
|
1405
|
-
jsonInput = JSON.stringify(
|
|
1601
|
+
jsonInput = JSON.stringify(input);
|
|
1406
1602
|
}
|
|
1407
|
-
catch (
|
|
1603
|
+
catch (_error) {
|
|
1408
1604
|
jsonInput = '[]';
|
|
1409
1605
|
}
|
|
1410
|
-
const attrInput = this.attribifyMessages('input',
|
|
1606
|
+
const attrInput = this.attribifyMessages('input', input);
|
|
1411
1607
|
const span = this.span(ctx, start.name || `${start.provider} / ${start.model}`, SpanType.Completion, {
|
|
1412
1608
|
attributes: {
|
|
1413
|
-
[
|
|
1414
|
-
[
|
|
1609
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI._deprecated.system]: start.provider,
|
|
1610
|
+
[ATTRIBUTES.LATITUDE.request.configuration]: jsonConfiguration,
|
|
1415
1611
|
...attrConfiguration,
|
|
1416
|
-
[
|
|
1612
|
+
[ATTRIBUTES.LATITUDE.request.messages]: jsonInput,
|
|
1417
1613
|
...attrInput,
|
|
1418
1614
|
...(start.attributes || {}),
|
|
1419
|
-
[
|
|
1420
|
-
[
|
|
1421
|
-
[
|
|
1615
|
+
[ATTRIBUTES.LATITUDE.commitUuid]: start.versionUuid,
|
|
1616
|
+
[ATTRIBUTES.LATITUDE.documentUuid]: start.promptUuid,
|
|
1617
|
+
[ATTRIBUTES.LATITUDE.experimentUuid]: start.experimentUuid,
|
|
1422
1618
|
},
|
|
1423
1619
|
});
|
|
1424
1620
|
return {
|
|
1425
1621
|
context: span.context,
|
|
1426
1622
|
end: (options) => {
|
|
1427
|
-
const end = options;
|
|
1623
|
+
const end = options ?? {};
|
|
1624
|
+
const output = end.output ?? [];
|
|
1428
1625
|
let jsonOutput = '';
|
|
1429
1626
|
try {
|
|
1430
|
-
jsonOutput = JSON.stringify(
|
|
1627
|
+
jsonOutput = JSON.stringify(output);
|
|
1431
1628
|
}
|
|
1432
|
-
catch (
|
|
1629
|
+
catch (_error) {
|
|
1433
1630
|
jsonOutput = '[]';
|
|
1434
1631
|
}
|
|
1435
|
-
const attrOutput = this.attribifyMessages('output',
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1632
|
+
const attrOutput = this.attribifyMessages('output', output);
|
|
1633
|
+
const tokens = {
|
|
1634
|
+
prompt: end.tokens?.prompt ?? 0,
|
|
1635
|
+
cached: end.tokens?.cached ?? 0,
|
|
1636
|
+
reasoning: end.tokens?.reasoning ?? 0,
|
|
1637
|
+
completion: end.tokens?.completion ?? 0,
|
|
1638
|
+
};
|
|
1639
|
+
const inputTokens = tokens.prompt + tokens.cached;
|
|
1640
|
+
const outputTokens = tokens.reasoning + tokens.completion;
|
|
1641
|
+
const finishReason = end.finishReason ?? '';
|
|
1438
1642
|
span.end({
|
|
1439
1643
|
attributes: {
|
|
1440
|
-
[
|
|
1644
|
+
[ATTRIBUTES.LATITUDE.response.messages]: jsonOutput,
|
|
1441
1645
|
...attrOutput,
|
|
1442
|
-
[
|
|
1443
|
-
[
|
|
1444
|
-
[
|
|
1445
|
-
[
|
|
1446
|
-
[
|
|
1447
|
-
[
|
|
1448
|
-
[
|
|
1449
|
-
[
|
|
1646
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.usage.inputTokens]: inputTokens,
|
|
1647
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.usage.outputTokens]: outputTokens,
|
|
1648
|
+
[ATTRIBUTES.LATITUDE.usage.promptTokens]: tokens.prompt,
|
|
1649
|
+
[ATTRIBUTES.LATITUDE.usage.cachedTokens]: tokens.cached,
|
|
1650
|
+
[ATTRIBUTES.LATITUDE.usage.reasoningTokens]: tokens.reasoning,
|
|
1651
|
+
[ATTRIBUTES.LATITUDE.usage.completionTokens]: tokens.completion,
|
|
1652
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.response.model]: start.model,
|
|
1653
|
+
[ATTRIBUTES.OPENTELEMETRY.GEN_AI.response.finishReasons]: [
|
|
1654
|
+
finishReason,
|
|
1655
|
+
],
|
|
1450
1656
|
...(end.attributes || {}),
|
|
1451
1657
|
},
|
|
1452
1658
|
});
|
|
@@ -1457,16 +1663,10 @@ class ManualInstrumentation {
|
|
|
1457
1663
|
embedding(ctx, options) {
|
|
1458
1664
|
return this.span(ctx, options?.name || SPAN_SPECIFICATIONS[SpanType.Embedding].name, SpanType.Embedding, options);
|
|
1459
1665
|
}
|
|
1460
|
-
retrieval(ctx, options) {
|
|
1461
|
-
return this.span(ctx, options?.name || SPAN_SPECIFICATIONS[SpanType.Retrieval].name, SpanType.Retrieval, options);
|
|
1462
|
-
}
|
|
1463
|
-
reranking(ctx, options) {
|
|
1464
|
-
return this.span(ctx, options?.name || SPAN_SPECIFICATIONS[SpanType.Reranking].name, SpanType.Reranking, options);
|
|
1465
|
-
}
|
|
1466
1666
|
attribifyHeaders(direction, headers) {
|
|
1467
1667
|
const prefix = direction === 'request'
|
|
1468
|
-
?
|
|
1469
|
-
:
|
|
1668
|
+
? ATTRIBUTES.OPENTELEMETRY.HTTP.request.header
|
|
1669
|
+
: ATTRIBUTES.OPENTELEMETRY.HTTP.response.header;
|
|
1470
1670
|
const attributes = {};
|
|
1471
1671
|
for (const key in headers) {
|
|
1472
1672
|
const field = this.toKebabCase(key);
|
|
@@ -1490,16 +1690,16 @@ class ManualInstrumentation {
|
|
|
1490
1690
|
try {
|
|
1491
1691
|
finalBody = JSON.stringify(start.request.body);
|
|
1492
1692
|
}
|
|
1493
|
-
catch (
|
|
1693
|
+
catch (_error) {
|
|
1494
1694
|
finalBody = '{}';
|
|
1495
1695
|
}
|
|
1496
1696
|
}
|
|
1497
1697
|
const span = this.span(ctx, start.name || `${method} ${start.request.url}`, SpanType.Http, {
|
|
1498
1698
|
attributes: {
|
|
1499
|
-
[
|
|
1500
|
-
[
|
|
1699
|
+
[ATTRIBUTES.OPENTELEMETRY.HTTP.request.method]: method,
|
|
1700
|
+
[ATTRIBUTES.OPENTELEMETRY.HTTP.request.url]: start.request.url,
|
|
1501
1701
|
...attrHeaders,
|
|
1502
|
-
[
|
|
1702
|
+
[ATTRIBUTES.OPENTELEMETRY.HTTP.request.body]: finalBody,
|
|
1503
1703
|
...(start.attributes || {}),
|
|
1504
1704
|
},
|
|
1505
1705
|
});
|
|
@@ -1517,15 +1717,15 @@ class ManualInstrumentation {
|
|
|
1517
1717
|
try {
|
|
1518
1718
|
finalBody = JSON.stringify(end.response.body);
|
|
1519
1719
|
}
|
|
1520
|
-
catch (
|
|
1720
|
+
catch (_error) {
|
|
1521
1721
|
finalBody = '{}';
|
|
1522
1722
|
}
|
|
1523
1723
|
}
|
|
1524
1724
|
span.end({
|
|
1525
1725
|
attributes: {
|
|
1526
|
-
[
|
|
1726
|
+
[ATTRIBUTES.OPENTELEMETRY.HTTP.response.statusCode]: end.response.status,
|
|
1527
1727
|
...attrHeaders,
|
|
1528
|
-
[
|
|
1728
|
+
[ATTRIBUTES.OPENTELEMETRY.HTTP.response.body]: finalBody,
|
|
1529
1729
|
...(end.attributes || {}),
|
|
1530
1730
|
},
|
|
1531
1731
|
});
|
|
@@ -1538,49 +1738,84 @@ class ManualInstrumentation {
|
|
|
1538
1738
|
try {
|
|
1539
1739
|
jsonParameters = JSON.stringify(parameters || {});
|
|
1540
1740
|
}
|
|
1541
|
-
catch (
|
|
1741
|
+
catch (_error) {
|
|
1542
1742
|
jsonParameters = '{}';
|
|
1543
1743
|
}
|
|
1544
1744
|
const attributes = {
|
|
1545
|
-
[
|
|
1546
|
-
[
|
|
1547
|
-
[
|
|
1548
|
-
[
|
|
1549
|
-
[
|
|
1550
|
-
|
|
1551
|
-
...(experimentUuid && {
|
|
1745
|
+
[ATTRIBUTES.LATITUDE.request.template]: template,
|
|
1746
|
+
[ATTRIBUTES.LATITUDE.request.parameters]: jsonParameters,
|
|
1747
|
+
[ATTRIBUTES.LATITUDE.commitUuid]: versionUuid || HEAD_COMMIT,
|
|
1748
|
+
[ATTRIBUTES.LATITUDE.documentUuid]: promptUuid,
|
|
1749
|
+
[ATTRIBUTES.LATITUDE.projectId]: projectId,
|
|
1750
|
+
[ATTRIBUTES.LATITUDE.documentLogUuid]: documentLogUuid,
|
|
1751
|
+
...(experimentUuid && {
|
|
1752
|
+
[ATTRIBUTES.LATITUDE.experimentUuid]: experimentUuid,
|
|
1753
|
+
}),
|
|
1552
1754
|
...(testDeploymentId && {
|
|
1553
|
-
[
|
|
1755
|
+
[ATTRIBUTES.LATITUDE.testDeploymentId]: testDeploymentId,
|
|
1554
1756
|
}),
|
|
1555
|
-
...(externalId && { [
|
|
1556
|
-
...(source && { [
|
|
1757
|
+
...(externalId && { [ATTRIBUTES.LATITUDE.externalId]: externalId }),
|
|
1758
|
+
...(source && { [ATTRIBUTES.LATITUDE.source]: source }),
|
|
1557
1759
|
...(rest.attributes || {}),
|
|
1558
1760
|
};
|
|
1559
1761
|
return this.span(ctx, name || `prompt-${promptUuid}`, SpanType.Prompt, {
|
|
1560
1762
|
attributes,
|
|
1561
1763
|
});
|
|
1562
1764
|
}
|
|
1563
|
-
|
|
1564
|
-
|
|
1765
|
+
chat(ctx, { documentLogUuid, previousTraceId, source, name, versionUuid, promptUuid, ...rest }) {
|
|
1766
|
+
const attributes = {
|
|
1767
|
+
[ATTRIBUTES.LATITUDE.documentLogUuid]: documentLogUuid,
|
|
1768
|
+
[ATTRIBUTES.LATITUDE.previousTraceId]: previousTraceId,
|
|
1769
|
+
...(versionUuid && { [ATTRIBUTES.LATITUDE.commitUuid]: versionUuid }),
|
|
1770
|
+
...(promptUuid && { [ATTRIBUTES.LATITUDE.documentUuid]: promptUuid }),
|
|
1771
|
+
...(source && { [ATTRIBUTES.LATITUDE.source]: source }),
|
|
1772
|
+
...(rest.attributes || {}),
|
|
1773
|
+
};
|
|
1774
|
+
return this.span(ctx, name || 'chat', SpanType.Chat, { attributes });
|
|
1775
|
+
}
|
|
1776
|
+
external(ctx, { promptUuid, documentLogUuid, source, versionUuid, externalId, name, ...rest }) {
|
|
1777
|
+
const attributes = {
|
|
1778
|
+
[ATTRIBUTES.LATITUDE.documentUuid]: promptUuid,
|
|
1779
|
+
[ATTRIBUTES.LATITUDE.documentLogUuid]: documentLogUuid,
|
|
1780
|
+
[ATTRIBUTES.LATITUDE.source]: source ?? LogSources.API,
|
|
1781
|
+
...(versionUuid && { [ATTRIBUTES.LATITUDE.commitUuid]: versionUuid }),
|
|
1782
|
+
...(externalId && { [ATTRIBUTES.LATITUDE.externalId]: externalId }),
|
|
1783
|
+
...(rest.attributes || {}),
|
|
1784
|
+
};
|
|
1785
|
+
return this.span(ctx, name || `external-${promptUuid}`, SpanType.External, {
|
|
1786
|
+
attributes,
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
unresolvedExternal(ctx, { path, projectId, versionUuid, conversationUuid, name, ...rest }) {
|
|
1790
|
+
const attributes = {
|
|
1791
|
+
[ATTRIBUTES.LATITUDE.promptPath]: path,
|
|
1792
|
+
[ATTRIBUTES.LATITUDE.projectId]: projectId,
|
|
1793
|
+
...(versionUuid && { [ATTRIBUTES.LATITUDE.commitUuid]: versionUuid }),
|
|
1794
|
+
...(conversationUuid && {
|
|
1795
|
+
[ATTRIBUTES.LATITUDE.documentLogUuid]: conversationUuid,
|
|
1796
|
+
}),
|
|
1797
|
+
...(rest.attributes || {}),
|
|
1798
|
+
};
|
|
1799
|
+
return this.span(ctx, name || `capture-${path}`, SpanType.UnresolvedExternal, { attributes });
|
|
1565
1800
|
}
|
|
1566
1801
|
}
|
|
1567
1802
|
|
|
1568
1803
|
class LatitudeInstrumentation {
|
|
1569
1804
|
options;
|
|
1570
|
-
|
|
1805
|
+
manualTelemetry;
|
|
1571
1806
|
constructor(tracer, options) {
|
|
1572
|
-
this.
|
|
1807
|
+
this.manualTelemetry = new ManualInstrumentation(tracer);
|
|
1573
1808
|
this.options = options;
|
|
1574
1809
|
}
|
|
1575
1810
|
isEnabled() {
|
|
1576
|
-
return this.
|
|
1811
|
+
return this.manualTelemetry.isEnabled();
|
|
1577
1812
|
}
|
|
1578
1813
|
enable() {
|
|
1579
1814
|
this.options.module.instrument(this);
|
|
1580
|
-
this.
|
|
1815
|
+
this.manualTelemetry.enable();
|
|
1581
1816
|
}
|
|
1582
1817
|
disable() {
|
|
1583
|
-
this.
|
|
1818
|
+
this.manualTelemetry.disable();
|
|
1584
1819
|
this.options.module.uninstrument();
|
|
1585
1820
|
}
|
|
1586
1821
|
countTokens(messages) {
|
|
@@ -1604,7 +1839,8 @@ class LatitudeInstrumentation {
|
|
|
1604
1839
|
}
|
|
1605
1840
|
async wrapRenderChain(fn, ...args) {
|
|
1606
1841
|
const { prompt, parameters } = args[0];
|
|
1607
|
-
const $prompt = this.
|
|
1842
|
+
const $prompt = this.manualTelemetry.prompt(otel.context.active(), {
|
|
1843
|
+
documentLogUuid: uuid.v4(),
|
|
1608
1844
|
versionUuid: prompt.versionUuid,
|
|
1609
1845
|
promptUuid: prompt.uuid,
|
|
1610
1846
|
template: prompt.content,
|
|
@@ -1621,26 +1857,13 @@ class LatitudeInstrumentation {
|
|
|
1621
1857
|
$prompt.end();
|
|
1622
1858
|
return result;
|
|
1623
1859
|
}
|
|
1624
|
-
async wrapRenderStep(fn, ...args) {
|
|
1625
|
-
const $step = this.telemetry.step(otel.context.active());
|
|
1626
|
-
let result;
|
|
1627
|
-
try {
|
|
1628
|
-
result = await otel.context.with($step.context, async () => await fn(...args));
|
|
1629
|
-
}
|
|
1630
|
-
catch (error) {
|
|
1631
|
-
$step.fail(error);
|
|
1632
|
-
throw error;
|
|
1633
|
-
}
|
|
1634
|
-
$step.end();
|
|
1635
|
-
return result;
|
|
1636
|
-
}
|
|
1637
1860
|
async wrapRenderCompletion(fn, ...args) {
|
|
1638
1861
|
if (!this.options.completions) {
|
|
1639
1862
|
return await fn(...args);
|
|
1640
1863
|
}
|
|
1641
1864
|
const { provider, config, messages } = args[0];
|
|
1642
1865
|
const model = config.model || 'unknown';
|
|
1643
|
-
const $completion = this.
|
|
1866
|
+
const $completion = this.manualTelemetry.completion(otel.context.active(), {
|
|
1644
1867
|
name: `${provider} / ${model}`,
|
|
1645
1868
|
provider: provider,
|
|
1646
1869
|
model: model,
|
|
@@ -1667,14 +1890,14 @@ class LatitudeInstrumentation {
|
|
|
1667
1890
|
completion: completionTokens,
|
|
1668
1891
|
},
|
|
1669
1892
|
finishReason: result.toolRequests.length > 0
|
|
1670
|
-
?
|
|
1671
|
-
:
|
|
1893
|
+
? VALUES.OPENTELEMETRY.GEN_AI.response.finishReasons.toolCalls
|
|
1894
|
+
: VALUES.OPENTELEMETRY.GEN_AI.response.finishReasons.stop,
|
|
1672
1895
|
});
|
|
1673
1896
|
return result;
|
|
1674
1897
|
}
|
|
1675
1898
|
async wrapRenderTool(fn, ...args) {
|
|
1676
1899
|
const { toolRequest } = args[0];
|
|
1677
|
-
const $tool = this.
|
|
1900
|
+
const $tool = this.manualTelemetry.tool(otel.context.active(), {
|
|
1678
1901
|
name: toolRequest.toolName,
|
|
1679
1902
|
call: {
|
|
1680
1903
|
id: toolRequest.toolCallId,
|
|
@@ -1699,10 +1922,157 @@ class LatitudeInstrumentation {
|
|
|
1699
1922
|
}
|
|
1700
1923
|
}
|
|
1701
1924
|
|
|
1925
|
+
var LatitudeErrorCodes;
|
|
1926
|
+
(function (LatitudeErrorCodes) {
|
|
1927
|
+
LatitudeErrorCodes["UnexpectedError"] = "UnexpectedError";
|
|
1928
|
+
LatitudeErrorCodes["OverloadedError"] = "OverloadedError";
|
|
1929
|
+
LatitudeErrorCodes["RateLimitError"] = "RateLimitError";
|
|
1930
|
+
LatitudeErrorCodes["UnauthorizedError"] = "UnauthorizedError";
|
|
1931
|
+
LatitudeErrorCodes["ForbiddenError"] = "ForbiddenError";
|
|
1932
|
+
LatitudeErrorCodes["BadRequestError"] = "BadRequestError";
|
|
1933
|
+
LatitudeErrorCodes["NotFoundError"] = "NotFoundError";
|
|
1934
|
+
LatitudeErrorCodes["ConflictError"] = "ConflictError";
|
|
1935
|
+
LatitudeErrorCodes["UnprocessableEntityError"] = "UnprocessableEntityError";
|
|
1936
|
+
LatitudeErrorCodes["NotImplementedError"] = "NotImplementedError";
|
|
1937
|
+
LatitudeErrorCodes["PaymentRequiredError"] = "PaymentRequiredError";
|
|
1938
|
+
LatitudeErrorCodes["AbortedError"] = "AbortedError";
|
|
1939
|
+
LatitudeErrorCodes["BillingError"] = "BillingError";
|
|
1940
|
+
})(LatitudeErrorCodes || (LatitudeErrorCodes = {}));
|
|
1941
|
+
// NOTE: If you add a new error code, please add it to the pg enum in models/runErrors.ts
|
|
1942
|
+
var RunErrorCodes;
|
|
1943
|
+
(function (RunErrorCodes) {
|
|
1944
|
+
RunErrorCodes["AIProviderConfigError"] = "ai_provider_config_error";
|
|
1945
|
+
RunErrorCodes["AIRunError"] = "ai_run_error";
|
|
1946
|
+
RunErrorCodes["ChainCompileError"] = "chain_compile_error";
|
|
1947
|
+
RunErrorCodes["DefaultProviderExceededQuota"] = "default_provider_exceeded_quota_error";
|
|
1948
|
+
RunErrorCodes["DefaultProviderInvalidModel"] = "default_provider_invalid_model_error";
|
|
1949
|
+
RunErrorCodes["DocumentConfigError"] = "document_config_error";
|
|
1950
|
+
RunErrorCodes["ErrorGeneratingMockToolResult"] = "error_generating_mock_tool_result";
|
|
1951
|
+
RunErrorCodes["FailedToWakeUpIntegrationError"] = "failed_to_wake_up_integration_error";
|
|
1952
|
+
RunErrorCodes["InvalidResponseFormatError"] = "invalid_response_format_error";
|
|
1953
|
+
RunErrorCodes["MaxStepCountExceededError"] = "max_step_count_exceeded_error";
|
|
1954
|
+
RunErrorCodes["MissingProvider"] = "missing_provider_error";
|
|
1955
|
+
RunErrorCodes["RateLimit"] = "rate_limit_error";
|
|
1956
|
+
RunErrorCodes["Unknown"] = "unknown_error";
|
|
1957
|
+
RunErrorCodes["UnsupportedProviderResponseTypeError"] = "unsupported_provider_response_type_error";
|
|
1958
|
+
RunErrorCodes["PaymentRequiredError"] = "payment_required_error";
|
|
1959
|
+
RunErrorCodes["AbortError"] = "abort_error";
|
|
1960
|
+
// DEPRECATED, but do not delete
|
|
1961
|
+
RunErrorCodes["EvaluationRunMissingProviderLogError"] = "ev_run_missing_provider_log_error";
|
|
1962
|
+
RunErrorCodes["EvaluationRunMissingWorkspaceError"] = "ev_run_missing_workspace_error";
|
|
1963
|
+
RunErrorCodes["EvaluationRunResponseJsonFormatError"] = "ev_run_response_json_format_error";
|
|
1964
|
+
RunErrorCodes["EvaluationRunUnsupportedResultTypeError"] = "ev_run_unsupported_result_type_error";
|
|
1965
|
+
})(RunErrorCodes || (RunErrorCodes = {}));
|
|
1966
|
+
var ApiErrorCodes;
|
|
1967
|
+
(function (ApiErrorCodes) {
|
|
1968
|
+
ApiErrorCodes["HTTPException"] = "http_exception";
|
|
1969
|
+
ApiErrorCodes["InternalServerError"] = "internal_server_error";
|
|
1970
|
+
})(ApiErrorCodes || (ApiErrorCodes = {}));
|
|
1971
|
+
|
|
1972
|
+
class LatitudeError extends Error {
|
|
1973
|
+
statusCode = 500;
|
|
1974
|
+
name = LatitudeErrorCodes.UnexpectedError;
|
|
1975
|
+
headers = {};
|
|
1976
|
+
details;
|
|
1977
|
+
constructor(message, details, status, name) {
|
|
1978
|
+
super(message);
|
|
1979
|
+
this.details = details ?? {};
|
|
1980
|
+
this.statusCode = status ?? this.statusCode;
|
|
1981
|
+
this.name = name ?? this.constructor.name;
|
|
1982
|
+
}
|
|
1983
|
+
serialize() {
|
|
1984
|
+
return {
|
|
1985
|
+
name: this.name,
|
|
1986
|
+
code: this.name,
|
|
1987
|
+
status: this.statusCode,
|
|
1988
|
+
message: this.message,
|
|
1989
|
+
details: this.details,
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
static deserialize(json) {
|
|
1993
|
+
return new LatitudeError(json.message, json.details, json.status, json.name);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
class BadRequestError extends LatitudeError {
|
|
1997
|
+
statusCode = 400;
|
|
1998
|
+
name = LatitudeErrorCodes.BadRequestError;
|
|
1999
|
+
}
|
|
2000
|
+
|
|
1702
2001
|
const TRACES_URL = `${env.GATEWAY_BASE_URL}/api/v3/traces`;
|
|
1703
2002
|
const SERVICE_NAME = process.env.npm_package_name || 'unknown';
|
|
1704
2003
|
const SCOPE_VERSION = process.env.npm_package_version || 'unknown';
|
|
1705
2004
|
const BACKGROUND = () => otel__namespace.ROOT_CONTEXT;
|
|
2005
|
+
class SpanFactory {
|
|
2006
|
+
telemetry;
|
|
2007
|
+
constructor(telemetry) {
|
|
2008
|
+
this.telemetry = telemetry;
|
|
2009
|
+
}
|
|
2010
|
+
tool(options, ctx) {
|
|
2011
|
+
return this.telemetry.tool(ctx ?? otel.context.active(), options);
|
|
2012
|
+
}
|
|
2013
|
+
completion(options, ctx) {
|
|
2014
|
+
return this.telemetry.completion(ctx ?? otel.context.active(), options);
|
|
2015
|
+
}
|
|
2016
|
+
embedding(options, ctx) {
|
|
2017
|
+
return this.telemetry.embedding(ctx ?? otel.context.active(), options);
|
|
2018
|
+
}
|
|
2019
|
+
http(options, ctx) {
|
|
2020
|
+
return this.telemetry.http(ctx ?? otel.context.active(), options);
|
|
2021
|
+
}
|
|
2022
|
+
prompt(options, ctx) {
|
|
2023
|
+
return this.telemetry.prompt(ctx ?? otel.context.active(), options);
|
|
2024
|
+
}
|
|
2025
|
+
chat(options, ctx) {
|
|
2026
|
+
return this.telemetry.chat(ctx ?? otel.context.active(), options);
|
|
2027
|
+
}
|
|
2028
|
+
external(options, ctx) {
|
|
2029
|
+
return this.telemetry.external(ctx ?? otel.context.active(), options);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
class ContextManager {
|
|
2033
|
+
telemetry;
|
|
2034
|
+
constructor(telemetry) {
|
|
2035
|
+
this.telemetry = telemetry;
|
|
2036
|
+
}
|
|
2037
|
+
resume(ctx) {
|
|
2038
|
+
return this.telemetry.resume(ctx);
|
|
2039
|
+
}
|
|
2040
|
+
active() {
|
|
2041
|
+
return otel.context.active();
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
class InstrumentationManager {
|
|
2045
|
+
instrumentations;
|
|
2046
|
+
constructor(instrumentations) {
|
|
2047
|
+
this.instrumentations = instrumentations;
|
|
2048
|
+
}
|
|
2049
|
+
enable() {
|
|
2050
|
+
this.instrumentations.forEach((instrumentation) => {
|
|
2051
|
+
if (!instrumentation.isEnabled())
|
|
2052
|
+
instrumentation.enable();
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
disable() {
|
|
2056
|
+
this.instrumentations.forEach((instrumentation) => {
|
|
2057
|
+
if (instrumentation.isEnabled())
|
|
2058
|
+
instrumentation.disable();
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
class TracerManager {
|
|
2063
|
+
nodeProvider;
|
|
2064
|
+
scopeVersion;
|
|
2065
|
+
constructor(nodeProvider, scopeVersion) {
|
|
2066
|
+
this.nodeProvider = nodeProvider;
|
|
2067
|
+
this.scopeVersion = scopeVersion;
|
|
2068
|
+
}
|
|
2069
|
+
get(scope) {
|
|
2070
|
+
return this.provider(scope).getTracer('');
|
|
2071
|
+
}
|
|
2072
|
+
provider(scope) {
|
|
2073
|
+
return new ScopedTracerProvider(`${SCOPE_LATITUDE}.${scope}`, this.scopeVersion, this.nodeProvider);
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
1706
2076
|
class ScopedTracerProvider {
|
|
1707
2077
|
scope;
|
|
1708
2078
|
version;
|
|
@@ -1740,9 +2110,13 @@ exports.Instrumentation = void 0;
|
|
|
1740
2110
|
})(exports.Instrumentation || (exports.Instrumentation = {}));
|
|
1741
2111
|
class LatitudeTelemetry {
|
|
1742
2112
|
options;
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
2113
|
+
nodeProvider;
|
|
2114
|
+
manualInstrumentation;
|
|
2115
|
+
instrumentationsList;
|
|
2116
|
+
span;
|
|
2117
|
+
context;
|
|
2118
|
+
instrumentation;
|
|
2119
|
+
tracer;
|
|
1746
2120
|
constructor(apiKey, options) {
|
|
1747
2121
|
this.options = options || {};
|
|
1748
2122
|
if (!this.options.exporter) {
|
|
@@ -1756,63 +2130,61 @@ class LatitudeTelemetry {
|
|
|
1756
2130
|
new core.W3CBaggagePropagator(),
|
|
1757
2131
|
],
|
|
1758
2132
|
}));
|
|
1759
|
-
this.
|
|
2133
|
+
this.nodeProvider = new sdkTraceNode.NodeTracerProvider({
|
|
1760
2134
|
resource: new resources.Resource({ [semanticConventions.ATTR_SERVICE_NAME]: SERVICE_NAME }),
|
|
1761
2135
|
});
|
|
1762
2136
|
// Note: important, must run before the exporter span processors
|
|
1763
|
-
this.
|
|
2137
|
+
this.nodeProvider.addSpanProcessor(new baggageSpanProcessor.BaggageSpanProcessor(baggageSpanProcessor.ALLOW_ALL_BAGGAGE_KEYS));
|
|
1764
2138
|
if (this.options.processors) {
|
|
1765
2139
|
this.options.processors.forEach((processor) => {
|
|
1766
|
-
this.
|
|
2140
|
+
this.nodeProvider.addSpanProcessor(processor);
|
|
1767
2141
|
});
|
|
1768
2142
|
}
|
|
1769
2143
|
else {
|
|
1770
|
-
this.
|
|
2144
|
+
this.nodeProvider.addSpanProcessor(DEFAULT_REDACT_SPAN_PROCESSOR());
|
|
1771
2145
|
}
|
|
1772
2146
|
if (this.options.disableBatch) {
|
|
1773
|
-
this.
|
|
2147
|
+
this.nodeProvider.addSpanProcessor(new sdkTraceNode.SimpleSpanProcessor(this.options.exporter));
|
|
1774
2148
|
}
|
|
1775
2149
|
else {
|
|
1776
|
-
this.
|
|
2150
|
+
this.nodeProvider.addSpanProcessor(new sdkTraceNode.BatchSpanProcessor(this.options.exporter));
|
|
1777
2151
|
}
|
|
1778
|
-
this.
|
|
2152
|
+
this.nodeProvider.register();
|
|
1779
2153
|
process.on('SIGTERM', async () => this.shutdown);
|
|
1780
2154
|
process.on('SIGINT', async () => this.shutdown);
|
|
1781
|
-
this.
|
|
1782
|
-
this.
|
|
2155
|
+
this.manualInstrumentation = null;
|
|
2156
|
+
this.instrumentationsList = [];
|
|
2157
|
+
this.tracer = new TracerManager(this.nodeProvider, SCOPE_VERSION);
|
|
1783
2158
|
this.initInstrumentations();
|
|
1784
|
-
this.
|
|
2159
|
+
this.instrumentation = new InstrumentationManager(this.instrumentationsList);
|
|
2160
|
+
this.instrumentation.enable();
|
|
2161
|
+
this.span = new SpanFactory(this.manualInstrumentation);
|
|
2162
|
+
this.context = new ContextManager(this.manualInstrumentation);
|
|
1785
2163
|
}
|
|
1786
2164
|
async flush() {
|
|
1787
|
-
await this.
|
|
2165
|
+
await this.nodeProvider.forceFlush();
|
|
1788
2166
|
await this.options.exporter.forceFlush?.();
|
|
1789
2167
|
}
|
|
1790
2168
|
async shutdown() {
|
|
1791
2169
|
await this.flush();
|
|
1792
|
-
await this.
|
|
2170
|
+
await this.nodeProvider.shutdown();
|
|
1793
2171
|
await this.options.exporter.shutdown?.();
|
|
1794
2172
|
}
|
|
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
2173
|
// TODO(tracing): auto instrument outgoing HTTP requests
|
|
1802
2174
|
initInstrumentations() {
|
|
1803
|
-
this.
|
|
1804
|
-
const tracer = this.tracer(InstrumentationScope.Manual);
|
|
1805
|
-
this.
|
|
1806
|
-
this.
|
|
2175
|
+
this.instrumentationsList = [];
|
|
2176
|
+
const tracer = this.tracer.get(InstrumentationScope.Manual);
|
|
2177
|
+
this.manualInstrumentation = new ManualInstrumentation(tracer);
|
|
2178
|
+
this.instrumentationsList.push(this.manualInstrumentation);
|
|
1807
2179
|
const latitude = this.options.instrumentations?.latitude;
|
|
1808
2180
|
if (latitude) {
|
|
1809
|
-
const tracer = this.tracer(exports.Instrumentation.Latitude);
|
|
2181
|
+
const tracer = this.tracer.get(exports.Instrumentation.Latitude);
|
|
1810
2182
|
const instrumentation = new LatitudeInstrumentation(tracer, typeof latitude === 'object' ? latitude : { module: latitude });
|
|
1811
|
-
this.
|
|
2183
|
+
this.instrumentationsList.push(instrumentation);
|
|
1812
2184
|
}
|
|
1813
2185
|
const configureInstrumentation = (instrumentationType, InstrumentationConstructor, instrumentationOptions) => {
|
|
1814
2186
|
const providerPkg = this.options.instrumentations?.[instrumentationType];
|
|
1815
|
-
const provider = this.
|
|
2187
|
+
const provider = this.tracer.provider(instrumentationType);
|
|
1816
2188
|
const instrumentation$1 = new InstrumentationConstructor(instrumentationOptions); // prettier-ignore
|
|
1817
2189
|
instrumentation$1.setTracerProvider(provider);
|
|
1818
2190
|
if (providerPkg) {
|
|
@@ -1822,7 +2194,7 @@ class LatitudeTelemetry {
|
|
|
1822
2194
|
instrumentations: [instrumentation$1],
|
|
1823
2195
|
tracerProvider: provider,
|
|
1824
2196
|
});
|
|
1825
|
-
this.
|
|
2197
|
+
this.instrumentationsList.push(instrumentation$1);
|
|
1826
2198
|
};
|
|
1827
2199
|
configureInstrumentation(exports.Instrumentation.Anthropic, instrumentationAnthropic.AnthropicInstrumentation); // prettier-ignore
|
|
1828
2200
|
configureInstrumentation(exports.Instrumentation.AIPlatform, instrumentationVertexai.AIPlatformInstrumentation); // prettier-ignore
|
|
@@ -1830,48 +2202,28 @@ class LatitudeTelemetry {
|
|
|
1830
2202
|
configureInstrumentation(exports.Instrumentation.Cohere, instrumentationCohere.CohereInstrumentation); // prettier-ignore
|
|
1831
2203
|
configureInstrumentation(exports.Instrumentation.Langchain, instrumentationLangchain.LangChainInstrumentation); // prettier-ignore
|
|
1832
2204
|
configureInstrumentation(exports.Instrumentation.LlamaIndex, instrumentationLlamaindex.LlamaIndexInstrumentation); // prettier-ignore
|
|
1833
|
-
|
|
1834
|
-
configureInstrumentation(exports.Instrumentation.
|
|
2205
|
+
// NOTE: `stream: true` in OpenAI make enrichTokens fail, so disabling.
|
|
2206
|
+
configureInstrumentation(exports.Instrumentation.OpenAI, instrumentationOpenai.OpenAIInstrumentation, { enrichTokens: false }); // prettier-ignore
|
|
2207
|
+
configureInstrumentation(exports.Instrumentation.TogetherAI, instrumentationTogether.TogetherInstrumentation, { enrichTokens: false }); // prettier-ignore
|
|
1835
2208
|
configureInstrumentation(exports.Instrumentation.VertexAI, instrumentationVertexai.VertexAIInstrumentation); // prettier-ignore
|
|
1836
2209
|
}
|
|
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);
|
|
2210
|
+
async capture(options, fn) {
|
|
2211
|
+
if (!DOCUMENT_PATH_REGEXP.test(options.path)) {
|
|
2212
|
+
throw new BadRequestError("Invalid path, no spaces. Only letters, numbers, '.', '-' and '_'");
|
|
2213
|
+
}
|
|
2214
|
+
const span = this.manualInstrumentation.unresolvedExternal(otel__namespace.ROOT_CONTEXT, options);
|
|
2215
|
+
try {
|
|
2216
|
+
const result = await otel.context.with(span.context, () => fn(span.context));
|
|
2217
|
+
span.end();
|
|
2218
|
+
return result;
|
|
2219
|
+
}
|
|
2220
|
+
catch (error) {
|
|
2221
|
+
span.fail(error);
|
|
2222
|
+
throw error;
|
|
2223
|
+
}
|
|
2224
|
+
finally {
|
|
2225
|
+
await this.flush();
|
|
2226
|
+
}
|
|
1875
2227
|
}
|
|
1876
2228
|
}
|
|
1877
2229
|
|