@cloudbase/agent-observability 1.0.1-alpha.9
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 +231 -0
- package/dist/chunk-NFEGQTCC.mjs +27 -0
- package/dist/chunk-NFEGQTCC.mjs.map +1 -0
- package/dist/chunk-ZGEMAYS4.mjs +716 -0
- package/dist/chunk-ZGEMAYS4.mjs.map +1 -0
- package/dist/esm-PGEDANAI.mjs +1030 -0
- package/dist/esm-PGEDANAI.mjs.map +1 -0
- package/dist/index.d.mts +728 -0
- package/dist/index.d.ts +728 -0
- package/dist/index.js +732 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +52 -0
- package/dist/index.mjs.map +1 -0
- package/dist/langchain.d.mts +108 -0
- package/dist/langchain.d.ts +108 -0
- package/dist/langchain.js +1237 -0
- package/dist/langchain.js.map +1 -0
- package/dist/langchain.mjs +535 -0
- package/dist/langchain.mjs.map +1 -0
- package/dist/server.d.mts +163 -0
- package/dist/server.d.ts +163 -0
- package/dist/server.js +1528 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +175 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +91 -0
- package/src/core/attributes.ts +233 -0
- package/src/core/constants.ts +75 -0
- package/src/core/spanWrapper.ts +417 -0
- package/src/core/tracerProvider.ts +136 -0
- package/src/index.ts +775 -0
- package/src/langchain/CallbackHandler.ts +893 -0
- package/src/langchain/index.ts +7 -0
- package/src/server/config.ts +160 -0
- package/src/server/index.ts +21 -0
- package/src/server/setup.ts +344 -0
- package/src/types.ts +254 -0
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cloudbase/agent-observability",
|
|
3
|
+
"version": "1.0.1-alpha.9",
|
|
4
|
+
"description": "OpenInference-compatible observability for AG-Kit",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"./langchain": {
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/langchain.d.mts",
|
|
22
|
+
"default": "./dist/langchain.mjs"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "./dist/langchain.d.ts",
|
|
26
|
+
"default": "./dist/langchain.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"./core": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/core.d.mts",
|
|
32
|
+
"default": "./dist/core.mjs"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"types": "./dist/core.d.ts",
|
|
36
|
+
"default": "./dist/core.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"./server": {
|
|
40
|
+
"import": {
|
|
41
|
+
"types": "./dist/server.d.mts",
|
|
42
|
+
"default": "./dist/server.mjs"
|
|
43
|
+
},
|
|
44
|
+
"require": {
|
|
45
|
+
"types": "./dist/server.d.ts",
|
|
46
|
+
"default": "./dist/server.js"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"src"
|
|
53
|
+
],
|
|
54
|
+
"keywords": [
|
|
55
|
+
"ag-kit",
|
|
56
|
+
"observability",
|
|
57
|
+
"opentelemetry",
|
|
58
|
+
"openinference",
|
|
59
|
+
"langfuse",
|
|
60
|
+
"tracing"
|
|
61
|
+
],
|
|
62
|
+
"author": "",
|
|
63
|
+
"license": "ISC",
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@arizeai/openinference-semantic-conventions": "^2.1.7",
|
|
66
|
+
"@opentelemetry/api": "^1.9.0",
|
|
67
|
+
"@opentelemetry/semantic-conventions": "^1.39.0"
|
|
68
|
+
},
|
|
69
|
+
"optionalDependencies": {
|
|
70
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.210.0",
|
|
71
|
+
"@opentelemetry/resources": "^2.4.0",
|
|
72
|
+
"@opentelemetry/sdk-node": "^0.210.0",
|
|
73
|
+
"@opentelemetry/sdk-trace-base": "^2.4.0",
|
|
74
|
+
"@opentelemetry/sdk-trace-node": "^2.4.0"
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@langchain/core": "^1.0.2",
|
|
78
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.210.0",
|
|
79
|
+
"@types/node": "^20.0.0",
|
|
80
|
+
"tsup": "^8.5.0",
|
|
81
|
+
"typescript": "^5.0.0"
|
|
82
|
+
},
|
|
83
|
+
"peerDependencies": {
|
|
84
|
+
"@langchain/core": "^1.0.0"
|
|
85
|
+
},
|
|
86
|
+
"scripts": {
|
|
87
|
+
"build": "tsup --config tsup.config.ts",
|
|
88
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
89
|
+
"typecheck": "tsc --noEmit"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { OBSERVABILITY_TRACER_NAME, OtelSpanAttributes } from "./constants.js";
|
|
2
|
+
import { SemanticConventions } from "@arizeai/openinference-semantic-conventions";
|
|
3
|
+
import { ObservationAttributes, TraceAttributes, ObservationType } from "../types.js";
|
|
4
|
+
import { type Attributes } from "@opentelemetry/api";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates OpenTelemetry attributes from trace attributes.
|
|
8
|
+
*
|
|
9
|
+
* Converts user-friendly trace attributes into OpenTelemetry attribute format
|
|
10
|
+
* using OpenInference semantic conventions where applicable.
|
|
11
|
+
*
|
|
12
|
+
* @param attributes - Trace attributes to convert
|
|
13
|
+
* @returns OpenTelemetry attributes object
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const otelAttributes = createTraceAttributes({
|
|
18
|
+
* name: 'user-workflow',
|
|
19
|
+
* userId: 'user-123',
|
|
20
|
+
* sessionId: 'session-456',
|
|
21
|
+
* tags: ['checkout', 'payment']
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export function createTraceAttributes({
|
|
28
|
+
name,
|
|
29
|
+
userId,
|
|
30
|
+
sessionId,
|
|
31
|
+
version,
|
|
32
|
+
release,
|
|
33
|
+
input,
|
|
34
|
+
output,
|
|
35
|
+
metadata,
|
|
36
|
+
tags,
|
|
37
|
+
environment,
|
|
38
|
+
public: isPublic,
|
|
39
|
+
}: TraceAttributes = {}): Attributes {
|
|
40
|
+
const attributes = {
|
|
41
|
+
[OtelSpanAttributes.TRACE_NAME]: name,
|
|
42
|
+
// Use OpenInference standard attributes for user and session
|
|
43
|
+
[OtelSpanAttributes.USER_ID]: userId,
|
|
44
|
+
[OtelSpanAttributes.SESSION_ID]: sessionId,
|
|
45
|
+
[OtelSpanAttributes.VERSION]: version,
|
|
46
|
+
[OtelSpanAttributes.RELEASE]: release,
|
|
47
|
+
[OtelSpanAttributes.TRACE_INPUT]: _serialize(input),
|
|
48
|
+
[OtelSpanAttributes.TRACE_OUTPUT]: _serialize(output),
|
|
49
|
+
[OtelSpanAttributes.TRACE_TAGS]: tags,
|
|
50
|
+
[OtelSpanAttributes.ENVIRONMENT]: environment,
|
|
51
|
+
[OtelSpanAttributes.TRACE_PUBLIC]: isPublic,
|
|
52
|
+
..._flattenAndSerializeMetadata(metadata, OtelSpanAttributes.TRACE_METADATA),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return Object.fromEntries(
|
|
56
|
+
Object.entries(attributes).filter(([_, v]) => v != null),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Creates OpenTelemetry attributes from observation attributes.
|
|
62
|
+
*
|
|
63
|
+
* Maps observation attributes to OpenInference semantic conventions:
|
|
64
|
+
* - Uses `openinference.span.kind` for span type
|
|
65
|
+
* - Uses `llm.*` for LLM-specific attributes
|
|
66
|
+
* - Uses `tool.*` for tool-specific attributes
|
|
67
|
+
* - Falls back to `agkit.observation.*` for non-standard attributes
|
|
68
|
+
*
|
|
69
|
+
* @param type - Observation type (llm, tool, chain, etc.)
|
|
70
|
+
* @param attributes - Observation attributes to convert
|
|
71
|
+
* @returns OpenTelemetry attributes object
|
|
72
|
+
*
|
|
73
|
+
* @public
|
|
74
|
+
*/
|
|
75
|
+
export function createObservationAttributes(
|
|
76
|
+
type: ObservationType,
|
|
77
|
+
attributes: ObservationAttributes,
|
|
78
|
+
): Attributes {
|
|
79
|
+
const {
|
|
80
|
+
metadata,
|
|
81
|
+
input,
|
|
82
|
+
output,
|
|
83
|
+
level,
|
|
84
|
+
statusMessage,
|
|
85
|
+
version,
|
|
86
|
+
completionStartTime,
|
|
87
|
+
model,
|
|
88
|
+
modelParameters,
|
|
89
|
+
usageDetails,
|
|
90
|
+
} = attributes;
|
|
91
|
+
|
|
92
|
+
// Base attributes for all observation types
|
|
93
|
+
const otelAttributes: Attributes = {
|
|
94
|
+
[SemanticConventions.OPENINFERENCE_SPAN_KIND]: type.toUpperCase(),
|
|
95
|
+
[OtelSpanAttributes.OBSERVATION_TYPE]: type,
|
|
96
|
+
[OtelSpanAttributes.OBSERVATION_LEVEL]: level,
|
|
97
|
+
[OtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,
|
|
98
|
+
[OtelSpanAttributes.VERSION]: version,
|
|
99
|
+
// Use OpenInference input.value convention
|
|
100
|
+
[SemanticConventions.INPUT_VALUE]: _serialize(input),
|
|
101
|
+
// Also set legacy agkit.observation.input for compatibility
|
|
102
|
+
[OtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),
|
|
103
|
+
// Use OpenInference output.value convention
|
|
104
|
+
[SemanticConventions.OUTPUT_VALUE]: _serialize(output),
|
|
105
|
+
// Also set legacy agkit.observation.output for compatibility
|
|
106
|
+
[OtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// LLM-specific attributes
|
|
110
|
+
if (type === "llm") {
|
|
111
|
+
if (model) {
|
|
112
|
+
otelAttributes[SemanticConventions.LLM_MODEL_NAME] = model;
|
|
113
|
+
}
|
|
114
|
+
if (modelParameters) {
|
|
115
|
+
otelAttributes[SemanticConventions.LLM_INVOCATION_PARAMETERS] =
|
|
116
|
+
_serialize(modelParameters);
|
|
117
|
+
// Also set agkit.llm.model_parameters for compatibility
|
|
118
|
+
otelAttributes[OtelSpanAttributes.LLM_MODEL_PARAMETERS] =
|
|
119
|
+
_serialize(modelParameters);
|
|
120
|
+
}
|
|
121
|
+
if (usageDetails) {
|
|
122
|
+
// Map to OpenInference llm.token_count.* attributes
|
|
123
|
+
if (typeof usageDetails === "object") {
|
|
124
|
+
const usage = usageDetails as Record<string, number>;
|
|
125
|
+
if (usage.promptTokens !== undefined) {
|
|
126
|
+
otelAttributes[SemanticConventions.LLM_TOKEN_COUNT_PROMPT] =
|
|
127
|
+
usage.promptTokens;
|
|
128
|
+
}
|
|
129
|
+
if (usage.completionTokens !== undefined) {
|
|
130
|
+
otelAttributes[SemanticConventions.LLM_TOKEN_COUNT_COMPLETION] =
|
|
131
|
+
usage.completionTokens;
|
|
132
|
+
}
|
|
133
|
+
if (usage.totalTokens !== undefined) {
|
|
134
|
+
otelAttributes[SemanticConventions.LLM_TOKEN_COUNT_TOTAL] =
|
|
135
|
+
usage.totalTokens;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Also set legacy agkit.llm.usage_details for compatibility
|
|
139
|
+
otelAttributes[OtelSpanAttributes.LLM_USAGE_DETAILS] =
|
|
140
|
+
_serialize(usageDetails);
|
|
141
|
+
}
|
|
142
|
+
if (completionStartTime) {
|
|
143
|
+
otelAttributes[OtelSpanAttributes.LLM_COMPLETION_START_TIME] =
|
|
144
|
+
_serialize(completionStartTime);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Embedding-specific attributes
|
|
149
|
+
if (type === "embedding") {
|
|
150
|
+
if (model) {
|
|
151
|
+
otelAttributes[SemanticConventions.EMBEDDING_MODEL_NAME] = model;
|
|
152
|
+
}
|
|
153
|
+
if (modelParameters) {
|
|
154
|
+
otelAttributes[SemanticConventions.LLM_INVOCATION_PARAMETERS] =
|
|
155
|
+
_serialize(modelParameters);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Add metadata (use OpenInference metadata convention)
|
|
160
|
+
const metadataAttrs = _flattenAndSerializeMetadata(
|
|
161
|
+
metadata,
|
|
162
|
+
SemanticConventions.METADATA,
|
|
163
|
+
);
|
|
164
|
+
Object.assign(otelAttributes, metadataAttrs);
|
|
165
|
+
|
|
166
|
+
// Also add agkit.observation.metadata for compatibility
|
|
167
|
+
const obsetvabilityMetadataAttrs = _flattenAndSerializeMetadata(
|
|
168
|
+
metadata,
|
|
169
|
+
OtelSpanAttributes.OBSERVATION_METADATA
|
|
170
|
+
);
|
|
171
|
+
Object.assign(otelAttributes, obsetvabilityMetadataAttrs);
|
|
172
|
+
|
|
173
|
+
// Filter out null/undefined values
|
|
174
|
+
return Object.fromEntries(
|
|
175
|
+
Object.entries(otelAttributes).filter(([_, v]) => v != null),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Safely serializes an object to JSON string.
|
|
181
|
+
*
|
|
182
|
+
* @param obj - Object to serialize
|
|
183
|
+
* @returns JSON string or undefined if null/undefined
|
|
184
|
+
* @internal
|
|
185
|
+
*/
|
|
186
|
+
function _serialize(obj: unknown): string | undefined {
|
|
187
|
+
try {
|
|
188
|
+
if (typeof obj === "string") return obj;
|
|
189
|
+
if (obj instanceof Date) return obj.toISOString();
|
|
190
|
+
return obj != null ? JSON.stringify(obj) : undefined;
|
|
191
|
+
} catch {
|
|
192
|
+
return "<failed to serialize>";
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Flattens and serializes metadata into OpenTelemetry attribute format.
|
|
198
|
+
*
|
|
199
|
+
* Converts nested metadata objects into dot-notation attribute keys.
|
|
200
|
+
* For example, `{ database: { host: 'localhost' } }` becomes
|
|
201
|
+
* `{ 'metadata.database.host': 'localhost' }` (or 'agkit.observation.metadata.database.host').
|
|
202
|
+
*
|
|
203
|
+
* @param metadata - Metadata object to flatten
|
|
204
|
+
* @param prefix - Attribute prefix (e.g., 'metadata' or 'agkit.observation.metadata')
|
|
205
|
+
* @returns Flattened metadata attributes
|
|
206
|
+
* @internal
|
|
207
|
+
*/
|
|
208
|
+
function _flattenAndSerializeMetadata(
|
|
209
|
+
metadata: unknown,
|
|
210
|
+
prefix: string,
|
|
211
|
+
): Record<string, string> {
|
|
212
|
+
const metadataAttributes: Record<string, string> = {};
|
|
213
|
+
|
|
214
|
+
if (metadata === undefined || metadata === null) {
|
|
215
|
+
return metadataAttributes;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
219
|
+
const serialized = _serialize(metadata);
|
|
220
|
+
if (serialized) {
|
|
221
|
+
metadataAttributes[prefix] = serialized;
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
225
|
+
const serialized = typeof value === "string" ? value : _serialize(value);
|
|
226
|
+
if (serialized) {
|
|
227
|
+
metadataAttributes[`${prefix}.${key}`] = serialized;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return metadataAttributes;
|
|
233
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OTEL attribute constants for AG-Kit observability.
|
|
3
|
+
*
|
|
4
|
+
* Uses OpenInference semantic conventions where applicable:
|
|
5
|
+
* https://github.com/Arize-ai/openinference/tree/main/spec
|
|
6
|
+
*
|
|
7
|
+
* Falls back to AG-Kit specific attributes where OpenInference
|
|
8
|
+
* doesn't define a standard.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
SemanticConventions,
|
|
15
|
+
OpenInferenceSpanKind,
|
|
16
|
+
} from "@arizeai/openinference-semantic-conventions";
|
|
17
|
+
|
|
18
|
+
// Re-export OpenInference types for convenience
|
|
19
|
+
export { OpenInferenceSpanKind };
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* SDK information
|
|
23
|
+
*/
|
|
24
|
+
export const OBSERVABILITY_TRACER_NAME = "agkit-tracer";
|
|
25
|
+
export const OBSERVABILITY_SDK_NAME = "@agkit/observability";
|
|
26
|
+
// Version will be injected from package.json
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Combined attribute namespace for internal use
|
|
30
|
+
* Provides a single namespace for all OTEL attributes used by AG-Kit
|
|
31
|
+
*
|
|
32
|
+
* Combines OpenInference SemanticConventions with AG-Kit specific attributes
|
|
33
|
+
*/
|
|
34
|
+
export const OtelSpanAttributes = {
|
|
35
|
+
// OpenInference - re-export all standard conventions
|
|
36
|
+
...SemanticConventions,
|
|
37
|
+
|
|
38
|
+
// AG-Kit Trace attributes (non-standard)
|
|
39
|
+
TRACE_NAME: "trace.name",
|
|
40
|
+
TRACE_TAGS: "trace.tags",
|
|
41
|
+
TRACE_PUBLIC: "trace.public",
|
|
42
|
+
TRACE_METADATA: "trace.metadata",
|
|
43
|
+
TRACE_INPUT: "trace.input",
|
|
44
|
+
TRACE_OUTPUT: "trace.output",
|
|
45
|
+
|
|
46
|
+
// AG-Kit Observation attributes (non-standard)
|
|
47
|
+
OBSERVATION_TYPE: "observation.type",
|
|
48
|
+
OBSERVATION_LEVEL: "observation.level",
|
|
49
|
+
OBSERVATION_STATUS_MESSAGE: "observation.status_message",
|
|
50
|
+
OBSERVATION_INPUT: "observation.input",
|
|
51
|
+
OBSERVATION_OUTPUT: "observation.output",
|
|
52
|
+
OBSERVATION_METADATA: "observation.metadata",
|
|
53
|
+
|
|
54
|
+
// AG-Kit LLM-specific (non-standard)
|
|
55
|
+
LLM_COMPLETION_START_TIME: "llm.completion_start_time",
|
|
56
|
+
LLM_MODEL_PARAMETERS: "llm.model_parameters",
|
|
57
|
+
LLM_USAGE_DETAILS: "llm.usage_details",
|
|
58
|
+
LLM_COST_DETAILS: "llm.cost_details",
|
|
59
|
+
|
|
60
|
+
// AG-Kit Retriever-specific (non-standard)
|
|
61
|
+
RETRIEVER_NAME: "retriever.name",
|
|
62
|
+
RETRIEVER_QUERY: "retriever.query",
|
|
63
|
+
RETRIEVER_INDEX_ID: "retriever.index_id",
|
|
64
|
+
RETRIEVER_TOP_K: "retriever.top_k",
|
|
65
|
+
|
|
66
|
+
// AG-Kit General (non-standard)
|
|
67
|
+
ENVIRONMENT: "environment",
|
|
68
|
+
RELEASE: "release",
|
|
69
|
+
VERSION: "version",
|
|
70
|
+
} as const;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Type for the OtelSpanAttributes object values
|
|
74
|
+
*/
|
|
75
|
+
export type OtelSpanAttributeValues = typeof OtelSpanAttributes[keyof typeof OtelSpanAttributes];
|