MCPcopy
hub / github.com/coder/mux / buildPlanInstructions

Function buildPlanInstructions

src/node/services/streamContextBuilder.ts:103–222  ·  view source on GitHub ↗
(
  opts: BuildPlanInstructionsOptions
)

Source from the content-addressed store, hash-verified

101 * used a plan-like agent
102 */
103export async function buildPlanInstructions(
104 opts: BuildPlanInstructionsOptions
105): Promise<PlanInstructionsResult> {
106 const {
107 runtime,
108 metadata,
109 workspaceId,
110 effectiveMode,
111 effectiveAgentId,
112 agentIsPlanLike,
113 agentDiscoveryRuntime,
114 agentDiscoveryPath,
115 additionalSystemInstructions,
116 shouldDisableTaskToolsForDepth,
117 taskDepth,
118 taskSettings,
119 requestPayloadMessages,
120 } = opts;
121
122 const workspaceLog = log.withFields({ workspaceId, workspaceName: metadata.name });
123
124 // Construct plan mode instruction if in plan mode
125 // This is done backend-side because we have access to the plan file path
126 let effectiveAdditionalInstructions = additionalSystemInstructions;
127 const muxHome = runtime.getMuxHome();
128 const planFilePath = getPlanFilePath(metadata.name, metadata.projectName, muxHome);
129
130 // Read plan file (handles legacy migration transparently)
131 const planResult = await readPlanFile(runtime, metadata.name, metadata.projectName, workspaceId);
132
133 const chatHasStartHerePlanSummary = hasStartHerePlanSummary(requestPayloadMessages);
134
135 if (effectiveMode === "plan") {
136 const planModeInstruction = getPlanModeInstruction(planFilePath, planResult.exists);
137 effectiveAdditionalInstructions = additionalSystemInstructions
138 ? `${planModeInstruction}\n\n${additionalSystemInstructions}`
139 : planModeInstruction;
140 } else if (planResult.exists && planResult.content.trim()) {
141 // Users often use "Replace all chat history" after plan mode. In exec (or other non-plan)
142 // modes, the model can lose the plan file location because plan path injection only
143 // happens in plan mode.
144 //
145 // Exception: the ProposePlanToolCall "Start Here" flow already stores the full plan
146 // (and plan path) directly in chat history. In that case, prompting the model to
147 // re-open the plan file is redundant and often results in an extra "read …KB" step.
148 if (!chatHasStartHerePlanSummary) {
149 const planFileHint = getPlanFileHint(planFilePath, planResult.exists);
150 if (planFileHint) {
151 effectiveAdditionalInstructions = effectiveAdditionalInstructions
152 ? `${planFileHint}\n\n${effectiveAdditionalInstructions}`
153 : planFileHint;
154 }
155 } else {
156 workspaceLog.debug(
157 "Skipping plan file hint: Start Here already includes the plan in chat history."
158 );
159 }
160 }

Callers 2

streamMessageMethod · 0.90

Calls 11

getPlanFilePathFunction · 0.90
readPlanFileFunction · 0.90
hasStartHerePlanSummaryFunction · 0.90
getPlanModeInstructionFunction · 0.90
getPlanFileHintFunction · 0.90
readAgentDefinitionFunction · 0.90
getErrorMessageFunction · 0.90
debugMethod · 0.80
getMuxHomeMethod · 0.65

Tested by

no test coverage detected