mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-21 13:44:03 +00:00
fix: scope cron payload.model fallback to disallowed refs
This commit is contained in:
@@ -39,14 +39,18 @@ vi.mock("../../agents/model-catalog.js", () => ({
|
||||
loadModelCatalog: vi.fn().mockResolvedValue({ models: [] }),
|
||||
}));
|
||||
|
||||
vi.mock("../../agents/model-selection.js", () => ({
|
||||
getModelRefStatus: getModelRefStatusMock,
|
||||
isCliProvider: isCliProviderMock,
|
||||
resolveAllowedModelRef: resolveAllowedModelRefMock,
|
||||
resolveConfiguredModelRef: resolveConfiguredModelRefMock,
|
||||
resolveHooksGmailModel: resolveHooksGmailModelMock,
|
||||
resolveThinkingDefault: resolveThinkingDefaultMock,
|
||||
}));
|
||||
vi.mock("../../agents/model-selection.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("../../agents/model-selection.js")>();
|
||||
return {
|
||||
...actual,
|
||||
getModelRefStatus: getModelRefStatusMock,
|
||||
isCliProvider: isCliProviderMock,
|
||||
resolveAllowedModelRef: resolveAllowedModelRefMock,
|
||||
resolveConfiguredModelRef: resolveConfiguredModelRefMock,
|
||||
resolveHooksGmailModel: resolveHooksGmailModelMock,
|
||||
resolveThinkingDefault: resolveThinkingDefaultMock,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../../agents/model-fallback.js", () => ({
|
||||
runWithModelFallback: vi.fn().mockResolvedValue({
|
||||
@@ -417,6 +421,27 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
|
||||
await expectPrimaryOverridePreservesDefaults({ primary: "anthropic/claude-sonnet-4-5" });
|
||||
});
|
||||
|
||||
it("applies payload.model override when model is allowed", async () => {
|
||||
resolveAllowedModelRefMock.mockReturnValueOnce({
|
||||
ref: { provider: "anthropic", model: "claude-sonnet-4-6" },
|
||||
});
|
||||
|
||||
const result = await runCronIsolatedAgentTurn(
|
||||
makeParams({
|
||||
job: makeJob({
|
||||
payload: { kind: "agentTurn", message: "test", model: "anthropic/claude-sonnet-4-6" },
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.status).toBe("ok");
|
||||
expect(logWarnMock).not.toHaveBeenCalled();
|
||||
expect(runWithModelFallbackMock).toHaveBeenCalledOnce();
|
||||
const runParams = runWithModelFallbackMock.mock.calls[0][0];
|
||||
expect(runParams.provider).toBe("anthropic");
|
||||
expect(runParams.model).toBe("claude-sonnet-4-6");
|
||||
});
|
||||
|
||||
it("falls back to agent defaults when payload.model is not allowed", async () => {
|
||||
resolveAllowedModelRefMock.mockReturnValueOnce({
|
||||
error: "model not allowed: anthropic/claude-sonnet-4-6",
|
||||
@@ -449,5 +474,24 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
|
||||
expect(model?.primary).toBe("openai-codex/gpt-5.3-codex");
|
||||
expect(model?.fallbacks).toEqual(defaultFallbacks);
|
||||
});
|
||||
|
||||
it("returns an error when payload.model is invalid", async () => {
|
||||
resolveAllowedModelRefMock.mockReturnValueOnce({
|
||||
error: "invalid model: openai/",
|
||||
});
|
||||
|
||||
const result = await runCronIsolatedAgentTurn(
|
||||
makeParams({
|
||||
job: makeJob({
|
||||
payload: { kind: "agentTurn", message: "test", model: "openai/" },
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.status).toBe("error");
|
||||
expect(result.error).toBe("invalid model: openai/");
|
||||
expect(logWarnMock).not.toHaveBeenCalled();
|
||||
expect(runWithModelFallbackMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import type { CliDeps } from "../../cli/outbound-send-deps.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { AgentDefaultsConfig } from "../../config/types.js";
|
||||
import type { CronJob, CronRunOutcome, CronRunTelemetry } from "../types.js";
|
||||
import {
|
||||
resolveAgentConfig,
|
||||
resolveAgentDir,
|
||||
@@ -34,11 +30,14 @@ import {
|
||||
normalizeVerboseLevel,
|
||||
supportsXHighThinking,
|
||||
} from "../../auto-reply/thinking.js";
|
||||
import type { CliDeps } from "../../cli/outbound-send-deps.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import {
|
||||
resolveSessionTranscriptPath,
|
||||
setSessionRuntimeModel,
|
||||
updateSessionStore,
|
||||
} from "../../config/sessions.js";
|
||||
import type { AgentDefaultsConfig } from "../../config/types.js";
|
||||
import { registerAgentRunContext } from "../../infra/agent-events.js";
|
||||
import { logWarn } from "../../logger.js";
|
||||
import { buildAgentMainSessionKey, normalizeAgentId } from "../../routing/session-key.js";
|
||||
@@ -49,6 +48,7 @@ import {
|
||||
isExternalHookSession,
|
||||
} from "../../security/external-content.js";
|
||||
import { resolveCronDeliveryPlan } from "../delivery.js";
|
||||
import type { CronJob, CronRunOutcome, CronRunTelemetry } from "../types.js";
|
||||
import {
|
||||
dispatchCronDelivery,
|
||||
matchesMessagingToolDeliveryTarget,
|
||||
@@ -198,7 +198,13 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
defaultModel: resolvedDefault.model,
|
||||
});
|
||||
if ("error" in resolvedOverride) {
|
||||
logWarn(`cron: payload.model '${modelOverride}' not allowed, falling back to agent defaults`);
|
||||
if (resolvedOverride.error.startsWith("model not allowed:")) {
|
||||
logWarn(
|
||||
`cron: payload.model '${modelOverride}' not allowed, falling back to agent defaults`,
|
||||
);
|
||||
} else {
|
||||
return { status: "error", error: resolvedOverride.error };
|
||||
}
|
||||
} else {
|
||||
provider = resolvedOverride.ref.provider;
|
||||
model = resolvedOverride.ref.model;
|
||||
|
||||
Reference in New Issue
Block a user