Skip to content

Add planning_questionnaire to the agent mode#2566

Merged
wwwillchen merged 15 commits into
dyad-sh:mainfrom
azizmejri1:questionnaire-agent-mode
Feb 23, 2026
Merged

Add planning_questionnaire to the agent mode#2566
wwwillchen merged 15 commits into
dyad-sh:mainfrom
azizmejri1:questionnaire-agent-mode

Conversation

@azizmejri1

@azizmejri1 azizmejri1 commented Feb 8, 2026

Copy link
Copy Markdown
Collaborator

Summary by cubic

Enable planning_questionnaire in normal agent mode and enforce a clarify‑before‑plan workflow with explicit examples. Also adds a one‑pass todo follow‑up so the agent completes remaining tasks before stopping.

  • New Features

    • planning_questionnaire is available in both plan and normal modes.
    • Clarify step: call planning_questionnaire to ask 1–3 focused questions for vague requests; skip when specific; STOP until the user replies. Always use it for new app/major feature requests.
    • One-pass todo follow-up: if a turn ends with incomplete todos, inject a short reminder and run another pass to finish them.
  • Bug Fixes

    • Always stop after planning_questionnaire in both modes to prevent repeated tool calls.
    • Gate plan-only tools: write_plan and exit_plan are plan‑mode only; questionnaire remains available in normal mode.

Written for commit c6a67ea. Summary will update on new commits.


Open with Devin

@wwwillchen

Copy link
Copy Markdown
Collaborator

@BugBot run

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @azizmejri1, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the agent's ability to interact with users by integrating a crucial clarification step into its core workflow. By making the planning_questionnaire tool universally available and explicitly requiring its use for ambiguous requests, the agent can proactively gather necessary information, leading to more accurate problem understanding and more effective task execution from the outset.

Highlights

  • Expanded Tool Availability: The planning_questionnaire tool is now available in the agent's normal operating mode, not just in explicit plan mode, allowing for upfront clarification of user requirements.
  • Enhanced Agent Workflow: A new "Clarify (REQUIRED)" step has been added to the agent's development workflow prompt, mandating the use of planning_questionnaire to gather requirements before proceeding with planning.
  • Refactored Tool Management: Tool definitions were refactored to distinguish between tools that are generally planning-specific but can modify state, and those strictly exclusive to plan mode, improving clarity and control over tool access.
  • Improved Stop Conditions: The agent's execution stopWhen conditions were updated to ensure it always yields control to the user immediately after calling the planning_questionnaire tool, preventing unwanted tool chaining.
Changelog
  • src/pro/main/ipc/handlers/local_agent/local_agent_handler.ts
    • Modified the stopWhen array to unconditionally include hasToolCall(planningQuestionnaireTool.name), ensuring the agent pauses after presenting a questionnaire in any mode.
    • Adjusted the conditional inclusion of writePlanTool and exitPlanTool to only apply when planModeOnly is true.
  • src/pro/main/ipc/handlers/local_agent/tool_definitions.ts
    • Updated the JSDoc comment for PLANNING_SPECIFIC_TOOLS to reflect that these tools are allowed in plan mode despite modifying state.
    • Introduced a new constant PLAN_MODE_ONLY_TOOLS to specifically list tools that should only be available in plan mode, explicitly excluding planning_questionnaire.
    • Updated the buildAgentToolSet function to filter tools based on PLAN_MODE_ONLY_TOOLS when not in plan mode.
  • src/pro/main/ipc/handlers/local_agent/tools/planning_questionnaire.ts
    • Revised the DESCRIPTION constant for the planningQuestionnaire tool, removing the phrase "during the planning phase" to reflect its broader applicability.
  • src/prompts/local_agent_prompt.ts
    • Inserted a new step, "2. Clarify (REQUIRED):", into the PRO_DEVELOPMENT_WORKFLOW_BLOCK. This step instructs the agent to use planning_questionnaire for ambiguous requests and to wait for user responses before proceeding.
    • Re-numbered subsequent steps in the workflow block.
Activity
  • The pull request was opened by azizmejri1.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully extends the planning_questionnaire tool to be available in the standard agent mode, not just in plan mode. This allows the agent to proactively ask clarifying questions before starting implementation, which should improve its performance on ambiguous tasks. The changes are well-executed across the board: the agent's stopping condition is updated, tool definitions are refactored for clarity, and the system prompt is modified to instruct the agent on this new workflow step. The implementation is clean and logical. I have no specific comments as the changes are solid.

@github-actions

github-actions Bot commented Feb 8, 2026

Copy link
Copy Markdown
Contributor

🔍 Multi-Agent Code Review

Found 5 issue(s) flagged by consensus of 3 independent reviewers.

Summary

Severity Count
🔴 HIGH 0
🟡 MEDIUM 3
🟢 LOW 2

Issues to Address

Severity File Issue
🟡 MEDIUM src/pro/main/ipc/handlers/local_agent/tool_definitions.ts:311 PLANNING_SPECIFIC_TOOLS and PLAN_MODE_ONLY_TOOLS can drift out of sync
🟡 MEDIUM src/prompts/local_agent_prompt.ts:86 Clarify step too aggressive — MUST call + stopWhen halt forces round-trip even for trivial requests
🟡 MEDIUM src/prompts/local_agent_prompt.ts:86 Basic agent mode gets the tool available but no prompt guidance to use it
🟢 Low Priority Issues (2 items)
  • Trailing space in tool descriptionsrc/pro/main/ipc/handlers/local_agent/tools/planning_questionnaire.ts:61"from the user ." has an extra space before the period
  • Trailing space in promptsrc/prompts/local_agent_prompt.ts:86"completely unambiguous ." has an extra space before the period

See inline comments for details on MEDIUM issues.

Generated by multi-agent consensus review (3 agents, 2+ agreement threshold)

github-actions[bot]

This comment was marked as resolved.

github-actions[bot]

This comment was marked as resolved.

github-actions[bot]

This comment was marked as resolved.

@wwwillchen

Copy link
Copy Markdown
Collaborator

@BugBot run

@wwwillchen

Copy link
Copy Markdown
Collaborator

@BugBot run

github-actions[bot]

This comment was marked as resolved.

github-actions[bot]

This comment was marked as resolved.

github-actions[bot]

This comment was marked as resolved.

github-actions[bot]

This comment was marked as resolved.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Dyadbot Code Review Summary

Found 1 new issue(s) flagged by 3 independent reviewers.
(2 issue(s) skipped — already commented)

Summary

Severity Count
🔴 HIGH 0
🟡 MEDIUM 1
🟢 LOW 0

Issues to Address

Severity File Issue
🟡 MEDIUM src/pro/main/ipc/handlers/local_agent/tools/planning_questionnaire.ts:61 Trailing space before period in tool description
🟢 Low Priority Issues (5 items — not consensus, single-agent only)
  • Unnecessary commit/deploy attempt after questionnairesrc/pro/main/ipc/handlers/local_agent/local_agent_handler.ts:823 (Correctness)
  • planning_questionnaire excluded from readOnly/ask modesrc/pro/main/ipc/handlers/local_agent/tool_definitions.ts:352 (Correctness)
  • Clarify step duplicates tool description contentsrc/prompts/local_agent_prompt.ts:95 (Code Health)
  • Tool name "planning_questionnaire" is now misleadingsrc/pro/main/ipc/handlers/local_agent/tools/planning_questionnaire.ts:106 (Code Health)
  • IPC channel still named 'plan:questionnaire'src/pro/main/ipc/handlers/local_agent/tools/planning_questionnaire.ts:120 (UX)

See inline comments for details.

Generated by Dyadbot multi-agent code review (3 independent reviewers with consensus voting)

github-actions[bot]

This comment was marked as resolved.

@github-actions github-actions Bot added the needs-human:review-issue ai agent flagged an issue that requires human review label Feb 12, 2026
@wwwillchen

Copy link
Copy Markdown
Collaborator

@BugBot run

@github-actions

github-actions Bot commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Dyadbot Code Review Summary

Found 7 consensus issue(s) flagged by 2+ of 3 independent reviewers.

Summary

Severity Count
🟡 MEDIUM 7

Issues to Address

Severity File Issue
🟡 MEDIUM src/pro/main/ipc/handlers/local_agent/prepare_step_utils.ts:35 Magic string "incomplete todo(s)" coupling between production and test code
🟡 MEDIUM src/renderer.tsx:95 Telemetry sampling reads stale localStorage on first load
🟡 MEDIUM src/components/ChatPanel.tsx:87 Double requestAnimationFrame without cleanup can cause stale scroll operations
🟡 MEDIUM src/components/ChatModeSelector.tsx:128 Mode selector color/icon logic has dead default branch
🟡 MEDIUM src/components/chat/MessagesList.tsx:350 Removing right/bottom padding from messages list may clip content
🟡 MEDIUM src/pro/main/ipc/handlers/local_agent/local_agent_handler.ts:858 passEndedWithText check may trigger wasted follow-up pass on failed stream
🟡 MEDIUM src/components/chat/ChatInput.tsx:428 Inconsistent outer padding between ChatInput (p-2 pt-0) and HomeChatInput (p-4)
🟢 Low Priority Issues (5 items)
  • Misleading comment about passEndedWithText reliability - src/pro/main/ipc/handlers/local_agent/local_agent_handler.ts:858
  • SAFE_PIPE_PATTERN duplicated between hook files - .claude/hooks/python-permission-hook.py:69
  • HomeChatInput has hover:border-primary/30 but ChatInput does not - src/components/chat/HomeChatInput.tsx:90
  • DropdownMenuTrigger (Wrench icon) has no accessible label - src/app/TitleBar.tsx:231
  • Double requestAnimationFrame needs a 'why' comment - src/components/ChatPanel.tsx:97

See inline comments for details on MEDIUM issues.

Generated by Dyadbot multi-agent code review (3 agents, consensus voting)

github-actions[bot]

This comment was marked as resolved.

github-actions[bot]

This comment was marked as resolved.

Comment on lines +108 to +110
<p className="text-sm text-foreground/90 leading-relaxed">
{current.answer}
</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM | edge-cases-in-ui

Long answers overflow without wrapping or truncation

The answer text is rendered in a simple <p> tag with no overflow handling. If a user provides a very long free-text answer (e.g., multiple paragraphs), or if checkbox answers are concatenated into a long string, the card will expand vertically without limit, pushing other content down and making the questionnaire response card hard to scan.

💡 Suggestion: Add max-h-32 overflow-y-auto or a "show more" toggle for long answers:

Suggested change
<p className="text-sm text-foreground/90 leading-relaxed">
{current.answer}
</p>
<p className="text-sm text-foreground/90 leading-relaxed max-h-32 overflow-y-auto">
{current.answer}
</p>

@github-actions

Copy link
Copy Markdown
Contributor

🎭 Playwright Test Results

❌ Some tests failed

OS Passed Failed Flaky Skipped
🍎 macOS 356 1 3 115
🪟 Windows 361 0 8 115

Summary: 717 passed, 1 failed, 11 flaky, 230 skipped

Failed Tests

🍎 macOS

  • setup_flow.spec.ts > Setup Flow > node.js install flow
    • Error: expect(locator).toBeVisible() failed

📋 Re-run Failing Tests (macOS)

Copy and paste to re-run all failing spec files locally:

npm run e2e \
  e2e-tests/setup_flow.spec.ts

⚠️ Flaky Tests

🍎 macOS

  • free_agent_quota.spec.ts > free agent quota - quota resets after 24 hours (passed after 1 retry)
  • refresh.spec.ts > preview navigation - forward and back buttons work (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > setup banner shows correct state when node.js is installed (passed after 1 retry)

🪟 Windows

  • chat_tabs.spec.ts > closing a tab removes it and selects adjacent tab (passed after 1 retry)
  • chat_tabs.spec.ts > right-click context menu: Close other tabs (passed after 1 retry)
  • chat_tabs.spec.ts > right-click context menu: Close tabs to the right (passed after 1 retry)
  • context_manage.spec.ts > manage context - exclude paths with smart context (passed after 1 retry)
  • partial_response.spec.ts > partial message is resumed (passed after 2 retries)
  • reject.spec.ts > reject (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > setup banner shows correct state when node.js is installed (passed after 1 retry)
  • template-create-nextjs.spec.ts > create next.js app (passed after 1 retry)

📊 View full report

@wwwillchen wwwillchen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! looks good, just a couple more changes needed:

  1. Let's have planning questionnaire work for all users (not just pro users) in agent modes.
  2. The dismiss questionnaire looks a little out of place, especially if the chat width is small (see screenshot below). let's instead move it to the top-right corner.
Image

@wwwillchen

Copy link
Copy Markdown
Collaborator

@BugBot run

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

24 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 557 to 564
stopWhen: [
stepCountIs(25),
hasToolCall(addIntegrationTool.name),
// In plan mode, stop immediately after presenting a questionnaire,
// writing a plan, or exiting plan mode so the agent yields control
// back to the user. Without this, some models (e.g. Gemini Pro 3)
// ignore the prompt-level "STOP" instruction and keep calling tools
// in a loop.
// In plan mode, also stop after writing a plan or exiting plan mode.
...(planModeOnly
? [
hasToolCall(planningQuestionnaireTool.name),
hasToolCall(writePlanTool.name),
hasToolCall(exitPlanTool.name),
]
? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
: []),
],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical: Agent continues after planning_questionnaire completes

planning_questionnaire was removed from stopWhen in both modes. While the tool blocks during user input (via waitForQuestionnaireResponse), once the user responds, the tool returns and the agent can continue making tool calls in the same turn.

This contradicts the PR description: "Always stop after planning_questionnaire in both modes to prevent repeated tool calls."

Expected behavior: Agent should yield control to user after questionnaire
Actual behavior: Agent continues executing after receiving questionnaire responses

The old code correctly included hasToolCall(planningQuestionnaireTool.name) in stopWhen for plan mode. It needs to be added for BOTH modes:

Suggested change
stopWhen: [
stepCountIs(25),
hasToolCall(addIntegrationTool.name),
// In plan mode, stop immediately after presenting a questionnaire,
// writing a plan, or exiting plan mode so the agent yields control
// back to the user. Without this, some models (e.g. Gemini Pro 3)
// ignore the prompt-level "STOP" instruction and keep calling tools
// in a loop.
// In plan mode, also stop after writing a plan or exiting plan mode.
...(planModeOnly
? [
hasToolCall(planningQuestionnaireTool.name),
hasToolCall(writePlanTool.name),
hasToolCall(exitPlanTool.name),
]
? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
: []),
],
stopWhen: [
stepCountIs(25),
hasToolCall(addIntegrationTool.name),
hasToolCall("planning_questionnaire"),
// In plan mode, also stop after writing a plan or exiting plan mode.
...(planModeOnly
? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
: []),
],
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/pro/main/ipc/handlers/local_agent/local_agent_handler.ts
Line: 557-564

Comment:
**Critical: Agent continues after `planning_questionnaire` completes**

`planning_questionnaire` was removed from `stopWhen` in both modes. While the tool blocks during user input (via `waitForQuestionnaireResponse`), once the user responds, the tool returns and the agent can continue making tool calls in the same turn.

This contradicts the PR description: "Always stop after `planning_questionnaire` in both modes to prevent repeated tool calls."

**Expected behavior**: Agent should yield control to user after questionnaire
**Actual behavior**: Agent continues executing after receiving questionnaire responses

The old code correctly included `hasToolCall(planningQuestionnaireTool.name)` in `stopWhen` for plan mode. It needs to be added for BOTH modes:

```suggestion
        stopWhen: [
          stepCountIs(25),
          hasToolCall(addIntegrationTool.name),
          hasToolCall("planning_questionnaire"),
          // In plan mode, also stop after writing a plan or exiting plan mode.
          ...(planModeOnly
            ? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
            : []),
        ],
```

How can I resolve this? If you propose a fix, please make it concise.

azizmejri1 and others added 15 commits February 22, 2026 04:02
- Remove debug onXmlComplete output from planning_questionnaire (HIGH)
- Fix tool-error field: read part.error instead of part.output
- Add Zod .refine() to enforce options for radio/checkbox questions
- Derive PLAN_MODE_ONLY_TOOLS from PLANNING_SPECIFIC_TOOLS to prevent drift
- Filter planning_questionnaire from basic agent mode toolset
- Add aria-label and aria-expanded to QuestionnaireInput buttons
- Update stale snapshot for local_agent_prompt test

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wwwillchen

Copy link
Copy Markdown
Collaborator

@BugBot run

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

24 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 557 to 564
stopWhen: [
stepCountIs(25),
hasToolCall(addIntegrationTool.name),
// In plan mode, stop immediately after presenting a questionnaire,
// writing a plan, or exiting plan mode so the agent yields control
// back to the user. Without this, some models (e.g. Gemini Pro 3)
// ignore the prompt-level "STOP" instruction and keep calling tools
// in a loop.
// In plan mode, also stop after writing a plan or exiting plan mode.
...(planModeOnly
? [
hasToolCall(planningQuestionnaireTool.name),
hasToolCall(writePlanTool.name),
hasToolCall(exitPlanTool.name),
]
? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
: []),
],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical: Agent continues after planning_questionnaire completes

planning_questionnaire was removed from stopWhen for both modes. The tool calls waitForQuestionnaireResponse (line 149 in planning_questionnaire.ts) which blocks until user input, but once the user responds and the tool returns, the agent can continue making additional tool calls in the same turn.

This contradicts the PR description: "Always stop after planning_questionnaire in both modes to prevent repeated tool calls."

Expected: Agent yields control to user after questionnaire
Actual: Agent continues executing after receiving responses

Add hasToolCall(PLANNING_QUESTIONNAIRE_TOOL_NAME) to the stopWhen array for BOTH modes:

Suggested change
stopWhen: [
stepCountIs(25),
hasToolCall(addIntegrationTool.name),
// In plan mode, stop immediately after presenting a questionnaire,
// writing a plan, or exiting plan mode so the agent yields control
// back to the user. Without this, some models (e.g. Gemini Pro 3)
// ignore the prompt-level "STOP" instruction and keep calling tools
// in a loop.
// In plan mode, also stop after writing a plan or exiting plan mode.
...(planModeOnly
? [
hasToolCall(planningQuestionnaireTool.name),
hasToolCall(writePlanTool.name),
hasToolCall(exitPlanTool.name),
]
? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
: []),
],
stopWhen: [
stepCountIs(25),
hasToolCall(addIntegrationTool.name),
hasToolCall(PLANNING_QUESTIONNAIRE_TOOL_NAME),
// In plan mode, also stop after writing a plan or exiting plan mode.
...(planModeOnly
? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
: []),
],
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/pro/main/ipc/handlers/local_agent/local_agent_handler.ts
Line: 557-564

Comment:
**Critical: Agent continues after `planning_questionnaire` completes**

`planning_questionnaire` was removed from `stopWhen` for both modes. The tool calls `waitForQuestionnaireResponse` (line 149 in planning_questionnaire.ts) which blocks until user input, but once the user responds and the tool returns, the agent can continue making additional tool calls in the same turn.

This contradicts the PR description: "Always stop after `planning_questionnaire` in both modes to prevent repeated tool calls."

**Expected**: Agent yields control to user after questionnaire
**Actual**: Agent continues executing after receiving responses

Add `hasToolCall(PLANNING_QUESTIONNAIRE_TOOL_NAME)` to the `stopWhen` array for BOTH modes:

```suggestion
        stopWhen: [
          stepCountIs(25),
          hasToolCall(addIntegrationTool.name),
          hasToolCall(PLANNING_QUESTIONNAIRE_TOOL_NAME),
          // In plan mode, also stop after writing a plan or exiting plan mode.
          ...(planModeOnly
            ? [hasToolCall(writePlanTool.name), hasToolCall(exitPlanTool.name)]
            : []),
        ],
```

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd18dac76d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/renderer.tsx
Comment on lines +222 to +226
setPendingQuestionnaire((prev) => {
if (!prev.has(chatId)) return prev;
const next = new Map(prev);
next.delete(chatId);
return next;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve questionnaire until matching stream/request completes

This unconditionally drops the active questionnaire on any chat:stream:end for the chat, but chat:stream:end is not tied to a specific request and overlapping streams are possible (the stream handler keys only by chatId). If an older stream ends after a newer stream has already opened a questionnaire, the UI banner disappears while waitForQuestionnaireResponse in main is still pending, leaving the user unable to answer and the agent stalled until timeout.

Useful? React with 👍 / 👎.

Comment on lines +176 to +178
const next = new Map(prev);
next.set(payload.chatId, payload);
return next;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Key pending questionnaires by request id

Storing only one questionnaire per chatId means a newer questionnaire overwrites an older one from the same chat. The backend waits per requestId, so if the model emits multiple planning_questionnaire calls in one turn, only the last prompt is answerable in the UI and earlier requests remain unresolved until timeout, blocking completion of that turn.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Dyadbot Code Review Summary

Verdict: ✅ YES - Ready to merge

Reviewed by 3 independent agents: Correctness Expert, Code Health Expert, UX Wizard.

Issues Summary

Severity File Issue
🟡 MEDIUM src/components/chat/QuestionnaireInput.tsx:203 Nested setTimeout chain leaks on unmount
🟡 MEDIUM src/components/chat/QuestionnaireInput.tsx:90 Auto-dismiss after 5 min gives no warning
🟢 Low Priority Notes (7 items)
  • Empty PRO_AGENT_ONLY_TOOLS set is dead infrastructure - src/pro/main/ipc/handlers/local_agent/tool_definitions.ts:394 — Set is never populated, so basicAgentMode flag and its filter branch have no effect
  • Regex parser assumes fixed XML attribute order - src/components/chat/DyadQuestionnaire.tsx:25parseQAEntries regex requires question before type; will break if attribute order changes in the producer
  • let result should be const - src/pro/main/ipc/handlers/local_agent/local_agent_handler.ts:628 — Variable is never reassigned
  • Non-standard Tailwind class syntax - src/components/chat/DyadQuestionnaire.tsx:85bg-(--background-lightest) may not work in all Tailwind configurations
  • Frontend/backend 5-min timeout duplication - src/components/chat/QuestionnaireInput.tsx:101 — Same 5 * 60 * 1000 hardcoded in both frontend and backend with no shared constant
  • Dot navigation indicators below WCAG touch target size - src/components/chat/DyadQuestionnaire.tsx:119 — 6px inactive dots are well below the 44px minimum recommended touch target
  • 'Answers submitted' has no aria-live announcement - src/components/chat/MessagesList.tsx:228 — Screen readers won't announce the brief confirmation
🚫 Dropped False Positives (6 items)
  • part.output vs part.result for tool-result — Dropped: Already covered by existing comment about wrong field names in getPlanningQuestionnaireErrorFromStep
  • QuestionSchema id required vs optional mismatch — Dropped: Already covered by existing comment about duplicate QuestionSchema drift
  • isRecord returns true for arrays — Dropped: Theoretical; step.content elements are always objects, never nested arrays
  • Single-question shows heavy UI, multi-question forces pagination — Dropped: Design choice; 1-3 questions is a small fixed set, pagination is reasonable
  • No review step before final submit — Dropped: Back button is available and only 1-3 questions; design choice
  • Dismissing gives no feedback about consequences — Dropped: Already covered by existing comment about dismiss having no confirmation

Generated by Dyadbot multi-agent code review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multi-agent review: 2 new issue(s) found

return next;
});
}, 300);
}, 1700);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM | interaction

