fix(agents): honor heartbeat.model override instead of session model (#14181)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: f19b789057
Co-authored-by: 0xRaini <190923101+0xRaini@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
0xRain
2026-02-12 01:46:51 +08:00
committed by GitHub
parent 8c963dc5a6
commit 6d723c9f8a
5 changed files with 122 additions and 1 deletions

View File

@@ -153,4 +153,62 @@ describe("createModelSelectionState parent inheritance", () => {
expect(state.provider).toBe(defaultProvider);
expect(state.model).toBe(defaultModel);
});
it("applies stored override when heartbeat override was not resolved", async () => {
const cfg = {} as OpenClawConfig;
const sessionKey = "agent:main:discord:channel:c1";
const sessionEntry = makeEntry({
providerOverride: "openai",
modelOverride: "gpt-4o",
});
const sessionStore = {
[sessionKey]: sessionEntry,
};
const state = await createModelSelectionState({
cfg,
agentCfg: cfg.agents?.defaults,
sessionEntry,
sessionStore,
sessionKey,
defaultProvider,
defaultModel,
provider: "anthropic",
model: "claude-opus-4-5",
hasModelDirective: false,
hasResolvedHeartbeatModelOverride: false,
});
expect(state.provider).toBe("openai");
expect(state.model).toBe("gpt-4o");
});
it("skips stored override when heartbeat override was resolved", async () => {
const cfg = {} as OpenClawConfig;
const sessionKey = "agent:main:discord:channel:c1";
const sessionEntry = makeEntry({
providerOverride: "openai",
modelOverride: "gpt-4o",
});
const sessionStore = {
[sessionKey]: sessionEntry,
};
const state = await createModelSelectionState({
cfg,
agentCfg: cfg.agents?.defaults,
sessionEntry,
sessionStore,
sessionKey,
defaultProvider,
defaultModel,
provider: "anthropic",
model: "claude-opus-4-5",
hasModelDirective: false,
hasResolvedHeartbeatModelOverride: true,
});
expect(state.provider).toBe("anthropic");
expect(state.model).toBe("claude-opus-4-5");
});
});