Skip to content

Fix: seed the user turn from OpenInference nested content-parts messages - #52

Merged
AshwinUgale merged 1 commit into
mainfrom
fix/openinference-content-parts
Sep 3, 2026
Merged

Fix: seed the user turn from OpenInference nested content-parts messages#52
AshwinUgale merged 1 commit into
mainfrom
fix/openinference-content-parts

Conversation

@AshwinUgale

Copy link
Copy Markdown
Owner

What

The OTel/OpenInference adapter's _collect_messages read only the flat
llm.input_messages.N.message.content string. Many OpenInference instrumentors
(smolagents among them) instead emit the content-parts shape:

llm.input_messages.N.message.contents.M.message_content.text

Because that shape wasn't parsed, the user's own request was dropped from the
seeded input turns. With no record of what the agent observed, R3
(hallucinated-arg) falsely flagged an argument the user actually supplied

(e.g. order_id) as an underivable/hallucinated value.

This change collects the indexed text parts and joins them into content
(a flat message.content still wins when present).

Why it matters

This is a general OpenInference correctness fix, not a framework-specific
one — the content-parts shape is common across OpenInference instrumentation, so
the false positive affected any such trace.

How it was found & verified

Surfaced while linting a real agent trace via --format openinference. Verified
on a real gpt-4o-mini ToolCallingAgent run (genuine LLM spans, so the
user-prompt provenance was genuinely present in the trace, ruling out a
scripted-model artifact):

  • Before: R3 [candidate] order_id=A100 not derivable — false positive.
  • After: the trace lints clean, 0 findings.

Independently confirmed by collapsing the nested content into the flat form on a
copy of the spans and watching R3 vanish — isolating this parsing as the sole
cause.

Tests

tests/test_adapter_otel.py::test_input_messages_seed_from_nested_content_parts_shape
(built from the real trace). Full suite green.

The OTel adapter's _collect_messages read only the flat
llm.input_messages.N.message.content string. smolagents (and other
OpenInference instrumentors) emit the content-parts shape instead —
llm.input_messages.N.message.contents.M.message_content.text — so the
user's own request was dropped from the seeded input turns. With no
record of what the agent observed, R3 falsely flagged an argument the
user actually supplied (order_id) as an underivable/hallucinated value.

Collect the indexed text parts and join them into content (a flat
message.content still wins when present). Verified against a real
gpt-4o-mini smolagents ToolCallingAgent trace: R3's false positive on
order_id=A100 disappears and the trace lints clean. Not smolagents-
specific — this shape is common across OpenInference instrumentation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@AshwinUgale
AshwinUgale merged commit a29222c into main Sep 3, 2026
3 checks passed
@AshwinUgale
AshwinUgale deleted the fix/openinference-content-parts branch September 3, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant