fix: polish opencode-zen onboarding (#623) (thanks @magimetal)
This commit is contained in:
@@ -97,4 +97,57 @@ describe("applyAuthChoice", () => {
|
||||
};
|
||||
expect(parsed.profiles?.["minimax:default"]?.key).toBe("sk-minimax-test");
|
||||
});
|
||||
|
||||
it("does not override the default model when selecting opencode-zen without setDefaultModel", async () => {
|
||||
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
|
||||
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
|
||||
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
|
||||
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
|
||||
|
||||
const text = vi.fn().mockResolvedValue("sk-opencode-zen-test");
|
||||
const select: WizardPrompter["select"] = vi.fn(
|
||||
async (params) => params.options[0]?.value as never,
|
||||
);
|
||||
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
|
||||
const prompter: WizardPrompter = {
|
||||
intro: vi.fn(noopAsync),
|
||||
outro: vi.fn(noopAsync),
|
||||
note: vi.fn(noopAsync),
|
||||
select,
|
||||
multiselect,
|
||||
text,
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: noop, stop: noop })),
|
||||
};
|
||||
const runtime: RuntimeEnv = {
|
||||
log: vi.fn(),
|
||||
error: vi.fn(),
|
||||
exit: vi.fn((code: number) => {
|
||||
throw new Error(`exit:${code}`);
|
||||
}),
|
||||
};
|
||||
|
||||
const result = await applyAuthChoice({
|
||||
authChoice: "opencode-zen",
|
||||
config: {
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "anthropic/claude-opus-4-5" },
|
||||
},
|
||||
},
|
||||
},
|
||||
prompter,
|
||||
runtime,
|
||||
setDefaultModel: false,
|
||||
});
|
||||
|
||||
expect(text).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ message: "Enter OpenCode Zen API key" }),
|
||||
);
|
||||
expect(result.config.agents?.defaults?.model?.primary).toBe(
|
||||
"anthropic/claude-opus-4-5",
|
||||
);
|
||||
expect(result.config.models?.providers?.["opencode-zen"]).toBeDefined();
|
||||
expect(result.agentModelOverride).toBe("opencode-zen/claude-opus-4-5");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,6 +43,7 @@ import {
|
||||
applyMinimaxHostedProviderConfig,
|
||||
applyMinimaxProviderConfig,
|
||||
applyOpencodeZenConfig,
|
||||
applyOpencodeZenProviderConfig,
|
||||
MINIMAX_HOSTED_MODEL_REF,
|
||||
setAnthropicApiKey,
|
||||
setGeminiApiKey,
|
||||
@@ -678,7 +679,7 @@ export async function applyAuthChoice(params: {
|
||||
"Model configured",
|
||||
);
|
||||
} else {
|
||||
nextConfig = applyOpencodeZenConfig(nextConfig);
|
||||
nextConfig = applyOpencodeZenProviderConfig(nextConfig);
|
||||
agentModelOverride = OPENCODE_ZEN_DEFAULT_MODEL;
|
||||
await noteAgentModel(OPENCODE_ZEN_DEFAULT_MODEL);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import {
|
||||
applyAuthProfileConfig,
|
||||
applyMinimaxApiConfig,
|
||||
applyMinimaxApiProviderConfig,
|
||||
applyOpencodeZenConfig,
|
||||
applyOpencodeZenProviderConfig,
|
||||
writeOAuthCredentials,
|
||||
} from "./onboard-auth.js";
|
||||
|
||||
@@ -250,3 +252,61 @@ describe("applyMinimaxApiProviderConfig", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("applyOpencodeZenProviderConfig", () => {
|
||||
it("adds opencode-zen provider with correct settings", () => {
|
||||
const cfg = applyOpencodeZenProviderConfig({});
|
||||
expect(cfg.models?.providers?.["opencode-zen"]).toMatchObject({
|
||||
baseUrl: "https://opencode.ai/zen/v1",
|
||||
apiKey: "opencode-zen",
|
||||
api: "openai-completions",
|
||||
});
|
||||
expect(
|
||||
cfg.models?.providers?.["opencode-zen"]?.models.length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("adds allowlist entries for fallback models", () => {
|
||||
const cfg = applyOpencodeZenProviderConfig({});
|
||||
const models = cfg.agents?.defaults?.models ?? {};
|
||||
expect(Object.keys(models)).toContain("opencode-zen/claude-opus-4-5");
|
||||
expect(Object.keys(models)).toContain("opencode-zen/gpt-5.2");
|
||||
});
|
||||
|
||||
it("preserves existing alias for the default model", () => {
|
||||
const cfg = applyOpencodeZenProviderConfig({
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"opencode-zen/claude-opus-4-5": { alias: "My Opus" },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(
|
||||
cfg.agents?.defaults?.models?.["opencode-zen/claude-opus-4-5"]?.alias,
|
||||
).toBe("My Opus");
|
||||
});
|
||||
});
|
||||
|
||||
describe("applyOpencodeZenConfig", () => {
|
||||
it("sets correct primary model", () => {
|
||||
const cfg = applyOpencodeZenConfig({});
|
||||
expect(cfg.agents?.defaults?.model?.primary).toBe(
|
||||
"opencode-zen/claude-opus-4-5",
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves existing model fallbacks", () => {
|
||||
const cfg = applyOpencodeZenConfig({
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { fallbacks: ["anthropic/claude-opus-4-5"] },
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(cfg.agents?.defaults?.model?.fallbacks).toEqual([
|
||||
"anthropic/claude-opus-4-5",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -402,18 +402,24 @@ export async function setOpencodeZenApiKey(key: string, agentDir?: string) {
|
||||
export function applyOpencodeZenProviderConfig(
|
||||
cfg: ClawdbotConfig,
|
||||
): ClawdbotConfig {
|
||||
const opencodeModels = getOpencodeZenStaticFallbackModels();
|
||||
|
||||
const providers = { ...cfg.models?.providers };
|
||||
providers["opencode-zen"] = {
|
||||
baseUrl: OPENCODE_ZEN_API_BASE_URL,
|
||||
apiKey: "opencode-zen",
|
||||
api: "openai-completions",
|
||||
models: getOpencodeZenStaticFallbackModels(),
|
||||
models: opencodeModels,
|
||||
};
|
||||
|
||||
const models = { ...cfg.agents?.defaults?.models };
|
||||
for (const model of opencodeModels) {
|
||||
const key = `opencode-zen/${model.id}`;
|
||||
models[key] = models[key] ?? {};
|
||||
}
|
||||
models[OPENCODE_ZEN_DEFAULT_MODEL_REF] = {
|
||||
...models[OPENCODE_ZEN_DEFAULT_MODEL_REF],
|
||||
alias: "Opus",
|
||||
alias: models[OPENCODE_ZEN_DEFAULT_MODEL_REF]?.alias ?? "Opus",
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user