mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-27 11:56:43 +02:00
fix(ci): align cron and session tests with runtime
This commit is contained in:
@@ -18,9 +18,11 @@ export function resolveThinkingDefault(params: {
|
||||
}): ThinkLevel {
|
||||
const normalizedProvider = normalizeProviderId(params.provider);
|
||||
const normalizedModel = normalizeLowercaseStringOrEmpty(params.model).replace(/\./g, "-");
|
||||
const catalogCandidate = params.catalog?.find(
|
||||
(entry) => entry.provider === params.provider && entry.id === params.model,
|
||||
);
|
||||
const catalogCandidate = Array.isArray(params.catalog)
|
||||
? params.catalog.find(
|
||||
(entry) => entry.provider === params.provider && entry.id === params.model,
|
||||
)
|
||||
: undefined;
|
||||
const configuredModels = params.cfg.agents?.defaults?.models;
|
||||
const canonicalKey = modelKey(params.provider, params.model);
|
||||
const legacyKey = legacyModelKey(params.provider, params.model);
|
||||
|
||||
@@ -8,17 +8,24 @@ const mocks = vi.hoisted(() => ({
|
||||
listAgentIds: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../../config/sessions.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../../config/sessions.js")>(
|
||||
"../../config/sessions.js",
|
||||
vi.mock("../../config/sessions/main-session.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../../config/sessions/main-session.js")>(
|
||||
"../../config/sessions/main-session.js",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
loadSessionStore: mocks.loadSessionStore,
|
||||
resolveStorePath: mocks.resolveStorePath,
|
||||
resolveExplicitAgentSessionKey: () => undefined,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../../config/sessions/paths.js", () => ({
|
||||
resolveStorePath: mocks.resolveStorePath,
|
||||
}));
|
||||
|
||||
vi.mock("../../config/sessions/store-load.js", () => ({
|
||||
loadSessionStore: mocks.loadSessionStore,
|
||||
}));
|
||||
|
||||
vi.mock("../../agents/agent-scope.js", () => ({
|
||||
listAgentIds: mocks.listAgentIds,
|
||||
}));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import "./isolated-agent.mocks.js";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { loadModelCatalog } from "../agents/model-catalog.js";
|
||||
import * as modelSelection from "../agents/model-selection.js";
|
||||
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
|
||||
import {
|
||||
DEFAULT_MESSAGE,
|
||||
@@ -10,10 +9,11 @@ import {
|
||||
runCronTurn,
|
||||
withTempHome,
|
||||
} from "./isolated-agent.turn-test-helpers.js";
|
||||
import * as isolatedAgentRunRuntime from "./isolated-agent/run.runtime.js";
|
||||
|
||||
describe("runCronIsolatedAgentTurn hook content wrapping", () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(modelSelection, "resolveThinkingDefault").mockReturnValue("off");
|
||||
vi.spyOn(isolatedAgentRunRuntime, "resolveThinkingDefault").mockReturnValue("off");
|
||||
vi.mocked(runEmbeddedPiAgent).mockClear();
|
||||
vi.mocked(loadModelCatalog).mockResolvedValue([]);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
|
||||
|
||||
const {
|
||||
loadModelCatalogMock,
|
||||
@@ -49,8 +50,6 @@ vi.mock("../agents/model-selection.js", () => ({
|
||||
import { resolveCronModelSelection } from "./isolated-agent/model-selection.js";
|
||||
|
||||
const DEFAULT_MESSAGE = "do it";
|
||||
const DEFAULT_PROVIDER = "anthropic";
|
||||
const DEFAULT_MODEL = "claude-opus-4-6";
|
||||
|
||||
type AgentTurnPayload = {
|
||||
kind: "agentTurn";
|
||||
@@ -88,7 +87,7 @@ function parseModelRef(raw: string): { provider: string; model: string } | { err
|
||||
}
|
||||
|
||||
const provider = providerRaw === "bedrock" ? "amazon-bedrock" : providerRaw;
|
||||
const model = provider === "anthropic" && modelRaw === "opus-4.5" ? "claude-opus-4-6" : modelRaw;
|
||||
const model = provider === "anthropic" && modelRaw === "opus-4.5" ? "claude-opus-4-5" : modelRaw;
|
||||
return { provider, model };
|
||||
}
|
||||
|
||||
@@ -204,7 +203,7 @@ describe("cron model formatting and precedence edge cases", () => {
|
||||
selectModel({
|
||||
payload: { kind: "agentTurn", message: DEFAULT_MESSAGE, model: "openai/" },
|
||||
}),
|
||||
).resolves.toEqual({ ok: false, error: "invalid model" });
|
||||
).resolves.toEqual({ ok: false, error: "invalid model: openai/" });
|
||||
});
|
||||
|
||||
it("rejects model with leading slash (empty provider)", async () => {
|
||||
@@ -212,7 +211,7 @@ describe("cron model formatting and precedence edge cases", () => {
|
||||
selectModel({
|
||||
payload: { kind: "agentTurn", message: DEFAULT_MESSAGE, model: "/gpt-4.1-mini" },
|
||||
}),
|
||||
).resolves.toEqual({ ok: false, error: "invalid model" });
|
||||
).resolves.toEqual({ ok: false, error: "invalid model: /gpt-4.1-mini" });
|
||||
});
|
||||
|
||||
it("normalizes provider casing", async () => {
|
||||
@@ -237,7 +236,7 @@ describe("cron model formatting and precedence edge cases", () => {
|
||||
model: "anthropic/opus-4.5",
|
||||
},
|
||||
},
|
||||
{ provider: "anthropic", model: "claude-opus-4-6" },
|
||||
{ provider: "anthropic", model: "claude-opus-4-5" },
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import "./isolated-agent.mocks.js";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { loadModelCatalog } from "../agents/model-catalog.js";
|
||||
import * as modelSelection from "../agents/model-selection.js";
|
||||
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
|
||||
import {
|
||||
DEFAULT_AGENT_TURN_PAYLOAD,
|
||||
@@ -13,10 +12,11 @@ import {
|
||||
runTurnWithStoredModelOverride,
|
||||
withTempHome,
|
||||
} from "./isolated-agent.turn-test-helpers.js";
|
||||
import * as isolatedAgentRunRuntime from "./isolated-agent/run.runtime.js";
|
||||
|
||||
describe("runCronIsolatedAgentTurn model overrides", () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(modelSelection, "resolveThinkingDefault").mockReturnValue("off");
|
||||
vi.spyOn(isolatedAgentRunRuntime, "resolveThinkingDefault").mockReturnValue("off");
|
||||
vi.mocked(runEmbeddedPiAgent).mockClear();
|
||||
vi.mocked(loadModelCatalog).mockResolvedValue([]);
|
||||
});
|
||||
@@ -176,7 +176,7 @@ describe("runCronIsolatedAgentTurn model overrides", () => {
|
||||
|
||||
it("passes through the resolved default thinking level", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
vi.mocked(modelSelection.resolveThinkingDefault).mockReturnValueOnce("low");
|
||||
vi.mocked(isolatedAgentRunRuntime.resolveThinkingDefault).mockReturnValueOnce("low");
|
||||
|
||||
await runCronTurn(home, {
|
||||
jobPayload: DEFAULT_AGENT_TURN_PAYLOAD,
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import "./isolated-agent.mocks.js";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as modelSelection from "../agents/model-selection.js";
|
||||
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { runCronIsolatedAgentTurn } from "./isolated-agent.js";
|
||||
import { makeCfg, makeJob, writeSessionStore } from "./isolated-agent.test-harness.js";
|
||||
import {
|
||||
@@ -16,13 +14,17 @@ import {
|
||||
withTempHome,
|
||||
} from "./isolated-agent.turn-test-helpers.js";
|
||||
import { setupRunCronIsolatedAgentTurnSuite } from "./isolated-agent/run.suite-helpers.js";
|
||||
import {
|
||||
mockRunCronFallbackPassthrough,
|
||||
runEmbeddedPiAgentMock,
|
||||
} from "./isolated-agent/run.test-harness.js";
|
||||
|
||||
setupRunCronIsolatedAgentTurnSuite();
|
||||
|
||||
describe("runCronIsolatedAgentTurn session identity", () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(modelSelection, "resolveThinkingDefault").mockReturnValue("off");
|
||||
vi.mocked(runEmbeddedPiAgent).mockClear();
|
||||
mockRunCronFallbackPassthrough();
|
||||
runEmbeddedPiAgentMock.mockClear();
|
||||
});
|
||||
|
||||
it("passes resolved agentDir to runEmbeddedPiAgent", async () => {
|
||||
@@ -32,7 +34,7 @@ describe("runCronIsolatedAgentTurn session identity", () => {
|
||||
});
|
||||
|
||||
expect(res.status).toBe("ok");
|
||||
const call = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0] as {
|
||||
const call = runEmbeddedPiAgentMock.mock.calls.at(-1)?.[0] as {
|
||||
agentDir?: string;
|
||||
};
|
||||
expect(call?.agentDir).toBe(path.join(home, ".openclaw", "agents", "main", "agent"));
|
||||
@@ -45,7 +47,7 @@ describe("runCronIsolatedAgentTurn session identity", () => {
|
||||
jobPayload: DEFAULT_AGENT_TURN_PAYLOAD,
|
||||
});
|
||||
|
||||
const call = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0] as {
|
||||
const call = runEmbeddedPiAgentMock.mock.calls.at(-1)?.[0] as {
|
||||
prompt?: string;
|
||||
};
|
||||
const lines = call?.prompt?.split("\n") ?? [];
|
||||
@@ -93,7 +95,7 @@ describe("runCronIsolatedAgentTurn session identity", () => {
|
||||
});
|
||||
|
||||
expect(res.status).toBe("ok");
|
||||
const call = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0] as {
|
||||
const call = runEmbeddedPiAgentMock.mock.calls.at(-1)?.[0] as {
|
||||
sessionKey?: string;
|
||||
workspaceDir?: string;
|
||||
sessionFile?: string;
|
||||
@@ -109,7 +111,7 @@ describe("runCronIsolatedAgentTurn session identity", () => {
|
||||
await runCronTurn(home, {
|
||||
jobPayload: DEFAULT_AGENT_TURN_PAYLOAD,
|
||||
});
|
||||
const call = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0] as {
|
||||
const call = runEmbeddedPiAgentMock.mock.calls.at(-1)?.[0] as {
|
||||
sessionFile?: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ vi.mock("./skills-snapshot.runtime.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("./run-model-selection.runtime.js", () => ({
|
||||
DEFAULT_MODEL: "gpt-4",
|
||||
DEFAULT_MODEL: "gpt-5.4",
|
||||
DEFAULT_PROVIDER: "openai",
|
||||
loadModelCatalog: loadModelCatalogMock,
|
||||
getModelRefStatus: getModelRefStatusMock,
|
||||
@@ -252,7 +252,7 @@ function makeDefaultModelFallbackResult() {
|
||||
meta: { agentMeta: { usage: { input: 10, output: 20 } } },
|
||||
},
|
||||
provider: "openai",
|
||||
model: "gpt-4",
|
||||
model: "gpt-5.4",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -292,8 +292,8 @@ function resetRunConfigMocks(): void {
|
||||
);
|
||||
resolveAgentModelFallbacksOverrideMock.mockReturnValue(undefined);
|
||||
resolveAgentSkillsFilterMock.mockReturnValue(undefined);
|
||||
resolveConfiguredModelRefMock.mockReturnValue({ provider: "openai", model: "gpt-4" });
|
||||
resolveAllowedModelRefMock.mockReturnValue({ ref: { provider: "openai", model: "gpt-4" } });
|
||||
resolveConfiguredModelRefMock.mockReturnValue({ provider: "openai", model: "gpt-5.4" });
|
||||
resolveAllowedModelRefMock.mockReturnValue({ ref: { provider: "openai", model: "gpt-5.4" } });
|
||||
resolveHooksGmailModelMock.mockReturnValue(null);
|
||||
resolveThinkingDefaultMock.mockReturnValue("off");
|
||||
getModelRefStatusMock.mockReturnValue({ allowed: false });
|
||||
@@ -315,7 +315,7 @@ function resetRunConfigMocks(): void {
|
||||
isExternalHookSessionMock.mockReturnValue(false);
|
||||
resolveHookExternalContentSourceMock.mockReturnValue(undefined);
|
||||
getSkillsSnapshotVersionMock.mockReturnValue(42);
|
||||
loadModelCatalogMock.mockResolvedValue({ models: [] });
|
||||
loadModelCatalogMock.mockResolvedValue([]);
|
||||
getRemoteSkillEligibilityMock.mockResolvedValue({ remoteSkillsEnabled: false });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user