Skip to content

Python: [Bug]: usage_details not available in ContextProvider / HistoryProvider #6842

Description

@auroranockert

Description

I would like to be able to look at the usage_details in the ContextProvider, but for some reason a fake AgentResponse is created right before calling the ContextProvider with limited information only to then right afterwards create the real AgentResponse with the full info.

await self._finalize_response(
response=response,
agent_name=context["agent_name"],
session=context["session"],
session_context=context["session_context"],
suppress_response_id=context["suppress_response_id"],
)
return AgentResponse(
messages=response.messages,
response_id=None if context["suppress_response_id"] else response.response_id,
created_at=response.created_at,
usage_details=response.usage_details,
value=response.value,
response_format=context["chat_options"].get("response_format"),
continuation_token=response.continuation_token,
raw_representation=response,
additional_properties=response.additional_properties,
)
here the "real" AgentResponse is created, but inside self._finalize_response ) another AgentResponse is created right before.
session_context._response = AgentResponse( # type: ignore[assignment]
messages=response.messages,
response_id=None if suppress_response_id else response.response_id,
)
# Run after_run providers (reverse order)
await self._run_after_providers(session=session, context=session_context)

If you just swap this around and make _parse_non_streaming_response look something like the following then it does what I assume is the correct behaviour?

    async def _parse_non_streaming_response(
        self,
        context: _RunContext,
        response: ChatResponse[Any],
    ) -> AgentResponse[Any]:
        """Finalize a non-streaming chat response into an AgentResponse."""
        if not response:
            raise AgentInvalidResponseException("Chat client did not return a response.")

        session = context["session"]
        session_context = context["session_context"]

        # Ensure that the author name is set for each message in the response.
        for message in response.messages:
            if message.author_name is None:
                message.author_name = context["agent_name"]

        # Propagate conversation_id back to session (e.g. thread ID from Assistants API).
        # For Responses-style APIs this can rotate every turn (response_id-based continuation),
        # so refresh when a newer value is returned.
        if (
            session
            and response.conversation_id
            and not is_local_history_conversation_id(response.conversation_id)
            and session.service_session_id != response.conversation_id
        ):
            session.service_session_id = response.conversation_id

        agent_response = AgentResponse(
            messages=response.messages,
            response_id=None if context["suppress_response_id"] else response.response_id,
            created_at=response.created_at,
            usage_details=response.usage_details,
            value=response.value,
            response_format=context["chat_options"].get("response_format"),
            continuation_token=response.continuation_token,
            raw_representation=response,
            additional_properties=response.additional_properties,
        )

        session_context._response = agent_response  # type: ignore[assignment]

        await self._run_after_providers(session=session, context=session_context)

        return agent_response

Code Sample

Error Messages / Stack Traces

Package Versions

agent-framework-core 1.19.0, but it is broken on main too

Python Version

Python 3.14.3

Additional Context

No response

Metadata

Metadata

Labels

pythonUsage: [Issues, PRs], Target: Python

Type

Fields

No fields configured for Bug.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions