From b0f182cef5e29ef1cffd33ae3514dcb974577d7c Mon Sep 17 00:00:00 2001 From: Vikas Singhal Date: Tue, 14 Jul 2026 16:41:42 +0530 Subject: [PATCH] =?UTF-8?q?fix(agents):=20deny=20native=20AskUserQuestion?= =?UTF-8?q?=20=E2=80=94=20it=20hangs=20unattended=20runs=20(v0.193.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude's built-in AskUserQuestion renders a multiple-choice picker in the TUI and blocks the turn until a keypress — but Agent OS runs have no human at the terminal, so it hangs forever (no output, nothing in the Inbox, stuck pane), and in the Chat surface it looked like the ask tool "wasn't rendering." The launcher now denies AskUserQuestion (applies even under --dangerously-skip-permissions) and the operating notes steer agents to ask_human (Inbox card + DM, blocks for the reply) or plain prose — both work in every surface. Latent bug for all unattended runs, surfaced by the Chat work. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 14 ++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- src/terminal.ts | 4 +++- terminal/claude-launch.sh | 8 +++++++- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a8a6e9..2a61a54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,20 @@ new version heading in the same commit. ## [Unreleased] +## [0.195.1] — 2026-07-14 +### Fixed +- **Agents can no longer hang a run on the native `AskUserQuestion` picker.** Claude's built-in + `AskUserQuestion` tool renders an interactive multiple-choice prompt in the terminal TUI and blocks the + turn until someone presses Enter at the keyboard — but an Agent OS run has no human at the terminal + (chat/automation/task/Slack runs are unattended). So an agent that reached for it (e.g. asked to "ask a + question") would **hang forever**: no turn output, nothing in the Inbox, a stuck pane — and in the new + Chat surface it looked like the question tool "wasn't rendering." The launcher now **denies + `AskUserQuestion`** (`terminal/claude-launch.sh`; deny rules apply even under + `--dangerously-skip-permissions`), and the operating notes steer agents to **`ask_human`** (governed → + Inbox card + DM, blocks for the reply) or plain prose — both work in every surface, including Chat. + This was a latent bug for all unattended runs, surfaced by the Chat work. (`terminal/claude-launch.sh`, + `src/terminal.ts`.) + ## [0.195.0] — 2026-07-14 ### Fixed - **Plain-text links in the terminal are now clickable — no scheme needed, and OSC-8 markdown links work diff --git a/package-lock.json b/package-lock.json index e43fdf2..feb6864 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "agent-os", - "version": "0.195.0", + "version": "0.195.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "agent-os", - "version": "0.195.0", + "version": "0.195.1", "license": "MIT", "bin": { "agent-os": "bin/agent-os" diff --git a/package.json b/package.json index 2e70001..83af551 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agent-os", - "version": "0.195.0", + "version": "0.195.1", "description": "A generic, governed operating system for running autonomous agents safely across brands. Ships with a local web console.", "license": "MIT", "type": "commonjs", diff --git a/src/terminal.ts b/src/terminal.ts index ca43e04..04a38d0 100644 --- a/src/terminal.ts +++ b/src/terminal.ts @@ -78,7 +78,9 @@ into this prompt — you must reach for it: ## Talking to the human — use the Inbox, not just the terminal Your terminal output may not be read. The operator lives in the Inbox: - \`ask\` when you're blocked on a judgement only the human can make — it waits for their reply. Prefer - asking over guessing on anything risky or ambiguous. + asking over guessing on anything risky or ambiguous. This is the ONLY way to ask a person here: there + is no human at your terminal, so a native multiple-choice/interactive prompt just hangs unanswered — + always use \`ask\` (or plain text if you're in a chat), never an interactive picker. - \`report\` exactly once when you finish, with the outcome and a one-line summary, so the result is visible without anyone reading the terminal. If the task taught you something durable, pass it in \`lessons\` — it's saved to your memory as a note to your future self. diff --git a/terminal/claude-launch.sh b/terminal/claude-launch.sh index 04f4200..f48e149 100755 --- a/terminal/claude-launch.sh +++ b/terminal/claude-launch.sh @@ -71,7 +71,13 @@ STATUSLINE="$(dirname "$HOOK")/statusline.js" # under it and a deny would block the agent reading its OWN files — so we deny only crown-jewel # paths that never overlap the agent folder. H="${HOME#/}" -DENYS="\"Read(//$H/.ssh/**)\", \"Read(//$H/.aws/**)\", \"Read(//$H/.gnupg/**)\", \"Read(//$H/.claude/**)\"" +# Deny the native AskUserQuestion tool: it renders a multiple-choice picker in the TUI and BLOCKS the +# turn until someone presses Enter at the keyboard — but an Agent OS run has no human at the terminal +# (chat/automation/task/Slack runs are unattended; even an attached session interacts via the console). +# So it hangs the run forever and never reaches the Inbox. Denied here, the agent asks via `ask_human` +# (governed → Inbox card + DM, blocks for the answer) or in plain prose — both work everywhere. (deny +# rules apply even under --dangerously-skip-permissions.) +DENYS="\"AskUserQuestion\", \"Read(//$H/.ssh/**)\", \"Read(//$H/.aws/**)\", \"Read(//$H/.gnupg/**)\", \"Read(//$H/.claude/**)\"" DATA_HOME="$(cd "$AGENT_DIR/../.." 2>/dev/null && pwd)" if [ -n "$DATA_HOME" ]; then DH="${DATA_HOME#/}"