fix: set gemini default model for api-key auth (#489) - thanks @jonasjancarik

This commit is contained in:
Peter Steinberger
2026-01-09 02:49:42 +01:00
parent 302d51fd40
commit e1789ba9e5
6 changed files with 108 additions and 0 deletions

View File

@@ -37,6 +37,7 @@
- Signal: accept UUID-only senders for pairing/allowlists/routing when sourceNumber is missing. (#523) — thanks @neist
- Agent system prompt: avoid automatic self-updates unless explicitly requested.
- Onboarding: tighten QuickStart hint copy for configuring later.
- Onboarding: set Gemini 3 Pro as the default model for Gemini API key auth. (#489) — thanks @jonasjancarik
- Onboarding: avoid “token expired” for Codex CLI when expiry is heuristic.
- Onboarding: QuickStart jumps straight into provider selection with Telegram preselected when unset.
- Onboarding: QuickStart auto-installs the Gateway daemon with Node (no runtime picker).

View File

@@ -25,6 +25,10 @@ import {
isRemoteEnvironment,
loginAntigravityVpsAware,
} from "./antigravity-oauth.js";
import {
applyGoogleGeminiModelDefault,
GOOGLE_GEMINI_DEFAULT_MODEL,
} from "./google-gemini-model-default.js";
import {
applyAuthProfileConfig,
applyMinimaxConfig,
@@ -427,6 +431,19 @@ export async function applyAuthChoice(params: {
provider: "google",
mode: "api_key",
});
if (params.setDefaultModel) {
const applied = applyGoogleGeminiModelDefault(nextConfig);
nextConfig = applied.next;
if (applied.changed) {
await params.prompter.note(
`Default model set to ${GOOGLE_GEMINI_DEFAULT_MODEL}`,
"Model configured",
);
}
} else {
agentModelOverride = GOOGLE_GEMINI_DEFAULT_MODEL;
await noteAgentModel(GOOGLE_GEMINI_DEFAULT_MODEL);
}
} else if (params.authChoice === "apiKey") {
const key = await params.prompter.text({
message: "Enter Anthropic API key",

View File

@@ -50,6 +50,10 @@ import {
GATEWAY_DAEMON_RUNTIME_OPTIONS,
type GatewayDaemonRuntime,
} from "./daemon-runtime.js";
import {
applyGoogleGeminiModelDefault,
GOOGLE_GEMINI_DEFAULT_MODEL,
} from "./google-gemini-model-default.js";
import { healthCommand } from "./health.js";
import {
applyAuthProfileConfig,
@@ -529,6 +533,14 @@ async function promptAuthConfig(
provider: "google",
mode: "api_key",
});
const applied = applyGoogleGeminiModelDefault(next);
next = applied.next;
if (applied.changed) {
note(
`Default model set to ${GOOGLE_GEMINI_DEFAULT_MODEL}`,
"Model configured",
);
}
} else if (authChoice === "apiKey") {
const key = guardCancel(
await text({

View File

@@ -0,0 +1,38 @@
import { describe, expect, it } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import {
applyGoogleGeminiModelDefault,
GOOGLE_GEMINI_DEFAULT_MODEL,
} from "./google-gemini-model-default.js";
describe("applyGoogleGeminiModelDefault", () => {
it("sets gemini default when model is unset", () => {
const cfg: ClawdbotConfig = { agent: {} };
const applied = applyGoogleGeminiModelDefault(cfg);
expect(applied.changed).toBe(true);
expect(applied.next.agent?.model).toEqual({
primary: GOOGLE_GEMINI_DEFAULT_MODEL,
});
});
it("overrides existing model", () => {
const cfg: ClawdbotConfig = {
agent: { model: "anthropic/claude-opus-4-5" },
};
const applied = applyGoogleGeminiModelDefault(cfg);
expect(applied.changed).toBe(true);
expect(applied.next.agent?.model).toEqual({
primary: GOOGLE_GEMINI_DEFAULT_MODEL,
});
});
it("no-ops when already gemini default", () => {
const cfg: ClawdbotConfig = {
agent: { model: GOOGLE_GEMINI_DEFAULT_MODEL },
};
const applied = applyGoogleGeminiModelDefault(cfg);
expect(applied.changed).toBe(false);
expect(applied.next).toEqual(cfg);
});
});

View File

@@ -0,0 +1,38 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { AgentModelListConfig } from "../config/types.js";
export const GOOGLE_GEMINI_DEFAULT_MODEL = "google/gemini-3-pro-preview";
function resolvePrimaryModel(
model?: AgentModelListConfig | string,
): string | undefined {
if (typeof model === "string") return model;
if (model && typeof model === "object" && typeof model.primary === "string") {
return model.primary;
}
return undefined;
}
export function applyGoogleGeminiModelDefault(cfg: ClawdbotConfig): {
next: ClawdbotConfig;
changed: boolean;
} {
const current = resolvePrimaryModel(cfg.agent?.model)?.trim();
if (current === GOOGLE_GEMINI_DEFAULT_MODEL) {
return { next: cfg, changed: false };
}
return {
next: {
...cfg,
agent: {
...cfg.agent,
model:
cfg.agent?.model && typeof cfg.agent.model === "object"
? { ...cfg.agent.model, primary: GOOGLE_GEMINI_DEFAULT_MODEL }
: { primary: GOOGLE_GEMINI_DEFAULT_MODEL },
},
},
changed: true,
};
}

View File

@@ -23,6 +23,7 @@ import {
DEFAULT_GATEWAY_DAEMON_RUNTIME,
isGatewayDaemonRuntime,
} from "./daemon-runtime.js";
import { applyGoogleGeminiModelDefault } from "./google-gemini-model-default.js";
import { healthCommand } from "./health.js";
import {
applyAuthProfileConfig,
@@ -133,6 +134,7 @@ export async function runNonInteractiveOnboarding(
provider: "google",
mode: "api_key",
});
nextConfig = applyGoogleGeminiModelDefault(nextConfig).next;
} else if (authChoice === "claude-cli") {
const store = ensureAuthProfileStore(undefined, {
allowKeychainPrompt: false,