Skip to content

[opentelemetry-instrumentation-genai-bedrock] Add inference spans for Converse and ConverseStream methods - #488

Merged
lmolkova merged 16 commits into
mainfrom
DylanRussell/add_bedrock_instrumentation_2
Sep 1, 2026
Merged

[opentelemetry-instrumentation-genai-bedrock] Add inference spans for Converse and ConverseStream methods#488
lmolkova merged 16 commits into
mainfrom
DylanRussell/add_bedrock_instrumentation_2

Conversation

@DylanRussell

@DylanRussell DylanRussell commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Description

Adds logic to create an InferenceInvocation and parse the request/response for attributes and set them on the invocation for the Converse and ConverseStream methods in boto3.

Remaining gaps:

  • Similar logic needs to be added for the InvokeModel & InvokeModelWithResponseStream methods
  • We need to monkey patch aioboto3 to get the async equivalents.

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

How has this been tested?

Unit tests..

Checklist

  • Followed the style guidelines of this project
  • Changelog updated if the change requires an entry
  • Unit tests added
  • Documentation updated

Copilot AI lite review requested due to automatic review settings August 27, 2026 15:42
@DylanRussell
DylanRussell requested a review from a team as a code owner August 27, 2026 15:42
@DylanRussell
DylanRussell changed the base branch from main to DylanRussell/add_bedrock_instrumentation August 27, 2026 15:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces and wires up a new opentelemetry-instrumentation-genai-bedrock package that instruments AWS Bedrock (via boto3/botocore) to emit GenAI inference (“chat”) spans for the Converse and ConverseStream APIs, including basic request/response extraction and streaming support.

Changes:

  • Added Bedrock runtime instrumentation by patching botocore.client.BaseClient._make_api_call for Converse/ConverseStream and mapping request/response fields onto an InferenceInvocation.
  • Added a streaming wrapper for converse_stream to keep the invocation open until the stream completes (or fails/closes).
  • Added package wiring (tox envs, workspace deps, docs requirements) plus unit tests, conformance scenarios, and VCR cassettes/examples.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
uv.lock Adds the Bedrock package to the workspace lock and pulls in boto3/botocore deps.
tox.ini Wires Bedrock test/conformance/lint envs; adjusts shellcheck env.
README.md Adds Bedrock instrumentation entry to the top-level table.
pyproject.toml Adds Bedrock package to workspace dependencies and pyright include/exclude.
docs-requirements.txt Adds boto3 as a docs build dependency.
instrumentation/opentelemetry-instrumentation-genai-bedrock/README.rst Documents supported Bedrock operations and configuration.
instrumentation/opentelemetry-instrumentation-genai-bedrock/pyproject.toml Defines the new package, deps, extras, and instrumentor entrypoint.
instrumentation/opentelemetry-instrumentation-genai-bedrock/LICENSE Adds Apache 2.0 license file for the new package.
instrumentation/opentelemetry-instrumentation-genai-bedrock/CHANGELOG.md Adds a towncrier-managed changelog stub.
instrumentation/opentelemetry-instrumentation-genai-bedrock/.changelog/.gitignore Keeps the changelog dir tracked.
instrumentation/opentelemetry-instrumentation-genai-bedrock/.changelog/359.added Towncrier fragment for initial package scaffold.
instrumentation/opentelemetry-instrumentation-genai-bedrock/.changelog/488.added Towncrier fragment for Converse/ConverseStream spans.
instrumentation/opentelemetry-instrumentation-genai-bedrock/src/opentelemetry/instrumentation/genai/bedrock/init.py Implements BedrockInstrumentor and completion-hook wiring.
instrumentation/opentelemetry-instrumentation-genai-bedrock/src/opentelemetry/instrumentation/genai/bedrock/version.py Sets package version.
instrumentation/opentelemetry-instrumentation-genai-bedrock/src/opentelemetry/instrumentation/genai/bedrock/package.py Declares _instruments dependency metadata.
instrumentation/opentelemetry-instrumentation-genai-bedrock/src/opentelemetry/instrumentation/genai/bedrock/patch.py Patches botocore API calls and creates/stops invocations.
instrumentation/opentelemetry-instrumentation-genai-bedrock/src/opentelemetry/instrumentation/genai/bedrock/extractors.py Extracts Bedrock request/response fields into invocation attributes.
instrumentation/opentelemetry-instrumentation-genai-bedrock/src/opentelemetry/instrumentation/genai/bedrock/stream.py Implements streaming wrapper to finalize spans on stream end/error/close.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/init.py Marks test package.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/conftest.py Adds shared fixtures + VCR config + Bedrock client/instrument fixtures.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/test_instrumentor.py Tests instrument/uninstrument lifecycle and dependency string.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/test_converse.py Tests non-streaming Converse spans and request/response extraction.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/test_converse_stream.py Tests ConverseStream spans, stream lifecycle, and error paths.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/test_completion_hook.py Tests completion hook invocation and default hook loading behavior.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/test_conformance.py Runs Bedrock conformance scenarios via weaver live-check.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/conformance/init.py Marks conformance scenario package.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/conformance/inference.py Conformance scenario for chat inference (Converse).
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/conformance/inference_streaming.py Conformance scenario for streaming chat (ConverseStream).
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/conformance/tool_calling.py Conformance scenario for tool calling in chat.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/requirements.oldest.txt Oldest factor requirements file (comment-only).
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/requirements.latest.txt Latest factor requirements incl. boto3 and editable workspace installs.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_with_content.yaml VCR cassette for Converse with content capture.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_no_content.yaml VCR cassette for Converse without content capture.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_with_invalid_model.yaml VCR cassette for Converse invalid-model error.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_with_content_different_events.yaml VCR cassette for Converse with different event patterns.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_no_content_different_events.yaml VCR cassette for Converse (no-content) with different event patterns.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_tool_call_with_content.yaml VCR cassette for tool call flow (with content).
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_tool_call_no_content.yaml VCR cassette for tool call flow (no content).
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_with_content.yaml VCR cassette for ConverseStream with content.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_no_content.yaml VCR cassette for ConverseStream without content.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_with_invalid_model.yaml VCR cassette for ConverseStream invalid-model error.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_with_content_different_events.yaml VCR cassette for streaming with different event patterns.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_no_content_different_events.yaml VCR cassette for streaming (no-content) with different event patterns.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_handles_event_stream_error.yaml VCR cassette for streaming error handling test.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_close_before_consumption.yaml VCR cassette for closing stream before iteration.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_caller_side_error.yaml VCR cassette for caller-side exception inside stream context manager.
instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/cassettes/test_converse_stream_tool_call_parsing_errors.yaml Adds a cassette intended for tool-call parsing error coverage.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/manual/README.rst Manual instrumentation example documentation.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/manual/main.py Manual instrumentation example code.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/manual/custom_hook.py Example showing a custom completion hook.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/manual/requirements.txt Requirements for the manual example.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/manual/.env Content-capture env for manual example.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/zero-code/README.rst Zero-code example documentation.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/zero-code/main.py Zero-code example application.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/zero-code/requirements.txt Requirements for the zero-code example.
instrumentation/opentelemetry-instrumentation-genai-bedrock/examples/zero-code/.env Content-capture env for zero-code example.
Suppressed comments (1)

