feat(gateway): publish native remote turn activity - #80217
Open
cmyk wants to merge 2 commits into
Open
Conversation
|
Operator +1 from a Windows Path 3 install ( This is the missing piece for Activity/working status without dumping tools into the channel. I can smoke-test once it is reviewable. |
Author
Don't hold your breath. Not going to chase this upstream. |
9 tasks
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.
What does this PR do?
Publishes structured remote turn activity from the Hermes Gateway to Buzz so users can distinguish an actively working agent from a stalled or completed turn.
The Gateway emits a neutral
TurnLifecycleEventcontract for turn start, session resolution, progress, tool execution, completion, failure, and interruption. Buzz translates those events into allowlisted, owner-encrypted NIP-44 v2 observer frames without coupling Gateway core logic to Buzz wire semantics.Terminal outcomes are latched at the agent-execution boundary, before later delivery, TTS, cache-refresh, or queued-follow-up work can rewrite the result. Buzz retains terminal frames until positive relay acknowledgement, performs one bounded delayed same-generation retry after rejection or send failure, and preserves exhausted terminals for replay after the next authenticated WebSocket generation.
The transport remains fail-open for Gateway execution and fail-safe for the Buzz UI: Activity requires WebSocket transport, polling fallback does not publish a false started state, stale-generation frames are not sent, retry cannot hot-loop, and cancellation during reset cannot leave
disconnect()hanging while the WebSocket loop reconnects.Activity payloads are privacy allowlisted. They exclude prompts, tool arguments, tool outputs, credentials, and model response content. Tool identifiers are bounded and opaque, and internal retry metadata is removed before encryption.
Related Issue
Fixes #76678
Related Buzz consumer/relay tracking: block/buzz#4964
Type of Change
Changes Made
gateway/turn_observer.pyGatewayTurnObserverand closed lifecycle-event contract.gateway/run.pygateway/platforms/base.pyplugins/platforms/buzz/adapter.pyplugins/platforms/buzz/nostr_auth.pytests/gateway/test_turn_observer.pytests/gateway/test_buzz_activity_bridge.pytests/gateway/test_buzz_websocket.pywebsite/docs/integrations/buzz.mdwebsite/docs/user-guide/messaging/buzz.mdactivity_owner_pubkey, WebSocket requirements, encryption, retry/reconnect behavior, and terminal deduplication expectations.How to Test
Configure Buzz with authenticated WebSocket transport and an
activity_owner_pubkey, start the Gateway, and send a turn that invokes a tool. Confirm Buzz receives ordered started, progress/tool, and terminal Activity frames without prompt, argument, output, or credential content.Reject a terminal event with
['OK', event_id, false, 'rate-limited: slow down'], and separately fail the first terminal WebSocket send while keeping the socket live. Confirm one delayed retry occurs, no hot loop occurs, and the terminal remains retained after retry exhaustion.Disconnect before terminal acknowledgement and reconnect. Confirm the retained terminal is replayed on the new authenticated generation, while stale-generation frames are never sent. Cancel/disconnect while transport reset is awaiting the sender and confirm teardown completes without reconnecting.
Run the focused repository-prescribed suite:
Expected result:
59 passed, 0 failed.Run the full Gateway suite:
Observed result:
4,879 passed, 2 failed. Both failures are pre-existing optional WeCom XML tests whereET is None; the same4 passed / 2 failedfile result was reproduced against a clean baseline checkout.Run static checks:
All passed.
Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passscripts/run_tests.shinstead of direct pytest. The focused suite passes 59/59; the full Gateway suite passes 4,879 tests with two baseline-confirmed optional WeCom XML failures.Documentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/Aextrasetting documented in both Buzz documentation surfaces, not a new top-level CLI configuration key.CONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AScreenshots / Logs
No Dashboard or ordinary message UI is changed by this contribution. The production-shaped WebSocket test exercises authentication, generation assignment, subscription, Activity replay, disconnect/reset, reconnect, replay on the new socket, and cancellation teardown through the real
_websocket_loop()ordering.Verification summary:
The terminal retry, reconnect, and cancellation remediation received an independent
APPROVEreview after targeted dynamic verification of the production code paths.