Previously mobile dropped the gateway's sudo.request and secret.request events, so any agent turn needing a sudo password or a secret value hung forever with no UI. Now: - EventParser maps sudo.request / secret.request -> WsEvent.SudoRequest / SecretRequest - ChatViewModel surfaces a secure dialog (SudoPromptUi / SecretPromptUi) and replies via sudo.respond / secret.respond with session_id + request_id + payload - ChatWsEventReducer explicitly branches the new events (no-op, VM-owned) - ChatScreen renders password-masked SudoPromptDialog / SecretPromptDialog - 6 unit tests cover prompt-state, RPC params, and prompt-clearing Mirrors desktop/web contract (apps/shared GatewayEventName + tui_gateway). Derives from audit of /opt/hermes-agent desktop app.
This commit is contained in:
8 files changed
+400
No files matched your search
@@ -115,6 +115,16 @@ object EventParser {
|
||||
WsEvent.ApprovalRequest(command, description, patternKeys, sessionId)
|
||||
}
|
||||
|
||||
"sudo.request" -> {
|
||||
val requestId = payload?.get("request_id") as? String
|
||||
WsEvent.SudoRequest(requestId, sessionId)
|
||||
}
|
||||
|
||||
"secret.request" -> {
|
||||
val requestId = payload?.get("request_id") as? String
|
||||
WsEvent.SecretRequest(requestId, sessionId)
|
||||
}
|
||||
|
||||
else -> {
|
||||
Log.w(TAG, "Unknown event type: $eventType")
|
||||
WsEvent.Unknown(rawJson)
|
||||
|
||||
@@ -94,6 +94,28 @@ sealed class WsEvent {
|
||||
val sessionId: String?,
|
||||
) : WsEvent()
|
||||
|
||||
// ── Sudo / secret requests ─────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Backend needs the user's sudo password to continue a turn
|
||||
* (desktop: `sudo.request` → `sudo.respond {request_id, password}`).
|
||||
* Mobile previously dropped this and the agent hung forever.
|
||||
*/
|
||||
data class SudoRequest(
|
||||
val requestId: String?,
|
||||
val sessionId: String?,
|
||||
) : WsEvent()
|
||||
|
||||
/**
|
||||
* Backend needs a secret value (password / token) to continue a turn
|
||||
* (desktop: `secret.request` → `secret.respond {request_id, value}`).
|
||||
* Mobile previously dropped this and the agent hung forever.
|
||||
*/
|
||||
data class SecretRequest(
|
||||
val requestId: String?,
|
||||
val sessionId: String?,
|
||||
) : WsEvent()
|
||||
|
||||
// ── Fallback ─────────────────────────────────────────────────────────
|
||||
|
||||
data class Unknown(
|
||||
|
||||
@@ -17,6 +17,8 @@ object WsMethods {
|
||||
const val PROMPT_SUBMIT = "prompt.submit"
|
||||
const val CLARIFY_RESPOND = "clarify.respond"
|
||||
const val APPROVAL_RESPOND = "approval.respond"
|
||||
const val SUDO_RESPOND = "sudo.respond"
|
||||
const val SECRET_RESPOND = "secret.respond"
|
||||
|
||||
// ── Commands catalog ──────────────────────────────────────────────────
|
||||
const val COMMANDS_CATALOG = "commands.catalog"
|
||||
|
||||
Reference in new issue
Block a user