fix: Modell nach Coding-Kommando auf vorheriges Modell zurücksetzen
selectRole() sichert jetzt ctx.model vor dem ersten Wechsel auf coding_model. deselectRole() stellt es danach wieder her — alle 10 Kommando-Exits (/coder, /judge, /fix, /shipit, /patch, /quick_check, /plan, /continue, /optimize finally, runUpdateDoku) rufen deselectRole(pi) statt currentRole = "idle" auf. Damit bleibt das OpenRouter-Modell des Nutzers aktiv für freien Chat (Wetter, Recherchen etc.), während Coding-Kommandos weiterhin explizit coding_model via selectRole() setzen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dc64a0eb4a
commit
b1bba172d7
1 changed files with 31 additions and 12 deletions
|
|
@ -460,15 +460,34 @@ async function ensureSingleModel(
|
||||||
// Setzt die aktive Rolle (steuert den per before_agent_start injizierten System-Prompt)
|
// Setzt die aktive Rolle (steuert den per before_agent_start injizierten System-Prompt)
|
||||||
// und stellt das Single-Modell sicher. Ersetzt das frühere switchModel(): da beide Rollen
|
// und stellt das Single-Modell sicher. Ersetzt das frühere switchModel(): da beide Rollen
|
||||||
// dasselbe Modell nutzen, ist der einzige echte Effekt das Setzen von currentRole.
|
// dasselbe Modell nutzen, ist der einzige echte Effekt das Setzen von currentRole.
|
||||||
|
// Speichert ctx.model vor dem ersten Wechsel damit deselectRole() es wiederherstellen kann.
|
||||||
async function selectRole(
|
async function selectRole(
|
||||||
pi: ExtensionAPI,
|
pi: ExtensionAPI,
|
||||||
ctx: ExtensionCommandContext,
|
ctx: ExtensionCommandContext,
|
||||||
role: "coder" | "judge"
|
role: "coder" | "judge"
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
|
if (previousModel === null && ctx.model) {
|
||||||
|
previousModel = ctx.model;
|
||||||
|
}
|
||||||
currentRole = role;
|
currentRole = role;
|
||||||
return ensureSingleModel(pi, ctx);
|
return ensureSingleModel(pi, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kehrt selectRole() um: setzt currentRole auf "idle" und stellt das vor dem letzten
|
||||||
|
// selectRole()-Aufruf aktive Modell wieder her (damit Free-Chat wieder das OpenRouter-Modell nutzt).
|
||||||
|
async function deselectRole(pi: ExtensionAPI): Promise<void> {
|
||||||
|
currentRole = "idle";
|
||||||
|
if (previousModel !== null) {
|
||||||
|
try {
|
||||||
|
await pi.setModel(previousModel);
|
||||||
|
} catch {
|
||||||
|
// Modell-Restore fehlgeschlagen — currentRole ist trotzdem "idle"
|
||||||
|
}
|
||||||
|
previousModel = null;
|
||||||
|
currentModelKey = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sendet eine Nachricht und wartet bis der Agent fertig ist.
|
// Sendet eine Nachricht und wartet bis der Agent fertig ist.
|
||||||
// Retry-Schleife fängt "Agent is already processing" ab — tritt auf wenn
|
// Retry-Schleife fängt "Agent is already processing" ab — tritt auf wenn
|
||||||
// waitForIdle() zu früh zurückkehrt (Race Condition im pi-Agent).
|
// waitForIdle() zu früh zurückkehrt (Race Condition im pi-Agent).
|
||||||
|
|
@ -762,7 +781,7 @@ async function runUpdateDoku(pi: ExtensionAPI, ctx: ExtensionCommandContext): Pr
|
||||||
|
|
||||||
ctx.ui.setStatus("update_doku", "✓ Dokumentation abgeschlossen");
|
ctx.ui.setStatus("update_doku", "✓ Dokumentation abgeschlossen");
|
||||||
ctx.ui.notify("Dokumentations-Phase abgeschlossen. Commit angelegt.", "info");
|
ctx.ui.notify("Dokumentations-Phase abgeschlossen. Commit angelegt.", "info");
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Versions-Verwaltung (SemVer + Git-Tags) ──────────────────────────────────
|
// ── Versions-Verwaltung (SemVer + Git-Tags) ──────────────────────────────────
|
||||||
|
|
@ -922,6 +941,7 @@ function finalNotify(
|
||||||
|
|
||||||
let cancelRequested = false;
|
let cancelRequested = false;
|
||||||
let currentModelKey = ""; // Cache für ensureSingleModel() — verhindert redundante setModel()-Aufrufe
|
let currentModelKey = ""; // Cache für ensureSingleModel() — verhindert redundante setModel()-Aufrufe
|
||||||
|
let previousModel: any = null; // Modell vor dem letzten selectRole()-Aufruf — wird in deselectRole() wiederhergestellt
|
||||||
// Aktive Rolle für die Single-Server-Architektur: steuert, welcher Persona-System-Prompt
|
// Aktive Rolle für die Single-Server-Architektur: steuert, welcher Persona-System-Prompt
|
||||||
// im before_agent_start-Hook injiziert wird. Wird ausschließlich über selectRole() gesetzt.
|
// im before_agent_start-Hook injiziert wird. Wird ausschließlich über selectRole() gesetzt.
|
||||||
// "idle" = kein aktiver Coding-Workflow → Hook injiziert keine Persona (freier Chat).
|
// "idle" = kein aktiver Coding-Workflow → Hook injiziert keine Persona (freier Chat).
|
||||||
|
|
@ -1082,7 +1102,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
await selectRole(pi, ctx, "coder");
|
await selectRole(pi, ctx, "coder");
|
||||||
currentActivity = "Coder implementiert…";
|
currentActivity = "Coder implementiert…";
|
||||||
await sendAndWait(pi, ctx, coderKickoff(task));
|
await sendAndWait(pi, ctx, coderKickoff(task));
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1096,7 +1116,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
await selectRole(pi, ctx, "judge");
|
await selectRole(pi, ctx, "judge");
|
||||||
currentActivity = "Judge reviewt…";
|
currentActivity = "Judge reviewt…";
|
||||||
await sendAndWait(pi, ctx, judgePrompt(args || ""));
|
await sendAndWait(pi, ctx, judgePrompt(args || ""));
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1110,7 +1130,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
await selectRole(pi, ctx, "coder");
|
await selectRole(pi, ctx, "coder");
|
||||||
currentActivity = "Coder fixt Judge-Kritik…";
|
currentActivity = "Coder fixt Judge-Kritik…";
|
||||||
await sendAndWait(pi, ctx, fixPrompt(args || ""));
|
await sendAndWait(pi, ctx, fixPrompt(args || ""));
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1133,7 +1153,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
} else if (shipVerdict === "NO-SHIP") {
|
} else if (shipVerdict === "NO-SHIP") {
|
||||||
ctx.ui.notify("NO-SHIP — noch Blocker offen. Bitte /fix aufrufen.", "error");
|
ctx.ui.notify("NO-SHIP — noch Blocker offen. Bitte /fix aufrufen.", "error");
|
||||||
}
|
}
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1394,9 +1414,8 @@ export default function (pi: ExtensionAPI) {
|
||||||
stopPhaseTimer();
|
stopPhaseTimer();
|
||||||
// Sicherstellen dass keine Zustandsvariable in späteren /optimize-Aufruf leckt
|
// Sicherstellen dass keine Zustandsvariable in späteren /optimize-Aufruf leckt
|
||||||
cancelRequested = false;
|
cancelRequested = false;
|
||||||
currentModelKey = "";
|
// Zurück auf idle + Modell wiederherstellen: freier Chat nach dem Lauf soll keine Coding-Persona erhalten.
|
||||||
// Zurück auf idle: freier Chat nach dem Lauf soll keine Coding-Persona erhalten.
|
await deselectRole(pi);
|
||||||
currentRole = "idle";
|
|
||||||
interactivePauseActive = false;
|
interactivePauseActive = false;
|
||||||
interactiveContinueRequested = false;
|
interactiveContinueRequested = false;
|
||||||
interactivePauseTask = "";
|
interactivePauseTask = "";
|
||||||
|
|
@ -1421,7 +1440,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
await selectRole(pi, ctx, "coder");
|
await selectRole(pi, ctx, "coder");
|
||||||
currentActivity = "Coder patcht…";
|
currentActivity = "Coder patcht…";
|
||||||
await sendAndWait(pi, ctx, patchPrompt(change));
|
await sendAndWait(pi, ctx, patchPrompt(change));
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1435,7 +1454,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
await selectRole(pi, ctx, "judge");
|
await selectRole(pi, ctx, "judge");
|
||||||
currentActivity = "Judge: Schnellcheck…";
|
currentActivity = "Judge: Schnellcheck…";
|
||||||
await sendAndWait(pi, ctx, quickCheckPrompt(args || ""));
|
await sendAndWait(pi, ctx, quickCheckPrompt(args || ""));
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1508,7 +1527,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
await sendAndWait(pi, ctx, planPrompt(task));
|
await sendAndWait(pi, ctx, planPrompt(task));
|
||||||
ctx.ui.setStatus("plan", "");
|
ctx.ui.setStatus("plan", "");
|
||||||
finalNotify(ctx, "📋 Plan", "Analyse abgeschlossen — PLAN.md + Chat");
|
finalNotify(ctx, "📋 Plan", "Analyse abgeschlossen — PLAN.md + Chat");
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1596,7 +1615,7 @@ export default function (pi: ExtensionAPI) {
|
||||||
"5. Fahre direkt mit dem nächsten sinnvollen Schritt fort — kein langer Bericht, einfach weitermachen.",
|
"5. Fahre direkt mit dem nächsten sinnvollen Schritt fort — kein langer Bericht, einfach weitermachen.",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
ctx.ui.setStatus("continue", "");
|
ctx.ui.setStatus("continue", "");
|
||||||
currentRole = "idle";
|
await deselectRole(pi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue