provider.go

v0.6.2
Doc Versions Source
1
package provider
2
3
// StaticModel represents a model available from a provider (no API fetch needed).
4
type StaticModel struct {
5
	ID     string
6
	Name   string
7
	Family string
8
}
9
10
// Plan describes one billing/access plan for a provider with multiple base URLs.
11
type Plan struct {
12
	Key         string // e.g. "api", "coding"
13
	Name        string // display name, e.g. "API (pay per token)"
14
	Description string
15
	BaseURL     string
16
	Compat      string // optional override; when set, switches the provider's Compat mode
17
	AuthEnvVar  string // optional override; when set, switches the auth env var
18
}
19
20
var zaiModels = []StaticModel{
21
	{ID: "glm-5", Name: "GLM-5", Family: "GLM-5"},
22
	{ID: "glm-5-turbo", Name: "GLM-5 Turbo", Family: "GLM-5"},
23
	{ID: "glm-4.7", Name: "GLM-4.7", Family: "GLM-4.7"},
24
	{ID: "glm-4.7-flash", Name: "GLM-4.7 Flash", Family: "GLM-4.7"},
25
	{ID: "glm-4.7-flashx", Name: "GLM-4.7 FlashX", Family: "GLM-4.7"},
26
	{ID: "glm-4.6", Name: "GLM-4.6", Family: "GLM-4.6"},
27
	{ID: "glm-4.5", Name: "GLM-4.5", Family: "GLM-4.5"},
28
	{ID: "glm-4.5-air", Name: "GLM-4.5 Air", Family: "GLM-4.5"},
29
	{ID: "glm-4.5-x", Name: "GLM-4.5 X", Family: "GLM-4.5"},
30
	{ID: "glm-4.5-airx", Name: "GLM-4.5 AirX", Family: "GLM-4.5"},
31
	{ID: "glm-4.5-flash", Name: "GLM-4.5 Flash", Family: "GLM-4.5"},
32
	{ID: "glm-4-32b-0414-128k", Name: "GLM-4 32B", Family: "GLM-4"},
33
}
34
35
var zaiCodingModels = []StaticModel{
36
	{ID: "glm-5.1", Name: "GLM-5.1", Family: "GLM-5"},
37
	{ID: "glm-5", Name: "GLM-5", Family: "GLM-5"},
38
	{ID: "glm-5-turbo", Name: "GLM-5 Turbo", Family: "GLM-5"},
39
	{ID: "glm-4.7", Name: "GLM-4.7", Family: "GLM-4.7"},
40
	{ID: "glm-4.7-flash", Name: "GLM-4.7 Flash", Family: "GLM-4.7"},
41
	{ID: "glm-4.7-flashx", Name: "GLM-4.7 FlashX", Family: "GLM-4.7"},
42
	{ID: "glm-4.5-air", Name: "GLM-4.5 Air", Family: "GLM-4.5"},
43
}
44
45
// StaticModels maps provider keys to their available models.
46
var StaticModels = map[string][]StaticModel{
47
	"zai":        zaiModels,
48
	"zai-coding": zaiCodingModels,
49
}
50
51
// Provider defines an alternative Claude Code API provider.
52
type Provider struct {
53
	Name        string
54
	Description string
55
	BaseURL     string
56
	Model       string
57
	SmallModel  string
58
	SonnetModel string
59
	OpusModel   string
60
	HaikuModel  string
61
	TimeoutMS   string
62
	// AuthEnvVar is the env var name used for the API key (some use AUTH_TOKEN, some API_KEY).
63
	AuthEnvVar string
64
	// Compat is "anthropic" (default) or "openai". When "openai", a local
65
	// translation proxy is started to convert Anthropic ↔ OpenAI API format.
66
	Compat string
67
	// ContextWindow is the model's context window size in tokens.
68
	// Claude Code assumes 200k by default; when this is smaller,
69
	// CLAUDE_AUTOCOMPACT_PCT_OVERRIDE is set so compaction triggers before
70
	// the real limit is hit.
71
	ContextWindow int
72
	// NoAuth indicates the provider does not require an API key (e.g. local Ollama).
73
	NoAuth bool
74
	// Plans lists alternative billing/access plans with different base URLs.
75
	// When non-empty, the TUI prompts the user to choose a plan.
76
	// BaseURL holds the default plan's URL.
77
	Plans []Plan
78
}
79
80
var Registry = map[string]Provider{
81
	"deepseek": {
82
		Name:          "DeepSeek",
83
		Description:   "DeepSeek Reasoner / V3 via Anthropic-compatible API",
84
		BaseURL:       "https://api.deepseek.com/anthropic",
85
		Model:         "deepseek-reasoner",
86
		SmallModel:    "deepseek-chat",
87
		SonnetModel:   "deepseek-reasoner",
88
		OpusModel:     "deepseek-reasoner",
89
		HaikuModel:    "deepseek-chat",
90
		TimeoutMS:     "600000",
91
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
92
		ContextWindow: 128_000,
93
	},
94
	"zai": {
95
		Name:          "z.AI API",
96
		Description:   "GLM-5 / GLM-4.7 via z.AI (pay-per-token)",
97
		BaseURL:       "https://api.z.ai/api/anthropic",
98
		Model:         "glm-5",
99
		SmallModel:    "glm-4.5-air",
100
		SonnetModel:   "glm-5",
101
		OpusModel:     "glm-5",
102
		HaikuModel:    "glm-4.5-air",
103
		TimeoutMS:     "3000000",
104
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
105
		ContextWindow: 205_000,
106
	},
107
	"zai-coding": {
108
		Name:          "z.AI Coding",
109
		Description:   "GLM-5.1 / GLM-5 via z.AI (subscription)",
110
		BaseURL:       "https://api.z.ai/api/coding/anthropic",
111
		Model:         "glm-5.1",
112
		SmallModel:    "glm-4.5-air",
113
		SonnetModel:   "glm-5.1",
114
		OpusModel:     "glm-5.1",
115
		HaikuModel:    "glm-4.5-air",
116
		TimeoutMS:     "3000000",
117
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
118
		ContextWindow: 205_000,
119
	},
120
	"minimax": {
121
		Name:          "MiniMax",
122
		Description:   "MiniMax-M2.5 via MiniMax Anthropic gateway",
123
		BaseURL:       "https://api.minimax.io/anthropic",
124
		Model:         "MiniMax-M2.5",
125
		SmallModel:    "MiniMax-M2.5",
126
		SonnetModel:   "MiniMax-M2.5",
127
		OpusModel:     "MiniMax-M2.5",
128
		HaikuModel:    "MiniMax-M2.5",
129
		TimeoutMS:     "3000000",
130
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
131
		ContextWindow: 205_000,
132
	},
133
	"kimi": {
134
		Name:          "Kimi Code",
135
		Description:   "Kimi K2.5 / K2 via Kimi Code (International)",
136
		BaseURL:       "https://api.kimi.com/coding/",
137
		Model:         "kimi-k2.5",
138
		SmallModel:    "kimi-k2-turbo-preview",
139
		SonnetModel:   "kimi-k2.5",
140
		OpusModel:     "kimi-k2.5",
141
		HaikuModel:    "kimi-k2-turbo-preview",
142
		TimeoutMS:     "600000",
143
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
144
		ContextWindow: 256_000,
145
	},
146
	"kimi-api-cn": {
147
		Name:          "Kimi API (China)",
148
		Description:   "Kimi via Moonshot Open Platform (api.moonshot.cn)",
149
		BaseURL:       "https://api.moonshot.cn/v1/",
150
		Model:         "kimi-k2.5",
151
		SmallModel:    "kimi-k2-turbo-preview",
152
		SonnetModel:   "kimi-k2.5",
153
		OpusModel:     "kimi-k2.5",
154
		HaikuModel:    "kimi-k2-turbo-preview",
155
		TimeoutMS:     "600000",
156
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
157
		ContextWindow: 256_000,
158
		Compat:        "openai",
159
	},
160
	"kimi-api-intl": {
161
		Name:          "Kimi API (Intl)",
162
		Description:   "Kimi via Moonshot Open Platform (api.moonshot.ai)",
163
		BaseURL:       "https://api.moonshot.ai/v1/",
164
		Model:         "kimi-k2.5",
165
		SmallModel:    "kimi-k2-turbo-preview",
166
		SonnetModel:   "kimi-k2.5",
167
		OpusModel:     "kimi-k2.5",
168
		HaikuModel:    "kimi-k2-turbo-preview",
169
		TimeoutMS:     "600000",
170
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
171
		ContextWindow: 256_000,
172
		Compat:        "openai",
173
	},
174
	"mistral": {
175
		Name:          "Mistral",
176
		Description:   "Devstral / Mistral Large via OpenAI-compatible API",
177
		BaseURL:       "https://api.mistral.ai/v1",
178
		Model:         "devstral-latest",
179
		SmallModel:    "devstral-small-latest",
180
		SonnetModel:   "devstral-latest",
181
		OpusModel:     "devstral-latest",
182
		HaikuModel:    "devstral-small-latest",
183
		TimeoutMS:     "600000",
184
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
185
		Compat:        "openai",
186
		ContextWindow: 256_000,
187
	},
188
	"copilot": {
189
		Name:          "GitHub Copilot",
190
		Description:   "Claude via GitHub Copilot",
191
		BaseURL:       "https://api.githubcopilot.com",
192
		Model:         "claude-sonnet-4.6",
193
		SmallModel:    "claude-haiku-4.5",
194
		SonnetModel:   "claude-sonnet-4.6",
195
		OpusModel:     "claude-opus-4.6",
196
		HaikuModel:    "claude-haiku-4.5",
197
		TimeoutMS:     "600000",
198
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
199
		Compat:        "openai",
200
		ContextWindow: 200_000,
201
	},
202
	"nvidia": {
203
		Name:          "NVIDIA NIM",
204
		Description:   "Access NVIDIA NIM models via OpenAI-compatible API",
205
		BaseURL:       "https://integrate.api.nvidia.com/v1",
206
		Model:         "nvidia/llama-3.1-nemotron-ultra-253b-v1",
207
		SmallModel:    "nvidia/llama-3.3-nemotron-super-49b-v1.5",
208
		SonnetModel:   "nvidia/llama-3.1-nemotron-ultra-253b-v1",
209
		OpusModel:     "nvidia/llama-3.1-nemotron-ultra-253b-v1",
210
		HaikuModel:    "nvidia/llama-3.3-nemotron-super-49b-v1.5",
211
		TimeoutMS:     "600000",
212
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
213
		Compat:        "openai",
214
		ContextWindow: 128_000,
215
	},
216
	"openrouter": {
217
		Name:          "OpenRouter",
218
		Description:   "Access multiple models via OpenRouter",
219
		BaseURL:       "https://openrouter.ai/api/v1",
220
		Model:         "anthropic/claude-sonnet-4.6",
221
		SmallModel:    "anthropic/claude-haiku-4.5",
222
		SonnetModel:   "anthropic/claude-sonnet-4.6",
223
		OpusModel:     "anthropic/claude-opus-4.6",
224
		HaikuModel:    "anthropic/claude-haiku-4.5",
225
		TimeoutMS:     "600000",
226
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
227
		Compat:        "openai",
228
		ContextWindow: 200_000,
229
	},
230
	"vkproxy": {
231
		Name:          "VK LLM Proxy",
232
		Description:   "Import models from claude-code-config.zip",
233
		BaseURL:       "https://llm-proxy.vkteam.ru",
234
		Model:         "deepseek-reasoner",
235
		SmallModel:    "deepseek-reasoner",
236
		SonnetModel:   "deepseek-reasoner",
237
		OpusModel:     "deepseek-reasoner",
238
		HaikuModel:    "deepseek-reasoner",
239
		TimeoutMS:     "600000",
240
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
241
		ContextWindow: 128_000,
242
	},
243
	"ollama": {
244
		Name:          "Ollama (local)",
245
		Description:   "Local Ollama with native Anthropic-compatible API",
246
		BaseURL:       "http://localhost:11434",
247
		Model:         "qwen3-coder",
248
		SmallModel:    "qwen3-coder",
249
		SonnetModel:   "qwen3-coder",
250
		OpusModel:     "qwen3-coder",
251
		HaikuModel:    "qwen3-coder",
252
		TimeoutMS:     "600000",
253
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
254
		ContextWindow: 32_000,
255
		NoAuth:        true,
256
	},
257
	"ollama-cloud": {
258
		Name:          "Ollama Cloud",
259
		Description:   "Cloud models via ollama.com API",
260
		BaseURL:       "https://ollama.com",
261
		Model:         "qwen3.5:397b",
262
		SmallModel:    "devstral-small-2:24b",
263
		SonnetModel:   "devstral-2:123b",
264
		OpusModel:     "qwen3.5:397b",
265
		HaikuModel:    "devstral-small-2:24b",
266
		TimeoutMS:     "600000",
267
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
268
		ContextWindow: 32_000,
269
	},
270
	"lmstudio": {
271
		Name:          "LM Studio",
272
		Description:   "Local LM Studio server with OpenAI-compatible API",
273
		BaseURL:       "http://localhost:1234/v1",
274
		Model:         "local-model",
275
		SmallModel:    "local-model",
276
		SonnetModel:   "local-model",
277
		OpusModel:     "local-model",
278
		HaikuModel:    "local-model",
279
		TimeoutMS:     "600000",
280
		AuthEnvVar:    "ANTHROPIC_AUTH_TOKEN",
281
		ContextWindow: 128_000,
282
		Compat:        "openai",
283
		NoAuth:        true,
284
	},
285
	"claude": {
286
		Name:        "Claude (Anthropic)",
287
		Description: "Native Claude API via Anthropic (passthrough proxy for accounting)",
288
		BaseURL:     "https://api.anthropic.com",
289
		Model:       "claude-sonnet-4-6-20250514",
290
		SmallModel:  "claude-haiku-4-5-20251001",
291
		SonnetModel: "claude-sonnet-4-6-20250514",
292
		OpusModel:   "claude-opus-4-6-20250610",
293
		HaikuModel:  "claude-haiku-4-5-20251001",
294
		TimeoutMS:   "600000",
295
		NoAuth:      true,
296
	},
297
}
298
299
// Order defines the display order of providers.
300
var Order = []string{"claude", "deepseek", "mistral", "zai", "zai-coding", "minimax", "kimi", "kimi-api-cn", "kimi-api-intl", "copilot", "nvidia", "openrouter", "ollama", "ollama-cloud", "lmstudio", "vkproxy"}
301

Source Files