Skip to content

feat: permission_request timeout + session_timeout event + frontend dismiss#454

Open
jlunder00 wants to merge 1 commit into
devfrom
feature/permission-timeout
Open

feat: permission_request timeout + session_timeout event + frontend dismiss#454
jlunder00 wants to merge 1 commit into
devfrom
feature/permission-timeout

Conversation

@jlunder00

Copy link
Copy Markdown
Owner

What

Wire the 15-minute permission request timeout end-to-end across the PermissionGate, session event stream, and frontend.

Parts implemented

A — PermissionGate timeout (permissions.py)

  • PermissionTimeoutError raised (not silent deny) when user doesn't respond within timeout
  • Default changed 60s → 900s; configurable via agent_layer.permission_timeout_seconds
  • Exception carries request_id for downstream event attribution
  • permission_pending still cleaned up via finally block even when raising

B — session_timeout event (session.py)

  • _handle_control_request catches PermissionTimeoutError, sends deny to pool before re-raising
  • run_turn catches it, emits {type: session_timeout, session_id, reason: permission_timeout, request_id} on WebSocket, then ends the generator cleanly

C — Frontend (chat.ts, PermissionModal.vue, BotChat.vue, types/chat.ts)

  • session_timeout added to WsIncomingEvent union type
  • Chat store handles it: clears pendingPermissionRequest/permissionQueue, sets sessionTimedOut = true, does not call sendRaw (backend already denied)
  • BotChat.vue: shows "Session timed out — send a message to resume" when sessionTimedOut
  • PermissionModal.vue: 60s timer now dismisses the modal to a compact "Waiting on your response" indicator instead of auto-denying — backend is the sole timeout authority (Option C)

Tests

  • 152 backend pytest tests passing (34 new in test_permissions.py + test_session.py)
  • 982 frontend vitest tests passing (12 new in PermissionModal.test.ts, 5 new in chat.test.ts)

Deferred

Part D (read_out_of_scope mid-execution permission emission) deferred — requires cross-process permission protocol design. The MCP server and PermissionGate run in separate OS processes; mid-execution permission requests cannot be emitted via the current can_use_tool pre-check mechanism. Needs its own spec and task.

…end dismiss

A — PermissionGate raises PermissionTimeoutError after 900s (configurable via
    agent_layer.permission_timeout_seconds; default bumped from 60→900).
    PermissionTimeoutError carries request_id for downstream event attribution.

B — _handle_control_request catches PermissionTimeoutError, sends deny to pool,
    re-raises. run_turn catches it, emits {type: session_timeout, session_id,
    reason: permission_timeout, request_id} on WebSocket, then ends cleanly.

C — Frontend: session_timeout event added to WsIncomingEvent type. Chat store
    handles it by clearing pendingPermissionRequest/permissionQueue, setting
    sessionTimedOut flag, and returning without sending permission_response.
    BotChat.vue shows "Session timed out — send a message to resume" on timeout.
    PermissionModal.vue 60s timer now dismisses to a compact waiting indicator
    (Option C) instead of auto-denying — backend is sole timeout authority.

Part D (read_out_of_scope mid-execution permission emission) deferred — requires
cross-process permission protocol design (MCP server and PermissionGate are in
separate processes).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant