fix(notifications): only run waiting-reply foreground service while a reply is pending (#795)
The chat notification FGS — and its mandatory persistent 'Waiting for Hermes replies' notification — was started on every ON_STOP of the chat screen, even when nothing was in flight, and lingered at app startup. Track a pending-reply flag on HermesWsClient (set when a prompt is submitted and on any in-flight turn event, cleared on MessageComplete), gate NotificationHelper.start() on it, and have the service retire itself after delivering the reply notification in the background. Replies sent from the notification re-arm the service for the follow-up turn. Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
1 parent
1870b375b1
commit
83ec590ed8
3 files changed
+71
-6
No files matched your search
@@ -157,6 +157,15 @@ object HermesWsClient {
|
||||
/** Observable connection status */
|
||||
val connectionStatus: StateFlow<ConnectionStatus> = _connectionStatus.asStateFlow()
|
||||
|
||||
// ── Reply-pending tracking ─────────────────────────────────────────
|
||||
// True while at least one agent turn is in flight. Drives the chat
|
||||
// notification foreground service: it only runs while a reply is
|
||||
// actually pending, instead of for the whole time the app is
|
||||
// backgrounded (issue #794).
|
||||
@Volatile
|
||||
var pendingReply: Boolean = false
|
||||
private set
|
||||
|
||||
// ── Credential warning (issue #534) ─────────────────────────────────
|
||||
// Backend surfaces `credential_warning` in `gateway.ready` / `session.info`
|
||||
// WS payloads (desktop `requestDesktopOnboarding`). Mobile has no equivalent
|
||||
@@ -207,6 +216,25 @@ object HermesWsClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Track whether a reply is actually in flight so the chat notification
|
||||
// foreground service only runs while the user is waiting for one
|
||||
// (issue #794), instead of for the whole time the app is backgrounded.
|
||||
// Also covers turns started from other devices on the same session.
|
||||
wsScope.launch {
|
||||
events.collect { event ->
|
||||
when (event) {
|
||||
is WsEvent.MessageStart,
|
||||
is WsEvent.MessageToken,
|
||||
is WsEvent.ThinkingDelta,
|
||||
is WsEvent.ReasoningDelta,
|
||||
is WsEvent.ToolStart,
|
||||
-> pendingReply = true
|
||||
|
||||
is WsEvent.MessageComplete -> pendingReply = false
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Connection helpers ────────────────────────────────────────────────
|
||||
@@ -584,12 +612,17 @@ object HermesWsClient {
|
||||
sessionId: String,
|
||||
text: String,
|
||||
onSent: ((String) -> Unit)? = null,
|
||||
): String =
|
||||
send(
|
||||
): String {
|
||||
// A reply is now pending — even before the first MessageStart event
|
||||
// (the agent may be in its tool phase), so backgrounding the app in
|
||||
// that window still arms the notification service (issue #794).
|
||||
pendingReply = true
|
||||
return send(
|
||||
method = WsMethods.PROMPT_SUBMIT,
|
||||
params = mapOf("session_id" to sessionId, "text" to text),
|
||||
onSent = onSent,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: redirect the active model turn while it is still generating
|
||||
|
||||
Reference in new issue
Block a user