OpenHands / OpenHands/software-agent-sdk

[Feature]: QuestionTool -- let the agent ask the user structured questions mid-task

Open
#2,697 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement question tools
Dominant language
Python
Stars
1.1k
Forks
539
Avg merge
1d 19h
Merged PRs (30d)
137

Description

Is there an existing feature request for this?
  • I have searched existing issues and feature requests, and this is not a duplicate.
Problem or Use Case

When the agent hits genuine ambiguity mid-task, it has no structured way to ask the user for input. It either guesses (risking wasted work) or dumps a question into a chat message (which doesn't pause execution or offer clear choices).

A few real examples where this comes up:

1. Architecture decisions the code doesn't encode

User: "Add authentication to this API."

The agent finds the project uses Express. It could add session-based auth, JWT, or OAuth. Each choice has cascading implications for middleware, database schema, and frontend changes. Today the agent picks one and hopes. With a question tool, it would pause and ask:

  • JWT with bearer tokens
  • Session-based with cookies
  • OAuth 2.0 with provider login

The user picks in one click and the agent proceeds with confidence.

2. Destructive migrations with multiple valid paths

User: "Upgrade this project from React class components to hooks."

The agent scans the codebase and finds 40 class components. Some are trivial, some use complex lifecycle methods. It could migrate everything at once, do it incrementally by directory, or start with the simplest ones. Today it just starts doing something. With a question tool:

  • Migrate all 40 components at once
  • Start with the 12 simple ones, leave complex ones for a follow-up
  • Migrate by directory (components/, pages/, layouts/)

The user picks a strategy and the agent follows it cleanly.

3. Ambiguous naming and conventions

User: "Create a user settings page."

The agent needs to decide: /settings, /account, or /preferences? Should it match the existing nav structure or create a new section? Should it include billing, notifications, both, neither? These are product decisions. With a question tool, the agent asks what it can't infer from the codebase and moves on.

Several other CLI-based coding agents have shipped this capability and it meaningfully reduces wasted iterations. The agent stays autonomous for everything it can figure out on its own, and asks only when the answer genuinely isn't in the code.

Proposed Solution

A QuestionTool that the agent can call to present the user with structured choices.

Tool schema (the agent's call):

# Agent calls the tool with:
questions: list[QuestionInfo]

# Each question:
question: str                              # "Which auth strategy?"
options: list[{label: str, description: str}]  # selectable choices
multiple: bool = False                     # allow multi-select
allow_custom: bool = True                  # show "type your own answer" option

Observation (what comes back):

answers: list[list[str]]  # selected labels, parallel to questions

Execution flow:

The SDK already has a working model for this: the confirmation flow. When the agent produces actions that need user approval, the run() loop sets execution_status = WAITING_FOR_CONFIRMATION, breaks, the client renders a panel, the user decides, and run() resumes.

A question tool would follow the same pattern:

  1. Agent calls question tool
  2. execution_status is set to a new WAITING_FOR_USER_INPUT state
  3. conversation.run() breaks
  4. Client (CLI, Cloud, etc.) renders the question panel
  5. User picks answer(s)
  6. Client calls conversation.answer_questions(answers)
  7. run() resumes, tool returns answers as the observation

This keeps the SDK's state machine explicit and works across all clients.

Headless/CI fallback:

Same approach as confirmation: a configurable policy. Default could auto-select the first option (or the one marked "recommended"), so headless runs never block.

Alternatives Considered

Chat-based questions (status quo): The agent includes questions in its regular text response. This doesn't pause execution, doesn't offer structured choices, and doesn't communicate "I need this answer before I can continue."

Tool-level blocking: The tool executor blocks the agent thread on a threading.Event while the UI collects input. Simpler to implement but hides control flow inside the executor, doesn't show up in the state machine, and is harder for non-CLI clients to implement.

Priority / Severity

Medium - Would improve experience

Estimated Scope

Medium - New feature with moderate complexity

Feature Area
  • Tools / Tool system
  • Agent API / Core functionality
Technical Implementation Ideas (Optional)

The confirmation flow (WAITING_FOR_CONFIRMATION status, reject_pending_actions(), the resume cycle in conversation.run()) is a direct template. The main additions:

  • New ConversationExecutionStatus.WAITING_FOR_USER_INPUT
  • pending_questions on ConversationState
  • answer_questions() and reject_questions() on LocalConversation
  • QuestionTool in openhands-tools (Action/Observation/Executor)
  • CLI panel modeled on the existing ConfirmationPanel

Happy to help with implementation if there's interest.

Additional Context

The SDK's ask_agent() method handles the reverse direction (user asking the agent a stateless question). This proposal completes the picture: agent asking the user a structured question that pauses and resumes execution.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the existing confirmation flow, especially ConversationExecutionStatus, ConversationState, LocalConversation, conversation.run(), and ConfirmationPanel. Trace how pending actions pause and resume execution, then map the proposed WAITING_FOR_USER_INPUT state, answer_questions(), reject_questions(), and QuestionTool across the SDK, CLI, and tool system. Done means structured questions pause and resume conversations consistently, with a headless fallback and client rendering.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design, cli, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.