tox.ini:374

  • The shellcheck command uses find ... -print | xargs shellcheck ..., which can break on paths with whitespace and can invoke shellcheck with no arguments depending on xargs behavior. Using find ... -exec ... + avoids these edge cases and is portable across GNU/BSD userlands.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tox.ini Outdated
@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Aug 27, 2026

Copy link
Copy Markdown

Pull request dashboard status

Merged · refreshed 2026-09-01 22:08 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

DylanRussell added a commit that referenced this pull request Aug 27, 2026
- Only extract tool_definitions when capture_content is True
- Remove unnecessary try/except TypeError in BedrockConverseStreamWrapper
- Restrict bedrock latest envlist to py3{10,14} matching repo convention
- Remove unused cassette files and add tests for tool calling with NO_CONTENT
- Update opentelemetry-util-genai floor to >= 1.2b0.dev in pyproject.toml
response=tool_result.get("content"),
)

return None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reasoningContent and the other non-text blocks are dropped, should we follow up on the other parts in a separate PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it in here.. WDYT of the various supported block types here (https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ReasoningContentBlock.html) -- i left out audio / video blocks, but added parsing for document / image types.. not sure what the best approach is

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can add them as GenericPart and create semconv issue to add others.

BTW, would you mind updating Blob (deprecated now) -> BlobPart and such?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened open-telemetry/semantic-conventions-genai#488 and used GenericPart for them. Switched to XPart types too..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought I wonder if it's worth adding these as GenericParts with just the type set, is that useful at all ? I don't think we will ever add raw audio / video to the telemetry, it's way too big.

Even a single image can be too big.. Google's telemetry API has a cap at 64KB for an attribute value for example.. Maybe we should be checking the size of BlobParts (like mages) and leaving them out if they exceed 50KB or something like that..

@linux-foundation-easycla

linux-foundation-easycla Bot commented Aug 31, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

Base automatically changed from DylanRussell/add_bedrock_instrumentation to main August 31, 2026 18:25
@DylanRussell

Copy link
Copy Markdown
Contributor Author

I recorded all the VCR tests against the real API and got passing results.. updated all the .yaml files with the real req/resp exchange..

DylanRussell added a commit that referenced this pull request Aug 31, 2026
- Only extract tool_definitions when capture_content is True
- Remove unnecessary try/except TypeError in BedrockConverseStreamWrapper
- Restrict bedrock latest envlist to py3{10,14} matching repo convention
- Remove unused cassette files and add tests for tool calling with NO_CONTENT
- Update opentelemetry-util-genai floor to >= 1.2b0.dev in pyproject.toml
@DylanRussell
DylanRussell force-pushed the DylanRussell/add_bedrock_instrumentation_2 branch from 12324ee to bb9bb86 Compare August 31, 2026 20:23
@DylanRussell
DylanRussell force-pushed the DylanRussell/add_bedrock_instrumentation_2 branch from d2f38ba to 0790ca7 Compare September 1, 2026 13:57
@lmolkova
lmolkova added this pull request to the merge queue Sep 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Sep 1, 2026
@lmolkova
lmolkova added this pull request to the merge queue Sep 1, 2026
Merged via the queue into main with commit d6d3aca Sep 1, 2026
71 checks passed
@lmolkova
lmolkova deleted the DylanRussell/add_bedrock_instrumentation_2 branch September 1, 2026 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants