Merge PR #6908: fix(acp): sync model status when the agent switches models internally (@marton78)

This commit is contained in:
can1357
2026-07-29 23:08:27 +02:00
8 changed files with 141 additions and 9 deletions
@@ -651,12 +651,17 @@ export class AcpAgent implements Agent {
});
}
// For `thinking` the lifetime subscription pushes post-bootstrap; only
// push here when it's not yet installed so pre-bootstrap callers still
// see the change without a post-bootstrap duplicate.
const thinkingHandledBySubscription =
params.configId === THINKING_CONFIG_ID && record.lifetimeUnsubscribe !== undefined;
if (!thinkingHandledBySubscription) {
// For `model`/`thinking`, `#setModelById`/`#setThinkingLevelById` change
// the session model/thinking level through AgentSession, which now emits
// a lifetime event (`model_changed`/`thinking_level_changed`) that
// `#handleLifetimeEvent` turns into a push once the subscription is
// installed. Only push here when that subscription is not yet
// installed, so pre-bootstrap callers still see the change without a
// post-bootstrap duplicate.
const handledBySubscription =
(params.configId === THINKING_CONFIG_ID || params.configId === MODEL_CONFIG_ID) &&
record.lifetimeUnsubscribe !== undefined;
if (!handledBySubscription) {
await this.#pushConfigOptionUpdate(record);
}
return { configOptions: this.#buildConfigOptions(record.session) };
@@ -1150,14 +1155,15 @@ export class AcpAgent implements Agent {
}
async #handleLifetimeEvent(record: ManagedSessionRecord, event: AgentSessionEvent): Promise<void> {
if (event.type !== "thinking_level_changed") {
if (event.type !== "thinking_level_changed" && event.type !== "model_changed") {
return;
}
try {
await this.#pushConfigOptionUpdate(record);
} catch (error) {
logger.warn("Failed to push thinking-level config_option_update", {
logger.warn("Failed to push config_option_update after a lifetime event", {
sessionId: record.session.sessionId,
eventType: event.type,
error,
});
}
@@ -193,6 +193,10 @@ export class EventController {
todo_auto_clear: e => this.#handleTodoAutoClear(e),
irc_message: e => this.#handleIrcMessage(e),
notice: e => this.#handleNotice(e),
model_changed: async () => {
this.ctx.statusLine.invalidate();
this.ctx.ui.requestRender();
},
thinking_level_changed: async () => {
this.ctx.statusLine.invalidate();
this.ctx.updateEditorBorderColor();
@@ -128,6 +128,7 @@ const sessionEventTypes = new Set<AgentSessionEvent["type"]>([
"irc_message",
"notice",
"thinking_level_changed",
"model_changed",
"goal_updated",
]);