| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
When extended thinking is enabled, assistant messages contain reasoningContent blocks alongside toolUse blocks. The filter was stripping toolUse/toolResult but leaving reasoningContent intact, producing a partial assistant message that Bedrock rejects with: ValidationException: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. reasoningContent blocks are semantically coupled to the tool calls that follow them — stripping the tool context without the accompanying reasoning leaves an incoherent and API-rejected message. The fix adds reasoningContent to the set of block types removed by the filter. Fixes aws#621 Signed-off-by: gingeekrishna <gingeekrishna@gmail.com>
Populate the OpenTelemetry semantic-convention ``enduser.id`` attribute on every span for the lifetime of a request, enabling user-level observability, auditability, and per-user analytics without any changes to agent code. Sources (in priority order): 1. ``X-Amzn-Bedrock-AgentCore-Runtime-User-Id`` request header — explicit override, useful when the caller already knows the user ID. 2. ``sub`` claim extracted from a Bearer JWT in the ``Authorization`` header — automatic extraction from Cognito or any OIDC-compatible token. The JWT payload is decoded for claim extraction only; no signature validation is performed (trust decisions belong to the inbound auth layer). The value is stored in a ``BedrockAgentCoreContext.enduser_id`` ContextVar so concurrent requests never see each other's user IDs. ``BaggageSpanProcessor.on_start`` reads the ContextVar and stamps ``enduser.id`` on every span, exactly as it already does for routing experiment attributes. All three entry paths are covered: - ``BedrockAgentCoreApp._build_request_context`` (HTTP/SSE) - ``BedrockCallContextBuilder.build`` (A2A) - ``AGUIApp._build_request_context`` (AG-UI) 22 new tests; 300 previously-passing tests still pass. Closes aws#592 Signed-off-by: gingeekrishna <gingeekrishna@gmail.com>
There was a problem hiding this comment.
Adds request-scoped end-user identity propagation into tracing by extracting a user ID from inbound headers/JWT and stamping it as the OpenTelemetry semantic attribute enduser.id on newly created spans.
Changes:
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file| File | Description |
|---|---|
| tests/bedrock_agentcore/runtime/test_utils.py | Adds unit tests for extract_sub_from_bearer() with malformed/edge-case coverage. |
| tests/bedrock_agentcore/runtime/test_tracing.py | Adds span-processor tests and end-to-end request tests validating header/JWT priority and context isolation. |
| tests/bedrock_agentcore/memory/integrations/strands/test_agentcore_memory_session_manager.py | Adds regression tests for filtering restored tool context with extended-thinking (reasoningContent). |
| src/bedrock_agentcore/runtime/utils.py | Adds JWT payload helper extract_sub_from_bearer() (no validation) for enduser.id extraction. |
| src/bedrock_agentcore/runtime/tracing.py | Stamps enduser.id on spans via BaggageSpanProcessor.on_start(). |
| src/bedrock_agentcore/runtime/models.py | Adds USER_ID_HEADER constant. |
| src/bedrock_agentcore/runtime/context.py | Adds enduser_id ContextVar + set_enduser_id / get_enduser_id. |
| src/bedrock_agentcore/runtime/app.py | Extracts and sets enduser_id during request context build. |
| src/bedrock_agentcore/runtime/a2a.py | Extracts and sets enduser_id for A2A requests. |
| src/bedrock_agentcore/runtime/ag_ui.py | Extracts and sets enduser_id for AG-UI requests/websockets. |
| src/bedrock_agentcore/memory/integrations/strands/session_manager.py | Extends _filter_restored_tool_context to also strip reasoningContent blocks. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Sorry, something went wrong.
| def on_start(self, span: object, parent_context: Optional[object] = None) -> None: | ||
| """Set routing experiment attributes on every new span. | ||
| """Set routing experiment and end-user identity attributes on every new span. | ||
|
|
||
| Primary source: ContextVars set by ``_build_request_context`` — covers | ||
| all spans created after request parsing (agent spans, tool spans, etc.). |
| enduser_id = _context.get_enduser_id() | ||
| if enduser_id is not None: | ||
| span.set_attribute("enduser.id", enduser_id) # type: ignore[union-attr] |
| """Strip historical toolUse/toolResult context from restored messages. | ||
|
|
||
| Extended-thinking (reasoningContent) blocks are coupled to the tool | ||
| calls that follow them. Bedrock rejects an assistant message whose | ||
| reasoningContent blocks have been separated from their companion |
| Back | FazBrowse Home | New Git URL |
Summary
Implements the request in #592 — automatically populate enduser.id on every OpenTelemetry span for the lifetime of a request.
How it works
Sources checked in priority order per request:
The value is stored in a BedrockAgentCoreContext.enduser_id ContextVar (same pattern as session_id / routing experiment), so concurrent requests never bleed user IDs into each other.
BaggageSpanProcessor.on_start reads the ContextVar and stamps enduser.id on every new span, alongside the existing routing-experiment attributes.
Files changed
Test plan
Fixes #592