mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-19 13:01:41 +00:00
fix(coding-agent): honor --model selection, thinking, and --api-key
This commit is contained in:
parent
7ccf809a5d
commit
56342258e1
4 changed files with 286 additions and 21 deletions
|
|
@ -1,6 +1,11 @@
|
|||
import type { Model } from "@mariozechner/pi-ai";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { defaultModelPerProvider, findInitialModel, parseModelPattern } from "../src/core/model-resolver.js";
|
||||
import {
|
||||
defaultModelPerProvider,
|
||||
findInitialModel,
|
||||
parseModelPattern,
|
||||
resolveCliModel,
|
||||
} from "../src/core/model-resolver.js";
|
||||
|
||||
// Mock models for testing
|
||||
const mockModels: Model<"anthropic-messages">[] = [
|
||||
|
|
@ -201,6 +206,114 @@ describe("parseModelPattern", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("resolveCliModel", () => {
|
||||
test("resolves --model provider/id without --provider", async () => {
|
||||
const registry = {
|
||||
getAll: () => allModels,
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
const result = await resolveCliModel({
|
||||
cliModel: "openai/gpt-4o",
|
||||
modelRegistry: registry,
|
||||
});
|
||||
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.model?.provider).toBe("openai");
|
||||
expect(result.model?.id).toBe("gpt-4o");
|
||||
});
|
||||
|
||||
test("resolves fuzzy patterns within an explicit provider", async () => {
|
||||
const registry = {
|
||||
getAll: () => allModels,
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
const result = await resolveCliModel({
|
||||
cliProvider: "openai",
|
||||
cliModel: "4o",
|
||||
modelRegistry: registry,
|
||||
});
|
||||
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.model?.provider).toBe("openai");
|
||||
expect(result.model?.id).toBe("gpt-4o");
|
||||
});
|
||||
|
||||
test("supports --model <pattern>:<thinking> (without explicit --thinking)", async () => {
|
||||
const registry = {
|
||||
getAll: () => allModels,
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
const result = await resolveCliModel({
|
||||
cliModel: "sonnet:high",
|
||||
modelRegistry: registry,
|
||||
});
|
||||
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.model?.id).toBe("claude-sonnet-4-5");
|
||||
expect(result.thinkingLevel).toBe("high");
|
||||
});
|
||||
|
||||
test("prefers exact model id match over provider inference (OpenRouter-style ids)", async () => {
|
||||
const registry = {
|
||||
getAll: () => allModels,
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
const result = await resolveCliModel({
|
||||
cliModel: "openai/gpt-4o:extended",
|
||||
modelRegistry: registry,
|
||||
});
|
||||
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.model?.provider).toBe("openrouter");
|
||||
expect(result.model?.id).toBe("openai/gpt-4o:extended");
|
||||
});
|
||||
|
||||
test("does not strip invalid :suffix as thinking level in --model (fail fast)", async () => {
|
||||
const registry = {
|
||||
getAll: () => allModels,
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
const result = await resolveCliModel({
|
||||
cliProvider: "openai",
|
||||
cliModel: "gpt-4o:extended",
|
||||
modelRegistry: registry,
|
||||
});
|
||||
|
||||
expect(result.model).toBeUndefined();
|
||||
expect(result.error).toContain("not found");
|
||||
});
|
||||
|
||||
test("returns a clear error when there are no models", async () => {
|
||||
const registry = {
|
||||
getAll: () => [],
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
const result = await resolveCliModel({
|
||||
cliProvider: "openai",
|
||||
cliModel: "gpt-4o",
|
||||
modelRegistry: registry,
|
||||
});
|
||||
|
||||
expect(result.model).toBeUndefined();
|
||||
expect(result.error).toContain("No models available");
|
||||
});
|
||||
|
||||
test("resolves provider-prefixed fuzzy patterns (openrouter/qwen -> openrouter model)", async () => {
|
||||
const registry = {
|
||||
getAll: () => allModels,
|
||||
} as unknown as Parameters<typeof resolveCliModel>[0]["modelRegistry"];
|
||||
|
||||
const result = await resolveCliModel({
|
||||
cliModel: "openrouter/qwen",
|
||||
modelRegistry: registry,
|
||||
});
|
||||
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.model?.provider).toBe("openrouter");
|
||||
expect(result.model?.id).toBe("qwen/qwen3-coder:exacto");
|
||||
});
|
||||
});
|
||||
|
||||
describe("default model selection", () => {
|
||||
test("ai-gateway default is opus 4.6", () => {
|
||||
expect(defaultModelPerProvider["vercel-ai-gateway"]).toBe("anthropic/claude-opus-4-6");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue