fix(openllmetry): support new gen_ai.input/output.messages format (v0.55.0+)#2931
fix(openllmetry): support new gen_ai.input/output.messages format (v0.55.0+)#2931
Conversation
….55.0+) opentelemetry-instrumentation-openai v0.55.0 (traceloop/openllmetry#3844) replaced gen_ai.prompt.{idx}.* / gen_ai.completion.{idx}.* span attributes with gen_ai.input.messages / gen_ai.output.messages JSON strings using a parts-based schema. This broke the OpenInferenceSpanProcessor which relied on gen_ai.prompt.* to detect and parse LLM spans. - Add _parse_genai_messages() to handle the new parts-based JSON format - Update on_end() guard to detect either old or new message format - Fall back to gen_ai.provider.name when gen_ai.system is absent - Support gen_ai.tool.definitions for tool lookup - Cache enum validation sets at module level for hot-path efficiency
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
_collect_oi_messages -> _parse_messages_from_attributes _parse_genai_messages -> _parse_messages_from_json Both produce the same output (OI Messages). The names now reflect the input format they parse, not the output type.
Use the same real TracerProvider + InMemorySpanExporter pattern as the existing VCR test. Also switches test attrs from gen_ai.system to gen_ai.provider.name to match the real v0.55.0+ attribute layout.
|
feel free to bump the pinned/minimum version of openllmetry that we supported in the |
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
Frame the JSON-based message format (v0.55.0+) as the default and the legacy attribute-per-field format as the fallback. Note gen_ai.system deprecation in favor of gen_ai.provider.name.
gen_ai.system is deprecated (OTel semconv v1.37.0) and v0.55.0+ only emits gen_ai.provider.name. Keep system_val sourced solely from gen_ai.system so it is None for newer spans rather than incorrectly deriving it from provider.name. Update tests accordingly.
… fix/openllmetry-genai-semconv-v055
|
@claude review |
|
Claude finished @nate-mar's task in 1m 55s —— View job Code Review
Overall this is a clean, well-structured fix for the OpenLLMetry v0.55.0 semconv change. The backwards-compatibility approach (detect format, route to appropriate parser) is correct. A few observations: Outstanding from reviewer feedback
Since the VCR test was renamed to Minor issues1. Missing test for
2. Missing test for malformed JSON input (
def test_parse_messages_from_json_invalid(self) -> None:
messages, finish_reasons = _parse_messages_from_json("not valid json")
assert messages == []
assert finish_reasons == []3. Pre-existing: "tools": json.loads(attrs[tool_key]) if tool_key else None,If What's done well
The main outstanding item is addressing @caroger's request to bump the pinned OpenLLMetry version in |
|
Discussed Roger's feedback off line; agreed to support both message formats for now since it's manageable. |
Summary
opentelemetry-instrumentation-openaiv0.55.0 (traceloop/openllmetry#3844), implementing OTel GenAI Semantic Conventions v0.5.1, changed how message data is attached to spans. This broke theOpenInferenceSpanProcessorwhich relied on the old format, causing the Python canary cron to fail onpy310-ci-openllmetry-latestandpy314-ci-openllmetry-latest.Before (v0.54.x and earlier) - flat indexed span attributes
After (v0.55.0+) - JSON strings with parts-based schema
Changes
_parse_messages_from_json()to handle the v0.55.0+ parts-based JSON format (text, tool_call, tool_call_response parts)on_end()to detect the JSON-based message format (default) or the legacy attribute-per-field format (fallback), routing to the appropriate parsergen_ai.tool.definitionsto the tool key lookup chainRelated upstream changes
Test plan
ruff-mypy-test-openllmetry)py310-ci-openllmetry-latest) withopentelemetry-instrumentation-openai==0.55.0test_openllmetry_instrumentorfails on v0.55.0 (assert is_openinference_span(span))_parse_messages_from_json()(simple messages, tool calls)OpenInferenceSpanProcessor.on_end()with updated message attributes_extract_llm_provider_and_system()