Skip to content

Commit abb5388

Browse files
committed
refactor: reuse canonical provider protocol constants
1 parent 2ff97ad commit abb5388

3 files changed

Lines changed: 63 additions & 48 deletions

File tree

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,107 @@
1-
import { getApiProtocol, providerIdentifiers } from "../index.js"
1+
import { ANTHROPIC_API_PROTOCOL, getApiProtocol, providerIdentifiers } from "../index.js"
22

33
describe("getApiProtocol", () => {
44
describe("Anthropic-style providers", () => {
55
it("should return 'anthropic' for anthropic provider", () => {
6-
expect(getApiProtocol("anthropic")).toBe("anthropic")
7-
expect(getApiProtocol("anthropic", "gpt-4")).toBe("anthropic")
6+
expect(getApiProtocol(providerIdentifiers.anthropic)).toBe(ANTHROPIC_API_PROTOCOL)
7+
expect(getApiProtocol(providerIdentifiers.anthropic, "gpt-4")).toBe(ANTHROPIC_API_PROTOCOL)
88
})
99

1010
it("should return 'anthropic' for bedrock provider", () => {
11-
expect(getApiProtocol("bedrock")).toBe("anthropic")
12-
expect(getApiProtocol("bedrock", "gpt-4")).toBe("anthropic")
13-
expect(getApiProtocol("bedrock", "claude-3-opus")).toBe("anthropic")
11+
expect(getApiProtocol(providerIdentifiers.bedrock)).toBe(ANTHROPIC_API_PROTOCOL)
12+
expect(getApiProtocol(providerIdentifiers.bedrock, "gpt-4")).toBe(ANTHROPIC_API_PROTOCOL)
13+
expect(getApiProtocol(providerIdentifiers.bedrock, "claude-3-opus")).toBe(ANTHROPIC_API_PROTOCOL)
1414
})
1515
})
1616

1717
describe("Vertex provider with Claude models", () => {
1818
it("should return 'anthropic' for vertex provider with claude models", () => {
19-
expect(getApiProtocol(providerIdentifiers.vertex, "claude-3-opus")).toBe("anthropic")
20-
expect(getApiProtocol("vertex", "Claude-3-Sonnet")).toBe("anthropic")
21-
expect(getApiProtocol("vertex", "CLAUDE-instant")).toBe("anthropic")
22-
expect(getApiProtocol("vertex", "anthropic/claude-3-haiku")).toBe("anthropic")
19+
expect(getApiProtocol(providerIdentifiers.vertex, "claude-3-opus")).toBe(ANTHROPIC_API_PROTOCOL)
20+
expect(getApiProtocol(providerIdentifiers.vertex, "Claude-3-Sonnet")).toBe(ANTHROPIC_API_PROTOCOL)
21+
expect(getApiProtocol(providerIdentifiers.vertex, "CLAUDE-instant")).toBe(ANTHROPIC_API_PROTOCOL)
22+
expect(getApiProtocol(providerIdentifiers.vertex, "anthropic/claude-3-haiku")).toBe(ANTHROPIC_API_PROTOCOL)
2323
})
2424

2525
it("should return 'openai' for vertex provider with non-claude models", () => {
26-
expect(getApiProtocol("vertex", "gpt-4")).toBe("openai")
27-
expect(getApiProtocol("vertex", "gemini-pro")).toBe("openai")
28-
expect(getApiProtocol("vertex", "llama-2")).toBe("openai")
26+
expect(getApiProtocol(providerIdentifiers.vertex, "gpt-4")).toBe("openai")
27+
expect(getApiProtocol(providerIdentifiers.vertex, "gemini-pro")).toBe("openai")
28+
expect(getApiProtocol(providerIdentifiers.vertex, "llama-2")).toBe("openai")
2929
})
3030

3131
it("should return 'openai' for vertex provider without model", () => {
32-
expect(getApiProtocol("vertex")).toBe("openai")
32+
expect(getApiProtocol(providerIdentifiers.vertex)).toBe("openai")
3333
})
3434
})
3535

3636
describe("Vercel AI Gateway provider", () => {
3737
it("uses canonical gateway identifiers for Anthropic model protocol selection", () => {
38-
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "anthropic/claude-3-opus")).toBe("anthropic")
39-
expect(getApiProtocol(providerIdentifiers.zooGateway, "anthropic/claude-3-opus")).toBe("anthropic")
38+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "anthropic/claude-3-opus")).toBe(
39+
ANTHROPIC_API_PROTOCOL,
40+
)
41+
expect(getApiProtocol(providerIdentifiers.zooGateway, "anthropic/claude-3-opus")).toBe(
42+
ANTHROPIC_API_PROTOCOL,
43+
)
4044
})
4145

