diff --git a/scripts/android-cua-smoke.py b/scripts/android-cua-smoke.py index 88369cf..7436dd6 100755 --- a/scripts/android-cua-smoke.py +++ b/scripts/android-cua-smoke.py @@ -1140,11 +1140,11 @@ def run_scenario_backgrounded_permission_notification(opencode_url: str, model: print(f" [api] WARNING: could not send permission-triggering message: {exc}") # Phase 4: DETERMINISTIC — poll notification drawer for permission notification. - # The actual notification fired by events.ts has title `req.permission || - # "Permission requested"` and body `req.patterns` or "A tool needs your approval" - # — there is NO "Agent needs approval" string. The only token guaranteed in every - # dumpsys record is our package name, so gate on APP_PACKAGE (deterministic) and - # treat the human-readable copy as a secondary signal. + # events.ts fires notify({ title: "Agent needs approval", body: ": ", + # category: "permissions", sessionId }) — only when app is backgrounded (AppState check + # in notifications.ts send()). The only token guaranteed in every dumpsys record is our + # package name, so gate on APP_PACKAGE (deterministic); fall back to the notification + # title/body as secondary signals. print(" [notify] polling notification drawer for permission notification...") appeared = check_notification_drawer(APP_PACKAGE, timeout=15) if not appeared: diff --git a/src/stores/events.ts b/src/stores/events.ts index cbab02e..8a26428 100644 --- a/src/stores/events.ts +++ b/src/stores/events.ts @@ -269,9 +269,18 @@ export const useEvents = create((set, get) => ({ })) notify({ category: "permissions", - title: req.permission || "Permission requested", - body: sanitizeBody(req.patterns?.join(", "), "A tool needs your approval"), + title: "Agent needs approval", + body: sanitizeBody( + req.permission + ? req.patterns?.length + ? `${req.permission}: ${req.patterns.join(", ")}` + : req.permission + : req.patterns?.join(", "), + "A tool needs your approval", + ), sessionId: req.sessionID, + dedupeKey: `perm-${req.id}`, + dedupeCooldownMs: 60_000, }) break } @@ -305,6 +314,8 @@ export const useEvents = create((set, get) => ({ title: req.questions?.[0]?.header || "Input needed", body: sanitizeBody(req.questions?.[0]?.question, "The assistant has a question"), sessionId: req.sessionID, + dedupeKey: `question-${req.id}`, + dedupeCooldownMs: 60_000, }) break }