mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 12:41:23 +00:00
Merged via /review-pr -> /prepare-pr -> /merge-pr.
Prepared head SHA: ec47d1a7bf
Co-authored-by: shtse8 <8020099+shtse8@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
@@ -173,6 +173,7 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
};
|
||||
// Resolve model - prefer hooks.gmail.model for Gmail hooks.
|
||||
const isGmailHook = baseSessionKey.startsWith("hook:gmail:");
|
||||
let hooksGmailModelApplied = false;
|
||||
const hooksGmailModelRef = isGmailHook
|
||||
? resolveHooksGmailModel({
|
||||
cfg: params.cfg,
|
||||
@@ -190,6 +191,7 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
if (status.allowed) {
|
||||
provider = hooksGmailModelRef.provider;
|
||||
model = hooksGmailModelRef.model;
|
||||
hooksGmailModelApplied = true;
|
||||
}
|
||||
}
|
||||
const modelOverrideRaw =
|
||||
@@ -247,6 +249,28 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
cronSession.sessionEntry.label = `Cron: ${labelSuffix}`;
|
||||
}
|
||||
|
||||
// Respect session model override — check session.modelOverride before falling
|
||||
// back to the default config model. This ensures /model changes are honoured
|
||||
// by cron and isolated agent runs.
|
||||
if (!modelOverride && !hooksGmailModelApplied) {
|
||||
const sessionModelOverride = cronSession.sessionEntry.modelOverride?.trim();
|
||||
if (sessionModelOverride) {
|
||||
const sessionProviderOverride =
|
||||
cronSession.sessionEntry.providerOverride?.trim() || resolvedDefault.provider;
|
||||
const resolvedSessionOverride = resolveAllowedModelRef({
|
||||
cfg: cfgWithAgentDefaults,
|
||||
catalog: await loadCatalog(),
|
||||
raw: `${sessionProviderOverride}/${sessionModelOverride}`,
|
||||
defaultProvider: resolvedDefault.provider,
|
||||
defaultModel: resolvedDefault.model,
|
||||
});
|
||||
if (!("error" in resolvedSessionOverride)) {
|
||||
provider = resolvedSessionOverride.ref.provider;
|
||||
model = resolvedSessionOverride.ref.model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve thinking level - job thinking > hooks.gmail.thinking > agent default
|
||||
const hooksGmailThinking = isGmailHook
|
||||
? normalizeThinkLevel(params.cfg.hooks?.gmail?.thinking)
|
||||
|
||||
73
src/cron/isolated-agent/session.test.ts
Normal file
73
src/cron/isolated-agent/session.test.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
|
||||
vi.mock("../../config/sessions.js", () => ({
|
||||
loadSessionStore: vi.fn(),
|
||||
resolveStorePath: vi.fn().mockReturnValue("/tmp/test-store.json"),
|
||||
}));
|
||||
|
||||
import { loadSessionStore } from "../../config/sessions.js";
|
||||
import { resolveCronSession } from "./session.js";
|
||||
|
||||
describe("resolveCronSession", () => {
|
||||
it("preserves modelOverride and providerOverride from existing session entry", () => {
|
||||
vi.mocked(loadSessionStore).mockReturnValue({
|
||||
"agent:main:cron:test-job": {
|
||||
sessionId: "old-session-id",
|
||||
updatedAt: 1000,
|
||||
modelOverride: "deepseek-v3-4bit-mlx",
|
||||
providerOverride: "inferencer",
|
||||
thinkingLevel: "high",
|
||||
model: "k2p5",
|
||||
},
|
||||
});
|
||||
|
||||
const result = resolveCronSession({
|
||||
cfg: {} as OpenClawConfig,
|
||||
sessionKey: "agent:main:cron:test-job",
|
||||
agentId: "main",
|
||||
nowMs: Date.now(),
|
||||
});
|
||||
|
||||
expect(result.sessionEntry.modelOverride).toBe("deepseek-v3-4bit-mlx");
|
||||
expect(result.sessionEntry.providerOverride).toBe("inferencer");
|
||||
expect(result.sessionEntry.thinkingLevel).toBe("high");
|
||||
// The model field (last-used model) should also be preserved
|
||||
expect(result.sessionEntry.model).toBe("k2p5");
|
||||
});
|
||||
|
||||
it("handles missing modelOverride gracefully", () => {
|
||||
vi.mocked(loadSessionStore).mockReturnValue({
|
||||
"agent:main:cron:test-job": {
|
||||
sessionId: "old-session-id",
|
||||
updatedAt: 1000,
|
||||
model: "claude-opus-4-5",
|
||||
},
|
||||
});
|
||||
|
||||
const result = resolveCronSession({
|
||||
cfg: {} as OpenClawConfig,
|
||||
sessionKey: "agent:main:cron:test-job",
|
||||
agentId: "main",
|
||||
nowMs: Date.now(),
|
||||
});
|
||||
|
||||
expect(result.sessionEntry.modelOverride).toBeUndefined();
|
||||
expect(result.sessionEntry.providerOverride).toBeUndefined();
|
||||
});
|
||||
|
||||
it("handles no existing session entry", () => {
|
||||
vi.mocked(loadSessionStore).mockReturnValue({});
|
||||
|
||||
const result = resolveCronSession({
|
||||
cfg: {} as OpenClawConfig,
|
||||
sessionKey: "agent:main:cron:new-job",
|
||||
agentId: "main",
|
||||
nowMs: Date.now(),
|
||||
});
|
||||
|
||||
expect(result.sessionEntry.modelOverride).toBeUndefined();
|
||||
expect(result.sessionEntry.providerOverride).toBeUndefined();
|
||||
expect(result.sessionEntry.model).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -23,6 +23,8 @@ export function resolveCronSession(params: {
|
||||
thinkingLevel: entry?.thinkingLevel,
|
||||
verboseLevel: entry?.verboseLevel,
|
||||
model: entry?.model,
|
||||
modelOverride: entry?.modelOverride,
|
||||
providerOverride: entry?.providerOverride,
|
||||
contextTokens: entry?.contextTokens,
|
||||
sendPolicy: entry?.sendPolicy,
|
||||
lastChannel: entry?.lastChannel,
|
||||
|
||||
Reference in New Issue
Block a user