fix(coding-agent): preserve plan exit rollback state
This commit is contained in:
@@ -2458,26 +2458,50 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
}
|
||||
|
||||
const planModeState = this.session.getPlanModeState();
|
||||
const planModeTools = this.session.getEnabledToolNames();
|
||||
const planModeModelState = this.session.model
|
||||
? { model: this.session.model, thinkingLevel: this.session.configuredThinkingLevel() }
|
||||
: undefined;
|
||||
this.session.setPlanModeState(undefined);
|
||||
try {
|
||||
if (this.#planModePreviousTools !== undefined) {
|
||||
await this.session.setActiveToolsByName(this.#planModePreviousTools);
|
||||
}
|
||||
if (this.#planModePreviousModelState) {
|
||||
if (!options?.deferModelRestore) {
|
||||
await this.#restorePlanPreviousModel(this.#planModePreviousModelState);
|
||||
}
|
||||
// If #applyPlanModeModel queued a deferred switch to the plan-role model
|
||||
// (because the session was streaming on entry), drop it now: we are
|
||||
// leaving plan mode, so flushing it on the next agent_end would land the
|
||||
// session on the plan-role model after the user has exited plan mode
|
||||
// (issue #816). This runs even when deferModelRestore is set
|
||||
// (compact-approval path): otherwise the stale plan switch survives and
|
||||
// flushPendingModelSwitch() later clobbers the restored/execution model.
|
||||
this.#clearPendingPlanModelSwitch();
|
||||
if (this.#planModePreviousModelState && !options?.deferModelRestore) {
|
||||
await this.#restorePlanPreviousModel(this.#planModePreviousModelState);
|
||||
}
|
||||
// If #applyPlanModeModel queued a deferred switch to the plan-role model
|
||||
// (because the session was streaming on entry), drop it now: we are
|
||||
// leaving plan mode, so flushing it on the next agent_end would land the
|
||||
// session on the plan-role model after the user has exited plan mode
|
||||
// (issue #816). This runs even when deferModelRestore is set
|
||||
// (compact-approval path): otherwise the stale plan switch survives and
|
||||
// flushPendingModelSwitch() later clobbers the restored/execution model.
|
||||
if (this.#planModePreviousModelState) this.#clearPendingPlanModelSwitch();
|
||||
} catch (error) {
|
||||
this.session.setPlanModeState(planModeState);
|
||||
if (
|
||||
planModeModelState &&
|
||||
(!modelsAreEqual(this.session.model, planModeModelState.model) ||
|
||||
this.session.configuredThinkingLevel() !== planModeModelState.thinkingLevel)
|
||||
) {
|
||||
try {
|
||||
await this.#restorePlanPreviousModel(planModeModelState);
|
||||
} catch (rollbackError) {
|
||||
logger.warn("Failed to restore plan model after plan exit failure", { error: String(rollbackError) });
|
||||
}
|
||||
}
|
||||
const enabledTools = this.session.getEnabledToolNames();
|
||||
if (
|
||||
enabledTools.length !== planModeTools.length ||
|
||||
enabledTools.some((name, index) => name !== planModeTools[index])
|
||||
) {
|
||||
try {
|
||||
await this.session.setActiveToolsByName(planModeTools);
|
||||
} catch (rollbackError) {
|
||||
logger.warn("Failed to restore plan tools after plan exit failure", { error: String(rollbackError) });
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
this.session.setPlanProposalHandler?.(null);
|
||||
|
||||
Reference in New Issue
Block a user