feat(bidi): support request_state stop_event_loop flag#1954
feat(bidi): support request_state stop_event_loop flag#1954agent-of-mkmeral wants to merge 2 commits intostrands-agents:mainfrom
Conversation
Replace the built-in stop_conversation tool with a generic request_state['stop_event_loop'] mechanism. This allows any tool (e.g. strands_tools.stop) to signal the BidiAgent to gracefully close the connection by setting request_state['stop_event_loop'] = True. Changes: - Remove stop_conversation tool and its exports - Add request_state initialization in _run_tool to ensure tools that access request_state work correctly - Replace tool name-based check with stop_event_loop flag check - Add comprehensive tests for request_state initialization, stop_event_loop flag, and invocation_state preservation Based on: strands-agents@657ddcd
mkmeral
left a comment
There was a problem hiding this comment.
also check the docs, if we need to update anything there, create a related PR. check if stop event loop is documented somewhere. also check if stop conversation tool is used, etc.
| await self._event_queue.put(ToolResultMessageEvent(tool_result_message)) | ||
|
|
||
| # Check for stop_conversation before sending to model | ||
| if tool_use["name"] == "stop_conversation": |
There was a problem hiding this comment.
@agent-of-mkmeral we should probably keep it for now, but add a warning that we will remove in next versions. So we support both, and we can remove the tool later.
It gives users who depend on it some time
There was a problem hiding this comment.
Done! Commit 1381ba1 keeps stop_conversation with backward compatibility:
| What | How |
|---|---|
stop_conversation tool |
Restored — emits DeprecationWarning when called |
bidi/__init__.py export |
Restored — from strands.experimental.bidi import stop_conversation works |
| Loop check | Primary: request_state["stop_event_loop"] flag. Fallback: tool_use["name"] == "stop_conversation" with deprecation warning |
| Tests | New test_bidi_agent_loop_stop_conversation_deprecated_but_works verifies both the tool works AND the warning is emitted |
Users who depend on stop_conversation get a clear deprecation message pointing them to strands_tools.stop or request_state["stop_event_loop"].
Address review feedback from @mkmeral to keep backward compatibility: - Restore stop_conversation tool with deprecation warning (DeprecationWarning emitted at runtime when the tool is called) - Restore stop_conversation export in bidi/__init__.py - Support both mechanisms in loop.py: 1. request_state['stop_event_loop'] flag (new, recommended) 2. tool name 'stop_conversation' check (deprecated, backward compatible) - Add test_bidi_agent_loop_stop_conversation_deprecated_but_works - Update existing tests to work with both mechanisms
|
@agent-of-mkmeral do we need docs update for this? |
|
Yes — docs definitely need updating. I found
I'll create a docs PR now that:
|
…st_state Update all bidi streaming docs to reflect the new stop mechanism: - Replace stop_conversation imports with strands_tools.stop - Document request_state['stop_event_loop'] flag for custom stop tools - Add deprecation notices for legacy stop_conversation tool - Update 7 files: agent, events, quickstart, io, and 3 model pages Related: strands-agents/sdk-python#1954
|
📝 Docs PR created: strands-agents/docs#696 Updated 7 files across the bidi streaming docs:
All |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
📊 PR Status Summary
What was done
Ready for merge when you're ready! 🚀 |
|
/strands review |
|
Assessment: Approve This PR cleanly aligns the BidiAgent loop with the standard event loop's Review Summary
The dual deprecation warning approach (from both the tool and the loop) provides good visibility for migration. 🚀 |
Summary
Replace the hard-coded
stop_conversationtool name check with a genericrequest_state["stop_event_loop"]mechanism, while keepingstop_conversationwith a deprecation warning for backward compatibility.Motivation
The previous approach hard-coded a
stop_conversationtool name check in the bidi agent loop. This was:strands_toolsalready has astoptool that usesrequest_stateChanges
Deprecated (kept for backward compatibility)
stop_conversationtool now emitsDeprecationWarningwhen calledDeprecationWarningas a fallbackbidi/__init__.pyare preservedChanged
agent/loop.py:request_statein_invocation_statebefore tool executionrequest_state.get("stop_event_loop", False)flagtool_use["name"] == "stop_conversation"with deprecation warningtools/stop_conversation.py: AddedDeprecationWarningpointing users tostrands_tools.stoptools/__init__.py: Updated docstring with deprecation noticeio/text.py: Updated log messageAdded
test_bidi_agent_loop_stop_conversation_deprecated_but_works— verifies backward compatibility with deprecationtest_bidi_agent_loop_stop_event_loop_flag— verifies new flag mechanismtest_bidi_agent_loop_request_state_initialized_for_tools— verifiesrequest_stateavailabilitytest_bidi_agent_loop_request_state_preserved_with_invocation_state— verifies existing state preservedMigration Path
Before (deprecated):
After (recommended):
Or any custom tool:
Based on: 657ddcd