Skip to content

v1.1.1 - OTel-canonical dual emission

Choose a tag to compare

@Mandark-droid Mandark-droid released this 28 Apr 11:01
· 17 commits to main since this release

v1.1.1 — Dual-emission of OTel-canonical gen_ai.input/output.messages

What changed

After filing issue #3672
and reading the upstream JSON schemas more carefully, it became clear that OTel's
gen-ai-input-messages.json / gen-ai-output-messages.json already define BlobPart,
FilePart, UriPart and a Modality enum (image, video, audio). The flat attribute
namespace shipped in v1.1.0 was a different shape from upstream's established pattern.

v1.1.1 keeps the flat attributes (still useful as a query-friendly convenience for backends
that index attribute scalars) but adds dual-emission so multimodal traces remain portable
across OTel-compatible backends.

How it works

When OTEL_SEMCONV_STABILITY_OPT_IN includes gen_ai, the instrumentor now also writes:

  • gen_ai.input.messages — JSON list of ChatMessage per the upstream schema
  • gen_ai.output.messages — same for completions

ContentParts map as:

Our internal shape Upstream canonical shape
text part TextPart
image/audio/video with media_uri UriPart (with modality, mime_type, byte_size)
image/audio/video with inline bytes BlobPart (base64 content)
document parts UriPart/BlobPart with modality: "document" (proposed addition)
reference_only / stripped parts StrippedPart (proposed addition, with stripped_reason)

New public API

from genai_otel.media import build_canonical_messages, ContentPart

messages = build_canonical_messages([
    ("user", [
        ContentPart(type="text", text="describe"),
        ContentPart(type="image", media_uri="s3://bucket/key.png", media_mime_type="image/png"),
    ]),
])

Upstream proposal narrowed

The redrafted upstream PR (in docs/proposals/upstream-pr-draft/) is much smaller:

  1. Add document value to the Modality enum
  2. Add optional byte_size field to BlobPart / FilePart / UriPart
  3. Add new StrippedPart type for fail-closed observability

This is ~30 lines of JSON schema diff vs the 480-line registry expansion originally
drafted. Mirrors the upstream pattern, not a parallel one.

New tests

9 new tests:

  • 7 in tests/media/test_canonical.py covering the ContentPart → upstream-shape mapping
  • 2 in tests/media/test_instrumentor_emit.py verifying dual-emission gating

Backwards compatibility

Purely additive. The flat gen_ai.prompt.{n}.content.{m}.* attributes from v1.1.0 are
unchanged. Dual-emission is gated on OTEL_SEMCONV_STABILITY_OPT_IN so existing deployments
see no change unless they opt in.