@cloudbase/agent-observability 0.0.16 → 0.0.18
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/README.md +20 -5
- package/dist/chunk-5EXUNUGP.mjs +60 -0
- package/dist/chunk-5EXUNUGP.mjs.map +1 -0
- package/dist/{chunk-ZGEMAYS4.mjs → chunk-AHSI4KTT.mjs} +399 -92
- package/dist/chunk-AHSI4KTT.mjs.map +1 -0
- package/dist/index.d.mts +369 -33
- package/dist/index.d.ts +369 -33
- package/dist/index.js +399 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -5
- package/dist/langchain.d.mts +7 -5
- package/dist/langchain.d.ts +7 -5
- package/dist/langchain.js +421 -60
- package/dist/langchain.js.map +1 -1
- package/dist/langchain.mjs +31 -11
- package/dist/langchain.mjs.map +1 -1
- package/dist/server.d.mts +72 -6
- package/dist/server.d.ts +72 -6
- package/dist/server.js +129 -13
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +96 -13
- package/dist/server.mjs.map +1 -1
- package/package.json +2 -2
- package/src/core/attributes.ts +256 -11
- package/src/core/constants.ts +14 -16
- package/src/core/spanWrapper.ts +34 -33
- package/src/core/trace-context.ts +469 -0
- package/src/core/tracerProvider.ts +1 -4
- package/src/index.ts +54 -40
- package/src/langchain/CallbackHandler.ts +48 -17
- package/src/langchain/index.ts +1 -1
- package/src/server/SingleLineConsoleSpanExporter.ts +141 -0
- package/src/server/config.ts +2 -4
- package/src/server/index.ts +9 -3
- package/src/server/setup.ts +30 -20
- package/src/types.ts +112 -10
- package/dist/chunk-ZGEMAYS4.mjs.map +0 -1
|
@@ -1,55 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OBSERVABILITY_SDK_NAME,
|
|
3
|
+
OBSERVABILITY_SDK_VERSION,
|
|
4
|
+
OpenInferenceSpanKind,
|
|
5
|
+
OtelSpanAttributes,
|
|
6
|
+
init_constants
|
|
7
|
+
} from "./chunk-5EXUNUGP.mjs";
|
|
1
8
|
import {
|
|
2
9
|
__esm,
|
|
3
10
|
__export,
|
|
4
11
|
__toCommonJS
|
|
5
12
|
} from "./chunk-NFEGQTCC.mjs";
|
|
6
13
|
|
|
7
|
-
// src/core/constants.ts
|
|
8
|
-
import {
|
|
9
|
-
SemanticConventions,
|
|
10
|
-
OpenInferenceSpanKind
|
|
11
|
-
} from "@arizeai/openinference-semantic-conventions";
|
|
12
|
-
var OtelSpanAttributes;
|
|
13
|
-
var init_constants = __esm({
|
|
14
|
-
"src/core/constants.ts"() {
|
|
15
|
-
"use strict";
|
|
16
|
-
OtelSpanAttributes = {
|
|
17
|
-
// OpenInference - re-export all standard conventions
|
|
18
|
-
...SemanticConventions,
|
|
19
|
-
// AG-Kit Trace attributes (non-standard)
|
|
20
|
-
TRACE_NAME: "trace.name",
|
|
21
|
-
TRACE_TAGS: "trace.tags",
|
|
22
|
-
TRACE_PUBLIC: "trace.public",
|
|
23
|
-
TRACE_METADATA: "trace.metadata",
|
|
24
|
-
TRACE_INPUT: "trace.input",
|
|
25
|
-
TRACE_OUTPUT: "trace.output",
|
|
26
|
-
// AG-Kit Observation attributes (non-standard)
|
|
27
|
-
OBSERVATION_TYPE: "observation.type",
|
|
28
|
-
OBSERVATION_LEVEL: "observation.level",
|
|
29
|
-
OBSERVATION_STATUS_MESSAGE: "observation.status_message",
|
|
30
|
-
OBSERVATION_INPUT: "observation.input",
|
|
31
|
-
OBSERVATION_OUTPUT: "observation.output",
|
|
32
|
-
OBSERVATION_METADATA: "observation.metadata",
|
|
33
|
-
// AG-Kit LLM-specific (non-standard)
|
|
34
|
-
LLM_COMPLETION_START_TIME: "llm.completion_start_time",
|
|
35
|
-
LLM_MODEL_PARAMETERS: "llm.model_parameters",
|
|
36
|
-
LLM_USAGE_DETAILS: "llm.usage_details",
|
|
37
|
-
LLM_COST_DETAILS: "llm.cost_details",
|
|
38
|
-
// AG-Kit Retriever-specific (non-standard)
|
|
39
|
-
RETRIEVER_NAME: "retriever.name",
|
|
40
|
-
RETRIEVER_QUERY: "retriever.query",
|
|
41
|
-
RETRIEVER_INDEX_ID: "retriever.index_id",
|
|
42
|
-
RETRIEVER_TOP_K: "retriever.top_k",
|
|
43
|
-
// AG-Kit General (non-standard)
|
|
44
|
-
ENVIRONMENT: "environment",
|
|
45
|
-
RELEASE: "release",
|
|
46
|
-
VERSION: "version"
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
|
|
51
14
|
// src/core/attributes.ts
|
|
52
|
-
import { SemanticConventions
|
|
15
|
+
import { SemanticConventions } from "@arizeai/openinference-semantic-conventions";
|
|
53
16
|
function createTraceAttributes({
|
|
54
17
|
name,
|
|
55
18
|
userId,
|
|
@@ -94,40 +57,53 @@ function createObservationAttributes(type, attributes) {
|
|
|
94
57
|
modelParameters,
|
|
95
58
|
usageDetails
|
|
96
59
|
} = attributes;
|
|
60
|
+
const spanKind = OpenInferenceSpanKind[type.toUpperCase()] || "CHAIN";
|
|
97
61
|
const otelAttributes = {
|
|
98
|
-
[
|
|
62
|
+
[SemanticConventions.OPENINFERENCE_SPAN_KIND]: spanKind,
|
|
99
63
|
[OtelSpanAttributes.OBSERVATION_TYPE]: type,
|
|
100
64
|
[OtelSpanAttributes.OBSERVATION_LEVEL]: level,
|
|
101
65
|
[OtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,
|
|
102
66
|
[OtelSpanAttributes.VERSION]: version,
|
|
103
67
|
// Use OpenInference input.value convention
|
|
104
|
-
[
|
|
105
|
-
// Also set
|
|
68
|
+
[SemanticConventions.INPUT_VALUE]: _serialize(input),
|
|
69
|
+
// Also set observation.input for compatibility
|
|
106
70
|
[OtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),
|
|
107
71
|
// Use OpenInference output.value convention
|
|
108
|
-
[
|
|
109
|
-
// Also set
|
|
72
|
+
[SemanticConventions.OUTPUT_VALUE]: _serialize(output),
|
|
73
|
+
// Also set observation.output for compatibility
|
|
110
74
|
[OtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output)
|
|
111
75
|
};
|
|
112
76
|
if (type === "llm") {
|
|
113
77
|
if (model) {
|
|
114
|
-
otelAttributes[
|
|
78
|
+
otelAttributes[SemanticConventions.LLM_MODEL_NAME] = model;
|
|
79
|
+
}
|
|
80
|
+
const system = attributes?.system;
|
|
81
|
+
const provider = attributes?.provider;
|
|
82
|
+
const inputMessages = attributes?.inputMessages;
|
|
83
|
+
const outputMessages = attributes?.outputMessages;
|
|
84
|
+
const inputMimeType = attributes?.inputMimeType;
|
|
85
|
+
const outputMimeType = attributes?.outputMimeType;
|
|
86
|
+
if (system !== void 0) {
|
|
87
|
+
otelAttributes[SemanticConventions.LLM_SYSTEM] = String(system);
|
|
88
|
+
}
|
|
89
|
+
if (provider !== void 0) {
|
|
90
|
+
otelAttributes[SemanticConventions.LLM_PROVIDER] = String(provider);
|
|
115
91
|
}
|
|
116
92
|
if (modelParameters) {
|
|
117
|
-
otelAttributes[
|
|
93
|
+
otelAttributes[SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
|
|
118
94
|
otelAttributes[OtelSpanAttributes.LLM_MODEL_PARAMETERS] = _serialize(modelParameters);
|
|
119
95
|
}
|
|
120
96
|
if (usageDetails) {
|
|
121
97
|
if (typeof usageDetails === "object") {
|
|
122
98
|
const usage = usageDetails;
|
|
123
99
|
if (usage.promptTokens !== void 0) {
|
|
124
|
-
otelAttributes[
|
|
100
|
+
otelAttributes[SemanticConventions.LLM_TOKEN_COUNT_PROMPT] = usage.promptTokens;
|
|
125
101
|
}
|
|
126
102
|
if (usage.completionTokens !== void 0) {
|
|
127
|
-
otelAttributes[
|
|
103
|
+
otelAttributes[SemanticConventions.LLM_TOKEN_COUNT_COMPLETION] = usage.completionTokens;
|
|
128
104
|
}
|
|
129
105
|
if (usage.totalTokens !== void 0) {
|
|
130
|
-
otelAttributes[
|
|
106
|
+
otelAttributes[SemanticConventions.LLM_TOKEN_COUNT_TOTAL] = usage.totalTokens;
|
|
131
107
|
}
|
|
132
108
|
}
|
|
133
109
|
otelAttributes[OtelSpanAttributes.LLM_USAGE_DETAILS] = _serialize(usageDetails);
|
|
@@ -135,18 +111,68 @@ function createObservationAttributes(type, attributes) {
|
|
|
135
111
|
if (completionStartTime) {
|
|
136
112
|
otelAttributes[OtelSpanAttributes.LLM_COMPLETION_START_TIME] = _serialize(completionStartTime);
|
|
137
113
|
}
|
|
114
|
+
if (inputMessages !== void 0 && Array.isArray(inputMessages)) {
|
|
115
|
+
const messageAttrs = _flattenLLMMessages(inputMessages, "llm.input_messages");
|
|
116
|
+
Object.assign(otelAttributes, messageAttrs);
|
|
117
|
+
}
|
|
118
|
+
if (outputMessages !== void 0 && Array.isArray(outputMessages)) {
|
|
119
|
+
const messageAttrs = _flattenLLMMessages(outputMessages, "llm.output_messages");
|
|
120
|
+
Object.assign(otelAttributes, messageAttrs);
|
|
121
|
+
}
|
|
122
|
+
if (inputMimeType !== void 0) {
|
|
123
|
+
otelAttributes[SemanticConventions.INPUT_MIME_TYPE] = String(inputMimeType);
|
|
124
|
+
}
|
|
125
|
+
if (outputMimeType !== void 0) {
|
|
126
|
+
otelAttributes[SemanticConventions.OUTPUT_MIME_TYPE] = String(outputMimeType);
|
|
127
|
+
}
|
|
138
128
|
}
|
|
139
129
|
if (type === "embedding") {
|
|
140
130
|
if (model) {
|
|
141
|
-
otelAttributes[
|
|
131
|
+
otelAttributes[SemanticConventions.EMBEDDING_MODEL_NAME] = model;
|
|
142
132
|
}
|
|
143
133
|
if (modelParameters) {
|
|
144
|
-
otelAttributes[
|
|
134
|
+
otelAttributes[SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (type === "tool") {
|
|
138
|
+
const toolName = attributes?.toolName ?? attributes?.tool_name;
|
|
139
|
+
const toolDescription = attributes?.toolDescription;
|
|
140
|
+
const toolParameters = attributes?.toolParameters;
|
|
141
|
+
const toolCall = attributes?.toolCall;
|
|
142
|
+
if (toolName !== void 0) {
|
|
143
|
+
otelAttributes[SemanticConventions.TOOL_NAME] = String(toolName);
|
|
144
|
+
}
|
|
145
|
+
if (toolDescription !== void 0) {
|
|
146
|
+
otelAttributes[SemanticConventions.TOOL_DESCRIPTION] = String(toolDescription);
|
|
147
|
+
}
|
|
148
|
+
if (toolParameters !== void 0) {
|
|
149
|
+
otelAttributes[SemanticConventions.TOOL_PARAMETERS] = _serialize(toolParameters);
|
|
150
|
+
}
|
|
151
|
+
if (toolCall !== void 0 && typeof toolCall === "object") {
|
|
152
|
+
const toolCallAttrs = _flattenToolCall(toolCall);
|
|
153
|
+
Object.assign(otelAttributes, toolCallAttrs);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (type === "agent") {
|
|
157
|
+
const agentName = attributes?.agentName;
|
|
158
|
+
if (agentName !== void 0) {
|
|
159
|
+
otelAttributes[SemanticConventions.AGENT_NAME] = String(agentName);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (type === "retriever") {
|
|
163
|
+
const documents = attributes?.documents;
|
|
164
|
+
const query = attributes?.query;
|
|
165
|
+
if (documents !== void 0 && Array.isArray(documents)) {
|
|
166
|
+
const docAttrs = _flattenDocuments(documents);
|
|
167
|
+
Object.assign(otelAttributes, docAttrs);
|
|
168
|
+
}
|
|
169
|
+
if (query !== void 0) {
|
|
170
|
+
otelAttributes["retriever.query"] = String(query);
|
|
145
171
|
}
|
|
146
172
|
}
|
|
147
173
|
const metadataAttrs = _flattenAndSerializeMetadata(
|
|
148
174
|
metadata,
|
|
149
|
-
|
|
175
|
+
SemanticConventions.METADATA
|
|
150
176
|
);
|
|
151
177
|
Object.assign(otelAttributes, metadataAttrs);
|
|
152
178
|
const obsetvabilityMetadataAttrs = _flattenAndSerializeMetadata(
|
|
@@ -154,6 +180,11 @@ function createObservationAttributes(type, attributes) {
|
|
|
154
180
|
OtelSpanAttributes.OBSERVATION_METADATA
|
|
155
181
|
);
|
|
156
182
|
Object.assign(otelAttributes, obsetvabilityMetadataAttrs);
|
|
183
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
184
|
+
if (!(key in otelAttributes) && value !== void 0 && value !== null) {
|
|
185
|
+
otelAttributes[key] = typeof value === "string" ? value : _serialize(value);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
157
188
|
return Object.fromEntries(
|
|
158
189
|
Object.entries(otelAttributes).filter(([_, v]) => v != null)
|
|
159
190
|
);
|
|
@@ -187,6 +218,96 @@ function _flattenAndSerializeMetadata(metadata, prefix) {
|
|
|
187
218
|
}
|
|
188
219
|
return metadataAttributes;
|
|
189
220
|
}
|
|
221
|
+
function _flattenLLMMessages(messages, prefix) {
|
|
222
|
+
const attributes = {};
|
|
223
|
+
if (!messages || !Array.isArray(messages)) {
|
|
224
|
+
return attributes;
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
messages.forEach((msg, index) => {
|
|
228
|
+
if (!msg || typeof msg !== "object") return;
|
|
229
|
+
const baseKey = `${prefix}.${index}.message`;
|
|
230
|
+
if (msg.role !== void 0) {
|
|
231
|
+
attributes[`${baseKey}.role`] = String(msg.role);
|
|
232
|
+
}
|
|
233
|
+
if (msg.content !== void 0) {
|
|
234
|
+
attributes[`${baseKey}.content`] = String(msg.content);
|
|
235
|
+
}
|
|
236
|
+
if (msg.toolCallId !== void 0) {
|
|
237
|
+
attributes[`${baseKey}.tool_call_id`] = String(msg.toolCallId);
|
|
238
|
+
}
|
|
239
|
+
if (msg.toolCalls && Array.isArray(msg.toolCalls)) {
|
|
240
|
+
msg.toolCalls.forEach((toolCall, tcIndex) => {
|
|
241
|
+
if (!toolCall || typeof toolCall !== "object") return;
|
|
242
|
+
const tcKey = `${baseKey}.tool_calls.${tcIndex}`;
|
|
243
|
+
if (toolCall.id !== void 0) {
|
|
244
|
+
attributes[`${tcKey}.id`] = String(toolCall.id);
|
|
245
|
+
}
|
|
246
|
+
if (toolCall.function !== void 0) {
|
|
247
|
+
if (toolCall.function.name !== void 0) {
|
|
248
|
+
attributes[`${tcKey}.function.name`] = String(toolCall.function.name);
|
|
249
|
+
}
|
|
250
|
+
if (toolCall.function.arguments !== void 0) {
|
|
251
|
+
attributes[`${tcKey}.function.arguments`] = String(toolCall.function.arguments);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
} catch (e) {
|
|
258
|
+
}
|
|
259
|
+
return attributes;
|
|
260
|
+
}
|
|
261
|
+
function _flattenDocuments(documents) {
|
|
262
|
+
const attributes = {};
|
|
263
|
+
if (!documents || !Array.isArray(documents)) {
|
|
264
|
+
return attributes;
|
|
265
|
+
}
|
|
266
|
+
try {
|
|
267
|
+
documents.forEach((doc, index) => {
|
|
268
|
+
if (!doc || typeof doc !== "object") return;
|
|
269
|
+
const baseKey = `retrieval.documents.${index}.document`;
|
|
270
|
+
if (doc.id !== void 0) {
|
|
271
|
+
attributes[`${baseKey}.id`] = String(doc.id);
|
|
272
|
+
}
|
|
273
|
+
if (doc.content !== void 0) {
|
|
274
|
+
attributes[`${baseKey}.content`] = String(doc.content);
|
|
275
|
+
}
|
|
276
|
+
if (doc.score !== void 0) {
|
|
277
|
+
attributes[`${baseKey}.score`] = String(doc.score);
|
|
278
|
+
}
|
|
279
|
+
if (doc.metadata !== void 0 && typeof doc.metadata === "object") {
|
|
280
|
+
const metadataSerialized = _serialize(doc.metadata);
|
|
281
|
+
if (metadataSerialized) {
|
|
282
|
+
attributes[`${baseKey}.metadata`] = metadataSerialized;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
} catch (e) {
|
|
287
|
+
}
|
|
288
|
+
return attributes;
|
|
289
|
+
}
|
|
290
|
+
function _flattenToolCall(toolCall) {
|
|
291
|
+
const attributes = {};
|
|
292
|
+
if (!toolCall || typeof toolCall !== "object") {
|
|
293
|
+
return attributes;
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
if (toolCall.id !== void 0) {
|
|
297
|
+
attributes["tool_call.id"] = String(toolCall.id);
|
|
298
|
+
}
|
|
299
|
+
if (toolCall.function !== void 0) {
|
|
300
|
+
if (toolCall.function.name !== void 0) {
|
|
301
|
+
attributes["tool_call.function.name"] = String(toolCall.function.name);
|
|
302
|
+
}
|
|
303
|
+
if (toolCall.function.arguments !== void 0) {
|
|
304
|
+
attributes["tool_call.function.arguments"] = String(toolCall.function.arguments);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
} catch (e) {
|
|
308
|
+
}
|
|
309
|
+
return attributes;
|
|
310
|
+
}
|
|
190
311
|
var init_attributes = __esm({
|
|
191
312
|
"src/core/attributes.ts"() {
|
|
192
313
|
"use strict";
|
|
@@ -241,18 +362,18 @@ function getTracer() {
|
|
|
241
362
|
OBSERVABILITY_SDK_VERSION
|
|
242
363
|
);
|
|
243
364
|
}
|
|
244
|
-
var OBSERVABILITY_GLOBAL_SYMBOL
|
|
365
|
+
var OBSERVABILITY_GLOBAL_SYMBOL;
|
|
245
366
|
var init_tracerProvider = __esm({
|
|
246
367
|
"src/core/tracerProvider.ts"() {
|
|
247
368
|
"use strict";
|
|
369
|
+
init_constants();
|
|
248
370
|
OBSERVABILITY_GLOBAL_SYMBOL = /* @__PURE__ */ Symbol.for("observability");
|
|
249
|
-
OBSERVABILITY_SDK_NAME = "ag-kit-observability";
|
|
250
|
-
OBSERVABILITY_SDK_VERSION = "0.1.0";
|
|
251
371
|
}
|
|
252
372
|
});
|
|
253
373
|
|
|
254
374
|
// src/core/spanWrapper.ts
|
|
255
|
-
|
|
375
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
376
|
+
var BaseObservation, ObservationLLM, ObservationEmbedding, ObservationAgent, ObservationTool, ObservationChain, ObservationRetriever, ObservationReranker, ObservationEvaluator, ObservationGuardrail;
|
|
256
377
|
var init_spanWrapper = __esm({
|
|
257
378
|
"src/core/spanWrapper.ts"() {
|
|
258
379
|
"use strict";
|
|
@@ -278,7 +399,7 @@ var init_spanWrapper = __esm({
|
|
|
278
399
|
);
|
|
279
400
|
}
|
|
280
401
|
}
|
|
281
|
-
/** Gets the
|
|
402
|
+
/** Gets the OpenTelemetry tracer instance */
|
|
282
403
|
get tracer() {
|
|
283
404
|
return getTracer();
|
|
284
405
|
}
|
|
@@ -290,6 +411,27 @@ var init_spanWrapper = __esm({
|
|
|
290
411
|
end(endTime) {
|
|
291
412
|
this.otelSpan.end(endTime);
|
|
292
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Sets the span status.
|
|
416
|
+
*
|
|
417
|
+
* @param status - The status to set on the span
|
|
418
|
+
*/
|
|
419
|
+
setStatus(status) {
|
|
420
|
+
this.otelSpan.setStatus(status);
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Sets the span status to ERROR.
|
|
424
|
+
*
|
|
425
|
+
* Convenience method for marking the span as failed.
|
|
426
|
+
*
|
|
427
|
+
* @param message - Error description message
|
|
428
|
+
*/
|
|
429
|
+
setErrorStatus(message) {
|
|
430
|
+
this.otelSpan.setStatus({
|
|
431
|
+
code: SpanStatusCode.ERROR,
|
|
432
|
+
message
|
|
433
|
+
});
|
|
434
|
+
}
|
|
293
435
|
/**
|
|
294
436
|
* Updates the OTEL span attributes.
|
|
295
437
|
*
|
|
@@ -313,22 +455,13 @@ var init_spanWrapper = __esm({
|
|
|
313
455
|
}
|
|
314
456
|
startObservation(name, attributes, options) {
|
|
315
457
|
const { startObservation: startObs } = (init_src(), __toCommonJS(src_exports));
|
|
316
|
-
const { asType = "
|
|
458
|
+
const { asType = "chain" } = options || {};
|
|
317
459
|
return startObs(name, attributes, {
|
|
318
460
|
asType,
|
|
319
461
|
parentSpanContext: this.otelSpan.spanContext()
|
|
320
462
|
});
|
|
321
463
|
}
|
|
322
464
|
};
|
|
323
|
-
ObservationSpan = class extends BaseObservation {
|
|
324
|
-
constructor(params) {
|
|
325
|
-
super({ ...params, type: "span" });
|
|
326
|
-
}
|
|
327
|
-
update(attributes) {
|
|
328
|
-
super.updateOtelSpanAttributes(attributes);
|
|
329
|
-
return this;
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
465
|
ObservationLLM = class extends BaseObservation {
|
|
333
466
|
constructor(params) {
|
|
334
467
|
super({ ...params, type: "llm" });
|
|
@@ -413,6 +546,170 @@ var init_spanWrapper = __esm({
|
|
|
413
546
|
}
|
|
414
547
|
});
|
|
415
548
|
|
|
549
|
+
// src/core/trace-context.ts
|
|
550
|
+
import { TraceFlags } from "@opentelemetry/api";
|
|
551
|
+
function validateTraceId(traceId) {
|
|
552
|
+
if (!traceId || typeof traceId !== "string") {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
if (traceId.length !== 32) {
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
const chunk1 = traceId.slice(0, 16);
|
|
559
|
+
const chunk2 = traceId.slice(16, 32);
|
|
560
|
+
const value1 = parseInt(chunk1, 16);
|
|
561
|
+
const value2 = parseInt(chunk2, 16);
|
|
562
|
+
if (isNaN(value1) || isNaN(value2)) {
|
|
563
|
+
return false;
|
|
564
|
+
}
|
|
565
|
+
if (value1 === 0 && value2 === 0) {
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
570
|
+
function validateSpanId(spanId) {
|
|
571
|
+
if (!spanId || typeof spanId !== "string") {
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
if (spanId.length !== 16) {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
const value = parseInt(spanId, 16);
|
|
578
|
+
if (isNaN(value)) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
if (value === 0) {
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
function validateTraceContext(traceId, parentSpanId) {
|
|
587
|
+
const result = {
|
|
588
|
+
errors: [],
|
|
589
|
+
isValid: false,
|
|
590
|
+
hasTraceId: false,
|
|
591
|
+
hasParentSpanId: false
|
|
592
|
+
};
|
|
593
|
+
if (!traceId && !parentSpanId) {
|
|
594
|
+
result.isValid = true;
|
|
595
|
+
return result;
|
|
596
|
+
}
|
|
597
|
+
if (!traceId && parentSpanId) {
|
|
598
|
+
result.errors.push(
|
|
599
|
+
"parentSpanId provided without traceId - traceId is required when inheriting parent span"
|
|
600
|
+
);
|
|
601
|
+
return result;
|
|
602
|
+
}
|
|
603
|
+
if (traceId) {
|
|
604
|
+
if (!validateTraceId(traceId)) {
|
|
605
|
+
result.errors.push(
|
|
606
|
+
`Invalid traceId format: '${traceId}' - must be 32 hex characters and not all zeros`
|
|
607
|
+
);
|
|
608
|
+
} else {
|
|
609
|
+
result.traceId = traceId.toLowerCase();
|
|
610
|
+
result.hasTraceId = true;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
if (parentSpanId) {
|
|
614
|
+
if (!validateSpanId(parentSpanId)) {
|
|
615
|
+
result.errors.push(
|
|
616
|
+
`Invalid parentSpanId format: '${parentSpanId}' - must be 16 hex characters and not all zeros`
|
|
617
|
+
);
|
|
618
|
+
} else {
|
|
619
|
+
result.parentSpanId = parentSpanId.toLowerCase();
|
|
620
|
+
result.hasParentSpanId = true;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
result.isValid = result.errors.length === 0;
|
|
624
|
+
return result;
|
|
625
|
+
}
|
|
626
|
+
function createSpanLinkFromContext(traceId, parentSpanId, linkType = "follows_from", sourceSystem = "gateway") {
|
|
627
|
+
const externalContext = {
|
|
628
|
+
traceId,
|
|
629
|
+
spanId: parentSpanId,
|
|
630
|
+
traceFlags: TraceFlags.SAMPLED
|
|
631
|
+
};
|
|
632
|
+
const link = {
|
|
633
|
+
context: externalContext,
|
|
634
|
+
attributes: {
|
|
635
|
+
"link.type": linkType,
|
|
636
|
+
"link.source": sourceSystem,
|
|
637
|
+
"link.trace_id": traceId,
|
|
638
|
+
"link.span_id": parentSpanId
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
return link;
|
|
642
|
+
}
|
|
643
|
+
function extractTraceContextFromHeaders(headers, traceIdHeader = "x-trace-id", parentSpanIdHeader = "x-parent-span-id") {
|
|
644
|
+
if (!headers) {
|
|
645
|
+
return [void 0, void 0];
|
|
646
|
+
}
|
|
647
|
+
let traceId;
|
|
648
|
+
let parentSpanId;
|
|
649
|
+
if (headers instanceof Headers) {
|
|
650
|
+
traceId = headers.get(traceIdHeader) || void 0;
|
|
651
|
+
parentSpanId = headers.get(parentSpanIdHeader) || void 0;
|
|
652
|
+
} else {
|
|
653
|
+
const headersLower = {};
|
|
654
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
655
|
+
headersLower[key.toLowerCase()] = value;
|
|
656
|
+
}
|
|
657
|
+
traceId = headersLower[traceIdHeader.toLowerCase()];
|
|
658
|
+
parentSpanId = headersLower[parentSpanIdHeader.toLowerCase()];
|
|
659
|
+
}
|
|
660
|
+
return [traceId, parentSpanId];
|
|
661
|
+
}
|
|
662
|
+
function processTraceContextFromHeaders(headers, logger, linkType = "follows_from", sourceSystem = "gateway") {
|
|
663
|
+
const [traceId, parentSpanId] = extractTraceContextFromHeaders(headers);
|
|
664
|
+
const validation = validateTraceContext(traceId, parentSpanId);
|
|
665
|
+
if (!validation.isValid) {
|
|
666
|
+
if (logger && logger.warn) {
|
|
667
|
+
validation.errors.forEach((error) => {
|
|
668
|
+
logger.warn(`Trace context validation failed: ${error}`);
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
return {
|
|
672
|
+
traceId: void 0,
|
|
673
|
+
parentSpanId: void 0,
|
|
674
|
+
isInherited: false,
|
|
675
|
+
hasParentLink: false,
|
|
676
|
+
spanAttributes: {},
|
|
677
|
+
links: []
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
const normalizedTraceId = validation.traceId;
|
|
681
|
+
const normalizedParentSpanId = validation.parentSpanId;
|
|
682
|
+
const attributes = {};
|
|
683
|
+
const links = [];
|
|
684
|
+
if (normalizedTraceId) {
|
|
685
|
+
attributes["trace.inherited"] = true;
|
|
686
|
+
attributes["trace.external_trace_id"] = normalizedTraceId;
|
|
687
|
+
}
|
|
688
|
+
if (normalizedTraceId && normalizedParentSpanId) {
|
|
689
|
+
const link = createSpanLinkFromContext(
|
|
690
|
+
normalizedTraceId,
|
|
691
|
+
normalizedParentSpanId,
|
|
692
|
+
linkType,
|
|
693
|
+
sourceSystem
|
|
694
|
+
);
|
|
695
|
+
links.push(link);
|
|
696
|
+
attributes["trace.external_parent_span_id"] = normalizedParentSpanId;
|
|
697
|
+
}
|
|
698
|
+
return {
|
|
699
|
+
traceId: normalizedTraceId,
|
|
700
|
+
parentSpanId: normalizedParentSpanId,
|
|
701
|
+
isInherited: !!normalizedTraceId,
|
|
702
|
+
hasParentLink: !!normalizedParentSpanId,
|
|
703
|
+
spanAttributes: attributes,
|
|
704
|
+
links
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
var init_trace_context = __esm({
|
|
708
|
+
"src/core/trace-context.ts"() {
|
|
709
|
+
"use strict";
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
|
|
416
713
|
// src/index.ts
|
|
417
714
|
var src_exports = {};
|
|
418
715
|
__export(src_exports, {
|
|
@@ -424,26 +721,34 @@ __export(src_exports, {
|
|
|
424
721
|
ObservationLLM: () => ObservationLLM,
|
|
425
722
|
ObservationReranker: () => ObservationReranker,
|
|
426
723
|
ObservationRetriever: () => ObservationRetriever,
|
|
427
|
-
ObservationSpan: () => ObservationSpan,
|
|
428
724
|
ObservationTool: () => ObservationTool,
|
|
429
725
|
createObservationAttributes: () => createObservationAttributes,
|
|
726
|
+
createSpanLinkFromContext: () => createSpanLinkFromContext,
|
|
430
727
|
createTraceAttributes: () => createTraceAttributes,
|
|
728
|
+
extractTraceContextFromHeaders: () => extractTraceContextFromHeaders,
|
|
431
729
|
getActiveSpanId: () => getActiveSpanId,
|
|
432
730
|
getActiveTraceId: () => getActiveTraceId,
|
|
433
731
|
getTracer: () => getTracer,
|
|
434
732
|
getTracerProvider: () => getTracerProvider,
|
|
435
733
|
observe: () => observe,
|
|
734
|
+
processTraceContextFromHeaders: () => processTraceContextFromHeaders,
|
|
436
735
|
setTracerProvider: () => setTracerProvider,
|
|
437
736
|
startActiveObservation: () => startActiveObservation,
|
|
438
737
|
startObservation: () => startObservation,
|
|
439
738
|
updateActiveObservation: () => updateActiveObservation,
|
|
440
|
-
updateActiveTrace: () => updateActiveTrace
|
|
739
|
+
updateActiveTrace: () => updateActiveTrace,
|
|
740
|
+
validateSpanId: () => validateSpanId,
|
|
741
|
+
validateTraceContext: () => validateTraceContext,
|
|
742
|
+
validateTraceId: () => validateTraceId
|
|
441
743
|
});
|
|
442
|
-
import { trace as trace2, context as context2, SpanStatusCode } from "@opentelemetry/api";
|
|
744
|
+
import { trace as trace2, context as context2, SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
|
|
443
745
|
function createOtelSpan(params) {
|
|
444
746
|
return getTracer().startSpan(
|
|
445
747
|
params.name,
|
|
446
|
-
{
|
|
748
|
+
{
|
|
749
|
+
startTime: params.startTime,
|
|
750
|
+
links: params.links || []
|
|
751
|
+
},
|
|
447
752
|
createParentContext(params.parentSpanContext)
|
|
448
753
|
);
|
|
449
754
|
}
|
|
@@ -452,7 +757,7 @@ function createParentContext(parentSpanContext) {
|
|
|
452
757
|
return trace2.setSpanContext(context2.active(), parentSpanContext);
|
|
453
758
|
}
|
|
454
759
|
function startObservation(name, attributes, options) {
|
|
455
|
-
const { asType = "
|
|
760
|
+
const { asType = "chain", ...observationOptions } = options || {};
|
|
456
761
|
const otelSpan = createOtelSpan({
|
|
457
762
|
name,
|
|
458
763
|
...observationOptions
|
|
@@ -503,9 +808,8 @@ function startObservation(name, attributes, options) {
|
|
|
503
808
|
otelSpan,
|
|
504
809
|
attributes
|
|
505
810
|
});
|
|
506
|
-
case "span":
|
|
507
811
|
default:
|
|
508
|
-
return new
|
|
812
|
+
return new ObservationChain({
|
|
509
813
|
otelSpan,
|
|
510
814
|
attributes
|
|
511
815
|
});
|
|
@@ -537,7 +841,7 @@ function wrapPromise(promise, span, endOnExit) {
|
|
|
537
841
|
},
|
|
538
842
|
(err) => {
|
|
539
843
|
span.setStatus({
|
|
540
|
-
code:
|
|
844
|
+
code: SpanStatusCode2.ERROR,
|
|
541
845
|
message: err instanceof Error ? err.message : "Unknown error"
|
|
542
846
|
});
|
|
543
847
|
if (endOnExit !== false) {
|
|
@@ -548,7 +852,7 @@ function wrapPromise(promise, span, endOnExit) {
|
|
|
548
852
|
);
|
|
549
853
|
}
|
|
550
854
|
function startActiveObservation(name, fn, options) {
|
|
551
|
-
const { asType = "
|
|
855
|
+
const { asType = "chain", endOnExit, ...observationOptions } = options || {};
|
|
552
856
|
return getTracer().startActiveSpan(
|
|
553
857
|
name,
|
|
554
858
|
{ startTime: observationOptions?.startTime },
|
|
@@ -569,9 +873,6 @@ function startActiveObservation(name, fn, options) {
|
|
|
569
873
|
case "tool":
|
|
570
874
|
observation = new ObservationTool({ otelSpan: span });
|
|
571
875
|
break;
|
|
572
|
-
case "chain":
|
|
573
|
-
observation = new ObservationChain({ otelSpan: span });
|
|
574
|
-
break;
|
|
575
876
|
case "retriever":
|
|
576
877
|
observation = new ObservationRetriever({ otelSpan: span });
|
|
577
878
|
break;
|
|
@@ -584,9 +885,9 @@ function startActiveObservation(name, fn, options) {
|
|
|
584
885
|
case "guardrail":
|
|
585
886
|
observation = new ObservationGuardrail({ otelSpan: span });
|
|
586
887
|
break;
|
|
587
|
-
case "
|
|
888
|
+
case "chain":
|
|
588
889
|
default:
|
|
589
|
-
observation = new
|
|
890
|
+
observation = new ObservationChain({ otelSpan: span });
|
|
590
891
|
}
|
|
591
892
|
const result = fn(observation);
|
|
592
893
|
if (result instanceof Promise) {
|
|
@@ -603,7 +904,7 @@ function startActiveObservation(name, fn, options) {
|
|
|
603
904
|
}
|
|
604
905
|
} catch (err) {
|
|
605
906
|
span.setStatus({
|
|
606
|
-
code:
|
|
907
|
+
code: SpanStatusCode2.ERROR,
|
|
607
908
|
message: err instanceof Error ? err.message : "Unknown error"
|
|
608
909
|
});
|
|
609
910
|
if (endOnExit !== false) {
|
|
@@ -622,7 +923,7 @@ function updateActiveObservation(attributes) {
|
|
|
622
923
|
);
|
|
623
924
|
return;
|
|
624
925
|
}
|
|
625
|
-
span.setAttributes(createObservationAttributes("
|
|
926
|
+
span.setAttributes(createObservationAttributes("chain", attributes));
|
|
626
927
|
}
|
|
627
928
|
function _captureArguments(args) {
|
|
628
929
|
if (args.length === 0) return {};
|
|
@@ -631,7 +932,7 @@ function _captureArguments(args) {
|
|
|
631
932
|
}
|
|
632
933
|
function observe(fn, options = {}) {
|
|
633
934
|
const {
|
|
634
|
-
asType = "
|
|
935
|
+
asType = "chain",
|
|
635
936
|
captureInput = true,
|
|
636
937
|
captureOutput = true,
|
|
637
938
|
...observationOptions
|
|
@@ -685,6 +986,7 @@ var init_src = __esm({
|
|
|
685
986
|
init_tracerProvider();
|
|
686
987
|
init_attributes();
|
|
687
988
|
init_tracerProvider();
|
|
989
|
+
init_trace_context();
|
|
688
990
|
}
|
|
689
991
|
});
|
|
690
992
|
|
|
@@ -694,7 +996,6 @@ export {
|
|
|
694
996
|
setTracerProvider,
|
|
695
997
|
getTracerProvider,
|
|
696
998
|
getTracer,
|
|
697
|
-
ObservationSpan,
|
|
698
999
|
ObservationLLM,
|
|
699
1000
|
ObservationEmbedding,
|
|
700
1001
|
ObservationAgent,
|
|
@@ -704,6 +1005,12 @@ export {
|
|
|
704
1005
|
ObservationReranker,
|
|
705
1006
|
ObservationEvaluator,
|
|
706
1007
|
ObservationGuardrail,
|
|
1008
|
+
validateTraceId,
|
|
1009
|
+
validateSpanId,
|
|
1010
|
+
validateTraceContext,
|
|
1011
|
+
createSpanLinkFromContext,
|
|
1012
|
+
extractTraceContextFromHeaders,
|
|
1013
|
+
processTraceContextFromHeaders,
|
|
707
1014
|
startObservation,
|
|
708
1015
|
updateActiveTrace,
|
|
709
1016
|
getActiveTraceId,
|
|
@@ -713,4 +1020,4 @@ export {
|
|
|
713
1020
|
observe,
|
|
714
1021
|
init_src
|
|
715
1022
|
};
|
|
716
|
-
//# sourceMappingURL=chunk-
|
|
1023
|
+
//# sourceMappingURL=chunk-AHSI4KTT.mjs.map
|