4246
it("should return 'anthropic' for vercel-ai-gateway provider with anthropic models", () => {
43-
expect(getApiProtocol("vercel-ai-gateway", "anthropic/claude-3-opus")).toBe("anthropic")
44-
expect(getApiProtocol("vercel-ai-gateway", "anthropic/claude-3.5-sonnet")).toBe("anthropic")
45-
expect(getApiProtocol("vercel-ai-gateway", "ANTHROPIC/claude-sonnet-4")).toBe("anthropic")
46-
expect(getApiProtocol("vercel-ai-gateway", "anthropic/claude-opus-4.1")).toBe("anthropic")
47+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "anthropic/claude-3-opus")).toBe(
48+
ANTHROPIC_API_PROTOCOL,
49+
)
50+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "anthropic/claude-3.5-sonnet")).toBe(
51+
ANTHROPIC_API_PROTOCOL,
52+
)
53+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "ANTHROPIC/claude-sonnet-4")).toBe(
54+
ANTHROPIC_API_PROTOCOL,
55+
)
56+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "anthropic/claude-opus-4.1")).toBe(
57+
ANTHROPIC_API_PROTOCOL,
58+
)
4759
})
4860

4961
it("should return 'openai' for vercel-ai-gateway provider with non-anthropic models", () => {
50-
expect(getApiProtocol("vercel-ai-gateway", "openai/gpt-4")).toBe("openai")
51-
expect(getApiProtocol("vercel-ai-gateway", "google/gemini-pro")).toBe("openai")
52-
expect(getApiProtocol("vercel-ai-gateway", "meta/llama-3")).toBe("openai")
53-
expect(getApiProtocol("vercel-ai-gateway", "mistral/mixtral")).toBe("openai")
62+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "openai/gpt-4")).toBe("openai")
63+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "google/gemini-pro")).toBe("openai")
64+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "meta/llama-3")).toBe("openai")
65+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway, "mistral/mixtral")).toBe("openai")
5466
})
5567

5668
it("should return 'openai' for vercel-ai-gateway provider without model", () => {
57-
expect(getApiProtocol("vercel-ai-gateway")).toBe("openai")
69+
expect(getApiProtocol(providerIdentifiers.vercelAiGateway)).toBe("openai")
5870
})
5971
})
6072

6173
describe("Opencode Go provider", () => {
6274
it("should return 'anthropic' for opencode-go Anthropic-format models (Qwen/MiniMax)", () => {
63-
expect(getApiProtocol(providerIdentifiers.opencodeGo, "qwen3.7-max")).toBe("anthropic")
64-
expect(getApiProtocol("opencode-go", "qwen3.7-plus")).toBe("anthropic")
65-
expect(getApiProtocol("opencode-go", "qwen3.6-plus")).toBe("anthropic")
66-
expect(getApiProtocol("opencode-go", "minimax-m3")).toBe("anthropic")
67-
expect(getApiProtocol("opencode-go", "minimax-m2.7")).toBe("anthropic")
68-
expect(getApiProtocol("opencode-go", "minimax-m2.5")).toBe("anthropic")
75+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "qwen3.7-max")).toBe(ANTHROPIC_API_PROTOCOL)
76+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "qwen3.7-plus")).toBe(ANTHROPIC_API_PROTOCOL)
77+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "qwen3.6-plus")).toBe(ANTHROPIC_API_PROTOCOL)
78+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "minimax-m3")).toBe(ANTHROPIC_API_PROTOCOL)
79+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "minimax-m2.7")).toBe(ANTHROPIC_API_PROTOCOL)
80+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "minimax-m2.5")).toBe(ANTHROPIC_API_PROTOCOL)
6981
})
7082

7183
it("should return 'openai' for opencode-go OpenAI-format models (GLM/DeepSeek/etc.)", () => {
72-
expect(getApiProtocol("opencode-go", "glm-5.2")).toBe("openai")
73-
expect(getApiProtocol("opencode-go", "deepseek-v4-pro")).toBe("openai")
74-
expect(getApiProtocol("opencode-go", "kimi-k2.5")).toBe("openai")
75-
expect(getApiProtocol("opencode-go", "mimo-v2.5")).toBe("openai")
84+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "glm-5.2")).toBe("openai")
85+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "deepseek-v4-pro")).toBe("openai")
86+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "kimi-k2.5")).toBe("openai")
87+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "mimo-v2.5")).toBe("openai")
7688
})
7789

7890
it("should return 'openai' for opencode-go without a model", () => {
79-
expect(getApiProtocol("opencode-go")).toBe("openai")
91+
expect(getApiProtocol(providerIdentifiers.opencodeGo)).toBe("openai")
8092
})
8193

8294
it("should return 'openai' for opencode-go with an unknown model id", () => {
83-
expect(getApiProtocol("opencode-go", "some-future-model")).toBe("openai")
95+
expect(getApiProtocol(providerIdentifiers.opencodeGo, "some-future-model")).toBe("openai")
8496
})
8597
})
8698

8799
describe("Other providers", () => {
88100
it("should return 'openai' for non-anthropic providers regardless of model", () => {
89-
expect(getApiProtocol("openrouter", "claude-3-opus")).toBe("openai")
90-
expect(getApiProtocol("openai", "claude-3-sonnet")).toBe("openai")
91-
expect(getApiProtocol("litellm", "claude-instant")).toBe("openai")
92-
expect(getApiProtocol("ollama", "claude-model")).toBe("openai")
101+
expect(getApiProtocol(providerIdentifiers.openrouter, "claude-3-opus")).toBe("openai")
102+
expect(getApiProtocol(providerIdentifiers.openai, "claude-3-sonnet")).toBe("openai")
103+
expect(getApiProtocol(providerIdentifiers.litellm, "claude-instant")).toBe("openai")
104+
expect(getApiProtocol(providerIdentifiers.ollama, "claude-model")).toBe("openai")
93105
})
94106
})
95107

@@ -100,13 +112,13 @@ describe("getApiProtocol", () => {
100112
})
101113

102114
it("should handle empty strings", () => {
103-
expect(getApiProtocol("vertex", "")).toBe("openai")
115+
expect(getApiProtocol(providerIdentifiers.vertex, "")).toBe("openai")
104116
})
105117

106118
it("should be case-insensitive for claude detection", () => {
107-
expect(getApiProtocol("vertex", "CLAUDE-3-OPUS")).toBe("anthropic")
108-
expect(getApiProtocol("vertex", "claude-3-opus")).toBe("anthropic")
109-
expect(getApiProtocol("vertex", "ClAuDe-InStAnT")).toBe("anthropic")
119+
expect(getApiProtocol(providerIdentifiers.vertex, "CLAUDE-3-OPUS")).toBe(ANTHROPIC_API_PROTOCOL)
120+
expect(getApiProtocol(providerIdentifiers.vertex, "claude-3-opus")).toBe(ANTHROPIC_API_PROTOCOL)
121+
expect(getApiProtocol(providerIdentifiers.vertex, "ClAuDe-InStAnT")).toBe(ANTHROPIC_API_PROTOCOL)
110122
})
111123
})
112124
})

packages/types/src/provider-settings.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import {
2929
minimaxModels,
3030
mimoModels,
3131
isOpencodeGoAnthropicFormatModel,
32+
ANTHROPIC_API_PROTOCOL,
33+
ANTHROPIC_MODEL_ID_PREFIX,
34+
CLAUDE_MODEL_ID_FRAGMENT,
3235
} from "./providers/index.js"
3336

3437
/**
@@ -587,9 +590,6 @@ export const ANTHROPIC_STYLE_PROVIDERS: ProviderName[] = [
587590
providerIdentifiers.minimax,
588591
]
589592

590-
const CLAUDE_MODEL_ID_FRAGMENT = "claude"
591-
const ANTHROPIC_MODEL_ID_PREFIX = "anthropic/"
592-
const ANTHROPIC_API_PROTOCOL = "anthropic"
593593
const ANTHROPIC_MODEL_GATEWAY_PROVIDERS: ProviderName[] = [
594594
providerIdentifiers.vercelAiGateway,
595595
providerIdentifiers.zooGateway,

packages/types/src/providers/anthropic.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import type { ModelInfo } from "../model.js"
55

66
export type AnthropicModelId = keyof typeof anthropicModels
77
export const anthropicDefaultModelId: AnthropicModelId = "claude-sonnet-4-5"
8+
export const ANTHROPIC_API_PROTOCOL = "anthropic"
9+
export const ANTHROPIC_MODEL_ID_PREFIX = "anthropic/"
10+
export const CLAUDE_MODEL_ID_FRAGMENT = "claude"
811

912
export const anthropicModels = {
1013
"claude-sonnet-4-6": {

0 commit comments

Comments
 (0)