test: add integration tests for Vercel AI Gateway model resolution
This commit is contained in:
@@ -4137,3 +4137,405 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strings when only Vercel AI Gateway is available 1`] = `
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
||||||
|
"agents": {
|
||||||
|
"atlas": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
"explore": {
|
||||||
|
"model": "vercel/anthropic/claude-haiku-4.5",
|
||||||
|
},
|
||||||
|
"hephaestus": {
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
"librarian": {
|
||||||
|
"model": "vercel/anthropic/claude-haiku-4.5",
|
||||||
|
},
|
||||||
|
"metis": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
"momus": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "xhigh",
|
||||||
|
},
|
||||||
|
"multimodal-looker": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5-nano",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
"oracle": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
"prometheus": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
"sisyphus": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
"sisyphus-junior": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"artistry": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
"deep": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
"quick": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-haiku-4.5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3-flash-preview",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4-mini",
|
||||||
|
},
|
||||||
|
"ultrabrain": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "xhigh",
|
||||||
|
},
|
||||||
|
"unspecified-high": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.3-codex",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3-flash-preview",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
"unspecified-low": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.3-codex",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3-flash-preview",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
"visual-engineering": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
"writing": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/google/gemini-3-flash-preview",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`generateModelConfig Vercel AI Gateway provider uses vercel/ model strings with isMax20 flag 1`] = `
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
|
||||||
|
"agents": {
|
||||||
|
"atlas": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
"explore": {
|
||||||
|
"model": "vercel/anthropic/claude-haiku-4.5",
|
||||||
|
},
|
||||||
|
"hephaestus": {
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
"librarian": {
|
||||||
|
"model": "vercel/anthropic/claude-haiku-4.5",
|
||||||
|
},
|
||||||
|
"metis": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
"momus": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "xhigh",
|
||||||
|
},
|
||||||
|
"multimodal-looker": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5-nano",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
"oracle": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
"prometheus": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
"sisyphus": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
"sisyphus-junior": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"artistry": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
"deep": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
"quick": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-haiku-4.5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3-flash-preview",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4-mini",
|
||||||
|
},
|
||||||
|
"ultrabrain": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "xhigh",
|
||||||
|
},
|
||||||
|
"unspecified-high": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.4",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
"unspecified-low": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/openai/gpt-5.3-codex",
|
||||||
|
"variant": "medium",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "vercel/google/gemini-3-flash-preview",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
"visual-engineering": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-opus-4.6",
|
||||||
|
"variant": "max",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/google/gemini-3.1-pro-preview",
|
||||||
|
"variant": "high",
|
||||||
|
},
|
||||||
|
"writing": {
|
||||||
|
"fallback_models": [
|
||||||
|
{
|
||||||
|
"model": "vercel/anthropic/claude-sonnet-4.6",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"model": "vercel/google/gemini-3-flash-preview",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ function createConfig(overrides: Partial<InstallConfig> = {}): InstallConfig {
|
|||||||
hasZaiCodingPlan: false,
|
hasZaiCodingPlan: false,
|
||||||
hasKimiForCoding: false,
|
hasKimiForCoding: false,
|
||||||
hasOpencodeGo: false,
|
hasOpencodeGo: false,
|
||||||
|
hasVercelAiGateway: false,
|
||||||
...overrides,
|
...overrides,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -607,6 +608,74 @@ describe("generateModelConfig", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("Vercel AI Gateway provider", () => {
|
||||||
|
test("uses vercel/ model strings when only Vercel AI Gateway is available", () => {
|
||||||
|
// #given only Vercel AI Gateway is available
|
||||||
|
const config = createConfig({ hasVercelAiGateway: true })
|
||||||
|
|
||||||
|
// #when generateModelConfig is called
|
||||||
|
const result = generateModelConfig(config)
|
||||||
|
|
||||||
|
// #then should use vercel/<sub-provider>/<model> format
|
||||||
|
expect(result).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("uses vercel/ model strings with isMax20 flag", () => {
|
||||||
|
// #given Vercel AI Gateway is available with Max 20 plan
|
||||||
|
const config = createConfig({ hasVercelAiGateway: true, isMax20: true })
|
||||||
|
|
||||||
|
// #when generateModelConfig is called
|
||||||
|
const result = generateModelConfig(config)
|
||||||
|
|
||||||
|
// #then should use higher capability models via gateway
|
||||||
|
expect(result).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("explore uses vercel/anthropic/claude-haiku-4.5 when only gateway available", () => {
|
||||||
|
// #given only Vercel AI Gateway is available
|
||||||
|
const config = createConfig({ hasVercelAiGateway: true })
|
||||||
|
|
||||||
|
// #when generateModelConfig is called
|
||||||
|
const result = generateModelConfig(config)
|
||||||
|
|
||||||
|
// #then explore should use gateway-routed claude-haiku
|
||||||
|
expect(result.agents?.explore?.model).toBe("vercel/anthropic/claude-haiku-4.5")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("librarian uses vercel/anthropic/claude-haiku-4.5 when only gateway available", () => {
|
||||||
|
// #given only Vercel AI Gateway is available
|
||||||
|
const config = createConfig({ hasVercelAiGateway: true })
|
||||||
|
|
||||||
|
// #when generateModelConfig is called
|
||||||
|
const result = generateModelConfig(config)
|
||||||
|
|
||||||
|
// #then librarian should use gateway-routed claude-haiku
|
||||||
|
expect(result.agents?.librarian?.model).toBe("vercel/anthropic/claude-haiku-4.5")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Hephaestus is created when only Vercel AI Gateway is available", () => {
|
||||||
|
// #given only Vercel AI Gateway is available
|
||||||
|
const config = createConfig({ hasVercelAiGateway: true })
|
||||||
|
|
||||||
|
// #when generateModelConfig is called
|
||||||
|
const result = generateModelConfig(config)
|
||||||
|
|
||||||
|
// #then hephaestus should be created with gateway-routed gpt-5.4
|
||||||
|
expect(result.agents?.hephaestus?.model).toBe("vercel/openai/gpt-5.4")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("native providers take priority over gateway", () => {
|
||||||
|
// #given Claude and Vercel AI Gateway are both available
|
||||||
|
const config = createConfig({ hasClaude: true, hasVercelAiGateway: true })
|
||||||
|
|
||||||
|
// #when generateModelConfig is called
|
||||||
|
const result = generateModelConfig(config)
|
||||||
|
|
||||||
|
// #then should prefer native anthropic over gateway
|
||||||
|
expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4.6")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("schema URL", () => {
|
describe("schema URL", () => {
|
||||||
test("always includes correct schema URL", () => {
|
test("always includes correct schema URL", () => {
|
||||||
// #given any config
|
// #given any config
|
||||||
|
|||||||
Reference in New Issue
Block a user