Unverified 提交 fd917781 authored 作者: wwwillchen-bot's avatar wwwillchen-bot 提交者: GitHub

feat: make Plan mode available for all users (#2625)

## Summary - Move the Plan mode option outside the `isProEnabled` conditional so it's accessible to all users - Agent v2 remains Pro-only - Plan mode allows users to design and plan before building, which is valuable for all users ## Test plan - [ ] Verify Plan mode appears in the chat mode selector for non-Pro users - [ ] Verify Agent v2 only appears for Pro users - [ ] Verify both modes work correctly when selected 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2625" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Made Plan mode available to all users in the chat mode selector, and allowed plan-only flows to run without Pro while Agent v2 remains Pro-only. Exiting Plan now requires explicit user confirmation before switching to implementation. <sup>Written for commit 7c2749bfbffca819792f962b99c5c4e13aba7c99. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: 's avatarWill Chen <willchen90@gmail.com> Co-authored-by: 's avatarClaude Opus 4.5 <noreply@anthropic.com>
上级 ceb61118
...@@ -128,7 +128,6 @@ export function ChatModeSelector() { ...@@ -128,7 +128,6 @@ export function ChatModeSelector() {
</Tooltip> </Tooltip>
<SelectContent align="start"> <SelectContent align="start">
{isProEnabled && ( {isProEnabled && (
<>
<SelectItem value="local-agent"> <SelectItem value="local-agent">
<div className="flex flex-col items-start"> <div className="flex flex-col items-start">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
...@@ -140,6 +139,7 @@ export function ChatModeSelector() { ...@@ -140,6 +139,7 @@ export function ChatModeSelector() {
</span> </span>
</div> </div>
</SelectItem> </SelectItem>
)}
<SelectItem value="plan"> <SelectItem value="plan">
<div className="flex flex-col items-start"> <div className="flex flex-col items-start">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
...@@ -151,8 +151,6 @@ export function ChatModeSelector() { ...@@ -151,8 +151,6 @@ export function ChatModeSelector() {
</span> </span>
</div> </div>
</SelectItem> </SelectItem>
</>
)}
{!isProEnabled && ( {!isProEnabled && (
<SelectItem value="local-agent" disabled={isQuotaExceeded}> <SelectItem value="local-agent" disabled={isQuotaExceeded}>
<div className="flex flex-col items-start"> <div className="flex flex-col items-start">
......
...@@ -263,7 +263,12 @@ export async function handleLocalAgentStream( ...@@ -263,7 +263,12 @@ export async function handleLocalAgentStream(
// Check Pro status or Basic Agent mode // Check Pro status or Basic Agent mode
// Basic Agent mode allows non-Pro users with quota (quota check is done in chat_stream_handlers) // Basic Agent mode allows non-Pro users with quota (quota check is done in chat_stream_handlers)
// Read-only mode (ask mode) is allowed for all users without Pro // Read-only mode (ask mode) is allowed for all users without Pro
if (!readOnly && !isDyadProEnabled(settings) && !isBasicAgentMode(settings)) { if (
!readOnly &&
!planModeOnly &&
!isDyadProEnabled(settings) &&
!isBasicAgentMode(settings)
) {
safeSend(event.sender, "chat:response:error", { safeSend(event.sender, "chat:response:error", {
chatId: req.chatId, chatId: req.chatId,
error: error:
......
...@@ -7,8 +7,10 @@ const logger = log.scope("exit_plan"); ...@@ -7,8 +7,10 @@ const logger = log.scope("exit_plan");
const exitPlanSchema = z.object({ const exitPlanSchema = z.object({
confirmation: z confirmation: z
.literal(true) .boolean()
.describe("Must be true to confirm the user has accepted the plan"), .describe(
"Whether the user has accepted the plan. Must be true to proceed.",
),
}); });
const DESCRIPTION = ` const DESCRIPTION = `
...@@ -50,7 +52,11 @@ export const exitPlanTool: ToolDefinition<z.infer<typeof exitPlanSchema>> = { ...@@ -50,7 +52,11 @@ export const exitPlanTool: ToolDefinition<z.infer<typeof exitPlanSchema>> = {
return `<dyad-exit-plan></dyad-exit-plan>`; return `<dyad-exit-plan></dyad-exit-plan>`;
}, },
execute: async (_args, ctx: AgentContext) => { execute: async (args, ctx: AgentContext) => {
if (!args.confirmation) {
throw new Error("User must confirm the plan before exiting plan mode");
}
logger.log("Exiting plan mode, transitioning to implementation"); logger.log("Exiting plan mode, transitioning to implementation");
safeSend(ctx.event.sender, "plan:exit", { safeSend(ctx.event.sender, "plan:exit", {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论