Open general

run-prompt never reports needs_you while a Claude AskUserQuestion is waiting; no API to answer it

John Lauer · 10d ago

What happened

On Adom Hydrogen v1.0.601 (ConfRoomROG), a remote AI started a long filmed build with POST /ai-threads/run-prompt {new:true, type:"claude", background:true} and polled GET /ai-threads/run-prompt/status?job=... every minute.

About 2 hours in, the Claude thread asked an AskUserQuestion: "Live stages: which machine, and when?", with four radio options and a Submit button. The job stayed working / still_working the whole time and never reached needs_you. GET /claude/conversation-state doesn't show it either: answering:true, and there's no field for a pending question. The run sat waiting for an unknown time until a screenshot happened to show the question.

The skill says needs_you means "a permission or question is waiting". A question from the AskUserQuestion tool doesn't trigger it.

What a caller AI needs

  1. needs_you for AskUserQuestion, using the PreToolUse hook on AskUserQuestion or the same signal the permission hook uses. Also send question: {header, text, options[]} in the status so the caller can show it or answer it.
  2. A way to answer it through the API, e.g. POST /ai-threads/answer {sid|job, option: <index|label>}. Without it, the only way is OS clicks at screenshot coordinates. That went wrong once here: the shotId mapped to the 1400 px safe image, not the full one, and the first click picked the wrong radio button.
  3. /claude/conversation-state: add pending_question (and pending_permission) so a watcher that doesn't own the job can see a blocked thread.
  4. Add one line to the hydrogen-ai-threads-api skill under "Know where your prompt went" on how to detect and answer a question.

The workaround I'm using for now: treat 4 minutes with no change in msgs as "probably blocked", then screenshot.

2 Replies

John Lauer · 9d ago

Items 1, 3 and 4 are in Hydrogen 1.0.607 (insiders). Item 2, answering through the API, is not built yet, so this stays open for it.

How: Hydrogen now also installs PreToolUse and PostToolUse hooks matched to AskUserQuestion (the merge runs on every launch, so existing workspaces get them with no action).

  • 1. The job goes to needs_you (terminal, so a poller stops) and carries job.question: {questions: [{header, text, options: [{label, description}], multi_select}], at_ms}. Once answered it returns to working, and question is gone.
  • 3. GET /claude/conversation-state has pending_questions: session id to the same object, for watchers that do not own the job.
  • 4. The hydrogen-ai-threads-api skill explains it under "Know where your prompt went".
  • The hook payload cap went from 4 KB to 16 KB, because a question with four described options outgrew 4 KB and a cut payload does not parse.

Verified on a test PC, 1.0.607, with run-prompt {new:true, type:"claude", submit:true} and a prompt asking Claude to ask "Which color do you prefer?" (Red / Blue):

step state job.question pending_questions
Claude asks needs_you (terminal) header "Color", text, both options with descriptions the same, under the session id
answered "Red" in the tab working gone
turn ends done gone {}

The release sweep passed on that PC (217/217).

John Lauer · 3d ago

Item 2 is written, in 6b584ebd for the next build after 1.0.658:

POST /ai-threads/answer {job | sid | tid, option} answers the question the way a person does, inside that thread's own tab: it selects the options, then presses Submit answers, and answers ok only once the question is gone.

  • option: a label (exact, else a unique prefix) or a 0-based index.
  • options: [...] for a multi-select question, other: "text" for a typed answer.
  • answers: [{question: <index or header>, option | options | other}, ...] when Claude asks several questions at once.
  • With no job/sid/tid it answers the one question showing anywhere, and refuses if several threads are asking.
  • A wrong label returns ok:false with the real options, so a caller can correct itself instead of clicking blind. answered lists what was picked.

No screenshots or OS clicks: it works on a backgrounded Hydrogen. The skill's "A question is waiting" section now shows it.

Gate entry ai-threads-answer: run-prompt asks Claude to ask Red / Blue; at needs_you, answer {job, option:"Blue"} is ok, the job returns to working, and Claude's reply names Blue. When that passes on the build, everything in this issue is done and I will close it.

Log in to reply.