@cloudbase/agent-observability 1.0.1-alpha.16 → 1.0.1-alpha.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/dist/index.d.ts CHANGED
@@ -45,6 +45,69 @@ type TokenUsage = {
45
45
  /** Total number of tokens */
46
46
  totalTokens?: number;
47
47
  };
48
+ /**
49
+ * LLM message for input/output tracking.
50
+ *
51
+ * Follows OpenInference semantic convention:
52
+ * - llm.input_messages.{i}.message.role
53
+ * - llm.input_messages.{i}.message.content
54
+ * - llm.output_messages.{i}.message.role
55
+ * - llm.output_messages.{i}.message.content
56
+ *
57
+ * @public
58
+ */
59
+ type LLMMessage = {
60
+ /** Message role (e.g., 'user', 'assistant', 'system', 'tool') */
61
+ role: string;
62
+ /** Message content */
63
+ content?: string;
64
+ /** Tool calls for assistant messages */
65
+ toolCalls?: ToolCall[];
66
+ /** Tool call ID for tool messages */
67
+ toolCallId?: string;
68
+ };
69
+ /**
70
+ * Tool call details.
71
+ *
72
+ * Follows OpenInference semantic convention:
73
+ * - tool_call.id
74
+ * - tool_call.function.name
75
+ * - tool_call.function.arguments
76
+ *
77
+ * @public
78
+ */
79
+ type ToolCall = {
80
+ /** Tool call ID */
81
+ id: string;
82
+ /** Function name */
83
+ function: {
84
+ /** Function name */
85
+ name: string;
86
+ /** Function arguments as JSON string */
87
+ arguments: string;
88
+ };
89
+ };
90
+ /**
91
+ * Document for retrieval tracking.
92
+ *
93
+ * Follows OpenInference semantic convention:
94
+ * - retrieval.documents.{i}.document.id
95
+ * - retrieval.documents.{i}.document.content
96
+ * - retrieval.documents.{i}.document.score
97
+ * - retrieval.documents.{i}.document.metadata
98
+ *
99
+ * @public
100
+ */
101
+ type Document = {
102
+ /** Document ID */
103
+ id?: string;
104
+ /** Document content */
105
+ content?: string;
106
+ /** Relevance score */
107
+ score?: number;
108
+ /** Document metadata */
109
+ metadata?: Record<string, unknown>;
110
+ };
48
111
  /**
49
112
  * Base attributes for all observation types.
50
113
  *
@@ -69,13 +132,18 @@ type BaseSpanAttributes = {
69
132
  version?: string;
70
133
  /** Environment where the operation is running (e.g., 'production', 'staging') */
71
134
  environment?: string;
135
+ /** Allow additional custom attributes (e.g., http.*, agui.*) */
136
+ [key: string]: unknown;
72
137
  };
73
138
  /**
74
139
  * LLM-specific attributes following OpenInference semantic conventions.
75
140
  *
76
141
  * Uses attributes like:
77
142
  * - llm.model_name
78
- * - llm.parameters.*
143
+ * - llm.system
144
+ * - llm.provider
145
+ * - llm.input_messages
146
+ * - llm.output_messages
79
147
  * - llm.token_count.*
80
148
  * - llm.invocation_parameters
81
149
  *
@@ -86,10 +154,22 @@ type LLMAttributes = BaseSpanAttributes & {
86
154
  completionStartTime?: Date;
87
155
  /** Name of the language model (e.g., 'gpt-4', 'claude-3-opus') */
88
156
  model?: string;
157
+ /** AI system/vendor identifier (e.g., 'openai', 'anthropic') */
158
+ system?: string;
159
+ /** Hosting provider (e.g., 'openai', 'azure', 'aws') */
160
+ provider?: string;
89
161
  /** Parameters passed to the model (temperature, max_tokens, etc.) */
90
162
  modelParameters?: Record<string, string | number>;
91
163
  /** Token usage metrics */
92
164
  usageDetails?: TokenUsage | Record<string, number>;
165
+ /** Input messages for chat completions */
166
+ inputMessages?: LLMMessage[];
167
+ /** Output messages from the model */
168
+ outputMessages?: LLMMessage[];
169
+ /** MIME type of input (e.g., 'application/json') */
170
+ inputMimeType?: string;
171
+ /** MIME type of output (e.g., 'application/json') */
172
+ outputMimeType?: string;
93
173
  };
94
174
  /**
95
175
  * Embedding-specific attributes following OpenInference semantic conventions.
@@ -108,10 +188,22 @@ type EmbeddingAttributes = LLMAttributes;
108
188
  * - tool.name
109
189
  * - tool.description
110
190
  * - tool.parameters
191
+ * - tool_call.id
192
+ * - tool_call.function.name
193
+ * - tool_call.function.arguments
111
194
  *
112
195
  * @public
113
196
  */
114
- type ToolAttributes = BaseSpanAttributes;
197
+ type ToolAttributes = BaseSpanAttributes & {
198
+ /** Tool name */
199
+ toolName?: string;
200
+ /** Tool description */
201
+ toolDescription?: string;
202
+ /** Tool parameters schema */
203
+ toolParameters?: Record<string, unknown>;
204
+ /** Tool call details */
205
+ toolCall?: ToolCall;
206
+ };
115
207
  /**
116
208
  * Agent-specific attributes following OpenInference semantic conventions.
117
209
  *
@@ -121,7 +213,10 @@ type ToolAttributes = BaseSpanAttributes;
121
213
  *
122
214
  * @public
123
215
  */
124
- type AgentAttributes = BaseSpanAttributes;
216
+ type AgentAttributes = BaseSpanAttributes & {
217
+ /** Agent name */
218
+ agentName?: string;
219
+ };
125
220
  /**
126
221
  * Chain-specific attributes following OpenInference semantic conventions.
127
222
  *
@@ -138,11 +233,16 @@ type ChainAttributes = BaseSpanAttributes;
138
233
  * Uses attributes like:
139
234
  * - retriever.name
140
235
  * - retriever.query
141
- * - retriever.*
236
+ * - retrieval.documents
142
237
  *
143
238
  * @public
144
239
  */
145
- type RetrieverAttributes = BaseSpanAttributes;
240
+ type RetrieverAttributes = BaseSpanAttributes & {
241
+ /** Retrieved documents */
242
+ documents?: Document[];
243
+ /** Query used for retrieval */
244
+ query?: string;
245
+ };
146
246
  /**
147
247
  * Reranker-specific attributes following OpenInference semantic conventions.
148
248
  *
@@ -725,4 +825,4 @@ type ObserveOptions = Omit<StartObservationOpts, "name"> & {
725
825
  */
726
826
  declare function observe<T extends (...args: any[]) => any>(fn: T, options?: ObserveOptions): T;
727
827
 
728
- export { type AgentAttributes, type BaseSpanAttributes, type ChainAttributes, type EmbeddingAttributes, type EvaluatorAttributes, type GuardrailAttributes, type LLMAttributes, type Observation, ObservationAgent, type ObservationAttributes, ObservationChain, ObservationEmbedding, ObservationEvaluator, ObservationGuardrail, ObservationLLM, type ObservationLevel, ObservationReranker, ObservationRetriever, ObservationSpan, ObservationTool, type ObservationType, type ObserveOptions, type RerankerAttributes, type RetrieverAttributes, type StartActiveObservationOpts, type StartObservationOptions, type StartObservationOpts, type ToolAttributes, type TraceAttributes, createObservationAttributes, createTraceAttributes, getActiveSpanId, getActiveTraceId, getTracer, getTracerProvider, observe, setTracerProvider, startActiveObservation, startObservation, updateActiveObservation, updateActiveTrace };
828
+ export { type AgentAttributes, type BaseSpanAttributes, type ChainAttributes, type Document, type EmbeddingAttributes, type EvaluatorAttributes, type GuardrailAttributes, type LLMAttributes, type LLMMessage, type Observation, ObservationAgent, type ObservationAttributes, ObservationChain, ObservationEmbedding, ObservationEvaluator, ObservationGuardrail, ObservationLLM, type ObservationLevel, ObservationReranker, ObservationRetriever, ObservationSpan, ObservationTool, type ObservationType, type ObserveOptions, type RerankerAttributes, type RetrieverAttributes, type StartActiveObservationOpts, type StartObservationOptions, type StartObservationOpts, type ToolAttributes, type ToolCall, type TraceAttributes, createObservationAttributes, createTraceAttributes, getActiveSpanId, getActiveTraceId, getTracer, getTracerProvider, observe, setTracerProvider, startActiveObservation, startObservation, updateActiveObservation, updateActiveTrace };
package/dist/index.js CHANGED
@@ -125,6 +125,18 @@ function createObservationAttributes(type, attributes) {
125
125
  if (model) {
126
126
  otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_MODEL_NAME] = model;
127
127
  }
