🤖 perf: context-efficient plan mode #1072
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Optimizes context usage in plan mode by:
planContentfrompropose_plantool results (plan is already visible viafile_edit_*diffs)Changes
propose_plantool: No longer returnsplanContentin the result, saving context during iterative planning sessionsProposePlanToolCallfetches content on-demand for the latest plan; shows path info for historical plans without embedded contentplanContentin results still renders correctlyContext Flow
file_edit_*diffs + full plan inpropose_planresultfile_edit_*diffs onlyTesting
Plan
Plan: Context-Efficient Plan Mode
Summary
Improve the plan mode → exec mode transition to include the approved plan content in the model's context only when relevant, avoiding redundant context when the plan is already visible in conversation history or no plan was created.
Current Behavior
How Plan Mode Works Now
System Prompt: When in plan mode,
getPlanModeInstruction()adds instructions telling the model to write its plan to~/.mux/plans/{workspaceId}.mdpropose_plan Tool: When called, reads the plan file from disk and returns:
This content is stored in the tool result in chat history — this is redundant since the plan was already written via
file_edit_*calls.Mode Transition: When switching from plan → exec,
injectModeTransition()inserts a synthetic user message:Key Observation
The plan content is duplicated in multiple places:
file_edit_*tool calls - The actual writes/edits to the plan file (as diffs)propose_plantool result - The full plan content (redundant!)For iterative planning sessions, this means the plan content appears multiple times, wasting context:
file_edit_*diffs ✓ (necessary, minimal)propose_plancall duplicates the full content ✗ (redundant)Problem Statement
When the user switches from plan mode to exec mode (implicitly by changing the mode selector), the model:
Proposed Solution
Enhance the mode transition injection to optionally include the approved plan content when switching from plan → exec mode.
Design Principles
Implementation
1. Modify
injectModeTransition()to accept plan content (~20 LoC)File:
src/browser/utils/messages/modelMessageTransform.tsAdd an optional
planContentparameter that gets included when transitioning plan → exec:2. Read plan content during stream preparation (~15 LoC)
File:
src/node/services/aiService.tsBefore calling
injectModeTransition, check if we're transitioning plan→exec and read the plan file:3. Update test coverage (~40 LoC)
File:
src/browser/utils/messages/modelMessageTransform.test.tsAdd tests for:
Alternative Considered: Include in System Prompt
We could add the plan content to the system prompt during exec mode. However:
Edge Cases
4. Remove planContent from propose_plan tool result (~5 LoC)
File:
src/node/services/tools/propose_plan.tsThe tool currently returns the full plan content in the result. Since:
file_edit_*tool calls (as diffs)We can exclude it from the tool result to save context during iterative planning:
5. Update ProposePlanToolCall UI to fetch content on demand (~10 LoC)
File:
src/browser/components/tools/ProposePlanToolCall.tsxThe UI component already has logic to fetch fresh content via
getPlanContentfor the latest plan. We need to ensure it falls back to this API call whenplanContentis not in the result:Since the UI already prioritizes
freshContentfrom disk for the latest plan, this mostly works. For historical plans, we should show a minimal message indicating the plan exists at the path.Estimated LoC Changes
modelMessageTransform.tsaiService.tspropose_plan.tsProposePlanToolCall.tsxmodelMessageTransform.test.tsDesign Decisions
Generated with mux