@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/langchain.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"() {
@@ -727,6 +884,8 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
727
884
  last_trace_id = null;
728
885
  // External parent context from AG-UI.Server span
729
886
  externalParentSpanContext;
887
+ // External metadata from AG-UI.Server (e.g., threadId, runId)
888
+ externalMetadata;
730
889
  // Adapter name for ROOT span prefix
731
890
  adapterName;
732
891
  // Logger for debug output (defaults to noopLogger for silent operation)
@@ -748,10 +907,12 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
748
907
  * to the server-level span, creating a unified trace hierarchy.
749
908
  *
750
909
  * @param spanContext - SpanContext from the AG-UI.Server span
910
+ * @param metadata - Optional metadata from server (e.g., threadId, runId)
751
911
  * @public
752
912
  */
753
- setExternalParentContext(spanContext) {
913
+ setExternalParentContext(spanContext, metadata) {
754
914
  this.externalParentSpanContext = spanContext;
915
+ this.externalMetadata = metadata;
755
916
  }
756
917
  async handleLLMNewToken(token, _idx, runId, _parentRunId, _tags, _fields) {
757
918
  if (runId && !(runId in this.completionStartTimes)) {
@@ -781,7 +942,7 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
781
942
  parentRunId,
782
943
  runId,
783
944
  tags,
784
- metadata,
945
+ metadata: this.joinTagsAndMetaData(tags, metadata),
785
946
  attributes: {
786
947
  input: finalInput
787
948
  },
@@ -862,10 +1023,15 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
862
1023
  }
863
1024
  }
864
1025
  let extractedModelName;
1026
+ let extractedSystem;
1027
+ let extractedProvider;
865
1028
  if (extraParams) {
866
1029
  const invocationParamsModelName = extraParams.invocation_params.model;
867
1030
  const metadataModelName = metadata && "ls_model_name" in metadata ? metadata["ls_model_name"] : void 0;
868
1031
  extractedModelName = invocationParamsModelName ?? metadataModelName;
1032
+ if (metadata && "ls_provider" in metadata) {
1033
+ extractedProvider = metadata["ls_provider"];
1034
+ }
869
1035
  }
870
1036
  const registeredPrompt = this.promptToParentRunMap.get(
871
1037
  parentRunId ?? "root"
@@ -958,7 +1124,7 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
958
1124
  attributes: {
959
1125
  input
960
1126
  },
961
- metadata,
1127
+ metadata: this.joinTagsAndMetaData(tags, metadata),
962
1128
  tags,
963
1129
  asType: "tool"
964
1130
  });
@@ -977,7 +1143,7 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
977
1143
  input: query
978
1144
  },
979
1145
  tags,
980
- metadata,
1146
+ metadata: this.joinTagsAndMetaData(tags, metadata),
981
1147
  asType: "span"
982
1148
  });
983
1149
  } catch (e) {
@@ -1123,12 +1289,14 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
1123
1289
  if (!parentRunId && this.adapterName) {
1124
1290
  finalRunName = `Adapter.${this.adapterName}`;
1125
1291
  }
1292
+ const serverMetadata = this.externalMetadata ? { "agui.thread_id": this.externalMetadata.threadId, "agui.run_id": this.externalMetadata.runId } : {};
1126
1293
  const observation = startObservation(
1127
1294
  finalRunName,
1128
1295
  {
1129
1296
  version: this.version,
1130
1297
  metadata: this.joinTagsAndMetaData(tags, metadata),
1131
- ...attributes
1298
+ ...attributes,
1299
+ ...serverMetadata
1132
1300
  },
1133
1301
  {
1134
1302
  asType: asType ?? "span",
@@ -1145,6 +1313,19 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
1145
1313
  this.logger.warn?.("Observation not found in runMap. Skipping operation.");
1146
1314
  return;
1147
1315
  }
1316
+ const level = attributes.level;
1317
+ const statusMessage = attributes.statusMessage;
1318
+ if (level === "ERROR") {
1319
+ try {
1320
+ const { SpanStatusCode: SpanStatusCode2 } = require("@opentelemetry/api");
1321
+ observation.otelSpan.setStatus({
1322
+ code: SpanStatusCode2.ERROR,
1323
+ message: statusMessage || "Unknown error"
1324
+ });
1325
+ } catch (e) {
1326
+ this.logger.debug?.("Failed to set span error status:", e);
1327
+ }
1328
+ }
1148
1329
  observation.update(attributes).end();
1149
1330
  this.last_trace_id = observation.traceId;
1150
1331
  this.runMap.delete(runId);
@@ -1166,7 +1347,7 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
1166
1347
  if (!metadata) {
1167
1348
  return;
1168
1349
  }
1169
- const reservedKeys = ["promptInfo", "userId", "sessionId"];
1350
+ const reservedKeys = ["promptInfo", "userId", "sessionId", "thread_id", "runId", "run_id"];
1170
1351
  return Object.fromEntries(
1171
1352
  Object.entries(metadata).filter(([key, _]) => !reservedKeys.includes(key))
1172
1353
  );