128
+ const system = attributes?.system;
129
+ const provider = attributes?.provider;
130
+ const inputMessages = attributes?.inputMessages;
131
+ const outputMessages = attributes?.outputMessages;
132
+ const inputMimeType = attributes?.inputMimeType;
133
+ const outputMimeType = attributes?.outputMimeType;
134
+ if (system !== void 0) {
135
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_SYSTEM] = String(system);
136
+ }
137
+ if (provider !== void 0) {
138
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_PROVIDER] = String(provider);
139
+ }
128
140
  if (modelParameters) {
129
141
  otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
130
142
  otelAttributes[OtelSpanAttributes.LLM_MODEL_PARAMETERS] = _serialize(modelParameters);
@@ -147,6 +159,20 @@ function createObservationAttributes(type, attributes) {
147
159
  if (completionStartTime) {
148
160
  otelAttributes[OtelSpanAttributes.LLM_COMPLETION_START_TIME] = _serialize(completionStartTime);
149
161
  }
162
+ if (inputMessages !== void 0 && Array.isArray(inputMessages)) {
163
+ const messageAttrs = _flattenLLMMessages(inputMessages, "llm.input_messages");
164
+ Object.assign(otelAttributes, messageAttrs);
165
+ }
166
+ if (outputMessages !== void 0 && Array.isArray(outputMessages)) {
167
+ const messageAttrs = _flattenLLMMessages(outputMessages, "llm.output_messages");
168
+ Object.assign(otelAttributes, messageAttrs);
169
+ }
170
+ if (inputMimeType !== void 0) {
171
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.INPUT_MIME_TYPE] = String(inputMimeType);
172
+ }
173
+ if (outputMimeType !== void 0) {
174
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.OUTPUT_MIME_TYPE] = String(outputMimeType);
175
+ }
150
176
  }
151
177
  if (type === "embedding") {
152
178
  if (model) {
@@ -156,6 +182,42 @@ function createObservationAttributes(type, attributes) {
156
182
  otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.LLM_INVOCATION_PARAMETERS] = _serialize(modelParameters);
157
183
  }
158
184
  }
185
+ if (type === "tool") {
186
+ const toolName = attributes?.toolName ?? attributes?.tool_name;
187
+ const toolDescription = attributes?.toolDescription;
188
+ const toolParameters = attributes?.toolParameters;
189
+ const toolCall = attributes?.toolCall;
190
+ if (toolName !== void 0) {
191
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.TOOL_NAME] = String(toolName);
192
+ }
193
+ if (toolDescription !== void 0) {
194
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.TOOL_DESCRIPTION] = String(toolDescription);
195
+ }
196
+ if (toolParameters !== void 0) {
197
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.TOOL_PARAMETERS] = _serialize(toolParameters);
198
+ }
199
+ if (toolCall !== void 0 && typeof toolCall === "object") {
200
+ const toolCallAttrs = _flattenToolCall(toolCall);
201
+ Object.assign(otelAttributes, toolCallAttrs);
202
+ }
203
+ }
204
+ if (type === "agent") {
205
+ const agentName = attributes?.agentName;
206
+ if (agentName !== void 0) {
207
+ otelAttributes[import_openinference_semantic_conventions2.SemanticConventions.AGENT_NAME] = String(agentName);
208
+ }
209
+ }
210
+ if (type === "retriever") {
211
+ const documents = attributes?.documents;
212
+ const query = attributes?.query;
213
+ if (documents !== void 0 && Array.isArray(documents)) {
214
+ const docAttrs = _flattenDocuments(documents);
215
+ Object.assign(otelAttributes, docAttrs);
216
+ }
217
+ if (query !== void 0) {
218
+ otelAttributes["retriever.query"] = String(query);
219
+ }
220
+ }
159
221
  const metadataAttrs = _flattenAndSerializeMetadata(
160
222
  metadata,
161
223
  import_openinference_semantic_conventions2.SemanticConventions.METADATA
@@ -166,6 +228,11 @@ function createObservationAttributes(type, attributes) {
166
228
  OtelSpanAttributes.OBSERVATION_METADATA
167
229
  );
168
230
  Object.assign(otelAttributes, obsetvabilityMetadataAttrs);
231
+ for (const [key, value] of Object.entries(attributes)) {
232
+ if (!(key in otelAttributes) && value !== void 0 && value !== null) {
233
+ otelAttributes[key] = typeof value === "string" ? value : _serialize(value);
234
+ }
235
+ }
169
236
  return Object.fromEntries(
170
237
  Object.entries(otelAttributes).filter(([_, v]) => v != null)
171
238
  );
@@ -199,6 +266,96 @@ function _flattenAndSerializeMetadata(metadata, prefix) {
199
266
  }
200
267
  return metadataAttributes;
201
268
  }
269
+ function _flattenLLMMessages(messages, prefix) {
270
+ const attributes = {};
271
+ if (!messages || !Array.isArray(messages)) {
272
+ return attributes;
273
+ }
274
+ try {
275
+ messages.forEach((msg, index) => {
276
+ if (!msg || typeof msg !== "object") return;
277
+ const baseKey = `${prefix}.${index}.message`;
278
+ if (msg.role !== void 0) {
279
+ attributes[`${baseKey}.role`] = String(msg.role);
280
+ }
281
+ if (msg.content !== void 0) {
282
+ attributes[`${baseKey}.content`] = String(msg.content);
283
+ }
284
+ if (msg.toolCallId !== void 0) {
285
+ attributes[`${baseKey}.tool_call_id`] = String(msg.toolCallId);
286
+ }
287
+ if (msg.toolCalls && Array.isArray(msg.toolCalls)) {
288
+ msg.toolCalls.forEach((toolCall, tcIndex) => {
289
+ if (!toolCall || typeof toolCall !== "object") return;
290
+ const tcKey = `${baseKey}.tool_calls.${tcIndex}`;
291
+ if (toolCall.id !== void 0) {
292
+ attributes[`${tcKey}.id`] = String(toolCall.id);
293
+ }
294
+ if (toolCall.function !== void 0) {
295
+ if (toolCall.function.name !== void 0) {
296
+ attributes[`${tcKey}.function.name`] = String(toolCall.function.name);
297
+ }
298
+ if (toolCall.function.arguments !== void 0) {
299
+ attributes[`${tcKey}.function.arguments`] = String(toolCall.function.arguments);
300
+ }
301
+ }
302
+ });
303
+ }
304
+ });
305
+ } catch (e) {
306
+ }
307
+ return attributes;
308
+ }
309
+ function _flattenDocuments(documents) {
310
+ const attributes = {};
311
+ if (!documents || !Array.isArray(documents)) {
312
+ return attributes;
313
+ }
314
+ try {
315
+ documents.forEach((doc, index) => {
316
+ if (!doc || typeof doc !== "object") return;
317
+ const baseKey = `retrieval.documents.${index}.document`;
318
+ if (doc.id !== void 0) {
319
+ attributes[`${baseKey}.id`] = String(doc.id);
320
+ }
321
+ if (doc.content !== void 0) {
322
+ attributes[`${baseKey}.content`] = String(doc.content);
323
+ }
324
+ if (doc.score !== void 0) {
325
+ attributes[`${baseKey}.score`] = String(doc.score);
326
+ }
327
+ if (doc.metadata !== void 0 && typeof doc.metadata === "object") {
328
+ const metadataSerialized = _serialize(doc.metadata);
329
+ if (metadataSerialized) {
330
+ attributes[`${baseKey}.metadata`] = metadataSerialized;
331
+ }
332
+ }
333
+ });
334
+ } catch (e) {
335
+ }
336
+ return attributes;
337
+ }
338
+ function _flattenToolCall(toolCall) {
339
+ const attributes = {};
340
+ if (!toolCall || typeof toolCall !== "object") {
341
+ return attributes;
342
+ }
343
+ try {
344
+ if (toolCall.id !== void 0) {
345
+ attributes["tool_call.id"] = String(toolCall.id);
346
+ }
347
+ if (toolCall.function !== void 0) {
348
+ if (toolCall.function.name !== void 0) {
349
+ attributes["tool_call.function.name"] = String(toolCall.function.name);
350
+ }
351
+ if (toolCall.function.arguments !== void 0) {
352
+ attributes["tool_call.function.arguments"] = String(toolCall.function.arguments);
353
+ }
354
+ }
355
+ } catch (e) {
356
+ }
357
+ return attributes;
358
+ }
202
359
  var import_openinference_semantic_conventions2;
203
360
  var init_attributes = __esm({
204
361
  "src/core/attributes.ts"() {