Python: Add AgentExecutorResponse.with_text() to preserve conversation history through custom executors#5255
Conversation
|
@microsoft-github-policy-service agree |
moonbox3
left a comment
There was a problem hiding this comment.
Thanks for the PR. The helper itself looks correct and I'm supportive of merging it. One thing I'd like to see added before we do that, though:
The underlying issue in #5246 looks fundamentally like a discoverability problem. The typed-dispatch routing between from_str / from_response / from_message is working as designed (see _agent_executor.py:156-188), but a user writing a custom executor with output=str has no way to know they're silently dropping full_conversation. Adding with_text() gives them an escape hatch, but only if they already know it exists - the original reporter's code would have looked identical without this PR, and they'd hit the same wall.
Could we also:
- Add a docstring note on
AgentExecutor.from_str(and on the@executordecorator / tutorial docs for custom executors between agents) that explicitly calls out: "if the upstream executor received anAgentExecutorResponse, emitting a plain str will reset the conversation. UseAgentExecutorResponse.with_text(...)to preserve it." - Consider a logger.warning in
from_strwhen the cache is empty and the incoming text looks like it came from an agent turn - or at minimum when the sending executor's declared input type isAgentExecutorResponse. (Optional; docs alone may be enough.)
Without the docs change the helper is hard to find, and users will keep filing this same bug.
Python Test Coverage Report •
Python Unit Test Overview
|
|||||||||||||||||||||||||||||||||||
…y through custom executors Fixes microsoft#5246 When a custom @executor transforms agent output and sends a plain str, the downstream AgentExecutor.from_str handler loses the full conversation context. This adds a with_text() helper that creates a new AgentExecutorResponse with replaced text while preserving the prior conversation chain, so AgentExecutor.from_response is invoked instead. - Add with_text(text) method to AgentExecutorResponse dataclass - Add 3 regression tests in test_full_conversation.py
4b1de95 to
df06ee7
Compare
|
Thanks for the review! Updated with:
|
Motivation and Context
When a custom
@executorsits between twoAgentExecutornodes in a workflow chain, it receives anAgentExecutorResponse(which carries the full conversation) but typically sends a plainstrdownstream. This causes the nextAgentExecutor.from_strhandler to start fresh with only that string, losing all prior conversation turns.The issue reporter demonstrated this with a simple upper-case executor placed between four agents — the final agent could only see its own immediate input instead of the full history from all previous agents.
Fixes #5246
Description
The root cause is that custom executors have no convenient way to transform the agent's output text while keeping the
AgentExecutorResponsewrapper intact. Sending a plainstrroutes tofrom_str, which discards the conversation chain.This adds a
with_text(text)method toAgentExecutorResponsethat creates a new response with replaced text, preserving the prior conversation infull_conversation. This way the response type staysAgentExecutorResponseand routes tofrom_responseinstead, which properly feeds the full history into the next agent's cache.Three regression tests are included:
Contribution Checklist