Skip to content

fix(question): let the model set custom on a question - #45236

Closed
harshil-mistry wants to merge 1 commit into
anomalyco:devfrom
harshil-mistry:fix-question-custom-reachable
Closed

harshil-mistry wants to merge 1 commit into
anomalyco:devfrom
harshil-mistry:fix-question-custom-reachable

Conversation

@harshil-mistry

Copy link
Copy Markdown

Issue for this PR

Closes #45230

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The question tool's "Type your own answer" input cannot be turned off, even though the renderer implements the switch and the tool description advertises it.

custom was declared on QuestionV2.Info, but both tools accept QuestionV2.Prompt, which is Schema.Struct(base) and does not include it:

  • packages/opencode/src/tool/question.ts:7 — Schema.mutable(Schema.Array(Question.Prompt))
  • packages/core/src/tool/question.ts:26 — Schema.Array(QuestionV2.Prompt)

So custom never appears in the JSON schema the model sees, and a custom: false emitted anyway would be dropped as an excess property. Grepping the repo, nothing assigns custom anywhere — the only reader is packages/tui/src/routes/session/question.tsx:38:

const custom = createMemo(() => question()?.custom !== false)

The value is always undefined, so custom !== false is always true and the input is always shown. Info.custom, its description, and that !== false guard are all live code for a state that cannot occur.

Meanwhile question.txt tells the model:

When custom is enabled (default), a "Type your own answer" option is added automatically

"(default)" implies a reachable alternative.

The fix moves custom into base so it reaches Prompt. Info spreads base, so its shape is unchanged and nothing that consumes Info needs to change — the field simply becomes settable by the party that creates questions. Both the v1 and v2 tools pick it up, since both build their input from Prompt.

The alternative was to delete custom, the guard, and the sentence from both descriptions. I went the other way because the rendering side is already complete and correct; only the input schema was missing the field. If the intent was for custom to be host-controlled rather than model-controlled, say so and I will send the removal instead.

How did you verify your code works?

packages/schema/src/question.ts parses clean under bun build --no-bundle (bun 1.4.0).

I traced the field end to end before changing anything:

  • Producers — the only two are the v1 and v2 question tools, both typed on Prompt. A repo-wide grep for custom: outside unrelated identifiers (customBorderChars, CUSTOM_PROVIDER_OPTION_VALUE, formatter/LSP config named custom) returns no assignment to a question's custom.
  • Transport — QuestionV2.Request.questions is Schema.Array(Info), which already carries custom, so widening Prompt needs no change there. Prompt becoming structurally equal to Info is fine because custom is optional.
  • Consumer — question.tsx:38 reads it and defaults to shown, which is the behaviour that is preserved when the field is omitted.

So the change is additive: omitting custom behaves exactly as today, and supplying false now reaches the guard that was already written for it.

Screenshots / recordings

No visual change unless a caller opts out, which was previously impossible.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

custom was declared on Info but the tools accept Prompt, so it never
reached the model-facing schema and nothing in the repo ever set it.
The renderer's `question()?.custom !== false` guard was therefore always
true and the "Type your own answer" input could not be turned off,
despite the tool description presenting it as a default.

Moving it into `base` reaches Prompt while leaving Info's shape
unchanged.

Closes anomalyco#45230
@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

question tool: custom answer option cannot be disabled because "custom" is missing from the Prompt schema

1 participant