@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
package/dist/index.js
CHANGED
|
@@ -21,39 +21,41 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
21
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
22
|
|
|
23
23
|
// src/core/constants.ts
|
|
24
|
-
var import_openinference_semantic_conventions, OtelSpanAttributes;
|
|
24
|
+
var import_openinference_semantic_conventions, OBSERVABILITY_SDK_NAME, OBSERVABILITY_SDK_VERSION, OtelSpanAttributes;
|
|
25
25
|
var init_constants = __esm({
|
|
26
26
|
"src/core/constants.ts"() {
|
|
27
27
|
"use strict";
|
|
28
28
|
import_openinference_semantic_conventions = require("@arizeai/openinference-semantic-conventions");
|
|
29
|
+
OBSERVABILITY_SDK_NAME = "observability";
|
|
30
|
+
OBSERVABILITY_SDK_VERSION = "0.1.0";
|
|
29
31
|
OtelSpanAttributes = {
|
|
30
32
|
// OpenInference - re-export all standard conventions
|
|
31
33
|
...import_openinference_semantic_conventions.SemanticConventions,
|
|
32
|
-
//
|
|
34
|
+
// Trace attributes (non-standard)
|
|
33
35
|
TRACE_NAME: "trace.name",
|
|
34
36
|
TRACE_TAGS: "trace.tags",
|
|
35
37
|
TRACE_PUBLIC: "trace.public",
|
|
36
38
|
TRACE_METADATA: "trace.metadata",
|
|
37
39
|
TRACE_INPUT: "trace.input",
|
|
38
40
|
TRACE_OUTPUT: "trace.output",
|
|
39
|
-
//
|
|
41
|
+
// Observation attributes (non-standard)
|
|
40
42
|
OBSERVATION_TYPE: "observation.type",
|
|
41
43
|
OBSERVATION_LEVEL: "observation.level",
|
|
42
44
|
OBSERVATION_STATUS_MESSAGE: "observation.status_message",
|
|
43
45
|
OBSERVATION_INPUT: "observation.input",
|
|
44
46
|
OBSERVATION_OUTPUT: "observation.output",
|
|
45
47
|
OBSERVATION_METADATA: "observation.metadata",
|
|
46
|
-
//
|
|
48
|
+
// LLM-specific (non-standard)
|
|
47
49
|
LLM_COMPLETION_START_TIME: "llm.completion_start_time",
|
|
48
50
|
LLM_MODEL_PARAMETERS: "llm.model_parameters",
|
|
49
51
|
LLM_USAGE_DETAILS: "llm.usage_details",
|
|
50
52
|
LLM_COST_DETAILS: "llm.cost_details",
|
|
51
|
-
//
|
|
53
|
+
// Retriever-specific (non-standard)
|
|
52
54
|
RETRIEVER_NAME: "retriever.name",
|
|
53
55
|
RETRIEVER_QUERY: "retriever.query",
|
|
54
56
|
RETRIEVER_INDEX_ID: "retriever.index_id",
|
|
55
57
|
RETRIEVER_TOP_K: "retriever.top_k",
|
|
56
|
-
//
|
|
58
|
+
// General (non-standard)
|
|
57
59
|
ENVIRONMENT: "environment",
|
|
58
60
|
RELEASE: "release",
|
|
59
61
|
VERSION: "version"
|
|
@@ -106,25 +108,38 @@ function createObservationAttributes(type, attributes) {
|
|
|
106
108
|
modelParameters,
|
|
107
109
|
usageDetails
|
|
108
110
|
} = attributes;
|
|
111
|
+
const spanKind = import_openinference_semantic_conventions.OpenInferenceSpanKind[type.toUpperCase()] || "CHAIN";
|
|
109
112
|
const otelAttributes = {
|
|
110
|
-
[import_openinference_semantic_conventions2.SemanticConventions.OPENINFERENCE_SPAN_KIND]:
|
|
113
|
+
[import_openinference_semantic_conventions2.SemanticConventions.OPENINFERENCE_SPAN_KIND]: spanKind,
|
|
111
114
|
[OtelSpanAttributes.OBSERVATION_TYPE]: type,
|
|
112
115
|
[OtelSpanAttributes.OBSERVATION_LEVEL]: level,
|
|
113
116
|
[OtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,
|
|
114
117
|
[OtelSpanAttributes.VERSION]: version,
|
|
115
118
|
// Use OpenInference input.value convention
|
|
116
119
|
[import_openinference_semantic_conventions2.SemanticConventions.INPUT_VALUE]: _serialize(input),
|
|
117
|
-
// Also set
|
|
120
|
+
// Also set observation.input for compatibility
|
|
118
121
|
[OtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),
|
|
119
122
|
// Use OpenInference output.value convention
|
|
120
123
|
[import_openinference_semantic_conventions2.SemanticConventions.OUTPUT_VALUE]: _serialize(output),
|
|
121
|
-
// Also set
|
|
124
|
+
// Also set observation.output for compatibility
|
|
122
125
|
[OtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output)
|
|
123
126
|
};
|
|
124
127
|
if (type === "llm") {
|
|
125
128
|
if (model) {
|
|
126
129
|
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_MODEL_NAME] = model;
|
|
127
130
|
}
|
|
131
|
+
const system = attributes?.system;
|
|
132
|
+
const provider = attributes?.provider;
|
|
133
|
+
const inputMessages = attributes?.inputMessages;
|
|
134
|
+
const outputMessages = attributes?.outputMessages;
|
|
135
|
+
const inputMimeType = attributes?.inputMimeType;
|
|
136
|
+
const outputMimeType = attributes?.outputMimeType;
|
|
137
|
+
if (system !== void 0) {
|
|
138
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_SYSTEM] = String(system);
|
|
139
|
+
}
|
|
140
|
+
if (provider !== void 0) {
|
|
141
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_PROVIDER] = String(provider);
|
|
142
|
+
}
|
|
128
143
|
if (modelParameters) {
|
|
129
144
|
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
|
|
130
145
|
otelAttributes[OtelSpanAttributes.LLM_MODEL_PARAMETERS] = _serialize(modelParameters);
|
|
@@ -147,6 +162,20 @@ function createObservationAttributes(type, attributes) {
|
|
|
147
162
|
if (completionStartTime) {
|
|
148
163
|
otelAttributes[OtelSpanAttributes.LLM_COMPLETION_START_TIME] = _serialize(completionStartTime);
|
|
149
164
|
}
|
|
165
|
+
if (inputMessages !== void 0 && Array.isArray(inputMessages)) {
|
|
166
|
+
const messageAttrs = _flattenLLMMessages(inputMessages, "llm.input_messages");
|
|
167
|
+
Object.assign(otelAttributes, messageAttrs);
|
|
168
|
+
}
|
|
169
|
+
if (outputMessages !== void 0 && Array.isArray(outputMessages)) {
|
|
170
|
+
const messageAttrs = _flattenLLMMessages(outputMessages, "llm.output_messages");
|
|
171
|
+
Object.assign(otelAttributes, messageAttrs);
|
|
172
|
+
}
|
|
173
|
+
if (inputMimeType !== void 0) {
|
|
174
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.INPUT_MIME_TYPE] = String(inputMimeType);
|
|
175
|
+
}
|
|
176
|
+
if (outputMimeType !== void 0) {
|
|
177
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.OUTPUT_MIME_TYPE] = String(outputMimeType);
|
|
178
|
+
}
|
|
150
179
|
}
|
|
151
180
|
if (type === "embedding") {
|
|
152
181
|
if (model) {
|
|
@@ -156,6 +185,42 @@ function createObservationAttributes(type, attributes) {
|
|
|
156
185
|
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
|
|
157
186
|
}
|
|
158
187
|
}
|
|
188
|
+
if (type === "tool") {
|
|
189
|
+
const toolName = attributes?.toolName ?? attributes?.tool_name;
|
|
190
|
+
const toolDescription = attributes?.toolDescription;
|
|
191
|
+
const toolParameters = attributes?.toolParameters;
|
|
192
|
+
const toolCall = attributes?.toolCall;
|
|
193
|
+
if (toolName !== void 0) {
|
|
194
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.TOOL_NAME] = String(toolName);
|
|
195
|
+
}
|
|
196
|
+
if (toolDescription !== void 0) {
|
|
197
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.TOOL_DESCRIPTION] = String(toolDescription);
|
|
198
|
+
}
|
|
199
|
+
if (toolParameters !== void 0) {
|
|
200
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.TOOL_PARAMETERS] = _serialize(toolParameters);
|
|
201
|
+
}
|
|
202
|
+
if (toolCall !== void 0 && typeof toolCall === "object") {
|
|
203
|
+
const toolCallAttrs = _flattenToolCall(toolCall);
|
|
204
|
+
Object.assign(otelAttributes, toolCallAttrs);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (type === "agent") {
|
|
208
|
+
const agentName = attributes?.agentName;
|
|
209
|
+
if (agentName !== void 0) {
|
|
210
|
+
otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.AGENT_NAME] = String(agentName);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (type === "retriever") {
|
|
214
|
+
const documents = attributes?.documents;
|
|
215
|
+
const query = attributes?.query;
|
|
216
|
+
if (documents !== void 0 && Array.isArray(documents)) {
|
|
217
|
+
const docAttrs = _flattenDocuments(documents);
|
|
218
|
+
Object.assign(otelAttributes, docAttrs);
|
|
219
|
+
}
|
|
220
|
+
if (query !== void 0) {
|
|
221
|
+
otelAttributes["retriever.query"] = String(query);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
159
224
|
const metadataAttrs = _flattenAndSerializeMetadata(
|
|
160
225
|
metadata,
|
|
161
226
|
import_openinference_semantic_conventions2.SemanticConventions.METADATA
|
|
@@ -166,6 +231,11 @@ function createObservationAttributes(type, attributes) {
|
|
|
166
231
|
OtelSpanAttributes.OBSERVATION_METADATA
|
|
167
232
|
);
|
|
168
233
|
Object.assign(otelAttributes, obsetvabilityMetadataAttrs);
|
|
234
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
235
|
+
if (!(key in otelAttributes) && value !== void 0 && value !== null) {
|
|
236
|
+
otelAttributes[key] = typeof value === "string" ? value : _serialize(value);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
169
239
|
return Object.fromEntries(
|
|
170
240
|
Object.entries(otelAttributes).filter(([_, v]) => v != null)
|
|
171
241
|
);
|
|
@@ -199,6 +269,96 @@ function _flattenAndSerializeMetadata(metadata, prefix) {
|
|
|
199
269
|
}
|
|
200
270
|
return metadataAttributes;
|
|
201
271
|
}
|
|
272
|
+
function _flattenLLMMessages(messages, prefix) {
|
|
273
|
+
const attributes = {};
|
|
274
|
+
if (!messages || !Array.isArray(messages)) {
|
|
275
|
+
return attributes;
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
messages.forEach((msg, index) => {
|
|
279
|
+
if (!msg || typeof msg !== "object") return;
|
|
280
|
+
const baseKey = `${prefix}.${index}.message`;
|
|
281
|
+
if (msg.role !== void 0) {
|
|
282
|
+
attributes[`${baseKey}.role`] = String(msg.role);
|
|
283
|
+
}
|
|
284
|
+
if (msg.content !== void 0) {
|
|
285
|
+
attributes[`${baseKey}.content`] = String(msg.content);
|
|
286
|
+
}
|
|
287
|
+
if (msg.toolCallId !== void 0) {
|
|
288
|
+
attributes[`${baseKey}.tool_call_id`] = String(msg.toolCallId);
|
|
289
|
+
}
|
|
290
|
+
if (msg.toolCalls && Array.isArray(msg.toolCalls)) {
|
|
291
|
+
msg.toolCalls.forEach((toolCall, tcIndex) => {
|
|
292
|
+
if (!toolCall || typeof toolCall !== "object") return;
|
|
293
|
+
const tcKey = `${baseKey}.tool_calls.${tcIndex}`;
|
|
294
|
+
if (toolCall.id !== void 0) {
|
|
295
|
+
attributes[`${tcKey}.id`] = String(toolCall.id);
|
|
296
|
+
}
|
|
297
|
+
if (toolCall.function !== void 0) {
|
|
298
|
+
if (toolCall.function.name !== void 0) {
|
|
299
|
+
attributes[`${tcKey}.function.name`] = String(toolCall.function.name);
|
|
300
|
+
}
|
|
301
|
+
if (toolCall.function.arguments !== void 0) {
|
|
302
|
+
attributes[`${tcKey}.function.arguments`] = String(toolCall.function.arguments);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
} catch (e) {
|
|
309
|
+
}
|
|
310
|
+
return attributes;
|
|
311
|
+
}
|
|
312
|
+
function _flattenDocuments(documents) {
|
|
313
|
+
const attributes = {};
|
|
314
|
+
if (!documents || !Array.isArray(documents)) {
|
|
315
|
+
return attributes;
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
documents.forEach((doc, index) => {
|
|
319
|
+
if (!doc || typeof doc !== "object") return;
|
|
320
|
+
const baseKey = `retrieval.documents.${index}.document`;
|
|
321
|
+
if (doc.id !== void 0) {
|
|
322
|
+
attributes[`${baseKey}.id`] = String(doc.id);
|
|
323
|
+
}
|
|
324
|
+
if (doc.content !== void 0) {
|
|
325
|
+
attributes[`${baseKey}.content`] = String(doc.content);
|
|
326
|
+
}
|
|
327
|
+
if (doc.score !== void 0) {
|
|
328
|
+
attributes[`${baseKey}.score`] = String(doc.score);
|
|
329
|
+
}
|
|
330
|
+
if (doc.metadata !== void 0 && typeof doc.metadata === "object") {
|
|
331
|
+
const metadataSerialized = _serialize(doc.metadata);
|
|
332
|
+
if (metadataSerialized) {
|
|
333
|
+
attributes[`${baseKey}.metadata`] = metadataSerialized;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
} catch (e) {
|
|
338
|
+
}
|
|
339
|
+
return attributes;
|
|
340
|
+
}
|
|
341
|
+
function _flattenToolCall(toolCall) {
|
|
342
|
+
const attributes = {};
|
|
343
|
+
if (!toolCall || typeof toolCall !== "object") {
|
|
344
|
+
return attributes;
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
if (toolCall.id !== void 0) {
|
|
348
|
+
attributes["tool_call.id"] = String(toolCall.id);
|
|
349
|
+
}
|
|
350
|
+
if (toolCall.function !== void 0) {
|
|
351
|
+
if (toolCall.function.name !== void 0) {
|
|
352
|
+
attributes["tool_call.function.name"] = String(toolCall.function.name);
|
|
353
|
+
}
|
|
354
|
+
if (toolCall.function.arguments !== void 0) {
|
|
355
|
+
attributes["tool_call.function.arguments"] = String(toolCall.function.arguments);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
} catch (e) {
|
|
359
|
+
}
|
|
360
|
+
return attributes;
|
|
361
|
+
}
|
|
202
362
|
var import_openinference_semantic_conventions2;
|
|
203
363
|
var init_attributes = __esm({
|
|
204
364
|
"src/core/attributes.ts"() {
|
|
@@ -254,22 +414,22 @@ function getTracer() {
|
|
|
254
414
|
OBSERVABILITY_SDK_VERSION
|
|
255
415
|
);
|
|
256
416
|
}
|
|
257
|
-
var import_api, OBSERVABILITY_GLOBAL_SYMBOL
|
|
417
|
+
var import_api, OBSERVABILITY_GLOBAL_SYMBOL;
|
|
258
418
|
var init_tracerProvider = __esm({
|
|
259
419
|
"src/core/tracerProvider.ts"() {
|
|
260
420
|
"use strict";
|
|
261
421
|
import_api = require("@opentelemetry/api");
|
|
422
|
+
init_constants();
|
|
262
423
|
OBSERVABILITY_GLOBAL_SYMBOL = /* @__PURE__ */ Symbol.for("observability");
|
|
263
|
-
OBSERVABILITY_SDK_NAME = "ag-kit-observability";
|
|
264
|
-
OBSERVABILITY_SDK_VERSION = "0.1.0";
|
|
265
424
|
}
|
|
266
425
|
});
|
|
267
426
|
|
|
268
427
|
// src/core/spanWrapper.ts
|
|
269
|
-
var
|
|
428
|
+
var import_api2, BaseObservation, ObservationLLM, ObservationEmbedding, ObservationAgent, ObservationTool, ObservationChain, ObservationRetriever, ObservationReranker, ObservationEvaluator, ObservationGuardrail;
|
|
270
429
|
var init_spanWrapper = __esm({
|
|
271
430
|
"src/core/spanWrapper.ts"() {
|
|
272
431
|
"use strict";
|
|
432
|
+
import_api2 = require("@opentelemetry/api");
|
|
273
433
|
init_attributes();
|
|
274
434
|
init_tracerProvider();
|
|
275
435
|
BaseObservation = class {
|
|
@@ -292,7 +452,7 @@ var init_spanWrapper = __esm({
|
|
|
292
452
|
);
|
|
293
453
|
}
|
|
294
454
|
}
|
|
295
|
-
/** Gets the
|
|
455
|
+
/** Gets the OpenTelemetry tracer instance */
|
|
296
456
|
get tracer() {
|
|
297
457
|
return getTracer();
|
|
298
458
|
}
|
|
@@ -304,6 +464,27 @@ var init_spanWrapper = __esm({
|
|
|
304
464
|
end(endTime) {
|
|
305
465
|
this.otelSpan.end(endTime);
|
|
306
466
|
}
|
|
467
|
+
/**
|
|
468
|
+
* Sets the span status.
|
|
469
|
+
*
|
|
470
|
+
* @param status - The status to set on the span
|
|
471
|
+
*/
|
|
472
|
+
setStatus(status) {
|
|
473
|
+
this.otelSpan.setStatus(status);
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Sets the span status to ERROR.
|
|
477
|
+
*
|
|
478
|
+
* Convenience method for marking the span as failed.
|
|
479
|
+
*
|
|
480
|
+
* @param message - Error description message
|
|
481
|
+
*/
|
|
482
|
+
setErrorStatus(message) {
|
|
483
|
+
this.otelSpan.setStatus({
|
|
484
|
+
code: import_api2.SpanStatusCode.ERROR,
|
|
485
|
+
message
|
|
486
|
+
});
|
|
487
|
+
}
|
|
307
488
|
/**
|
|
308
489
|
* Updates the OTEL span attributes.
|
|
309
490
|
*
|
|
@@ -327,22 +508,13 @@ var init_spanWrapper = __esm({
|
|
|
327
508
|
}
|
|
328
509
|
startObservation(name, attributes, options) {
|
|
329
510
|
const { startObservation: startObs } = (init_src(), __toCommonJS(src_exports));
|
|
330
|
-
const { asType = "
|
|
511
|
+
const { asType = "chain" } = options || {};
|
|
331
512
|
return startObs(name, attributes, {
|
|
332
513
|
asType,
|
|
333
514
|
parentSpanContext: this.otelSpan.spanContext()
|
|
334
515
|
});
|
|
335
516
|
}
|
|
336
517
|
};
|
|
337
|
-
ObservationSpan = class extends BaseObservation {
|
|
338
|
-
constructor(params) {
|
|
339
|
-
super({ ...params, type: "span" });
|
|
340
|
-
}
|
|
341
|
-
update(attributes) {
|
|
342
|
-
super.updateOtelSpanAttributes(attributes);
|
|
343
|
-
return this;
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
518
|
ObservationLLM = class extends BaseObservation {
|
|
347
519
|
constructor(params) {
|
|
348
520
|
super({ ...params, type: "llm" });
|
|
@@ -427,6 +599,171 @@ var init_spanWrapper = __esm({
|
|
|
427
599
|
}
|
|
428
600
|
});
|
|
429
601
|
|
|
602
|
+
// src/core/trace-context.ts
|
|
603
|
+
function validateTraceId(traceId) {
|
|
604
|
+
if (!traceId || typeof traceId !== "string") {
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
607
|
+
if (traceId.length !== 32) {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
const chunk1 = traceId.slice(0, 16);
|
|
611
|
+
const chunk2 = traceId.slice(16, 32);
|
|
612
|
+
const value1 = parseInt(chunk1, 16);
|
|
613
|
+
const value2 = parseInt(chunk2, 16);
|
|
614
|
+
if (isNaN(value1) || isNaN(value2)) {
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
if (value1 === 0 && value2 === 0) {
|
|
618
|
+
return false;
|
|
619
|
+
}
|
|
620
|
+
return true;
|
|
621
|
+
}
|
|
622
|
+
function validateSpanId(spanId) {
|
|
623
|
+
if (!spanId || typeof spanId !== "string") {
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
626
|
+
if (spanId.length !== 16) {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
const value = parseInt(spanId, 16);
|
|
630
|
+
if (isNaN(value)) {
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
633
|
+
if (value === 0) {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
function validateTraceContext(traceId, parentSpanId) {
|
|
639
|
+
const result = {
|
|
640
|
+
errors: [],
|
|
641
|
+
isValid: false,
|
|
642
|
+
hasTraceId: false,
|
|
643
|
+
hasParentSpanId: false
|
|
644
|
+
};
|
|
645
|
+
if (!traceId && !parentSpanId) {
|
|
646
|
+
result.isValid = true;
|
|
647
|
+
return result;
|
|
648
|
+
}
|
|
649
|
+
if (!traceId && parentSpanId) {
|
|
650
|
+
result.errors.push(
|
|
651
|
+
"parentSpanId provided without traceId - traceId is required when inheriting parent span"
|
|
652
|
+
);
|
|
653
|
+
return result;
|
|
654
|
+
}
|
|
655
|
+
if (traceId) {
|
|
656
|
+
if (!validateTraceId(traceId)) {
|
|
657
|
+
result.errors.push(
|
|
658
|
+
`Invalid traceId format: '${traceId}' - must be 32 hex characters and not all zeros`
|
|
659
|
+
);
|
|
660
|
+
} else {
|
|
661
|
+
result.traceId = traceId.toLowerCase();
|
|
662
|
+
result.hasTraceId = true;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (parentSpanId) {
|
|
666
|
+
if (!validateSpanId(parentSpanId)) {
|
|
667
|
+
result.errors.push(
|
|
668
|
+
`Invalid parentSpanId format: '${parentSpanId}' - must be 16 hex characters and not all zeros`
|
|
669
|
+
);
|
|
670
|
+
} else {
|
|
671
|
+
result.parentSpanId = parentSpanId.toLowerCase();
|
|
672
|
+
result.hasParentSpanId = true;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
result.isValid = result.errors.length === 0;
|
|
676
|
+
return result;
|
|
677
|
+
}
|
|
678
|
+
function createSpanLinkFromContext(traceId, parentSpanId, linkType = "follows_from", sourceSystem = "gateway") {
|
|
679
|
+
const externalContext = {
|
|
680
|
+
traceId,
|
|
681
|
+
spanId: parentSpanId,
|
|
682
|
+
traceFlags: import_api3.TraceFlags.SAMPLED
|
|
683
|
+
};
|
|
684
|
+
const link = {
|
|
685
|
+
context: externalContext,
|
|
686
|
+
attributes: {
|
|
687
|
+
"link.type": linkType,
|
|
688
|
+
"link.source": sourceSystem,
|
|
689
|
+
"link.trace_id": traceId,
|
|
690
|
+
"link.span_id": parentSpanId
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
return link;
|
|
694
|
+
}
|
|
695
|
+
function extractTraceContextFromHeaders(headers, traceIdHeader = "x-trace-id", parentSpanIdHeader = "x-parent-span-id") {
|
|
696
|
+
if (!headers) {
|
|
697
|
+
return [void 0, void 0];
|
|
698
|
+
}
|
|
699
|
+
let traceId;
|
|
700
|
+
let parentSpanId;
|
|
701
|
+
if (headers instanceof Headers) {
|
|
702
|
+
traceId = headers.get(traceIdHeader) || void 0;
|
|
703
|
+
parentSpanId = headers.get(parentSpanIdHeader) || void 0;
|
|
704
|
+
} else {
|
|
705
|
+
const headersLower = {};
|
|
706
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
707
|
+
headersLower[key.toLowerCase()] = value;
|
|
708
|
+
}
|
|
709
|
+
traceId = headersLower[traceIdHeader.toLowerCase()];
|
|
710
|
+
parentSpanId = headersLower[parentSpanIdHeader.toLowerCase()];
|
|
711
|
+
}
|
|
712
|
+
return [traceId, parentSpanId];
|
|
713
|
+
}
|
|
714
|
+
function processTraceContextFromHeaders(headers, logger, linkType = "follows_from", sourceSystem = "gateway") {
|
|
715
|
+
const [traceId, parentSpanId] = extractTraceContextFromHeaders(headers);
|
|
716
|
+
const validation = validateTraceContext(traceId, parentSpanId);
|
|
717
|
+
if (!validation.isValid) {
|
|
718
|
+
if (logger && logger.warn) {
|
|
719
|
+
validation.errors.forEach((error) => {
|
|
720
|
+
logger.warn(`Trace context validation failed: ${error}`);
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
return {
|
|
724
|
+
traceId: void 0,
|
|
725
|
+
parentSpanId: void 0,
|
|
726
|
+
isInherited: false,
|
|
727
|
+
hasParentLink: false,
|
|
728
|
+
spanAttributes: {},
|
|
729
|
+
links: []
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
const normalizedTraceId = validation.traceId;
|
|
733
|
+
const normalizedParentSpanId = validation.parentSpanId;
|
|
734
|
+
const attributes = {};
|
|
735
|
+
const links = [];
|
|
736
|
+
if (normalizedTraceId) {
|
|
737
|
+
attributes["trace.inherited"] = true;
|
|
738
|
+
attributes["trace.external_trace_id"] = normalizedTraceId;
|
|
739
|
+
}
|
|
740
|
+
if (normalizedTraceId && normalizedParentSpanId) {
|
|
741
|
+
const link = createSpanLinkFromContext(
|
|
742
|
+
normalizedTraceId,
|
|
743
|
+
normalizedParentSpanId,
|
|
744
|
+
linkType,
|
|
745
|
+
sourceSystem
|
|
746
|
+
);
|
|
747
|
+
links.push(link);
|
|
748
|
+
attributes["trace.external_parent_span_id"] = normalizedParentSpanId;
|
|
749
|
+
}
|
|
750
|
+
return {
|
|
751
|
+
traceId: normalizedTraceId,
|
|
752
|
+
parentSpanId: normalizedParentSpanId,
|
|
753
|
+
isInherited: !!normalizedTraceId,
|
|
754
|
+
hasParentLink: !!normalizedParentSpanId,
|
|
755
|
+
spanAttributes: attributes,
|
|
756
|
+
links
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
var import_api3;
|
|
760
|
+
var init_trace_context = __esm({
|
|
761
|
+
"src/core/trace-context.ts"() {
|
|
762
|
+
"use strict";
|
|
763
|
+
import_api3 = require("@opentelemetry/api");
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
|
|
430
767
|
// src/index.ts
|
|
431
768
|
var src_exports = {};
|
|
432
769
|
__export(src_exports, {
|
|
@@ -438,35 +775,43 @@ __export(src_exports, {
|
|
|
438
775
|
ObservationLLM: () => ObservationLLM,
|
|
439
776
|
ObservationReranker: () => ObservationReranker,
|
|
440
777
|
ObservationRetriever: () => ObservationRetriever,
|
|
441
|
-
ObservationSpan: () => ObservationSpan,
|
|
442
778
|
ObservationTool: () => ObservationTool,
|
|
443
779
|
createObservationAttributes: () => createObservationAttributes,
|
|
780
|
+
createSpanLinkFromContext: () => createSpanLinkFromContext,
|
|
444
781
|
createTraceAttributes: () => createTraceAttributes,
|
|
782
|
+
extractTraceContextFromHeaders: () => extractTraceContextFromHeaders,
|
|
445
783
|
getActiveSpanId: () => getActiveSpanId,
|
|
446
784
|
getActiveTraceId: () => getActiveTraceId,
|
|
447
785
|
getTracer: () => getTracer,
|
|
448
786
|
getTracerProvider: () => getTracerProvider,
|
|
449
787
|
observe: () => observe,
|
|
788
|
+
processTraceContextFromHeaders: () => processTraceContextFromHeaders,
|
|
450
789
|
setTracerProvider: () => setTracerProvider,
|
|
451
790
|
startActiveObservation: () => startActiveObservation,
|
|
452
791
|
startObservation: () => startObservation,
|
|
453
792
|
updateActiveObservation: () => updateActiveObservation,
|
|
454
|
-
updateActiveTrace: () => updateActiveTrace
|
|
793
|
+
updateActiveTrace: () => updateActiveTrace,
|
|
794
|
+
validateSpanId: () => validateSpanId,
|
|
795
|
+
validateTraceContext: () => validateTraceContext,
|
|
796
|
+
validateTraceId: () => validateTraceId
|
|
455
797
|
});
|
|
456
798
|
module.exports = __toCommonJS(src_exports);
|
|
457
799
|
function createOtelSpan(params) {
|
|
458
800
|
return getTracer().startSpan(
|
|
459
801
|
params.name,
|
|
460
|
-
{
|
|
802
|
+
{
|
|
803
|
+
startTime: params.startTime,
|
|
804
|
+
links: params.links || []
|
|
805
|
+
},
|
|
461
806
|
createParentContext(params.parentSpanContext)
|
|
462
807
|
);
|
|
463
808
|
}
|
|
464
809
|
function createParentContext(parentSpanContext) {
|
|
465
810
|
if (!parentSpanContext) return;
|
|
466
|
-
return
|
|
811
|
+
return import_api4.trace.setSpanContext(import_api4.context.active(), parentSpanContext);
|
|
467
812
|
}
|
|
468
813
|
function startObservation(name, attributes, options) {
|
|
469
|
-
const { asType = "
|
|
814
|
+
const { asType = "chain", ...observationOptions } = options || {};
|
|
470
815
|
const otelSpan = createOtelSpan({
|
|
471
816
|
name,
|
|
472
817
|
...observationOptions
|
|
@@ -517,16 +862,15 @@ function startObservation(name, attributes, options) {
|
|
|
517
862
|
otelSpan,
|
|
518
863
|
attributes
|
|
519
864
|
});
|
|
520
|
-
case "span":
|
|
521
865
|
default:
|
|
522
|
-
return new
|
|
866
|
+
return new ObservationChain({
|
|
523
867
|
otelSpan,
|
|
524
868
|
attributes
|
|
525
869
|
});
|
|
526
870
|
}
|
|
527
871
|
}
|
|
528
872
|
function updateActiveTrace(attributes) {
|
|
529
|
-
const span =
|
|
873
|
+
const span = import_api4.trace.getActiveSpan();
|
|
530
874
|
if (!span) {
|
|
531
875
|
console.warn(
|
|
532
876
|
"[Observability] No active OTEL span in context. Skipping trace update."
|
|
@@ -536,10 +880,10 @@ function updateActiveTrace(attributes) {
|
|
|
536
880
|
span.setAttributes(createTraceAttributes(attributes));
|
|
537
881
|
}
|
|
538
882
|
function getActiveTraceId() {
|
|
539
|
-
return
|
|
883
|
+
return import_api4.trace.getActiveSpan()?.spanContext().traceId;
|
|
540
884
|
}
|
|
541
885
|
function getActiveSpanId() {
|
|
542
|
-
return
|
|
886
|
+
return import_api4.trace.getActiveSpan()?.spanContext().spanId;
|
|
543
887
|
}
|
|
544
888
|
function wrapPromise(promise, span, endOnExit) {
|
|
545
889
|
return promise.then(
|
|
@@ -551,7 +895,7 @@ function wrapPromise(promise, span, endOnExit) {
|
|
|
551
895
|
},
|
|
552
896
|
(err) => {
|
|
553
897
|
span.setStatus({
|
|
554
|
-
code:
|
|
898
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
555
899
|
message: err instanceof Error ? err.message : "Unknown error"
|
|
556
900
|
});
|
|
557
901
|
if (endOnExit !== false) {
|
|
@@ -562,11 +906,11 @@ function wrapPromise(promise, span, endOnExit) {
|
|
|
562
906
|
);
|
|
563
907
|
}
|
|
564
908
|
function startActiveObservation(name, fn, options) {
|
|
565
|
-
const { asType = "
|
|
909
|
+
const { asType = "chain", endOnExit, ...observationOptions } = options || {};
|
|
566
910
|
return getTracer().startActiveSpan(
|
|
567
911
|
name,
|
|
568
912
|
{ startTime: observationOptions?.startTime },
|
|
569
|
-
createParentContext(observationOptions?.parentSpanContext) ??
|
|
913
|
+
createParentContext(observationOptions?.parentSpanContext) ?? import_api4.context.active(),
|
|
570
914
|
(span) => {
|
|
571
915
|
try {
|
|
572
916
|
let observation;
|
|
@@ -583,9 +927,6 @@ function startActiveObservation(name, fn, options) {
|
|
|
583
927
|
case "tool":
|
|
584
928
|
observation = new ObservationTool({ otelSpan: span });
|
|
585
929
|
break;
|
|
586
|
-
case "chain":
|
|
587
|
-
observation = new ObservationChain({ otelSpan: span });
|
|
588
|
-
break;
|
|
589
930
|
case "retriever":
|
|
590
931
|
observation = new ObservationRetriever({ otelSpan: span });
|
|
591
932
|
break;
|
|
@@ -598,9 +939,9 @@ function startActiveObservation(name, fn, options) {
|
|
|
598
939
|
case "guardrail":
|
|
599
940
|
observation = new ObservationGuardrail({ otelSpan: span });
|
|
600
941
|
break;
|
|
601
|
-
case "
|
|
942
|
+
case "chain":
|
|
602
943
|
default:
|
|
603
|
-
observation = new
|
|
944
|
+
observation = new ObservationChain({ otelSpan: span });
|
|
604
945
|
}
|
|
605
946
|
const result = fn(observation);
|
|
606
947
|
if (result instanceof Promise) {
|
|
@@ -617,7 +958,7 @@ function startActiveObservation(name, fn, options) {
|
|
|
617
958
|
}
|
|
618
959
|
} catch (err) {
|
|
619
960
|
span.setStatus({
|
|
620
|
-
code:
|
|
961
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
621
962
|
message: err instanceof Error ? err.message : "Unknown error"
|
|
622
963
|
});
|
|
623
964
|
if (endOnExit !== false) {
|
|
@@ -629,14 +970,14 @@ function startActiveObservation(name, fn, options) {
|
|
|
629
970
|
);
|
|
630
971
|
}
|
|
631
972
|
function updateActiveObservation(attributes) {
|
|
632
|
-
const span =
|
|
973
|
+
const span = import_api4.trace.getActiveSpan();
|
|
633
974
|
if (!span) {
|
|
634
975
|
console.warn(
|
|
635
976
|
"[Observability] No active OTEL span in context. Skipping observation update."
|
|
636
977
|
);
|
|
637
978
|
return;
|
|
638
979
|
}
|
|
639
|
-
span.setAttributes(createObservationAttributes("
|
|
980
|
+
span.setAttributes(createObservationAttributes("chain", attributes));
|
|
640
981
|
}
|
|
641
982
|
function _captureArguments(args) {
|
|
642
983
|
if (args.length === 0) return {};
|
|
@@ -645,7 +986,7 @@ function _captureArguments(args) {
|
|
|
645
986
|
}
|
|
646
987
|
function observe(fn, options = {}) {
|
|
647
988
|
const {
|
|
648
|
-
asType = "
|
|
989
|
+
asType = "chain",
|
|
649
990
|
captureInput = true,
|
|
650
991
|
captureOutput = true,
|
|
651
992
|
...observationOptions
|
|
@@ -661,8 +1002,8 @@ function observe(fn, options = {}) {
|
|
|
661
1002
|
asType
|
|
662
1003
|
}
|
|
663
1004
|
);
|
|
664
|
-
const activeContext =
|
|
665
|
-
const result =
|
|
1005
|
+
const activeContext = import_api4.trace.setSpan(import_api4.context.active(), observation.otelSpan);
|
|
1006
|
+
const result = import_api4.context.with(activeContext, () => fn.apply(this, args));
|
|
666
1007
|
if (result instanceof Promise) {
|
|
667
1008
|
return result.then(
|
|
668
1009
|
(value) => {
|
|
@@ -692,15 +1033,16 @@ function observe(fn, options = {}) {
|
|
|
692
1033
|
Object.defineProperty(wrappedFunction, "length", { value: fn.length });
|
|
693
1034
|
return wrappedFunction;
|
|
694
1035
|
}
|
|
695
|
-
var
|
|
1036
|
+
var import_api4;
|
|
696
1037
|
var init_src = __esm({
|
|
697
1038
|
"src/index.ts"() {
|
|
698
|
-
|
|
1039
|
+
import_api4 = require("@opentelemetry/api");
|
|
699
1040
|
init_attributes();
|
|
700
1041
|
init_spanWrapper();
|
|
701
1042
|
init_tracerProvider();
|
|
702
1043
|
init_attributes();
|
|
703
1044
|
init_tracerProvider();
|
|
1045
|
+
init_trace_context();
|
|
704
1046
|
}
|
|
705
1047
|
});
|
|
706
1048
|
init_src();
|
|
@@ -714,19 +1056,24 @@ init_src();
|
|
|
714
1056
|
ObservationLLM,
|
|
715
1057
|
ObservationReranker,
|
|
716
1058
|
ObservationRetriever,
|
|
717
|
-
ObservationSpan,
|
|
718
1059
|
ObservationTool,
|
|
719
1060
|
createObservationAttributes,
|
|
1061
|
+
createSpanLinkFromContext,
|
|
720
1062
|
createTraceAttributes,
|
|
1063
|
+
extractTraceContextFromHeaders,
|
|
721
1064
|
getActiveSpanId,
|
|
722
1065
|
getActiveTraceId,
|
|
723
1066
|
getTracer,
|
|
724
1067
|
getTracerProvider,
|
|
725
1068
|
observe,
|
|
1069
|
+
processTraceContextFromHeaders,
|
|
726
1070
|
setTracerProvider,
|
|
727
1071
|
startActiveObservation,
|
|
728
1072
|
startObservation,
|
|
729
1073
|
updateActiveObservation,
|
|
730
|
-
updateActiveTrace
|
|
1074
|
+
updateActiveTrace,
|
|
1075
|
+
validateSpanId,
|
|
1076
|
+
validateTraceContext,
|
|
1077
|
+
validateTraceId
|
|
731
1078
|
});
|
|
732
1079
|
//# sourceMappingURL=index.js.map
|