fix: preserve Google Gemini 3 cron thinking

This commit is contained in:
clawsweeper
2026-05-22 07:25:24 +00:00
parent 97e33cc0fc
commit 43698ad83c
3 changed files with 79 additions and 7 deletions

View File

@@ -6,6 +6,7 @@ export const MOCK_ONLY_PROOF_LABEL = "triage: mock-only-proof";
export const MAINTAINER_TEAM_SLUG = "maintainer";
export const CLAWSWEEPER_PROOF_VERDICT_STATUS = "clawsweeper_exact_head_pass";
const CLAWSWEEPER_BOT_LOGIN = "clawsweeper[bot]";
const privilegedAuthorAssociations = new Set(["OWNER", "MEMBER", "COLLABORATOR"]);
@@ -246,7 +247,14 @@ function isTrustedClawSweeperComment(comment) {
const appSlug = String(
comment?.performed_via_github_app?.slug ?? comment?.performedViaGithubApp?.slug ?? "",
).toLowerCase();
return appSlug === "clawsweeper";
if (appSlug === "clawsweeper") {
return true;
}
// GitHub can omit performed_via_github_app on issue comments while still
// returning the reserved App bot identity.
const login = String(comment?.user?.login ?? "").toLowerCase();
const userType = String(comment?.user?.type ?? "");
return login === CLAWSWEEPER_BOT_LOGIN && userType === "Bot";
}
export function hasClawSweeperExactHeadProof({ pullRequest, comments = [] } = {}) {

View File

@@ -1,4 +1,5 @@
import "./isolated-agent.mocks.js";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { loadModelCatalog } from "../agents/model-catalog.js";
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
@@ -21,7 +22,7 @@ import * as isolatedAgentRunRuntime from "./isolated-agent/run.runtime.js";
function installThinkingTestProviders() {
const registry = createTestRegistry();
registry.providers = ["anthropic", "openai", "openrouter"].map(
registry.providers = ["anthropic", "google", "openai", "openrouter"].map(
(providerId): PluginProviderRegistration => ({
pluginId: providerId,
source: "test",
@@ -29,10 +30,18 @@ function installThinkingTestProviders() {
id: providerId,
label: providerId,
auth: [],
resolveThinkingProfile: () => ({
levels: BASE_THINKING_LEVELS.map((id) => ({ id })),
defaultLevel: "off",
}),
resolveThinkingProfile: ({ modelId }) =>
providerId === "google" && modelId === "gemini-3-flash-preview"
? {
levels: (["off", "minimal", "low", "medium", "adaptive", "high"] as const).map(
(id) => ({ id }),
),
preserveWhenCatalogReasoningFalse: true,
}
: {
levels: BASE_THINKING_LEVELS.map((id) => ({ id })),
defaultLevel: "off",
},
},
}),
);
@@ -253,4 +262,38 @@ describe("runCronIsolatedAgentTurn model overrides", () => {
expect(callArgs?.thinkLevel).toBe("low");
});
});
it("keeps configured Gemini 3 cron thinking when catalog reasoning metadata is stale", async () => {
await withTempHome(async (home) => {
vi.mocked(isolatedAgentRunRuntime.resolveThinkingDefault).mockReturnValueOnce("low");
vi.mocked(loadModelCatalog).mockResolvedValueOnce([
{
id: "gemini-3-flash-preview",
name: "Gemini 3 Flash Preview",
provider: "google",
reasoning: false,
},
]);
await runCronTurn(home, {
cfgOverrides: {
agents: {
defaults: {
model: "google/gemini-3-flash-preview",
workspace: path.join(home, "openclaw"),
thinkingDefault: "low",
},
},
},
jobPayload: DEFAULT_AGENT_TURN_PAYLOAD,
mockTexts: ["done"],
});
const calls = vi.mocked(runEmbeddedPiAgent).mock.calls;
const callArgs = calls[calls.length - 1]?.[0];
expect(callArgs?.provider).toBe("google");
expect(callArgs?.model).toBe("gemini-3-flash-preview");
expect(callArgs?.thinkLevel).toBe("low");
});
});
});

View File

@@ -234,7 +234,7 @@ describe("real-behavior-proof-policy", () => {
expect(evaluateClawSweeperExactHeadProof({ pullRequest, comments }).passed).toBe(false);
});
it("rejects bot-shaped ClawSweeper pass verdict markers without the GitHub App source", () => {
it("accepts exact ClawSweeper bot pass verdict markers when GitHub omits the app source", () => {
const pullRequest = {
number: 83581,
head: {
@@ -251,6 +251,27 @@ describe("real-behavior-proof-policy", () => {
},
];
expect(hasClawSweeperExactHeadProof({ pullRequest, comments })).toBe(true);
expect(evaluateClawSweeperExactHeadProof({ pullRequest, comments }).passed).toBe(true);
});
it("rejects bot-shaped pass verdict markers from other bot users", () => {
const pullRequest = {
number: 83581,
head: {
sha: "06ee95df6608d29a395c52ba8ab53fdd93a9dc4f",
},
};
const comments = [
{
user: {
login: "not-clawsweeper[bot]",
type: "Bot",
},
body: "<!-- clawsweeper-verdict:pass item=83581 sha=06ee95df6608d29a395c52ba8ab53fdd93a9dc4f confidence=high -->",
},
];
expect(hasClawSweeperExactHeadProof({ pullRequest, comments })).toBe(false);
expect(evaluateClawSweeperExactHeadProof({ pullRequest, comments }).passed).toBe(false);
});