@arizeai/openinference-genai 0.3.1 → 0.3.3
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/commonjs/attributes.d.ts.map +1 -1
- package/dist/commonjs/attributes.js +23 -10
- package/dist/commonjs/attributes.js.map +1 -1
- package/dist/commonjs/tsconfig.commonjs.tsbuildinfo +1 -1
- package/dist/esm/attributes.d.ts.map +1 -1
- package/dist/esm/attributes.js +23 -9
- package/dist/esm/attributes.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/attributes.ts +41 -10
package/src/attributes.ts
CHANGED
|
@@ -121,8 +121,21 @@ const ATTR_GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS = "gen_ai.usage.cache_read.input
|
|
|
121
121
|
const ATTR_GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS =
|
|
122
122
|
"gen_ai.usage.cache_creation.input_tokens" as const;
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* A reasoning (thinking) message part.
|
|
126
|
+
*
|
|
127
|
+
* Producers such as `@ai-sdk/otel` already emit `{ type: "reasoning", content: "..." }` parts in
|
|
128
|
+
* `gen_ai.input.messages` / `gen_ai.output.messages`, but the draft OTel GenAI message schemas the
|
|
129
|
+
* types in `__generated__` are derived from do not yet declare the part — hence the local type.
|
|
130
|
+
*/
|
|
131
|
+
interface ReasoningPart {
|
|
132
|
+
type: "reasoning";
|
|
133
|
+
content?: unknown;
|
|
134
|
+
[k: string]: unknown;
|
|
135
|
+
}
|
|
136
|
+
|
|
124
137
|
// Shared part parsing
|
|
125
|
-
type AnyPart = GenAIInputMessagePart | GenAIOutputMessagePart;
|
|
138
|
+
type AnyPart = GenAIInputMessagePart | GenAIOutputMessagePart | ReasoningPart;
|
|
126
139
|
|
|
127
140
|
/**
|
|
128
141
|
* Type guard for a GenAI chat message
|
|
@@ -241,6 +254,20 @@ const processMessageParts = ({
|
|
|
241
254
|
}
|
|
242
255
|
continue;
|
|
243
256
|
}
|
|
257
|
+
case "reasoning": {
|
|
258
|
+
// MESSAGE_CONTENTS entry carrying the reasoning text itself, not the serialized part
|
|
259
|
+
const contentPrefix = `${msgPrefix}${SemanticConventions.MESSAGE_CONTENTS}.${contentIndex}.`;
|
|
260
|
+
set(attrs, `${contentPrefix}${SemanticConventions.MESSAGE_CONTENT_TYPE}`, "reasoning");
|
|
261
|
+
if (part.content != null) {
|
|
262
|
+
set(
|
|
263
|
+
attrs,
|
|
264
|
+
`${contentPrefix}${SemanticConventions.MESSAGE_CONTENT_TEXT}`,
|
|
265
|
+
toStringContent(part.content),
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
contentIndex += 1;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
244
271
|
case "tool_call": {
|
|
245
272
|
const id = part.id ?? undefined;
|
|
246
273
|
const name = part.name;
|
|
@@ -265,13 +292,14 @@ const processMessageParts = ({
|
|
|
265
292
|
continue;
|
|
266
293
|
}
|
|
267
294
|
default: {
|
|
268
|
-
// Generic / unknown part type: capture as JSON text content
|
|
295
|
+
// Generic / unknown part type: capture as JSON text content. Only MESSAGE_CONTENTS is
|
|
296
|
+
// written — the flat MESSAGE_CONTENT is an alternative representation of the same message,
|
|
297
|
+
// so setting both duplicates the content in consumers that render each of them.
|
|
269
298
|
const genericPart = part as GenericPart;
|
|
270
299
|
const genericText = toStringContent(genericPart);
|
|
271
300
|
const contentPrefix = `${msgPrefix}${SemanticConventions.MESSAGE_CONTENTS}.${contentIndex}.`;
|
|
272
301
|
set(attrs, `${contentPrefix}${SemanticConventions.MESSAGE_CONTENT_TYPE}`, genericPart.type);
|
|
273
302
|
set(attrs, `${contentPrefix}${SemanticConventions.MESSAGE_CONTENT_TEXT}`, genericText);
|
|
274
|
-
set(attrs, `${msgPrefix}${SemanticConventions.MESSAGE_CONTENT}`, genericText);
|
|
275
303
|
contentIndex += 1;
|
|
276
304
|
}
|
|
277
305
|
}
|
|
@@ -519,13 +547,16 @@ export const mapSystemInstructions = (spanAttributes: Attributes): Attributes =>
|
|
|
519
547
|
if (systemInstructions) {
|
|
520
548
|
set(attrs, `${SemanticConventions.METADATA}.gen_ai.system_instructions`, systemInstructions);
|
|
521
549
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
550
|
+
// Only emit the synthetic system message when there are parts to put in it.
|
|
551
|
+
// mapInputMessages shifts its indexes by one on exactly this condition, so
|
|
552
|
+
// emitting here without parts would claim index 0 while the input messages
|
|
553
|
+
// still start at 0, overwriting the first message's role with "system".
|
|
554
|
+
const parts = getSystemInstructionParts(spanAttributes);
|
|
555
|
+
if (parts != null) {
|
|
556
|
+
const msgPrefix = `${SemanticConventions.LLM_INPUT_MESSAGES}.0.`;
|
|
557
|
+
set(attrs, `${msgPrefix}${SemanticConventions.MESSAGE_ROLE}`, "system");
|
|
558
|
+
processMessageParts({ attrs, msgPrefix, parts });
|
|
559
|
+
}
|
|
529
560
|
}
|
|
530
561
|
return attrs;
|
|
531
562
|
};
|