Skip to content

Fix QQBot reconnect lifecycle after transient websocket disconnects - #26878

Closed
yiantong35 wants to merge 1 commit into
NousResearch:mainfrom
yiantong35:fix/qqbot-reconnect-lifecycle
Closed

Fix QQBot reconnect lifecycle after transient websocket disconnects#26878
yiantong35 wants to merge 1 commit into
NousResearch:mainfrom
yiantong35:fix/qqbot-reconnect-lifecycle

Conversation

@yiantong35

Copy link
Copy Markdown

PR: Fix QQBot reconnect lifecycle after transient websocket disconnects

Branch prepared locally:

/tmp/hermes-agent-qqbot-pr
fix/qqbot-reconnect-lifecycle

Commit:

4ddf217a8 Fix QQBot reconnect lifecycle

Fork remote:

https://github.com/yiantong35/hermes-agent.git

Title

Fix QQBot reconnect lifecycle after transient websocket disconnects

Body

## Summary

Fixes QQBot reconnect lifecycle handling after transient WebSocket disconnects.

Previously the QQBot adapter called `_mark_disconnected()` for temporary gateway
socket closes/errors. That updates the adapter lifecycle state used by listener
and heartbeat logic, so a transient disconnect could leave the adapter in a
partially reconnected state without a healthy heartbeat task.

This change:

- adds `QQAdapter.is_connected` based on the active WebSocket state
- records transient disconnect status without stopping the adapter lifecycle
- restarts the heartbeat loop after successful reconnect if the previous task finished
- preserves WebSocket close code/reason for `CLOSED` / `ERROR` messages
- closes an unawaited coroutine when no event loop is available
- adds regression tests for reconnect lifecycle behavior

## Test

```bash
/home/tangyujie/.hermes/hermes-agent/venv/bin/python -m pytest tests/gateway/test_qqbot.py -q -n 0

Result:

74 passed in 3.24s

## Push Commands

Run from the prepared worktree after authenticating with GitHub:

```bash
cd /tmp/hermes-agent-qqbot-pr
git push yiantong35 fix/qqbot-reconnect-lifecycle

Then create the PR:

base repository: NousResearch/hermes-agent
base branch: main
head repository: yiantong35/hermes-agent
compare branch: fix/qqbot-reconnect-lifecycle

Direct compare URL after push:

https://github.com/NousResearch/hermes-agent/compare/main...yiantong35:hermes-agent:fix/qqbot-reconnect-lifecycle

Current Blocker

The code, branch, commit, and tests are ready. Push is blocked only by GitHub
authentication on this machine:

fatal: could not read Username for 'https://github.com': No such device or address

Do not paste a GitHub token into chat. Authenticate locally with GitHub CLI,
Git Credential Manager, or an SSH key, then rerun the push command above.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/qqbot QQ Bot adapter labels May 16, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #24357 (heartbeat lost after reconnect — same symptom), #19414 (superset 5-bug reconnect fix — overlapping scope), #17703 (reconnect stops after failed reconnect). This PR addresses the lifecycle state confusion that causes heartbeat loss.

@yiantong35
yiantong35 force-pushed the fix/qqbot-reconnect-lifecycle branch from 4ddf217 to 6ed64a3 Compare May 16, 2026 11:16
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the careful reconnect analysis. This automated hermes-sweeper review found that the lifecycle guarantee is already implemented on current main.

  • Commit 8199ec380 (fix(gateway): keep QQBot reconnect loop alive), included in v2026.5.16, introduced gateway/platforms/qqbot/adapter.py:178 _mark_transport_disconnected() specifically to preserve _running during transient transport drops.
  • Current gateway/platforms/qqbot/adapter.py:546 and :651 use that helper for both close and generic WebSocket-error paths, so _listen_loop continues into reconnect instead of being stopped by _mark_disconnected().
  • The existing heartbeat loop remains active while _running is true (gateway/platforms/qqbot/adapter.py:720-728) and skips closed sockets during the reconnect window.

The member's related-heartbeat discussion maps to the same symptom, but the requested lifecycle behavior is now present on main.

@teknium1 teknium1 closed this Jul 13, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/qqbot QQ Bot adapter sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants