Description
When a workflow executor emits an AgentResponseUpdate, wrapping the workflow with WorkflowAgent and consuming it through run(stream=True) silently drops several response metadata fields.
WorkflowAgent._convert_workflow_event_to_agent_response_updates() creates a new AgentResponseUpdate instance, but currently only copies the content, role, author, IDs, timestamp, and raw representation. The following fields are not forwarded:
finish_reason
continuation_token
additional_properties
The method documentation says that output and intermediate updates are forwarded "as-is", so this appears to be an unintended loss of streaming response semantics.
This is distinct from #1331 / #3146, which addressed author_name, and from #4261, which concerns user-role messages being emitted as agent output.
Actual Result
The metadata fields are returned as None even though they were present on the executor's original AgentResponseUpdate.
Expected Result
WorkflowAgent should preserve these fields when forwarding an AgentResponseUpdate, just as it preserves the content, role, author, response ID, message ID, and timestamp.
Code Sample
Tested on main at commit edfe115ea06bca57ae5a123d0fac5b3fdda13603.
import asyncio
from agent_framework import (
AgentResponseUpdate,
Content,
Executor,
Message,
WorkflowAgent,
WorkflowBuilder,
WorkflowContext,
handler,
)
class MetadataExecutor(Executor):
@handler
async def handle(
self,
messages: list[Message],
ctx: WorkflowContext[list[Message], AgentResponseUpdate],
) -> None:
await ctx.yield_output(
AgentResponseUpdate(
contents=[Content.from_text(text="payload")],
role="assistant",
author_name="source-agent",
response_id="source-response",
message_id="source-message",
finish_reason="stop",
continuation_token="resume-token",
additional_properties={
"provider_marker": "preserve-me",
},
)
)
async def main() -> None:
source = MetadataExecutor(id="metadata-executor")
workflow = WorkflowBuilder(start_executor=source).build()
agent = WorkflowAgent(workflow=workflow, name="wrapped-agent")
updates = [update async for update in agent.run("input", stream=True)]
update = updates[0]
print(
{
"finish_reason": update.finish_reason,
"continuation_token": update.continuation_token,
"additional_properties": update.additional_properties,
}
)
asyncio.run(main())
Run with:
uv run --no-sync python -
Error Messages / Stack Traces
No exception is raised. The metadata is silently dropped during the WorkflowAgent streaming conversion.
Package Versions
agent-framework-core: 1.16.0 (local source from main at commit edfe115ea06bca57ae5a123d0fac5b3fdda13603)
Python Version
Additional Context
- OS: Windows
- The current implementation loses the metadata before final response construction, so downstream consumers cannot recover it from
AgentResponse.from_updates().
- Long-running operations can lose their
continuation_token and become impossible to resume.
- Consumers cannot observe the provider/runtime finish reason.
- Provider-specific metadata in
additional_properties is lost.
- Streaming behavior differs between a direct agent and the same agent executed through a workflow wrapper.
- The existing test suite does not currently cover metadata preservation for this conversion path.
A focused implementation would preserve the missing fields when reconstructing the AgentResponseUpdate in _convert_workflow_event_to_agent_response_updates() and add regression coverage in python/packages/core/tests/workflow/test_workflow_agent.py.
I would like to work on this issue if the proposed behavior aligns with the project's expectations. I already have a deterministic reproduction and can prepare a focused fix with regression coverage. Please let me know whether this issue can be assigned to me.
Description
When a workflow executor emits an
AgentResponseUpdate, wrapping the workflow withWorkflowAgentand consuming it throughrun(stream=True)silently drops several response metadata fields.WorkflowAgent._convert_workflow_event_to_agent_response_updates()creates a newAgentResponseUpdateinstance, but currently only copies the content, role, author, IDs, timestamp, and raw representation. The following fields are not forwarded:finish_reasoncontinuation_tokenadditional_propertiesThe method documentation says that output and intermediate updates are forwarded "as-is", so this appears to be an unintended loss of streaming response semantics.
This is distinct from #1331 / #3146, which addressed
author_name, and from #4261, which concerns user-role messages being emitted as agent output.Actual Result
The metadata fields are returned as
Noneeven though they were present on the executor's originalAgentResponseUpdate.Expected Result
WorkflowAgentshould preserve these fields when forwarding anAgentResponseUpdate, just as it preserves the content, role, author, response ID, message ID, and timestamp.Code Sample
Tested on
mainat commitedfe115ea06bca57ae5a123d0fac5b3fdda13603.Run with:
Error Messages / Stack Traces
No exception is raised. The metadata is silently dropped during the
WorkflowAgentstreaming conversion.Package Versions
agent-framework-core: 1.16.0 (local source frommainat commitedfe115ea06bca57ae5a123d0fac5b3fdda13603)Python Version
Additional Context
AgentResponse.from_updates().continuation_tokenand become impossible to resume.additional_propertiesis lost.A focused implementation would preserve the missing fields when reconstructing the
AgentResponseUpdatein_convert_workflow_event_to_agent_response_updates()and add regression coverage inpython/packages/core/tests/workflow/test_workflow_agent.py.I would like to work on this issue if the proposed behavior aligns with the project's expectations. I already have a deterministic reproduction and can prepare a focused fix with regression coverage. Please let me know whether this issue can be assigned to me.