From b10dabbd31b83e43cf4dce16611755c6d25b2e18 Mon Sep 17 00:00:00 2001 From: "paseo-bot[bot]" <266920839+paseo-bot[bot]@users.noreply.github.com> Date: Sun, 1 Nov 2026 11:54:36 +0000 Subject: [PATCH] fix(claude): retain configured model metadata before a turn Rebuilding an idle session cleared its observed model and published null despite retaining an explicit model in its configuration. Fall back to that configuration until the next turn supplies an observed model. --- .../claude/agent.runtime-info.test.ts | 48 +++++++++++++++++++ .../server/agent/providers/claude/agent.ts | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 packages/server/src/server/agent/providers/claude/agent.runtime-info.test.ts diff --git a/packages/server/src/server/agent/providers/claude/agent.runtime-info.test.ts b/packages/server/src/server/agent/providers/claude/agent.runtime-info.test.ts new file mode 100644 index 0000000000..a23c95bc64 --- /dev/null +++ b/packages/server/src/server/agent/providers/claude/agent.runtime-info.test.ts @@ -0,0 +1,48 @@ +import pino from "pino"; +import { describe, expect, test } from "vitest"; + +import { ClaudeAgentClient } from "./agent.js"; + +describe("Claude runtime info before a turn", () => { + const client = new ClaudeAgentClient({ logger: pino({ level: "silent" }) }); + + test("reports the explicitly configured model before the first turn", async () => { + const session = await client.createSession({ + provider: "claude", + cwd: process.cwd(), + model: "claude-haiku-5-5", + }); + try { + expect(await session.getRuntimeInfo()).toMatchObject({ model: "claude-haiku-5-5" }); + } finally { + await session.close(); + } + }); + + test("reports the persisted configured model after rebuilding an idle session", async () => { + const session = await client.resumeSession({ + provider: "claude", + sessionId: "runtime-model-before-turn", + metadata: { cwd: process.cwd(), model: "claude-haiku-5-5" }, + }); + try { + expect(await session.getRuntimeInfo()).toMatchObject({ + sessionId: "runtime-model-before-turn", + model: "claude-haiku-5-5", + }); + expect((await session.getRuntimeInfo()).model).toBe("claude-haiku-5-5"); + expect((await session.getRuntimeInfo()).extra?.runtimeModel).toBeUndefined(); + } finally { + await session.close(); + } + }); + + test("leaves the model unknown when Claude will choose its default", async () => { + const session = await client.createSession({ provider: "claude", cwd: process.cwd() }); + try { + expect((await session.getRuntimeInfo()).model).toBeNull(); + } finally { + await session.close(); + } + }); +}); diff --git a/packages/server/src/server/agent/providers/claude/agent.ts b/packages/server/src/server/agent/providers/claude/agent.ts index d232185cbb..7a2c29e61c 100644 --- a/packages/server/src/server/agent/providers/claude/agent.ts +++ b/packages/server/src/server/agent/providers/claude/agent.ts @@ -2460,7 +2460,7 @@ class ClaudeAgentSession implements AgentSession { const info: AgentRuntimeInfo = { provider: "claude", sessionId: this.claudeSessionId, - model: this.lastOptionsModel, + model: this.lastOptionsModel ?? this.config.model ?? null, modeId: this.currentMode ?? null, ...(this.lastRuntimeModel ? {