Skip to content

feat: auto-flush cached outbound messages + user-visible stuck/anomaly notices - #7

Open
xwh5 wants to merge 3 commits into
pan17:mainfrom
xwh5:feat/auto-flush-pending
Open

feat: auto-flush cached outbound messages + user-visible stuck/anomaly notices#7
xwh5 wants to merge 3 commits into
pan17:mainfrom
xwh5:feat/auto-flush-pending

Conversation

@xwh5

@xwh5 xwh5 commented Aug 1, 2026

Copy link
Copy Markdown

Summary

Two user-experience fixes for the WeChat bridge:

  1. Auto /next (auto-continue) — WeChat caps consecutive messages per turn at 10. Previously the user had to manually send /next to flush the cached remainder. Now the bridge automatically flushes cached outbound segments wechat.autoFlushMs (default 60s) after the queue settles, and keeps re-arming while messages remain cached. Set wechat.autoFlushMs: 0 to disable and keep the manual /next behavior.

  2. User-visible stuck/anomaly notices — Previously a stuck agent turn (5 min without events) was silently force-finalized and channel failures only showed in logs. Now:

    • Stuck turn: user gets ⚠️ Agent 已 N 分钟无响应(可能卡住)… before the turn is ended
    • SSE event pipeline outage (reconnecting > 60s): warning ⚠️ Agent 事件连接异常…; recovery sends ✅ Agent 事件连接已恢复。
    • WeChat channel: session expiry (1h pause), repeated poll failures (backoff), and recovery are pushed to the chat

Changes

  • src/config.ts: new wechat.autoFlushMs option (default 60000, 0 disables)
  • src/bridge.ts: auto-flush timer (scheduleAutoFlush/runAutoFlush), wired at all five cache points; msgLimitNotice() text now matches auto-flush state; wires both onNotify callbacks (session + monitor) through sendReply (best-effort)
  • src/server/session.ts: onNotify opt; stuck-timeout notice before force-finalize; handlePipelineStatus outage (60s threshold) / recovery notices
  • src/weixin/monitor.ts: onNotify opt; session-expired / backoff / recovery notices
  • Tests: src/__tests__/test-auto-flush.mjs (7 tests), src/__tests__/test-stuck-notices.mjs (4 tests); full suite 588 passing
  • README.md: documented auto-continue and the new notices

Commits

  • fc0e287 feat: auto-flush cached outbound messages (auto /next)
  • 361aa0f feat: notify user about stuck turns and channel anomalies

xwh5 added 3 commits August 1, 2026 12:13
When WeChat's 10-consecutive-message send limit is hit, remaining
outbound segments are cached in pendingOutbound and previously only
delivered on the next user message or an explicit /next.

Add wechat.autoFlushMs (default 60s, 0 disables): on the first cache
hit the bridge arms a timer and flushes cached messages automatically
when it elapses — no user message required. If the limit still holds
after a flush (more than 10 segments cached), the timer re-arms for
another round until everything is delivered. The flush waits for any
in-flight outbound send on the same contextToken to settle first, so
messages never reorder with an agent reply.

The 10-msg-limit warning text now says messages will auto-resend when
the feature is enabled, instead of asking for a manual /next.
- SessionManager: onNotify callback; the 5-minute stuck-turn timeout
  now tells the user the agent was unresponsive before force-finalizing
- SessionManager: SSE event pipeline outages (reconnecting > 60s) send a
  warning, recovery sends an OK notice
- monitor: WeChat-channel session expiry, repeated poll failures
  (backoff) and recovery are pushed to the user instead of only logs
- bridge: wires both callbacks through sendReply (best-effort,
  contextToken falls back to the most recent user message)
- tests: test-stuck-notices.mjs (stuck timeout, outage threshold,
  recovery, no-op when onNotify omitted); 588 tests pass
OpenCode servers retry failed model calls internally and emit
session.status=retry; when the retry also fails the turn ends with
zero output and the user sees only the WeChat typing indicator before
silence (e.g. rate-limited or unpaid models).

- AccumulatedTurn.retried flag set when session.status=retry arrives
  mid-turn
- finalizeTurn: zero-output turn that was retried now sends
  "❌ Agent 请求失败…" instead of dropping the turn silently
- tests: 2 new cases (retry-failure notice, no false positives for
  plain zero-output turns); 590 tests pass
@pan17

pan17 commented Aug 3, 2026

Copy link
Copy Markdown
Owner

@xwh5 我在本地拉了 PR head build,然后在真实微信里端到端试了 auto-flush 场景。

结果:失败。 触发 10 条限制后等了 60 秒,微信端没收到缓存的那批消息。

我有个疑问:
关于你对微信的 10 条消息限制具体规则的了解是什么?经验值 60s 怎么来的?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants