Skip to content

feat(plugin): add interactive question() tool-context method with prefilled answers - #43059

Closed
SaeedAqamiri wants to merge 2 commits into
anomalyco:devfrom
SaeedAqamiri:question-interactive
Closed

SaeedAqamiri wants to merge 2 commits into
anomalyco:devfrom
SaeedAqamiri:question-interactive

Conversation

@SaeedAqamiri

@SaeedAqamiri SaeedAqamiri commented Aug 17, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #43068 (notebook memory feature) — the interactive question() review/edit helper powers the notebook notes_commit approval UX (a proposed summary, editable by the user, per note).

Type of change

  • New feature

What does this PR do?

Adds question() to the plugin ToolContext: presents the same modal as the question tool and resolves with the selected labels per question, in order, rejecting when the user dismisses the modal. Bridged to Question.Service in the registry. QuestionInfo gains an optional default that pre-fills the custom answer textarea, enabling review/edit workflows. The app question dock pre-fills from default; v1 + v2 schema and generated sdk types carry the field.

How did you verify your code works?

  • bun typecheck green.
  • The default pre-fill is additive to the existing question dock.

Screenshots / recordings

N/A — no visual change beyond the pre-filled textarea in an existing modal.

Checklist

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

…filled answers

Add a question() method to ToolContext that presents the same modal as the
question tool and resolves with the selected labels (rejects on dismiss),
bridged to Question.Service in the registry. QuestionInfo gains an optional
default that pre-fills the custom answer textarea for review/edit workflows
(app + v1/v2 schema + generated sdk types).
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Aug 17, 2026
@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Aug 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

  • packages/app/src/pages/session/composer/session-question-dock.tsx:113 — The prefill effect tracks store.custom[tab], so the moment a user deliberately clears the textarea the effect re-runs, sees "" again, and re-inserts the proposal — the field can never be emptied while a default exists; gate on a per-(request,tab) "already prefilled" marker instead of re-reading the live value.
  • packages/app/src/pages/session/composer/session-question-dock.tsx:119 — The prefill sets customOn to true without checking whether the question allows custom answers at all (custom?: false hides the textarea), leaving the dock in a state where a hidden field is marked active and submitted content may come from an invisible prefill; bail out early when question().custom === false.
  • packages/opencode/src/tool/registry.ts:153 — The plugin→schema mapping (including default passthrough and the callID-optional tool reference) has no test; one unit case asserting the exact QuestionService.ask payload — plus a variant without toolCtx.callID — would pin both branches before plugins start depending on them.
  • packages/plugin/src/tool.ts:55 — Documented rejection-on-dismiss is good, but nothing states whether resolution ORDER matches input order across multiple:true selections; since callers will zip questions with answers by index, say so explicitly in the JSDoc.

— AI code review (automated)

@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

  • packages/opencode/src/tool/registry.ts:152 (question) — good bridge reuse: plugins get the exact same modal + answer pipeline as the built-in question tool, including tool-call attribution via callID.
  • Contract check worth confirming: the JSDoc promises rejection "if the user dismisses the modal" — verify Question.Service.ask actually rejects (vs resolving empty) on dismissal, since a resolve-with-empty would silently hand plugins [] answers and break that documented behavior.
  • packages/app/src/pages/session/composer/session-question-dock.tsx:111 — prefill guards are right: skips when custom mode already on or field non-empty, and the customOn latch prevents re-filling after the user deliberately clears the text. Nice.
  • packages/plugin/src/tool.ts:41 — QuestionAnswer = ReadonlyArray<string> reads like a single answer list per question but the method returns an array of these (one per question); consider naming it QuestionAnswers or documenting the outer/inner distinction to avoid misuse.
  • Schema addition is optional and backward compatible in both v1/v2; SDK types regenerated accordingly.

- session-question-dock: prefill proposed content at most once per tab via a
  latch (clearing the field or toggling customOn can no longer re-insert the
  proposal), and bail when question().custom === false so a hidden field is
  not silently marked as an active answer.
- plugin/tool.ts: document that answers resolve in input order (callers zip
  by index) and that multiple:true yields all selected labels.
- registry.test.ts: unit test pinning the exact QuestionService.ask payload the
  plugin question() bridge forwards, for both with- and without-callID contexts.
@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.

@SaeedAqamiri

Copy link
Copy Markdown
Author

Still active. The automated review feedback is addressed: the custom-field prefill now latches once per tab (clearing the field no longer re-inserts the proposal) and bails when custom === false; the answer-order contract is documented; and a unit test pins the exact QuestionService.ask payload for both the with- and without-callID contexts. Part of the notebook memory proposal in #43068. Could a maintainer please reopen it for human review?

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.

[FEATURE] Per-folder notebook memory (notes_get/notes_commit) for the agent

2 participants