Skip to content

Commit 9bcef8d

Browse files
committed
fix(instrumentation-utils): Add modality field to block mappers document cases
1 parent 999bd70 commit 9bcef8d

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

packages/instrumentation-utils/src/content-block-mappers.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ export function mapAnthropicContentBlock(block: any): object {
6565

6666
// -------------------------------------------------------------------------
6767
// Document — sources: base64 | text | url | file
68-
// Note: document blocks have no OTel modality (modality is image/video/audio only)
68+
// OTel modality accepts any string (anyOf: [Modality enum, string]), so
69+
// "document" is a valid value for BlobPart/UriPart/FilePart modality.
6970
// -------------------------------------------------------------------------
7071
case "document": {
7172
const src = block.source;
@@ -75,6 +76,7 @@ export function mapAnthropicContentBlock(block: any): object {
7576
// (can be "application/pdf" or "text/plain")
7677
return {
7778
type: "blob",
79+
modality: "document",
7880
mime_type: src.media_type,
7981
content: src.data,
8082
};
@@ -83,10 +85,15 @@ export function mapAnthropicContentBlock(block: any): object {
8385
return { type: "text", content: src.data };
8486
case "url":
8587
// URL-referenced PDF
86-
return { type: "uri", mime_type: "application/pdf", uri: src.url };
88+
return {
89+
type: "uri",
90+
modality: "document",
91+
mime_type: "application/pdf",
92+
uri: src.url,
93+
};
8794
case "file":
8895
// Files API reference — file_id is on source.file_id
89-
return { type: "file", file_id: src.file_id };
96+
return { type: "file", modality: "document", file_id: src.file_id };
9097
default:
9198
return { type: block.type, ...block };
9299
}
@@ -158,8 +165,8 @@ export function mapAnthropicContentBlock(block: any): object {
158165
// image_url (regular URL) → UriPart { modality: "image" }
159166
// image_url (data: URI) → BlobPart { modality: "image", mime_type parsed from URI }
160167
// input_audio → BlobPart { modality: "audio", mime_type: "audio/{format}" }
161-
// file (file_id) → FilePart { file_id }
162-
// file (file_data) → BlobPart { no modality — documents }
168+
// file (file_id) → FilePart { modality: "document", file_id }
169+
// file (file_data) → BlobPart { modality: "document", mime_type }
163170
// refusal → GenericPart { type: "refusal", content }
164171
// <unknown> → GenericPart
165172

@@ -212,14 +219,14 @@ export function mapOpenAIContentBlock(block: any): object {
212219

213220
// -------------------------------------------------------------------------
214221
// File — can be file_id reference or inline file_data
215-
// OTel FilePart and BlobPart require `modality` (image/video/audio),
216-
// but OpenAI files don't specify modality. Use GenericPart to preserve
217-
// all info without violating the schema.
222+
// OpenAI file content parts are used for documents (PDFs etc.), not images
223+
// (images use image_url). modality accepts any string, so "document" is valid.
218224
// -------------------------------------------------------------------------
219225
case "file": {
220226
if (block.file?.file_id) {
221227
return {
222228
type: "file",
229+
modality: "document",
223230
file_id: block.file.file_id,
224231
...(block.file.filename && { filename: block.file.filename }),
225232
};
@@ -228,6 +235,7 @@ export function mapOpenAIContentBlock(block: any): object {
228235
// Inline file data → BlobPart. OTel FilePart is a reference type (file_id only).
229236
return {
230237
type: "blob",
238+
modality: "document",
231239
mime_type: block.file.mime_type || "application/octet-stream",
232240
content: block.file.file_data,
233241
};

0 commit comments

Comments
 (0)