Repository navigation
refactor(bus): type outbound runtime events - #4590
Merged
Merged
Conversation
chengyongru
force-pushed
the
codex/typed-outbound-events
branch
2 times, most recently
from
June 29, 2026 17:09
65b2ad1 to
b98d695
Compare
chengyongru
marked this pull request as ready for review
June 29, 2026 17:16
chengyongru
commented
Jun 29, 2026
chengyongru
left a comment
Collaborator
Author
There was a problem hiding this comment.
Automated PR review by nanobot. This is not a human maintainer review or approval.
I found one backward-compatibility side effect around outbound event dispatch.
chengyongru
force-pushed
the
codex/typed-outbound-events
branch
from
June 30, 2026 11:44
b98d695 to
4eca1a6
Compare
chengyongru
force-pushed
the
codex/typed-outbound-events
branch
from
July 1, 2026 08:36
4eca1a6 to
55870de
Compare
Re-bin
approved these changes
Jul 1, 2026
Re-bin
left a comment
Collaborator
There was a problem hiding this comment.
LGTM. This is a worthwhile cleanup of the outbound runtime protocol: runtime/UI semantics move onto typed OutboundMessage.event payloads while channel routing metadata stays metadata.
I paid special attention to yongru’s compatibility comments. I pushed two focused follow-ups:
- legacy channel hook signatures still receive the old metadata shape when they do not accept the new keyword arguments
- legacy in-process producers that still publish
_progress,_stream_delta,_stream_end,_turn_end,_goal_status,_goal_state_sync,_session_updated,_runtime_model_updated,_retry_wait, or_streamedmetadata are bridged back into typed events
Validated locally:
- python -m pytest tests/bus/test_outbound_events.py tests/channels/test_channel_plugins.py tests/channels/test_channel_manager_delta_coalescing.py tests/channels/test_channel_manager_reasoning.py -q
- python -m pytest tests/bus/test_outbound_events.py tests/channels/test_channel_plugins.py tests/channels/test_channel_manager_delta_coalescing.py tests/channels/test_channel_manager_reasoning.py tests/channels/test_websocket_channel.py tests/channels/test_websocket_http_routes.py tests/channels/test_websocket_integration.py tests/agent/test_loop_progress.py tests/agent/test_loop_runner_integration.py tests/agent/test_runner_reasoning.py -q
- python -m ruff check nanobot/bus/outbound_events.py nanobot/channels/manager.py tests/bus/test_outbound_events.py tests/channels/test_channel_plugins.py tests/channels/test_channel_manager_delta_coalescing.py
GitHub Actions is green across the full matrix.
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
Introduces a typed outbound event layer for runtime/UI messages carried by
OutboundMessage.event.nanobot.bus.outbound_eventswith dataclass event types for progress, retry wait, streaming, turn end, goal/session status, and runtime model updates.ChannelManager, WebSocketsend(), and CLI interactive consumption to branch on typed events instead of reserved_...metadata flags.OutboundMessage.metadatafor routing/context such as message IDs, thread IDs, and rich UI blobs.Compatibility notes
OutboundMessageinstances should useevent=...for runtime/UI semantics. Legacy metadata flags such as_progress,_stream_delta,_stream_end,_turn_end, and_goal_statusare ordinary metadata now; they are not parsed back into runtime events.send_delta()must accept keyword-onlystream_id,stream_end, andresumingarguments.send_reasoning_delta()orsend_reasoning_end()must accept keyword-onlystream_id.Why
The previous runtime/UI protocol was spread across ad hoc metadata flags, which made the bus boundary hard to reason about and forced user-facing entry points to know internal flag combinations. This PR creates a single typed outbound event boundary while preserving the existing channel wire payloads.
Validation
PYTHONPATH=. uv run --extra dev ruff check nanobot/bus/outbound_events.py nanobot/bus/events.py nanobot/bus/progress.py nanobot/agent/loop.py nanobot/session/webui_turns.py nanobot/session/turn_continuation.py nanobot/channels/manager.py nanobot/channels/websocket.py nanobot/cli/commands.py tests/bus/test_outbound_events.py tests/channels/test_channel_manager_reasoning.py tests/session/test_turn_continuation.pyPYTHONPATH=. uv run --extra dev ruff check nanobot/channels/weixin.py nanobot/bus/outbound_events.py nanobot/channels/manager.pyPYTHONPATH=. uv run --extra dev pytest tests/bus/test_outbound_events.py tests/channels/test_channel_manager_reasoning.py tests/cli/test_interactive_retry_wait.py tests/agent/test_loop_progress.py::TestToolEventProgress::test_streaming_channel_streams_provider_deltas_for_codex_style_provider tests/agent/test_loop_progress.py::TestToolEventProgress::test_websocket_dispatch_publishes_final_turn_end_marker tests/agent/test_loop_save_turn.py::test_internal_continuation_preserves_streaming_route_metadata tests/channels/test_websocket_channel.py::test_send_turn_end_emits_turn_end_event tests/channels/test_channel_manager_delta_coalescing.py tests/session/test_turn_continuation.py::test_maybe_continue_turn_queues_internal_messagePYTHONPATH=. uv run --extra dev pytest tests/bus/test_outbound_events.py tests/channels/test_channel_manager_delta_coalescing.py -qPYTHONPATH=. uv run --extra dev pytest tests/channels/test_weixin_channel.py::test_buffer_flushed_on_stream_end tests/channels/test_weixin_channel.py::test_stream_end_flushes_buffered_answer tests/channels/test_weixin_channel.py::test_stream_end_send_failure_keeps_buffer_for_retry -q/webui/bootstrapreturned HTTP 200.goal_status,stream_end,message, andturn_end.webuijob.