fix(cloud-tasks): re-ask pending question on resume instead of skipping it#3003
fix(cloud-tasks): re-ask pending question on resume instead of skipping it#3003MattPua wants to merge 2 commits into
Conversation
…ng it
When a session is re-initialized while a permission request is still pending
(e.g. a seamless resume or a reconnect that rebuilds the session),
`cleanupSession` drained the pending request by resolving it as a deliberate
`{ outcome: "selected", optionId: "reject" }`. The agent persisted that as the
user's choice, so on resume the question was treated as answered and the choice
box was silently skipped — even though the user was watching and never replied.
Resolve pending permissions as `{ outcome: "cancelled" }` on re-init instead.
The user never answered; the session is just being rebuilt underneath them, so
"cancelled" leaves the request unanswered and the resumed turn re-asks it. Real
shutdown/close paths are unchanged and still record a reject.
Also collapse two hand-rolled permission-response unions onto the SDK's
`RequestPermissionResponse` type (single source of truth).
Tests: shutdown cleanup still rejects; re-init cleanup cancels; and
`_doInitializeSession` (the practical trigger) routes through cleanup with the
cancel flag set.
Generated-By: PostHog Code
Task-Id: 14da7a0f-aa44-4b0d-89b3-52e58f66b1e8
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
|
Address review feedback and close the coverage gap on the re-init cancel path:
- Parameterize the two twin drain tests (shutdown rejects / re-init cancels)
into a single it.each, per the repo's preference for parameterized tests.
- Add cancelPendingPermissions to stubSessionCleanup's return type so tests
call cleanupSession({ cancelPendingPermissions: true }) without re-casting.
- Add an integration test that drives the real ACP requestPermission() entry
point: the agent's question call blocks while relayed, a re-init tears the
session down, and the promise the agent is awaiting resolves as "cancelled"
(not a reject the resumed turn would skip). Documents the one piece a unit
test can't reach — whether the external agent re-asks — which needs e2e.
- Drop inline comments that just restated the integration test's header.
Generated-By: PostHog Code
Task-Id: 14da7a0f-aa44-4b0d-89b3-52e58f66b1e8
|
Reviews (2): Last reviewed commit: "test(cloud-tasks): strengthen pending-qu..." | Re-trigger Greptile |
Problem
When the agent raises an
AskUserQuestionchoice box on a session a desktop is watching, the user sometimes sees it silently skipped — as if they'd answered when they never did.Root cause: a relayed, still-pending permission is drained by
cleanupSession, which resolved it as a deliberate{ outcome: "selected", optionId: "reject" }. That blanket reject is correct for a real shutdown, but_doInitializeSessionalso callscleanupSessionwhenever it rebuilds an existing session — i.e. a seamless resume / reconnect. The reject then gets persisted as the user's choice, so the resumed turn treats the question as answered and skips it.This is the only path where a connected desktop's choice box gets skipped — the relay-vs-auto-resolve decision (gated on
hasDesktopConnected) was already correct, so that behavior is intentionally untouched: a truly headless run (cron/Slack/autonomous) still auto-resolves rather than hanging forever.Fix
cleanupSessiontakes acancelPendingPermissionsflag. Only the re-init caller (_doInitializeSession) passes it. When set, pending permissions resolve as{ outcome: "cancelled" }— the honest "the user never answered" state (the same outcome the permission handler already uses elsewhere).cancelledunblocks the ACP teardown the same way a reject did (no deadlock), but is not recorded as a choice, so the resumed turn re-asks the question.stop()and theclosecommand are unchanged — they still reject on genuine shutdown.Also collapsed two hand-rolled permission-response unions onto the SDK's
RequestPermissionResponsetype so the shape is expressed once and can't drift.Tests
rejects pending permissions on shutdown cleanup— unchanged shutdown path still records a reject.cancels (does not reject) pending permissions on re-init cleanup— the drain branch resolves ascancelledwhen the flag is set.re-init cleans up an existing session with permissions cancelled, not rejected— drives the practical trigger (_doInitializeSessionwith an existing session) and asserts it routes throughcleanupSessionwithcancelPendingPermissions: true, so a wiring regression is caught.All 124 tests in
agent-server.test.ts+question-relay.test.tspass;tscand Biome are clean.Not covered
These are unit tests — they don't stand up the full agent/ACP harness, so there's no single uninterrupted end-to-end "raise question over live SSE → resume → re-asked" run. The downstream assumption that an ACP
cancelledoutcome causes the resumed turn to re-ask (rather than drop the request) is reasoned from the protocol, not asserted by a test here.