From f8c70bf1f1b0b6d6829418f12b24f306b9d5bb84 Mon Sep 17 00:00:00 2001 From: Bruce MacDonald Date: Tue, 17 Mar 2026 13:59:44 -0700 Subject: [PATCH] fix(ollama): don't auto-pull glm-4.7-flash during Local mode onboarding --- extensions/ollama/index.ts | 3 +-- src/commands/ollama-setup.test.ts | 27 ++++++++++++++------------- src/plugins/provider-ollama-setup.ts | 12 +++++------- src/wizard/setup.ts | 3 ++- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/extensions/ollama/index.ts b/extensions/ollama/index.ts index 6f7ec7f2088..41b225ef871 100644 --- a/extensions/ollama/index.ts +++ b/extensions/ollama/index.ts @@ -49,7 +49,6 @@ export default definePluginEntry({ }, ], configPatch: result.config, - defaultModel: `ollama/${result.defaultModelId}`, }; }, runNonInteractive: async (ctx: ProviderAuthMethodNonInteractiveContext) => { @@ -118,7 +117,7 @@ export default definePluginEntry({ return; } const providerSetup = await loadProviderSetup(); - await providerSetup.ensureOllamaModelPulled({ config, prompter }); + await providerSetup.ensureOllamaModelPulled({ config, model, prompter }); }, }); }, diff --git a/src/commands/ollama-setup.test.ts b/src/commands/ollama-setup.test.ts index 0b9b5d0e414..b85c3ff451b 100644 --- a/src/commands/ollama-setup.test.ts +++ b/src/commands/ollama-setup.test.ts @@ -14,15 +14,11 @@ vi.mock("../agents/auth-profiles.js", () => ({ })); const openUrlMock = vi.hoisted(() => vi.fn(async () => false)); -vi.mock("./onboard-helpers.js", async (importOriginal) => { - const original = await importOriginal(); - return { ...original, openUrl: openUrlMock }; -}); - const isRemoteEnvironmentMock = vi.hoisted(() => vi.fn(() => false)); -vi.mock("./oauth-env.js", () => ({ - isRemoteEnvironment: isRemoteEnvironmentMock, -})); +vi.mock("../plugins/setup-browser.js", async (importOriginal) => { + const original = await importOriginal(); + return { ...original, openUrl: openUrlMock, isRemoteEnvironment: isRemoteEnvironmentMock }; +}); function createOllamaFetchMock(params: { tags?: string[]; @@ -104,26 +100,28 @@ describe("ollama setup", () => { isRemoteEnvironmentMock.mockReset().mockReturnValue(false); }); - it("returns suggested default model for local mode", async () => { + it("puts suggested local model first in local mode", async () => { const prompter = createModePrompter("local"); const fetchMock = createOllamaFetchMock({ tags: ["llama3:8b"] }); vi.stubGlobal("fetch", fetchMock); const result = await promptAndConfigureOllama({ cfg: {}, prompter }); + const modelIds = result.config.models?.providers?.ollama?.models?.map((m) => m.id); - expect(result.defaultModelId).toBe("glm-4.7-flash"); + expect(modelIds?.[0]).toBe("glm-4.7-flash"); }); - it("returns suggested default model for remote mode", async () => { + it("puts suggested cloud model first in remote mode", async () => { const prompter = createModePrompter("remote"); const fetchMock = createOllamaFetchMock({ tags: ["llama3:8b"] }); vi.stubGlobal("fetch", fetchMock); const result = await promptAndConfigureOllama({ cfg: {}, prompter }); + const modelIds = result.config.models?.providers?.ollama?.models?.map((m) => m.id); - expect(result.defaultModelId).toBe("kimi-k2.5:cloud"); + expect(modelIds?.[0]).toBe("kimi-k2.5:cloud"); }); it("mode selection affects model ordering (local)", async () => { @@ -134,7 +132,6 @@ describe("ollama setup", () => { const result = await promptAndConfigureOllama({ cfg: {}, prompter }); - expect(result.defaultModelId).toBe("glm-4.7-flash"); const modelIds = result.config.models?.providers?.ollama?.models?.map((m) => m.id); expect(modelIds?.[0]).toBe("glm-4.7-flash"); expect(modelIds).toContain("llama3:8b"); @@ -238,6 +235,7 @@ describe("ollama setup", () => { await ensureOllamaModelPulled({ config: createDefaultOllamaConfig("ollama/glm-4.7-flash"), + model: "ollama/glm-4.7-flash", prompter, }); @@ -253,6 +251,7 @@ describe("ollama setup", () => { await ensureOllamaModelPulled({ config: createDefaultOllamaConfig("ollama/glm-4.7-flash"), + model: "ollama/glm-4.7-flash", prompter, }); @@ -266,6 +265,7 @@ describe("ollama setup", () => { await ensureOllamaModelPulled({ config: createDefaultOllamaConfig("ollama/kimi-k2.5:cloud"), + model: "ollama/kimi-k2.5:cloud", prompter, }); @@ -281,6 +281,7 @@ describe("ollama setup", () => { config: { agents: { defaults: { model: { primary: "openai/gpt-4o" } } }, }, + model: "openai/gpt-4o", prompter, }); diff --git a/src/plugins/provider-ollama-setup.ts b/src/plugins/provider-ollama-setup.ts index ac3fd5d1fc7..5d8cab0303a 100644 --- a/src/plugins/provider-ollama-setup.ts +++ b/src/plugins/provider-ollama-setup.ts @@ -293,7 +293,7 @@ async function storeOllamaCredential(agentDir?: string): Promise { export async function promptAndConfigureOllama(params: { cfg: OpenClawConfig; prompter: WizardPrompter; -}): Promise<{ config: OpenClawConfig; defaultModelId: string }> { +}): Promise<{ config: OpenClawConfig }> { const { prompter } = params; // 1. Prompt base URL @@ -398,14 +398,13 @@ export async function promptAndConfigureOllama(params: { ...modelNames.filter((name) => !suggestedModels.includes(name)), ]; - const defaultModelId = suggestedModels[0] ?? OLLAMA_DEFAULT_MODEL; const config = applyOllamaProviderConfig( params.cfg, baseUrl, orderedModelNames, discoveredModelsByName, ); - return { config, defaultModelId }; + return { config }; } /** Non-interactive: auto-discover models and configure provider. */ @@ -512,15 +511,14 @@ export async function configureOllamaNonInteractive(params: { /** Pull the configured default Ollama model if it isn't already available locally. */ export async function ensureOllamaModelPulled(params: { config: OpenClawConfig; + model: string; prompter: WizardPrompter; }): Promise { - const modelCfg = params.config.agents?.defaults?.model; - const modelId = typeof modelCfg === "string" ? modelCfg : modelCfg?.primary; - if (!modelId?.startsWith("ollama/")) { + if (!params.model.startsWith("ollama/")) { return; } const baseUrl = params.config.models?.providers?.ollama?.baseUrl ?? OLLAMA_DEFAULT_BASE_URL; - const modelName = modelId.slice("ollama/".length); + const modelName = params.model.slice("ollama/".length); if (isOllamaCloudModel(modelName)) { return; } diff --git a/src/wizard/setup.ts b/src/wizard/setup.ts index 5e87a967c25..8d1a98883d0 100644 --- a/src/wizard/setup.ts +++ b/src/wizard/setup.ts @@ -486,7 +486,8 @@ export async function runSetupWizard( const modelSelection = await promptDefaultModel({ config: nextConfig, prompter, - allowKeep: true, + // For ollama, don't allow "keep current" since we may need to download the selected model + allowKeep: authChoice !== "ollama", ignoreAllowlist: true, includeProviderPluginSetups: true, preferredProvider: await resolvePreferredProviderForAuthChoice({