Repository navigation
fix(android): stop the idle watchdog interrupting healthy turns - #675
BrokeSkill wants to merge 2 commits into
Conversation
|
🤖 Hermes-Relay automated PR intake Thanks for contributing the Android watchdog change! The PR targets The remaining evidence is Android lint (or a rationale for skipping it) and the relevant Gateway fixture/current-upstream conformance checks for the turn-liveness change. Please add exact commands/results when available, or explain why a lane is not applicable. The body already explicitly identifies the checks that were not run; intake has not independently verified the reported results. A maintainer will review the verification gaps, relationship to #668, and implementation. |
|
Sorry for the interruptions and the slow turnaround, @BrokeSkill. I kept both of your commits intact in #694 and added recovery for missed events. Closing this one in favor of the combined fix. Thanks for digging into this! |
Extend the preserved PR Codename-11#675 commits with read-only quiet probes, exact unsolicited settlement, passive reconnect and shutdown, native ask replay, and missing-final history reconciliation. Cover owner and observer paths through real Gateway transport and rendered fixture tests. Update current-upstream conformance for extracted helpers and additive requests. Adapt cancellation-only diagnostics from PR Codename-11#668. Supersede PR Codename-11#662's eventual interrupt lease; quiet tools use server-owned liveness instead. Co-authored-by: ophirhan <ophirhan@users.noreply.github.com>
Summary
The Android client's idle-progress watchdog armed
session.interruptafter 180sof client-visible silence and then failed the turn with "Gateway turn timed
out". Silence should not equal death: a slow provider prefill on a large prompt, a long
tool call, or a quiet background run all look like that while the turn is
healthy. The interrupt carries no reason, so the Gateway logs it as "explicit
stop requested" and the transcript records "Operation interrupted" even though
the user never pressed Stop. Overnight and background runs were my usual
victims in testing, and no agent ever caught it as theres no record.
This removes the client-side kill. The watchdog now only logs the quiet and
keeps waiting; the server owns turn liveness, and the existing
settleFromAuthoritativeSessionStatepath settles a turn the Gateway reports asended. A real Stop still interrupts-
Related: #668 covers the same behavior with a narrower fix (it keeps the local
stream failure and the per-kind leases). This change goes further and drops the
leases that only decided when to kill.
Changes
session.interruptand no longer fails thestream. It is a re-arm loop that logs the quiet interval and waits.
watchdogTimeoutFor, theASK_*constants, the compacting lease) and the
compactingTimeoutMstest seam. Withno kill, they only moved the deadline.
retargetedThisTurnflag; arejoin after a route change uses the same watchdog as any other rejoin.
cancel()is unchanged: a real Stop still interrupts the Gateway turn.Verification
./gradlew :app:testSideloadDebugUnitTest --tests "com.hermesandroid.relay.network.upstream.GatewayChatClientTest" -Pandroid.aapt2FromMavenOverride=/opt/android-sdk/build-tools/35.0.0/aapt2on this branch rebased on
origin/dev: the watchdog tests pass. After silencethey assert no stream error, no
session.interrupt, and that a latemessage.completestill lands.native approval queue keeps each decision and rejects answers after session clear, a native-ask test that shares no code path with this change (thewatchdog returns early while an ask is pending, so it never launches). It
reproduces on unmodified
devin one of five consecutive runs and passes inisolation, so it is a pre-existing timing flake rather than this change.
lane.
Screenshots
No visual change.
Compatibility / risk
plugin or host contract change.
in the app until the Gateway reports it ended or the socket drops, instead of
dying at 180s. That is the intended trade: the server owns the turn.
Lineage / contributor credit
Checklist
devCHANGELOG.mdis updated