opencode icon indicating copy to clipboard operation
opencode copied to clipboard

feat(new tool):Adding a new tool to opencode -> askquestion tool

Open iljod opened this issue 2 months ago • 31 comments

This PR introduces the askquestion tool, a new interactive primitive that allows the AI to pause execution and solicit structured feedback from the user via a TUI wizard very similarly to claude code's tool. It also resolves a critical race condition in the tool execution lifecycle that previously caused UI updates to be missed.

The "AskQuestion" Tool

The askquestion tool bridges the gap between the AI's autonomous execution and user intent. Instead of guessing preferences, the agent can now halts its process to ask specific configuration questions (e.g., "Which database do you prefer?", "Select features to enable").

How It Works (User Flow)

  1. Invocation The Agent calls the askquestion tool with a schema of 1-6 questions (Single Select, Multi-Select, or Confirm).
  2. Suspension The Tool registers a pending request and enters a waiting state. Execution is effectively paused, awaiting a Promise resolution.
  3. Intervention The TUI detects the waiting metadata and renders a modal overlay (Wizard) on top of the chat.
  4. Interaction The user navigates options using the keyboard (Space to toggle, Enter to confirm).
  5. Resumption Upon submission, the Promise resolves, the tool returns the structured answers to the Agent, and the AI resumes execution with the new context.

Robust State Synchronization (The Fix)

A core issue addressed in this PR was a race condition where the tool would attempt to emit metadata updates before the system had fully registered the tool execution part.

  • The execute() method ran faster than the event propagation for the tool call, causing the "Waiting for user..." signal to be lost.
  • Implemented a polling retry mechanism in src/session/prompt.ts. The system now waits (exponential backoff up to 1s) for the specific Tool Part to transition to the running state before attempting to attach metadata. This ensures the TUI guarantees valid state reads.

2. The Tool Definition (src/tool/askquestion.ts)

  • Uses Zod to strictly enforce a limit of 1-6 questions to prevent context window bloat.
  • Formats the output as a human-readable markdown string for the LLM to easily ingest the user's choices.

3. TUI & UX Enhancements

  • Reactivity The TUI (src/cli/cmd/tui/) now contains a reactive memo pendingAskQuestionFromSync that listens specifically for tool parts in the waiting state.

  • Visual Polish

    • Added distinct visual indicators for selection types: ○/● (Radio) vs [ ]/[✓] (Checkbox).
    • Implemented "Auto-Advance" logic for single-select questions to reduce keystrokes.

    Resolves #3844

Currently this tool is CLI ONLY

  • CLI TUI sends x-opencode-client: tui header
  • Web/Desktop apps don't send this header (defaults to "web")
  • Server passes client type through prompt system
  • askquestion tool is only provided to TUI clients

iljod avatar Dec 22 '25 13:12 iljod

this is what it looks like in practice image image and the tool also supports lists by which the user can use to select items image

iljod avatar Dec 22 '25 13:12 iljod

any & all suggestions welcome, because I would love for this to get merged into the real codebase :saluting_face:

btw also resolves #5960

iljod avatar Dec 22 '25 13:12 iljod

Can I say a fantastic addition if it gets merged! The only issue I see here is that it seems to be tied to the TUI. So it would need to be added to the web as well as the desktop app. If it gets merged like this what would happen for desktop app users if the tool gets triggered? Can any custom client render their own UI based on the current implementation? I have yet to see the code itself, but these are the first questions that come to mind

malhashemi avatar Dec 22 '25 14:12 malhashemi

Can I say a fantastic addition if it gets merged! The only issue I see here is that it seems to be tied to the TUI. So it would need to be added to the web as well as the desktop app. If it gets merged like this what would happen for desktop app users if the tool gets triggered? Can any custom client render their own UI based on the current implementation? I have yet to see the code itself, but these are the first questions that come to mind

thanks for the feedback & the love! yea I 100% forgot the desktop app & the webui, the current implementation makes it really easy for other to tack stuff unto it -> fetch('/askquestion/respond', ...) etc

I'm not really that good at webdev for the website, so any other help would be welcome!!!

iljod avatar Dec 22 '25 15:12 iljod

@rekram1-node I'm really not that big of an expert on the desktop or the web ui part of opencode Would it be okay if I just limit the askquestion tool to just the CLI for the time being? or no

iljod avatar Dec 22 '25 17:12 iljod

This is looking great!!

Last week i tried to solve the same thing with a different approach:

https://github.com/sst/opencode/pull/5563

My main goal posting here is not to compete with this PR by any means but just to add context on using a different approach, this PR is more similar to Claude Code, the other PR uses TUI and Dialog, which feels more unique to OpenCode design model.

Either way, i'm more excited about the feature than the implementation, so either works for me 😄

dbpolito avatar Dec 22 '25 19:12 dbpolito

This is really nice, and works perfectly fine. I would restrict it to the primary agents only. You can update the task tool call in the packages/opencode/src/tool/task.ts file and disable it from subagents.

arsham avatar Dec 22 '25 22:12 arsham

What's the difference from just asking the model to propose questions in numbered list one question at a time?

Does this tool mean that we minimise requests? Otherwise it's not different.

Also I really think this kind of thing should wait until plugins can create their own UI elements.

relevant: https://github.com/sst/opencode/pull/5563#issuecomment-3683967148

airtonix avatar Dec 23 '25 02:12 airtonix

This is looking great!!

Last week i tried to solve the same thing with a different approach:

#5563

My main goal posting here is not to compete with this PR by any means but just to add context on using a different approach, this PR is more similar to Claude Code, the other PR uses TUI and Dialog, which feels more unique to OpenCode design model.

Either way, i'm more excited about the feature than the implementation, so either works for me 😄

Thank you! I also really like your implementation! I just made it similar to Claude's since I like to see all the chat history when answering the questions, but just like you I love the implementation more then who makes it haha

iljod avatar Dec 23 '25 08:12 iljod

What's the difference from just asking the model to propose questions in numbered list one question at a time?

Does this tool mean that we minimise requests? Otherwise it's not different.

Also I really think this kind of thing should wait until plugins can create their own UI elements.

relevant: #5563 (comment)

The askquestion tool is specifically designed for the planning phase, it pauses execution and presents a wizard UI so the AI can gather requirements before starting work, rather than guessing or making assumptions that lead to costly corrections. (token wise, and code debt wise), and this would encourage better system usage & token usage for most users who don't ask questions

With the tool, execution pauses while the user answers all questions in the wizard, then the AI proceeds with complete context. Without it, the AI would need to:

  • Process partial information and make assumptions
  • Possibly generate incorrect output based on those assumptions
  • Cycle back for corrections when assumptions were wrong

This actually reduces hallucinations and wasted tokens because the AI gets clear requirements upfront instead of trying to infer them.

Totally agree this would be better long-term for ui plugins! The askquestion tool is intentionally minimal and backward-compatible while the team figures out how plugin-defined UI widgets would work in the client-server architecture. It can coexist with a proper plugin UI system down the line.

iljod avatar Dec 23 '25 09:12 iljod

@rekram1-node could you perhaps review this? And then I'd make any changes you want :))

iljod avatar Dec 23 '25 13:12 iljod

What's the difference from just asking the model to propose questions in numbered list one question at a time? Does this tool mean that we minimise requests? Otherwise it's not different. Also I really think this kind of thing should wait until plugins can create their own UI elements. relevant: #5563 (comment)

The askquestion tool is specifically designed for the planning phase, it pauses execution and presents a wizard UI so the AI can gather requirements before starting work, rather than guessing or making assumptions that lead to costly corrections. (token wise, and code debt wise), and this would encourage better system usage & token usage for most users who don't ask questions

With the tool, execution pauses while the user answers all questions in the wizard, then the AI proceeds with complete context. Without it, the AI would need to:

* Process partial information and make assumptions

* Possibly generate incorrect output based on those assumptions

* Cycle back for corrections when assumptions were wrong

This actually reduces hallucinations and wasted tokens because the AI gets clear requirements upfront instead of trying to infer them.

Totally agree this would be better long-term for ui plugins! The askquestion tool is intentionally minimal and backward-compatible while the team figures out how plugin-defined UI widgets would work in the client-server architecture. It can coexist with a proper plugin UI system down the line.

Right but I ask again...

what's the difference between asking my model to just give me the questions it wants to me as a numbered list, asking the questions one by one?

I can't really see any difference tbh.

airtonix avatar Dec 24 '25 08:12 airtonix

I like the concept but we also need to consider how other clients besides the TUI will be able to handle these tool calls. Currently in the web/desktop client, when the askquestion tool is called, the session just hangs and has to be resumed from the tui

shuv1337 avatar Dec 24 '25 09:12 shuv1337

Right but I ask again...

what's the difference between asking my model to just give me the questions it wants to me as a numbered list, asking the questions one by one?

I can't really see any difference tbh.

I think what both of these PRs lack to express. Is where this should be going. The way I see it they shouldn't be thought of as a forms. But the end goal here is something like Generative-TUI. What starts as form could become a library of TUI components that would allow the models to render certain information beyond text. I still do not see this as a core feature into OpenCode yet, we probably should add that as a plugin first.

malhashemi avatar Dec 24 '25 09:12 malhashemi

Right but I ask again...

what's the difference between asking my model to just give me the questions it wants to me as a numbered list, asking the questions one by one?

I can't really see any difference tbh.

I think what both of these PRs lack to express. Is where this should be going. The way I see it they shouldn't be thought of as a forms. But the end goal here is something like Generative-TUI. What starts as form could become a library of TUI components that would allow the models to render certain information beyond text. I still do not see this as a core feature into OpenCode yet, we probably should add that as a plugin first.

it's not something i would personally need but it's a core feature in claude code plan mode, so a lot of new-comers have requested it and i think it would help with adoption for that reason alone

shuv1337 avatar Dec 24 '25 10:12 shuv1337

it's not something i would personally need but it's a core feature in claude code plan mode, so a lot of new-comers have requested it and i think it would help with adoption for that reason alone

I'm one of them. This feature is very helpful in Claude Code and I will be very glad to see it in OpenCode. In Claude Code, it sometimes asks very precise questions that I wouldn't have thought of myself.

Kolger avatar Dec 24 '25 11:12 Kolger

Hi guys, great feature thank you!

I was testing this PR locally and I noticed that if I have text inserted but not sent, in plan mode.

When askquestiontool is triggered - I lose all text in the textbox that I was working on.

Small detail, but can be quite frustrating if I am queuing up the next message (possibly waiting for the current work to finish before I hit enter).

cosier avatar Dec 27 '25 04:12 cosier

@airtonix

Right but I ask again...

what's the difference between asking my model to just give me the questions it wants to me as a numbered list, asking the questions one by one?

I can't really see any difference tbh.

It's purely DX. It's one of the best features added to Claude Code IMO, because it allows you to quickly select different options (which would require a good bit of typing otherwise).

When I'm running a plan and I have the agent ask me questions, it helps to be able to pick between two options or provide a nice "explainer" for the agent if the options it provided aren't quite good enough.

Are you asking why people would want this? If so, that's your answer. It's a highly regarded feature of Claude Code.

eXamadeus avatar Dec 28 '25 20:12 eXamadeus

I agree, I loved the code claude plan with questions, the only thing I'm missing from it to be honest just using opencode day-to-day. but the screenshots shown in the post here are actually not good: CleanShot 2025-12-30 at 15 07 47@2x

the point is to be very precise with the questions, give great options, and good explanations of pros/cons of all. listing "what db you want" or "what are you building" with options makes no sense to be honest. those are way too high level questions.. not sure if this was just bad example done quickly to demo it, or is there a fundamental difference on what questions it asks and what answers it provides

lgandecki avatar Dec 30 '25 14:12 lgandecki

This is such a killer feature in Claude Code and as my "Holiday Gifted 2xLimits" ran out I'm looking for alternatives, so far opencode looks like a good fit. But I use AskUserQuestion a lot in my prompts to have the LLM generate options and give me this super intuitive tabbed interface to jump between questions and choose one of the LLM Generated options or combine them with my own twist.

To the people who repeatedly ask how this is different from going into different turns with the LLM to answer questions: Try out claude code first and come back!

As I just highlighted, the ability to pick an answer, tab to the next question, realise that this question provides another angle the LLM already thought off that I didn't and go back to the previous tab to adjust my answer is JUST ONE OF MANY examples where having this tool for the LLM is vastly superior!

Not only that, but read also Anthropic and Cloudflare papers on the problem with MCP tool calls (passing the conversation back and forth between user and LLM repeatedly) versus having a single call resolve multiple questions and sending those answers back in one turn! It's so much faster, keeps the interaction snappy and honestly shows why CC is leading other Agent Shells by far.

Until this feature is in OpenCode, I'm afraid I will have to stay with Claude Code!

OpenCode is super promising and I'm happy I gave it try this holiday season!

so0k avatar Jan 01 '26 04:01 so0k

Are you asking why people would want this? If so, that's your answer. It's a highly regarded feature of Claude Code.

I think this kind of thinking is a logical fallacy. Appeal to authority I think it is.

I can see why lots of people would like it.

I don't understand why it needs to be in core.

How do I disable it?

If everything goes in core then we're back in the box of poorly named booleans to disable things.

The plugin system already enables this... That's already a feature flag system.

I 💯 encourage all ideas, just not in core.

The only thing in core I'm enthusiastic about is things that expand the capability of what plugins can do (in a way that is uniform across all three modes)

airtonix avatar Jan 01 '26 16:01 airtonix

The plugin system already enables this... That's already a feature flag system.

no it doesn't, but with https://github.com/sst/opencode/issues/6330 it might

anyone reading this discussion would appreciate the design proposal there to ensure plugins can provide AskUserTool and more

so0k avatar Jan 01 '26 16:01 so0k

The plugin system already enables this... That's already a feature flag system.

no it doesn't, but with https://github.com/sst/opencode/issues/6330 it might

anyone reading this discussion would appreciate the design proposal there to ensure plugins can provide AskUserTool and more

Glad you see my point.

The plugin system is open codes strength above all the others.

If I don't want this I simply didn't install the plugin

airtonix avatar Jan 01 '26 16:01 airtonix

@eXamadeus

When I'm running a plan and I have the agent ask me questions, it helps to be able to pick between two options or provide a nice "explainer" for the agent if the options it provided aren't quite good enough.

I can already do this without this pr though.

airtonix avatar Jan 01 '26 16:01 airtonix

Glad you see my point.

and can you at least try to see ours too? Thanks, I think we can close this thread as mentioned the proposal to add plugin support for this type of feature is promising

so0k avatar Jan 01 '26 16:01 so0k

and can you at least try to see ours too?

Not really. I don't think this UI feature needs to be rushed into core.

Biggest issue I have is that I can already get this feature without a UI implementation with much richer and more flexible interaction.

think we can close this thread as mentioned the proposal to add plugin support for this type of feature is promising

That isn't how github works.

Not only that, but read also Anthropic and Cloudflare papers on the problem with MCP tool calls (passing the conversation back and forth between user and LLM repeatedly) versus having a single call resolve multiple questions and sending those answers back in one turn! It's so much faster, keeps the interaction snappy and honestly shows why CC is leading other Agent Shells by far.

@so0k It'd be great if you could link to this information.

you seem to be indicating that this particular PR does something to reduce the amount of LLM requests?

Questions I have around this kind of UI feature is:

  • how does it work out how to disect the initial LLM response into sections and answers? a. Does it transform the user prompt when question like phrases are detected to try to force the LLM to repsond in a particular format? b. Does it make extra llm requests to work this out? c. Or are is there some code here that tries to do RegEx.

But overall:

Any of these approaches just makes me feel:

  • If it's in core, i can't disable it
  • I don't get to control the style of Q&A format
  • Does it break opencode run '/q-an-a-json-format @current-questions-state.txt, continue asking in a Q&A format one question at a time' ?

airtonix avatar Jan 01 '26 23:01 airtonix

hey thanks for taking a swing at this - this is one of our most requested features so we will be adding this functionality

given that it'll be one of the most complex UX interactions in the product we'll need to look at it from scratch - hopefully next week!

thdxr avatar Jan 03 '26 06:01 thdxr

@so0k It'd be great if you could link to this information.

Sure - Anthropic Blog Post - Section on Intermediate Result Token consumption which links to CloudFlare Research.

so0k avatar Jan 03 '26 07:01 so0k

FWIW @airtonix I'm in agreement that this PR is not the way to go. I much prefer the proposed approach in #6330 for the core intent layer.

eXamadeus avatar Jan 03 '26 08:01 eXamadeus

Not really. I don't think this UI feature needs to be rushed into core.

yeah that's not what I meant, we all agree the proposal I linked seems like the way to go

so0k avatar Jan 03 '26 14:01 so0k