Nested setTimeout chain leaks on unmount

The nested setTimeout calls in handleSubmit (1700ms outer, then 300ms inner) are fire-and-forget — they are not cleaned up if the component unmounts or the user navigates to a different chat. This can cause setSubmittedChatIds to update state for a chat the user is no longer viewing, and in React strict mode may trigger "can't update unmounted component" warnings.

💡 Suggestion: Store the timeout IDs in a ref and clear them in a useEffect cleanup, or move the animation state machine into a useEffect that watches the questionnaireSubmittedChatIdsAtom state.

});
clearQuestionnaire();
},
5 * 60 * 1000,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM | interaction

Auto-dismiss after 5 minutes gives no warning to the user

The questionnaire silently disappears after 5 minutes with no countdown or warning. A user who stepped away or is thinking about their answers will return to find the questionnaire gone and their in-progress answers lost. The agent will then receive a null response indicating dismissal, which may confuse the user since they did not intentionally dismiss it.

💡 Suggestion: Show a countdown indicator or at least a warning toast (e.g., at 30 seconds remaining) so the user knows the questionnaire is about to expire.

@github-actions

Copy link
Copy Markdown
Contributor

🎭 Playwright Test Results

❌ Some tests failed

OS Passed Failed Flaky Skipped
🍎 macOS 358 2 2 115
🪟 Windows 361 0 5 115

Summary: 719 passed, 2 failed, 7 flaky, 230 skipped

Failed Tests

🍎 macOS

  • problems.spec.ts > problems - fix all
    • Error: expect(locator).toBeVisible() failed
  • problems.spec.ts > problems - select specific problems and fix
    • Error: expect(locator).toBeVisible() failed

📋 Re-run Failing Tests (macOS)

Copy and paste to re-run all failing spec files locally:

npm run e2e \
  e2e-tests/problems.spec.ts

⚠️ Flaky Tests

🍎 macOS

  • setup_flow.spec.ts > Setup Flow > setup banner shows correct state when node.js is installed (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > node.js install flow (passed after 2 retries)

🪟 Windows

  • context_manage.spec.ts > manage context - exclude paths (passed after 1 retry)
  • edit_code.spec.ts > edit code (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > setup banner shows correct state when node.js is installed (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > node.js install flow (passed after 1 retry)
  • template-create-nextjs.spec.ts > create next.js app (passed after 1 retry)

📊 View full report

@wwwillchen wwwillchen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @azizmejri1 - lgtm, merging now.

A good follow-up is to show some kind of notification to the user when they need to answer a questionnaire:

  • Not focused on Dyad app: when the setting "Show notification when chat completes" is toggled on, we show a native notification when the chat stream is done. we should also show a notification when a questionnaire is asked if the dyad app is not focused on or the user is looking at a different app within the dyad app (e.g. different tab).

a lot of times users are multi-tasking so having this UX feedback will nudge them to answer in a timely manner before the 5 minute timeout kicks in.

@github-actions

Copy link
Copy Markdown
Contributor

🎭 Playwright Test Results

❌ Some tests failed

OS Passed Failed Flaky Skipped
🍎 macOS 348 8 5 115
🪟 Windows 351 1 8 115

Summary: 699 passed, 9 failed, 13 flaky, 230 skipped

Failed Tests

🍎 macOS

  • mcp.spec.ts > mcp - call calculator
    • Error: expect(locator).toBeVisible() failed
  • mcp.spec.ts > mcp - call calculator via http
    • Error: expect(locator).toBeVisible() failed
  • problems.spec.ts > problems auto-fix - enabled
    • Error: expect(locator).toBeVisible() failed
  • problems.spec.ts > problems auto-fix - gives up after 2 attempts
    • Error: expect(locator).toBeVisible() failed
  • problems.spec.ts > problems auto-fix - complex delete-rename-write
    • Error: expect(locator).toBeVisible() failed
  • problems.spec.ts > problems - fix all
    • Error: expect(locator).toBeVisible() failed
  • problems.spec.ts > problems - select specific problems and fix
    • Error: expect(locator).toBeVisible() failed
  • setup_flow.spec.ts > Setup Flow > node.js install flow
    • TimeoutError: locator.click: Timeout 30000ms exceeded.

🪟 Windows

  • chat_input.spec.ts > send button disabled during pending proposal - reject
    • Error: expect(locator).toBeVisible() failed

📋 Re-run Failing Tests (macOS)

Copy and paste to re-run all failing spec files locally:

npm run e2e \
  e2e-tests/mcp.spec.ts \
  e2e-tests/problems.spec.ts \
  e2e-tests/setup_flow.spec.ts

⚠️ Flaky Tests

🍎 macOS

  • context_compaction.spec.ts > local-agent - context compaction triggers and shows summary (passed after 1 retry)
  • local_agent_consent.spec.ts > local-agent - add_dependency consent: always allow (passed after 1 retry)
  • problems.spec.ts > problems - manual edit (react/vite) (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > setup banner shows correct state when node.js is installed (passed after 1 retry)
  • smart_context_balanced.spec.ts > smart context balanced - simple (passed after 1 retry)

🪟 Windows

  • chat_mode.spec.ts > chat mode selector - ask mode (passed after 1 retry)
  • chat_tabs.spec.ts > clicking a tab switches to that chat (passed after 1 retry)
  • chat_tabs.spec.ts > closing a tab removes it and selects adjacent tab (passed after 1 retry)
  • chat_tabs.spec.ts > right-click context menu: Close tabs to the right (passed after 2 retries)
  • context_limit_banner.spec.ts > context limit banner shows 'running out' when near context limit (passed after 1 retry)
  • context_manage.spec.ts > manage context - exclude paths with smart context (passed after 2 retries)
  • edit_code.spec.ts > edit code (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > setup banner shows correct state when node.js is installed (passed after 1 retry)

📊 View full report

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

Labels

needs-human:review-issue ai agent flagged an issue that requires human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants