From b67e9f9d38dc40c3aeb9b4d5fef72b1a9168fe74 Mon Sep 17 00:00:00 2001 From: 18243133 <37695126+18243133@users.noreply.github.com> Date: Mon, 18 May 2026 21:57:15 +0800 Subject: [PATCH] Fix/plan paste fixes (#1238) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 降低 paste 检测阈值,修复非 bracketed-paste 终端粘贴文本损坏 非 bracketed-paste 终端下,短粘贴(<800 chars)的 stdin chunk 作为独立 keystroke 走 useTextInput.onInput 路径,闭包中 cursor 未刷新导致多次插入 竞态。现将 ≥3 字符的非特殊键输入纳入 paste 累积模式,绕过逐 chunk 处理。 Co-Authored-By: Claude Opus 4.7 * @ fix: Plan模式三处缺陷修复 — ExploreAgent可用性 + 弹窗一致性 + 方案文件保护 1. areExplorePlanAgentsEnabled()移除GrowthBook A/B实验依赖(tengu_amber_stoat), 始终返回true,确保Explore/Plan agent在BUILTIN_EXPLORE_PLAN_AGENTS开启时始终可用 2. ExitPlanMode clear-context路径补setNeedsPlanModeExitAttachment(true), 确保清除上下文退出Plan模式后生成plan_mode_exit附件 3. Plan mode full/sparse指令强化Plan文件读取要求: "can read" -> "MUST use FileRead to read first before any changes", 新增"do NOT overwrite"禁止覆盖,Phase 1指令强化并行Explore Agent引导 Co-Authored-By: Claude Opus 4.7 @ --------- Co-authored-by: psj88520 Co-authored-by: Claude Opus 4.7 --- .../src/tools/AgentTool/builtInAgents.ts | 4 +--- .../ExitPlanModePermissionRequest.tsx | 1 + src/hooks/usePasteHandler.ts | 10 +++++++++- src/utils/messages.ts | 12 ++++++------ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts b/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts index 5735a4692..a50ef199a 100644 --- a/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts +++ b/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts @@ -12,9 +12,7 @@ import type { AgentDefinition } from './loadAgentsDir.js' export function areExplorePlanAgentsEnabled(): boolean { if (feature('BUILTIN_EXPLORE_PLAN_AGENTS')) { - // 3P default: true — Bedrock/Vertex keep agents enabled (matches pre-experiment - // external behavior). A/B test treatment sets false to measure impact of removal. - return getFeatureValue_CACHED_MAY_BE_STALE('tengu_amber_stoat', true) + return true } return false } diff --git a/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx b/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx index a07f0a2b3..98ddf64a1 100644 --- a/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx +++ b/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx @@ -450,6 +450,7 @@ export function ExitPlanModePermissionRequest({ })); setHasExitedPlanMode(true); + setNeedsPlanModeExitAttachment(true); onDone(); onReject(); // Reject the tool use to unblock the query loop diff --git a/src/hooks/usePasteHandler.ts b/src/hooks/usePasteHandler.ts index a2ed7f306..4b2bd6fcd 100644 --- a/src/hooks/usePasteHandler.ts +++ b/src/hooks/usePasteHandler.ts @@ -255,7 +255,15 @@ export function usePasteHandler({ (input.length > PASTE_THRESHOLD || pastePendingRef.current || hasImageFilePath || - isFromPaste) + isFromPaste || + (input.length >= 3 && + !key.return && + !key.tab && + !key.escape && + !key.upArrow && + !key.downArrow && + !key.leftArrow && + !key.rightArrow)) if (shouldHandleAsPaste) { pastePendingRef.current = true diff --git a/src/utils/messages.ts b/src/utils/messages.ts index 237c9dc42..e4623198a 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -3586,7 +3586,7 @@ function getPlanModeV2Instructions(attachment: { const agentCount = getPlanModeV2AgentCount() const exploreAgentCount = getPlanModeV2ExploreAgentCount() const planFileInfo = attachment.planExists - ? `A plan file already exists at ${attachment.planFilePath}. You can read it and make incremental edits using the ${FileEditTool.name} tool.` + ? `A plan file already exists at ${attachment.planFilePath}. You MUST use ${FileReadTool.name} to read it first before making any changes. Make incremental edits using the ${FileEditTool.name} tool — do NOT overwrite the entire file unless the user explicitly asks for a complete rewrite.` : `No plan file exists yet. You should create your plan at ${attachment.planFilePath} using the ${FileWriteTool.name} tool.` const content = `Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supercedes any other instructions you have received. @@ -3603,10 +3603,10 @@ Goal: Gain a comprehensive understanding of the user's request by reading throug 1. Focus on understanding the user's request and the code associated with their request. Actively search for existing functions, utilities, and patterns that can be reused — avoid proposing new code when suitable implementations already exist. 2. **Launch up to ${exploreAgentCount} ${EXPLORE_AGENT.agentType} agents IN PARALLEL** (single message, multiple tool calls) to efficiently explore the codebase. - - Use 1 agent when the task is isolated to known files, the user provided specific file paths, or you're making a small targeted change. + - For tasks with well-known file targets, 1 agent may suffice. In most cases, prefer launching 2-3 agents with complementary search focuses to maximize coverage. - Use multiple agents when: the scope is uncertain, multiple areas of the codebase are involved, or you need to understand existing patterns before planning. - - Quality over quantity - ${exploreAgentCount} agents maximum, but you should try to use the minimum number of agents necessary (usually just 1) - - If using multiple agents: Provide each agent with a specific search focus or area to explore. Example: One agent searches for existing implementations, another explores related components, a third investigating testing patterns + - Quality over quantity - ${exploreAgentCount} agents maximum. Do NOT skip exploration — always use at least 1 Explore agent in Phase 1. + - When using multiple agents: Provide each agent with a specific search focus or area to explore. Example: One agent searches for existing implementations, another explores related components, a third investigates testing patterns ### Phase 2: Design Goal: Design an implementation approach. @@ -3690,7 +3690,7 @@ function getPlanModeInterviewInstructions(attachment: { planExists?: boolean }): UserMessage[] { const planFileInfo = attachment.planExists - ? `A plan file already exists at ${attachment.planFilePath}. You can read it and make incremental edits using the ${FileEditTool.name} tool.` + ? `A plan file already exists at ${attachment.planFilePath}. You MUST use ${FileReadTool.name} to read it first before making any changes. Make incremental edits using the ${FileEditTool.name} tool — do NOT overwrite the entire file unless the user explicitly asks for a complete rewrite.` : `No plan file exists yet. You should create your plan at ${attachment.planFilePath} using the ${FileWriteTool.name} tool.` const content = `Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supercedes any other instructions you have received. @@ -3752,7 +3752,7 @@ function getPlanModeV2SparseInstructions(attachment: { }): UserMessage[] { const workflowDescription = isPlanModeInterviewPhaseEnabled() ? 'Follow iterative workflow: explore codebase, interview user, write to plan incrementally.' - : 'Follow 5-phase workflow.' + : `Follow 5-phase workflow. Phase 1: use ${EXPLORE_AGENT.agentType} agents for code exploration.` const content = `Plan mode still active (see full instructions earlier in conversation). Read-only except plan file (${attachment.planFilePath}). ${workflowDescription} End turns with ${ASK_USER_QUESTION_TOOL_NAME} (for clarifications) or ${ExitPlanModeV2Tool.name} (for plan approval). Never ask about plan approval via text or AskUserQuestion.`