Skip to content

Make user-input / approval wait timeout configurable (and disableable) #6003

Description

@7jrxt42BxFZo4iAnN4CX

Problem

When codewhale asks the user a question (await_user_input) or waits for an approval decision, it waits a fixed 300 seconds and then cancels with a timeout:

// crates/tui/src/core/engine/approval.rs:15
const USER_INPUT_TIMEOUT: Duration = Duration::from_secs(300);
// crates/tui/src/runtime_threads.rs:547
const APPROVAL_DECISION_TIMEOUT: Duration = Duration::from_secs(300);

This is hard-coded — there is no config key and no env var in the engine to change it (only [tools] user_input_max_questions / user_input_max_options, which cap the count of questions, not the wait). The wait is also not documented in docs/CONFIGURATION.md.

The fixed 5-minute window is wrong for two groups:

  • Users who need longer: they step away or read carefully, come back after 5 minutes, and the question/approval has already timed out (ToolError::Timeout { seconds: 300 }).
  • Users who want no timeout at all (e.g. overnight automation, long human review), which is currently impossible.

A timeout that silently cancels a question the user was about to answer is a real workflow breaker — related closed bug: #3821 (approval dialog timeout left the agent unable to respond).

Proposed solution

Make the wait timeout configurable and disableable, mirroring how other limits are already exposed:

  • Add a config key such as:
    [tools]
    # seconds to wait for a user answer / approval decision
    # user_input_timeout_secs = 300   # default; 0 = wait indefinitely
  • Or an env var, e.g. CODEWHALE_USER_INPUT_TIMEOUT_SECS, applied at engine start.
  • 0 (or none) should mean wait indefinitely (no timeout), for users who explicitly opt out.
  • Unify/alias both constants (USER_INPUT_TIMEOUT in approval.rs, APPROVAL_DECISION_TIMEOUT in runtime_threads.rs) so the knob controls both paths consistently.

Use case

I routinely have several questions/approvals pending while I context-switch. After ~5 minutes codewhale cancels them even though I am about to answer. I want to raise the window — or disable it entirely for unattended stretches — instead of losing the turn.

Alternatives considered

  • Re-asking the question after a timeout (today it is just cancelled; the agent may or may not re-ask).
  • Per-invocation timeout in the question payload (the user_input tool already carries other fields; a timeout_secs there would allow "answer this within N" without a global knob).
  • A notification/beeper when a question is about to expire (does not fix the fixed-window problem).

My preferred option: global config key with 0 = unlimited, plus optionally per-invocation override later.

Impact

Anyone who does not answer within 5 minutes loses the question/approval. Configurability removes a silent failure mode and matches the pattern already used for user_input_max_questions / user_input_max_options (PR #5963).

Additional context

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions