otelMiddleware: captureContent drops image/audio/video/document parts, recording only '[image]' placeholders
Maintainers usually reply within 1 day
Assessment
This issue has not been assessed yet.
Description
Summary
With captureContent: true, otelMiddleware replaces every non-text content part with a placeholder string before writing gen_ai.input.messages / langfuse.observation.input. A vision call's recorded input reads:
[{"role":"user","content":"Describe this reference image. [image]"}]
The image is gone from the trace. For vision classification this is the part you most need when debugging. For example: why did the model call this image an illustration? You can see the model's answer but not what it looked at.
Root cause
serializeContent (packages/ai/src/middlewares/otel.ts:185) flattens each message to one string. Image, audio, video and document parts become '[image]', '[audio]' and so on, and source is discarded:
case 'image':
parts.push('[image]')
break
The result is written as { role, content: string } (line ~584), so there is nowhere to put a structured part even if one survived.
There is no way to work around this from outside the middleware:
attributeEnricherruns before thecaptureContentblock, so anything it sets ongen_ai.input.messagesgets overwritten.redactonly ever sees the already-flattened string.
Proposal
Keep content parts structured in gen_ai.input.messages, following the OTel GenAI semconv parts shape, which PostHog, Langfuse and Datadog all render:
text→{ type: 'text', content }image/audio/video/documentwithsource.type === 'url'→{ type: 'uri', modality, uri: source.value, mime_type? }source.type === 'data'(inline base64) → keep the placeholder by default, since it would blowmaxContentLengthand span attribute limits. Optionally add an opt-in hook (e.g.serializePart?: (part) => unknown) so an app can upload the blob and substitute a URL.
redact should still apply to the text parts.
If changing the attribute shape is too breaking for 0.x, an opt-in structuredContent: true flag would also work.
Version
@tanstack/ai 0.58.0 (current main has the same code).
I'm happy to open a PR.
- Dominant language
- TypeScript
- Stars
- 3.1k
- Forks
- 340
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 174
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from TanStack/ai
-
StreamProcessor ignores the stream's message ids and files agent-loop calls on the wrong assistant messagePossibly taken @tombeckenham claimed this today. Openwaiting-on: maintainer
TanStack/ai#1533 · 1 assignee ·
Maintainers usually reply within 1 day
-
StreamProcessor drops TEXT_MESSAGE_CHUNK events without a warningPossibly taken @AlemTuzlak claimed this today. Openwaiting-on: maintainer
TanStack/ai#1531 · 1 assignee ·
Maintainers usually reply within 1 day
-
feat(ai): add a timeout option to chat(), matching the media activitiesPossibly taken @AlemTuzlak claimed this 1 day ago. Openwaiting-on: maintainer
TanStack/ai#1517 · 1 assignee ·
Maintainers usually reply within 1 day
-
Does a hosted provider package have to carry a key?Possibly taken @AlemTuzlak claimed this 2 days ago. Openwaiting-on: author
TanStack/ai#1506 · 1 comment · 1 assignee ·
Maintainers usually reply within 1 day
-
Client tools never execute against spec-compliant AG-UI servers (plain `success` RUN_FINISHED)Possibly taken @jherr claimed this 4 days ago. Openwaiting-on: maintainer
TanStack/ai#1464 · 1 reaction · 1 assignee ·
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
rohitg00/agentmemory#1428 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
boxlite-ai/boxlite#1729 ·
Maintainers usually reply within 1 day
-
detectors enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
SM260845/readme-gen#1 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
angular/angularfire#3774 ·
Maintainers usually reply within 2 days