feat: add on_tool_progress hook for mid-execution tool progress updates#3406
Open
0xSudoSSH wants to merge 1 commit into
Open
feat: add on_tool_progress hook for mid-execution tool progress updates#34060xSudoSSH wants to merge 1 commit into
0xSudoSSH wants to merge 1 commit into
Conversation
Contributor
Author
|
This is an alternative approach to PR3397, which added a |
d12edb4 to
3c9a736
Compare
3c9a736 to
deb8593
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
on_tool_progresstoRunHooksandAgentHooks— a lifecycle hook that fires when a tool emits intermediate progress updates viaawait ctx.send_progress(data).This solves the core problem from #1333 (streaming events from long-running tools) by extending the existing
on_tool_start/on_tool_endlifecycle pattern, giving tools an official way to report mid-execution progress without requiring external shared state or event buses.Motivation (re: #1333)
Existing lifecycle hooks (
on_tool_start/on_tool_end) fire at the boundaries of tool execution, but they don't cover cases where a tool needs to emit multiple intermediate updates from inside the tool body. Without framework support, developers resort to external shared state or event buses, which add complexity and couple tool logic to infrastructure concerns. Providing an official lifecycle hook for mid-execution progress makes responsive UIs and long-running workflows (data processing, web scraping, multi-step API calls) much easier to build.How it works
Tool authors call
await ctx.send_progress(data)at any point during execution. The framework fireson_tool_progress(context, agent, tool, data)on both run-level and agent-level hooks concurrently (viaasyncio.gather), following the same dispatch pattern ason_tool_start/on_tool_end.Per-agent hooks
Design
on_tool_progressadded to bothRunHooksBaseandAgentHooksBaseas async no-op methods.ToolContext.send_progress(data)is an async method that delegates to a_progress_fncallback. It is a no-op by default._progress_fnin_run_single_toolvia a closure that captureshooks,agent_hooks,agent, andtool— all already in scope. This closure callsasyncio.gatheron both hook levels, matchingon_tool_start/on_tool_endexactly.ToolContextis created per tool call, so there is no stale closure risk.Runner.run_streamed) and non-streaming (Runner.run) modes.StreamEventunion is unchanged.RunContextWrapper,RunState, orrun.py.Test plan
send_progressfires callback when set, no-op when unset, multiple events arrive in orderRunHooks.on_tool_progressfires duringRunner.run()AgentHooks.on_tool_progressfires duringRunner.run()RunHooksandAgentHooksfire concurrentlyRunner.run_streamed()Issue number
Closes #1333
Checks
make lintandmake format