@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/src/index.ts
CHANGED
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { trace, context, TimeInput, SpanStatusCode, Span, SpanContext } from "@opentelemetry/api";
|
|
7
|
+
import { trace, context, TimeInput, SpanStatusCode, Span, SpanContext, Link } from "@opentelemetry/api";
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
createObservationAttributes,
|
|
11
11
|
createTraceAttributes,
|
|
12
|
-
} from "./core/attributes
|
|
12
|
+
} from "./core/attributes";
|
|
13
13
|
import {
|
|
14
|
-
ObservationSpan,
|
|
15
14
|
ObservationLLM,
|
|
16
15
|
ObservationEmbedding,
|
|
17
16
|
ObservationAgent,
|
|
@@ -22,8 +21,8 @@ import {
|
|
|
22
21
|
ObservationEvaluator,
|
|
23
22
|
ObservationGuardrail,
|
|
24
23
|
type Observation,
|
|
25
|
-
} from "./core/spanWrapper
|
|
26
|
-
import { getTracer } from "./core/tracerProvider
|
|
24
|
+
} from "./core/spanWrapper";
|
|
25
|
+
import { getTracer } from "./core/tracerProvider";
|
|
27
26
|
import {
|
|
28
27
|
ObservationType,
|
|
29
28
|
ObservationLevel,
|
|
@@ -39,7 +38,10 @@ import {
|
|
|
39
38
|
EmbeddingAttributes,
|
|
40
39
|
ObservationAttributes,
|
|
41
40
|
TraceAttributes,
|
|
42
|
-
|
|
41
|
+
LLMMessage,
|
|
42
|
+
ToolCall,
|
|
43
|
+
Document,
|
|
44
|
+
} from "./types";
|
|
43
45
|
|
|
44
46
|
// Export types
|
|
45
47
|
export type {
|
|
@@ -57,11 +59,13 @@ export type {
|
|
|
57
59
|
EmbeddingAttributes,
|
|
58
60
|
ObservationAttributes,
|
|
59
61
|
TraceAttributes,
|
|
62
|
+
LLMMessage,
|
|
63
|
+
ToolCall,
|
|
64
|
+
Document,
|
|
60
65
|
};
|
|
61
66
|
|
|
62
67
|
// Export observation classes
|
|
63
68
|
export {
|
|
64
|
-
ObservationSpan,
|
|
65
69
|
ObservationLLM,
|
|
66
70
|
ObservationEmbedding,
|
|
67
71
|
ObservationAgent,
|
|
@@ -80,12 +84,24 @@ export type { Observation };
|
|
|
80
84
|
export {
|
|
81
85
|
createTraceAttributes,
|
|
82
86
|
createObservationAttributes,
|
|
83
|
-
} from "./core/attributes
|
|
87
|
+
} from "./core/attributes";
|
|
84
88
|
export {
|
|
85
89
|
setTracerProvider,
|
|
86
90
|
getTracerProvider,
|
|
87
91
|
getTracer,
|
|
88
|
-
} from "./core/tracerProvider
|
|
92
|
+
} from "./core/tracerProvider";
|
|
93
|
+
|
|
94
|
+
// Export trace context utilities
|
|
95
|
+
export {
|
|
96
|
+
validateTraceId,
|
|
97
|
+
validateSpanId,
|
|
98
|
+
validateTraceContext,
|
|
99
|
+
createSpanLinkFromContext,
|
|
100
|
+
extractTraceContextFromHeaders,
|
|
101
|
+
processTraceContextFromHeaders,
|
|
102
|
+
type TraceContextValidation,
|
|
103
|
+
type ProcessedTraceContext,
|
|
104
|
+
} from "./core/trace-context";
|
|
89
105
|
|
|
90
106
|
/**
|
|
91
107
|
* Options for starting observations (spans).
|
|
@@ -97,6 +113,8 @@ export type StartObservationOptions = {
|
|
|
97
113
|
startTime?: Date;
|
|
98
114
|
/** Parent span context to attach this observation to */
|
|
99
115
|
parentSpanContext?: SpanContext;
|
|
116
|
+
/** Optional links to external or related spans */
|
|
117
|
+
links?: Link[];
|
|
100
118
|
};
|
|
101
119
|
|
|
102
120
|
/**
|
|
@@ -105,12 +123,12 @@ export type StartObservationOptions = {
|
|
|
105
123
|
* @public
|
|
106
124
|
*/
|
|
107
125
|
export type StartObservationOpts = StartObservationOptions & {
|
|
108
|
-
/** Type of observation to create. Defaults to '
|
|
126
|
+
/** Type of observation to create. Defaults to 'chain' */
|
|
109
127
|
asType?: ObservationType;
|
|
110
128
|
};
|
|
111
129
|
|
|
112
130
|
/**
|
|
113
|
-
* Creates an OpenTelemetry span with the
|
|
131
|
+
* Creates an OpenTelemetry span with the tracer.
|
|
114
132
|
*
|
|
115
133
|
* @param params - Parameters for span creation
|
|
116
134
|
* @returns The created OpenTelemetry span
|
|
@@ -120,10 +138,14 @@ function createOtelSpan(params: {
|
|
|
120
138
|
name: string;
|
|
121
139
|
startTime?: TimeInput;
|
|
122
140
|
parentSpanContext?: SpanContext;
|
|
141
|
+
links?: Link[];
|
|
123
142
|
}): Span {
|
|
124
143
|
return getTracer().startSpan(
|
|
125
144
|
params.name,
|
|
126
|
-
{
|
|
145
|
+
{
|
|
146
|
+
startTime: params.startTime,
|
|
147
|
+
links: params.links || [],
|
|
148
|
+
},
|
|
127
149
|
createParentContext(params.parentSpanContext),
|
|
128
150
|
);
|
|
129
151
|
}
|
|
@@ -199,19 +221,18 @@ export function startObservation(
|
|
|
199
221
|
export function startObservation(
|
|
200
222
|
name: string,
|
|
201
223
|
attributes?: BaseSpanAttributes,
|
|
202
|
-
options?: StartObservationOpts & { asType?: "
|
|
203
|
-
):
|
|
224
|
+
options?: StartObservationOpts & { asType?: "chain" },
|
|
225
|
+
): ObservationChain;
|
|
204
226
|
|
|
205
227
|
/**
|
|
206
|
-
* Creates and starts a new
|
|
228
|
+
* Creates and starts a new observation.
|
|
207
229
|
*
|
|
208
230
|
* Supports multiple observation types with full TypeScript type safety:
|
|
209
|
-
* - **
|
|
231
|
+
* - **chain**: Multi-step workflows (default for generic operations)
|
|
210
232
|
* - **llm**: LLM calls and AI model interactions
|
|
211
233
|
* - **embedding**: Text embedding and vector operations
|
|
212
234
|
* - **agent**: AI agent workflows
|
|
213
235
|
* - **tool**: Individual tool calls
|
|
214
|
-
* - **chain**: Multi-step processes
|
|
215
236
|
* - **retriever**: Document retrieval
|
|
216
237
|
* - **reranker**: Result reranking
|
|
217
238
|
* - **evaluator**: Quality assessment
|
|
@@ -261,7 +282,7 @@ export function startObservation(
|
|
|
261
282
|
| GuardrailAttributes,
|
|
262
283
|
options?: StartObservationOpts,
|
|
263
284
|
): Observation {
|
|
264
|
-
const { asType = "
|
|
285
|
+
const { asType = "chain", ...observationOptions } = options || {};
|
|
265
286
|
|
|
266
287
|
const otelSpan = createOtelSpan({
|
|
267
288
|
name,
|
|
@@ -323,9 +344,8 @@ export function startObservation(
|
|
|
323
344
|
attributes: attributes as GuardrailAttributes,
|
|
324
345
|
});
|
|
325
346
|
|
|
326
|
-
case "span":
|
|
327
347
|
default:
|
|
328
|
-
return new
|
|
348
|
+
return new ObservationChain({
|
|
329
349
|
otelSpan,
|
|
330
350
|
attributes: attributes as BaseSpanAttributes,
|
|
331
351
|
});
|
|
@@ -434,9 +454,6 @@ function wrapPromise<T>(
|
|
|
434
454
|
}
|
|
435
455
|
|
|
436
456
|
// Function overloads for startActiveObservation
|
|
437
|
-
export function startActiveObservation<
|
|
438
|
-
F extends (observation: ObservationSpan) => unknown,
|
|
439
|
-
>(name: string, fn: F, options?: StartActiveObservationOpts): ReturnType<F>;
|
|
440
457
|
export function startActiveObservation<
|
|
441
458
|
F extends (observation: ObservationLLM) => unknown,
|
|
442
459
|
>(name: string, fn: F, options?: StartActiveObservationOpts): ReturnType<F>;
|
|
@@ -484,12 +501,12 @@ export function startActiveObservation<
|
|
|
484
501
|
* import { startActiveObservation } from './observability';
|
|
485
502
|
*
|
|
486
503
|
* // Synchronous function
|
|
487
|
-
* const result = startActiveObservation('data-processing', (
|
|
488
|
-
*
|
|
504
|
+
* const result = startActiveObservation('data-processing', (chain) => {
|
|
505
|
+
* chain.update({ input: { data: [1, 2, 3] } });
|
|
489
506
|
* const processed = data.map(x => x * 2);
|
|
490
|
-
*
|
|
507
|
+
* chain.update({ output: { result: processed } });
|
|
491
508
|
* return processed;
|
|
492
|
-
* }, { asType: '
|
|
509
|
+
* }, { asType: 'chain' });
|
|
493
510
|
*
|
|
494
511
|
* // Asynchronous function
|
|
495
512
|
* const embeddings = await startActiveObservation(
|
|
@@ -511,12 +528,12 @@ export function startActiveObservation<
|
|
|
511
528
|
* // Disable automatic ending (for long-running operations)
|
|
512
529
|
* startActiveObservation(
|
|
513
530
|
* 'background-task',
|
|
514
|
-
* (
|
|
515
|
-
*
|
|
516
|
-
* startBackgroundProcess(
|
|
531
|
+
* (chain) => {
|
|
532
|
+
* chain.update({ input: { taskId: '123' } });
|
|
533
|
+
* startBackgroundProcess(chain);
|
|
517
534
|
* return 'started';
|
|
518
535
|
* },
|
|
519
|
-
* { asType: '
|
|
536
|
+
* { asType: 'chain', endOnExit: false }
|
|
520
537
|
* );
|
|
521
538
|
* ```
|
|
522
539
|
*
|
|
@@ -528,7 +545,7 @@ export function startActiveObservation<
|
|
|
528
545
|
export function startActiveObservation<
|
|
529
546
|
F extends (observation: Observation) => unknown,
|
|
530
547
|
>(name: string, fn: F, options?: StartActiveObservationOpts): ReturnType<F> {
|
|
531
|
-
const { asType = "
|
|
548
|
+
const { asType = "chain", endOnExit, ...observationOptions } = options || {};
|
|
532
549
|
|
|
533
550
|
return getTracer().startActiveSpan(
|
|
534
551
|
name,
|
|
@@ -552,9 +569,6 @@ export function startActiveObservation<
|
|
|
552
569
|
case "tool":
|
|
553
570
|
observation = new ObservationTool({ otelSpan: span });
|
|
554
571
|
break;
|
|
555
|
-
case "chain":
|
|
556
|
-
observation = new ObservationChain({ otelSpan: span });
|
|
557
|
-
break;
|
|
558
572
|
case "retriever":
|
|
559
573
|
observation = new ObservationRetriever({ otelSpan: span });
|
|
560
574
|
break;
|
|
@@ -567,9 +581,9 @@ export function startActiveObservation<
|
|
|
567
581
|
case "guardrail":
|
|
568
582
|
observation = new ObservationGuardrail({ otelSpan: span });
|
|
569
583
|
break;
|
|
570
|
-
case "
|
|
584
|
+
case "chain":
|
|
571
585
|
default:
|
|
572
|
-
observation = new
|
|
586
|
+
observation = new ObservationChain({ otelSpan: span });
|
|
573
587
|
}
|
|
574
588
|
|
|
575
589
|
const result = fn(observation as Parameters<F>[0]);
|
|
@@ -629,7 +643,7 @@ export function updateActiveObservation(
|
|
|
629
643
|
return;
|
|
630
644
|
}
|
|
631
645
|
|
|
632
|
-
span.setAttributes(createObservationAttributes("
|
|
646
|
+
span.setAttributes(createObservationAttributes("chain", attributes));
|
|
633
647
|
}
|
|
634
648
|
|
|
635
649
|
// ============================================================================
|
|
@@ -706,7 +720,7 @@ export function observe<T extends (...args: any[]) => any>(
|
|
|
706
720
|
options: ObserveOptions = {},
|
|
707
721
|
): T {
|
|
708
722
|
const {
|
|
709
|
-
asType = "
|
|
723
|
+
asType = "chain",
|
|
710
724
|
captureInput = true,
|
|
711
725
|
captureOutput = true,
|
|
712
726
|
...observationOptions
|
|
@@ -727,7 +741,7 @@ export function observe<T extends (...args: any[]) => any>(
|
|
|
727
741
|
inputData ? { input: inputData } : {},
|
|
728
742
|
{
|
|
729
743
|
...observationOptions,
|
|
730
|
-
asType: asType as "
|
|
744
|
+
asType: asType as "chain",
|
|
731
745
|
},
|
|
732
746
|
);
|
|
733
747
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LangChain Callback Handler for
|
|
2
|
+
* LangChain Callback Handler for Observability
|
|
3
3
|
*
|
|
4
|
-
* Converts LangChain callback events into
|
|
4
|
+
* Converts LangChain callback events into observations with OpenInference semantics.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { AgentAction, AgentFinish } from "@langchain/core/agents";
|
|
@@ -22,11 +22,10 @@ import type { ChainValues } from "@langchain/core/utils/types";
|
|
|
22
22
|
import {
|
|
23
23
|
startObservation,
|
|
24
24
|
type ObservationLLM,
|
|
25
|
-
type ObservationSpan,
|
|
26
25
|
type ObservationTool,
|
|
27
26
|
type Observation,
|
|
28
27
|
type ObservationAttributes,
|
|
29
|
-
} from "../index
|
|
28
|
+
} from "../index";
|
|
30
29
|
import type { SpanContext } from "@opentelemetry/api";
|
|
31
30
|
import { type Logger, noopLogger } from "@cloudbase/agent-shared";
|
|
32
31
|
|
|
@@ -79,10 +78,10 @@ type PromptInfo = {
|
|
|
79
78
|
};
|
|
80
79
|
|
|
81
80
|
/**
|
|
82
|
-
* LangChain Callback Handler for
|
|
81
|
+
* LangChain Callback Handler for Observability.
|
|
83
82
|
*
|
|
84
83
|
* This handler intercepts LangChain callbacks and converts them into
|
|
85
|
-
*
|
|
84
|
+
* Observations following OpenInference semantic conventions.
|
|
86
85
|
*
|
|
87
86
|
* @public
|
|
88
87
|
*/
|
|
@@ -104,6 +103,9 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
104
103
|
// External parent context from AG-UI.Server span
|
|
105
104
|
private externalParentSpanContext?: SpanContext;
|
|
106
105
|
|
|
106
|
+
// External metadata from AG-UI.Server (e.g., threadId, runId)
|
|
107
|
+
private externalMetadata?: Record<string, string>;
|
|
108
|
+
|
|
107
109
|
// Adapter name for ROOT span prefix
|
|
108
110
|
private adapterName?: string;
|
|
109
111
|
|
|
@@ -130,10 +132,12 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
130
132
|
* to the server-level span, creating a unified trace hierarchy.
|
|
131
133
|
*
|
|
132
134
|
* @param spanContext - SpanContext from the AG-UI.Server span
|
|
135
|
+
* @param metadata - Optional metadata from server (e.g., threadId, runId)
|
|
133
136
|
* @public
|
|
134
137
|
*/
|
|
135
|
-
setExternalParentContext(spanContext: SpanContext): void {
|
|
138
|
+
setExternalParentContext(spanContext: SpanContext, metadata?: Record<string, string>): void {
|
|
136
139
|
this.externalParentSpanContext = spanContext;
|
|
140
|
+
this.externalMetadata = metadata;
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
async handleLLMNewToken(
|
|
@@ -161,8 +165,6 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
161
165
|
name?: string
|
|
162
166
|
): Promise<void> {
|
|
163
167
|
try {
|
|
164
|
-
this.logger.debug?.(`Chain start with Id: ${runId}`);
|
|
165
|
-
|
|
166
168
|
const runName = name ?? chain.id.at(-1)?.toString() ?? "Langchain Run";
|
|
167
169
|
|
|
168
170
|
this.registerPromptInfo(parentRunId, metadata);
|
|
@@ -199,11 +201,11 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
199
201
|
parentRunId,
|
|
200
202
|
runId,
|
|
201
203
|
tags,
|
|
202
|
-
metadata,
|
|
204
|
+
metadata: this.joinTagsAndMetaData(tags, metadata),
|
|
203
205
|
attributes: {
|
|
204
206
|
input: finalInput,
|
|
205
207
|
},
|
|
206
|
-
asType: "
|
|
208
|
+
asType: "chain",
|
|
207
209
|
});
|
|
208
210
|
|
|
209
211
|
const traceTags = [...new Set([...(tags ?? []), ...this.tags])];
|
|
@@ -328,6 +330,8 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
328
330
|
}
|
|
329
331
|
|
|
330
332
|
let extractedModelName: string | undefined;
|
|
333
|
+
let extractedSystem: string | undefined;
|
|
334
|
+
let extractedProvider: string | undefined;
|
|
331
335
|
if (extraParams) {
|
|
332
336
|
const invocationParamsModelName = (
|
|
333
337
|
extraParams.invocation_params as InvocationParams
|
|
@@ -338,6 +342,11 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
338
342
|
: undefined;
|
|
339
343
|
|
|
340
344
|
extractedModelName = invocationParamsModelName ?? metadataModelName;
|
|
345
|
+
|
|
346
|
+
// Extract provider from metadata (e.g., "ls_provider" from LangChain)
|
|
347
|
+
if (metadata && "ls_provider" in metadata) {
|
|
348
|
+
extractedProvider = metadata["ls_provider"] as string;
|
|
349
|
+
}
|
|
341
350
|
}
|
|
342
351
|
|
|
343
352
|
const registeredPrompt = this.promptToParentRunMap.get(
|
|
@@ -479,7 +488,7 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
479
488
|
attributes: {
|
|
480
489
|
input,
|
|
481
490
|
},
|
|
482
|
-
metadata,
|
|
491
|
+
metadata: this.joinTagsAndMetaData(tags, metadata),
|
|
483
492
|
tags,
|
|
484
493
|
asType: "tool",
|
|
485
494
|
});
|
|
@@ -507,8 +516,8 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
507
516
|
input: query,
|
|
508
517
|
},
|
|
509
518
|
tags,
|
|
510
|
-
metadata,
|
|
511
|
-
asType: "
|
|
519
|
+
metadata: this.joinTagsAndMetaData(tags, metadata),
|
|
520
|
+
asType: "retriever",
|
|
512
521
|
});
|
|
513
522
|
} catch (e) {
|
|
514
523
|
this.logger.debug?.(e instanceof Error ? e.message : String(e));
|
|
@@ -710,7 +719,7 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
710
719
|
attributes: Record<string, unknown>;
|
|
711
720
|
metadata?: Record<string, unknown>;
|
|
712
721
|
tags?: string[];
|
|
713
|
-
asType?: "
|
|
722
|
+
asType?: "llm" | "tool" | "chain" | "retriever" | "agent";
|
|
714
723
|
}): Observation {
|
|
715
724
|
const { runName, runId, parentRunId, attributes, metadata, tags, asType } =
|
|
716
725
|
params;
|
|
@@ -736,15 +745,22 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
736
745
|
finalRunName = `Adapter.${this.adapterName}`;
|
|
737
746
|
}
|
|
738
747
|
|
|
748
|
+
// Add agui.thread_id and agui.run_id to ALL spans if external metadata available
|
|
749
|
+
// This ensures consistent tagging across the entire trace hierarchy
|
|
750
|
+
const serverMetadata = this.externalMetadata
|
|
751
|
+
? { "agui.thread_id": this.externalMetadata.threadId, "agui.run_id": this.externalMetadata.runId }
|
|
752
|
+
: {};
|
|
753
|
+
|
|
739
754
|
const observation = startObservation(
|
|
740
755
|
finalRunName,
|
|
741
756
|
{
|
|
742
757
|
version: this.version,
|
|
743
758
|
metadata: this.joinTagsAndMetaData(tags, metadata),
|
|
744
759
|
...attributes,
|
|
760
|
+
...serverMetadata,
|
|
745
761
|
},
|
|
746
762
|
{
|
|
747
|
-
asType: asType ?? "
|
|
763
|
+
asType: asType ?? "chain",
|
|
748
764
|
parentSpanContext,
|
|
749
765
|
}
|
|
750
766
|
);
|
|
@@ -765,6 +781,17 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
765
781
|
return;
|
|
766
782
|
}
|
|
767
783
|
|
|
784
|
+
// Check if this is an error and set span status accordingly
|
|
785
|
+
const level = attributes.level as string | undefined;
|
|
786
|
+
const statusMessage = attributes.statusMessage as string | undefined;
|
|
787
|
+
if (level === "ERROR") {
|
|
788
|
+
try {
|
|
789
|
+
observation.setErrorStatus(statusMessage || "Unknown error");
|
|
790
|
+
} catch (e) {
|
|
791
|
+
this.logger.debug?.("Failed to set span error status:", e);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
768
795
|
// Type-safe update: cast to ObservationAttributes which is the union of all observation attribute types
|
|
769
796
|
observation.update(attributes as ObservationAttributes).end();
|
|
770
797
|
|
|
@@ -797,7 +824,10 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
797
824
|
return;
|
|
798
825
|
}
|
|
799
826
|
|
|
800
|
-
|
|
827
|
+
// Filter out keys that should not be in metadata:
|
|
828
|
+
// - thread_id, run_id: Become agui.thread_id, agui.run_id at span level
|
|
829
|
+
// - promptInfo, userId, sessionId: Reserved for internal use
|
|
830
|
+
const reservedKeys = ["promptInfo", "userId", "sessionId", "thread_id", "runId", "run_id"];
|
|
801
831
|
|
|
802
832
|
return Object.fromEntries(
|
|
803
833
|
Object.entries(metadata).filter(([key, _]) => !reservedKeys.includes(key))
|
|
@@ -893,4 +923,5 @@ export class CallbackHandler extends BaseCallbackHandler {
|
|
|
893
923
|
|
|
894
924
|
return response;
|
|
895
925
|
}
|
|
926
|
+
|
|
896
927
|
}
|
package/src/langchain/index.ts
CHANGED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom console exporter that outputs single-line JSON.
|
|
3
|
+
*
|
|
4
|
+
* This exporter outputs spans as single-line JSON for easier parsing
|
|
5
|
+
* with line-based tools (grep, jq, etc.).
|
|
6
|
+
*
|
|
7
|
+
* To switch back to standard multi-line output, use ConsoleSpanExporter instead.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Single-line (current default)
|
|
12
|
+
* const exporter = new SingleLineConsoleSpanExporter();
|
|
13
|
+
*
|
|
14
|
+
* // Multi-line (standard OTel)
|
|
15
|
+
* import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
16
|
+
* const exporter = new ConsoleSpanExporter();
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @packageDocumentation
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';
|
|
23
|
+
import { OBSERVABILITY_TRACER_NAME } from '../core/constants';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Export result codes.
|
|
27
|
+
*/
|
|
28
|
+
export enum ExportResultCode {
|
|
29
|
+
SUCCESS = 0,
|
|
30
|
+
FAILED = 1,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Export result interface.
|
|
35
|
+
*/
|
|
36
|
+
export interface ExportResult {
|
|
37
|
+
code: ExportResultCode;
|
|
38
|
+
error?: Error;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Custom console exporter that outputs single-line JSON.
|
|
43
|
+
*
|
|
44
|
+
* This exporter outputs spans as single-line JSON for easier parsing
|
|
45
|
+
* with line-based tools (grep, jq, etc.).
|
|
46
|
+
*/
|
|
47
|
+
export class SingleLineConsoleSpanExporter implements SpanExporter {
|
|
48
|
+
/**
|
|
49
|
+
* Export spans as single-line JSON.
|
|
50
|
+
*/
|
|
51
|
+
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void {
|
|
52
|
+
try {
|
|
53
|
+
for (const span of spans) {
|
|
54
|
+
const spanDict = this.spanToDict(span);
|
|
55
|
+
// Single-line JSON output
|
|
56
|
+
const jsonLine = JSON.stringify(spanDict);
|
|
57
|
+
console.log(jsonLine);
|
|
58
|
+
}
|
|
59
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
60
|
+
} catch (error) {
|
|
61
|
+
resultCallback({ code: ExportResultCode.FAILED, error: error as Error });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Shutdown the exporter.
|
|
67
|
+
*/
|
|
68
|
+
shutdown(): Promise<void> {
|
|
69
|
+
return Promise.resolve();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Force flush the exporter.
|
|
74
|
+
*/
|
|
75
|
+
forceFlush?(): Promise<void> {
|
|
76
|
+
return Promise.resolve();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Convert a ReadableSpan to a dictionary for JSON serialization.
|
|
81
|
+
*/
|
|
82
|
+
private spanToDict(span: ReadableSpan): Record<string, unknown> {
|
|
83
|
+
try {
|
|
84
|
+
const context = span.spanContext();
|
|
85
|
+
|
|
86
|
+
// Get parent span ID from parentSpanContext if available
|
|
87
|
+
// Some versions use parentSpanId directly, others use parentSpanContext.spanId
|
|
88
|
+
const parentId = (span as any).parentSpanId || span.parentSpanContext?.spanId;
|
|
89
|
+
|
|
90
|
+
const result: Record<string, unknown> = {
|
|
91
|
+
name: span.name,
|
|
92
|
+
context: {
|
|
93
|
+
trace_id: context.traceId,
|
|
94
|
+
span_id: context.spanId,
|
|
95
|
+
trace_flags: context.traceFlags,
|
|
96
|
+
},
|
|
97
|
+
kind: span.kind,
|
|
98
|
+
parent_id: parentId,
|
|
99
|
+
start_time: span.startTime,
|
|
100
|
+
end_time: span.endTime,
|
|
101
|
+
status: {
|
|
102
|
+
status_code: span.status.code,
|
|
103
|
+
description: span.status.message,
|
|
104
|
+
},
|
|
105
|
+
attributes: span.attributes,
|
|
106
|
+
events: span.events.map((event) => ({
|
|
107
|
+
name: event.name,
|
|
108
|
+
timestamp: event.time,
|
|
109
|
+
attributes: event.attributes,
|
|
110
|
+
})),
|
|
111
|
+
links: span.links.map((link) => ({
|
|
112
|
+
context: {
|
|
113
|
+
trace_id: link.context.traceId,
|
|
114
|
+
span_id: link.context.spanId,
|
|
115
|
+
},
|
|
116
|
+
attributes: link.attributes,
|
|
117
|
+
})),
|
|
118
|
+
resource: {
|
|
119
|
+
attributes: span.resource.attributes,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// Add log source identifier for console output
|
|
124
|
+
result['_log_from'] = OBSERVABILITY_TRACER_NAME;
|
|
125
|
+
|
|
126
|
+
return result;
|
|
127
|
+
} catch {
|
|
128
|
+
return {};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check if single-line console exporter should be used.
|
|
135
|
+
*
|
|
136
|
+
* Set CONSOLE_EXPORTER_SINGLE_LINE=false to use standard multi-line output.
|
|
137
|
+
*/
|
|
138
|
+
export function isSingleLineConsoleExporterEnabled(): boolean {
|
|
139
|
+
const value = process.env.CONSOLE_EXPORTER_SINGLE_LINE?.toLowerCase() || 'true';
|
|
140
|
+
return ['true', '1', 'yes', 'on'].includes(value);
|
|
141
|
+
}
|
package/src/server/config.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Observability configuration types for
|
|
2
|
+
* Observability configuration types for the server.
|
|
3
3
|
*
|
|
4
4
|
* Provides a unified configuration interface for trace exporters:
|
|
5
5
|
* - Console: Development/debugging output
|
|
@@ -64,6 +64,7 @@ export interface BatchConfig {
|
|
|
64
64
|
* Console trace exporter configuration.
|
|
65
65
|
*
|
|
66
66
|
* Outputs traces to stdout in JSON format using ConsoleSpanExporter.
|
|
67
|
+
* Uses SimpleSpanProcessor for immediate export (no batching).
|
|
67
68
|
* Useful for development and debugging.
|
|
68
69
|
*
|
|
69
70
|
* @example
|
|
@@ -71,7 +72,6 @@ export interface BatchConfig {
|
|
|
71
72
|
* import { ExporterType } from '@cloudbase/agent-observability/server';
|
|
72
73
|
*
|
|
73
74
|
* { type: ExporterType.Console }
|
|
74
|
-
* { type: ExporterType.Console, batch: { maxExportBatchSize: 200 } }
|
|
75
75
|
* ```
|
|
76
76
|
*
|
|
77
77
|
* @public
|
|
@@ -79,8 +79,6 @@ export interface BatchConfig {
|
|
|
79
79
|
export interface ConsoleTraceConfig {
|
|
80
80
|
/** Discriminator for console exporter */
|
|
81
81
|
type: typeof ExporterType.Console;
|
|
82
|
-
/** Optional batch processing configuration */
|
|
83
|
-
batch?: BatchConfig;
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
/**
|
package/src/server/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Server utilities for
|
|
2
|
+
* Server utilities for observability.
|
|
3
3
|
*
|
|
4
4
|
* Provides server-side observability features like AUTO_TRACES_STDOUT
|
|
5
5
|
* and unified trace exporter configuration.
|
|
@@ -15,7 +15,13 @@ export {
|
|
|
15
15
|
type OTLPTraceConfig,
|
|
16
16
|
type CustomTraceConfig,
|
|
17
17
|
type BatchConfig,
|
|
18
|
-
} from './setup
|
|
18
|
+
} from './setup';
|
|
19
19
|
|
|
20
20
|
// Exporter type constants
|
|
21
|
-
export { ExporterType } from './config
|
|
21
|
+
export { ExporterType } from './config';
|
|
22
|
+
|
|
23
|
+
// Single-line console exporter for easier parsing
|
|
24
|
+
export {
|
|
25
|
+
SingleLineConsoleSpanExporter,
|
|
26
|
+
isSingleLineConsoleExporterEnabled,
|
|
27
|
+
} from './SingleLineConsoleSpanExporter';
|