Skip to content

Commit 43767ca

Browse files
authored
Merge pull request #4768 from hsp-sz/feat/add_zenmux
feat: add zenmux provider
2 parents ee8c1f8 + 060f57d commit 43767ca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1197
-12
lines changed

.changeset/green-sheep-mate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"kilo-code": minor
3+
---
4+
5+
feat: add Zenmux provider
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
---
2+
title: ZenMux
3+
---
4+
5+
import Codicon from "@site/src/components/Codicon";
6+
7+
# Using ZenMux With Kilo Code
8+
9+
[ZenMux](https://zenmux.ai) provides a unified API gateway to access multiple AI models from different providers through a single endpoint. It supports OpenAI, Anthropic, Google, and other major AI providers, automatically handling routing, fallbacks, and cost optimization.
10+
11+
## Getting Started
12+
13+
1. **Sign up for ZenMux:** Visit [zenmux.ai](https://zenmux.ai) to create an account.
14+
2. **Get your API key:** After signing up, navigate to your dashboard to generate an API key.
15+
3. **Configure in Kilo Code:** Add your API key to Kilo Code settings.
16+
17+
## Configuration in Kilo Code
18+
19+
1. **Open Kilo Code Settings:** Click the gear icon (<Codicon name="gear" />) in the Kilo Code panel.
20+
2. **Select Provider:** Choose "ZenMux" from the "API Provider" dropdown.
21+
3. **Enter API Key:** Paste your ZenMux API key into the "ZenMux API Key" field.
22+
4. **Select Model:** Choose your desired model from the "Model" dropdown.
23+
5. **(Optional) Custom Base URL:** If you need to use a custom base URL for the ZenMux API, check "Use custom base URL" and enter the URL. Leave this blank for most users.
24+
25+
## Supported Models
26+
27+
ZenMux supports a wide range of models from various providers:
28+
29+
Visi [zenmux.ai/models](https://zenmux.ai/models) to see the complete list of available models.
30+
31+
### Other Providers
32+
33+
ZenMux also supports models from Meta, Mistral, and many other providers. Check your ZenMux dashboard for the complete list of available models.
34+
35+
## API Compatibility
36+
37+
ZenMux provides multiple API endpoints for different protocols:
38+
39+
### OpenAI Compatible API
40+
41+
Use the standard OpenAI SDK with ZenMux's base URL:
42+
43+
```javascript
44+
import OpenAI from "openai"
45+
46+
const openai = new OpenAI({
47+
baseURL: "https://zenmux.ai/api/v1",
48+
apiKey: "<ZENMUX_API_KEY>",
49+
})
50+
51+
async function main() {
52+
const completion = await openai.chat.completions.create({
53+
model: "openai/gpt-5",
54+
messages: [
55+
{
56+
role: "user",
57+
content: "What is the meaning of life?",
58+
},
59+
],
60+
})
61+
62+
console.log(completion.choices[0].message)
63+
}
64+
65+
main()
66+
```
67+
68+
### Anthropic API
69+
70+
For Anthropic models, use the dedicated endpoint:
71+
72+
```typescript
73+
import Anthropic from "@anthropic-ai/sdk"
74+
75+
// 1. Initialize the Anthropic client
76+
const anthropic = new Anthropic({
77+
// 2. Replace with the API key from your ZenMux console
78+
apiKey: "<YOUR ZENMUX_API_KEY>",
79+
// 3. Point the base URL to the ZenMux endpoint
80+
baseURL: "https://zenmux.ai/api/anthropic",
81+
})
82+
83+
async function main() {
84+
const msg = await anthropic.messages.create({
85+
model: "anthropic/claude-sonnet-4.5",
86+
max_tokens: 1024,
87+
messages: [{ role: "user", content: "Hello, Claude" }],
88+
})
89+
console.log(msg)
90+
}
91+
92+
main()
93+
```
94+
95+
### Platform API
96+
97+
The Get generation interface is used to query generation information, such as usage and costs.
98+
99+
```bash
100+
curl https://zenmux.ai/api/v1/generation?id=<generation_id> \
101+
-H "Authorization: Bearer $ZENMUX_API_KEY"
102+
```
103+
104+
### Google Vertex AI API
105+
106+
For Google models:
107+
108+
```typescript
109+
const genai = require("@google/genai")
110+
111+
const client = new genai.GoogleGenAI({
112+
apiKey: "$ZENMUX_API_KEY",
113+
vertexai: true,
114+
httpOptions: {
115+
baseUrl: "https://zenmux.ai/api/vertex-ai",
116+
apiVersion: "v1",
117+
},
118+
})
119+
120+
const response = await client.models.generateContent({
121+
model: "google/gemini-2.5-pro",
122+
contents: "How does AI work?",
123+
})
124+
console.log(response)
125+
```
126+
127+
## Features
128+
129+
### Automatic Routing
130+
131+
ZenMux automatically routes your requests to the best available provider based on:
132+
133+
- Model availability
134+
- Response time
135+
- Cost optimization
136+
- Provider health status
137+
138+
### Fallback Support
139+
140+
If a provider is unavailable, ZenMux automatically falls back to alternative providers that support the same model capabilities.
141+
142+
### Cost Optimization
143+
144+
ZenMux can be configured to optimize for cost, routing requests to the most cost-effective provider while maintaining quality.
145+
146+
### Zero Data Retention (ZDR)
147+
148+
Enable ZDR mode to ensure that no request or response data is stored by ZenMux, providing maximum privacy for sensitive applications.
149+
150+
## Advanced Configuration
151+
152+
### Provider Routing
153+
154+
You can specify routing preferences:
155+
156+
- **Price**: Route to the lowest cost provider
157+
- **Throughput**: Route to the provider with highest tokens/second
158+
- **Latency**: Route to the provider with fastest response time
159+
160+
### Data Collection Settings
161+
162+
Control how ZenMux handles your data:
163+
164+
- **Allow**: Allow data collection for service improvement
165+
- **Deny**: Disable all data collection
166+
167+
### Middle-Out Transform
168+
169+
Enable the middle-out transform feature to optimize prompts that exceed model context limits.
170+
171+
## Troubleshooting
172+
173+
### API Key Issues
174+
175+
- Ensure your API key is correctly copied without any extra spaces
176+
- Check that your ZenMux account is active and has available credits
177+
- Verify the API key has the necessary permissions
178+
179+
### Model Availability
180+
181+
- Some models may have regional restrictions
182+
- Check the ZenMux dashboard for current model availability
183+
- Ensure your account tier has access to the desired models
184+
185+
### Connection Issues
186+
187+
- Verify your internet connection
188+
- Check if you're behind a firewall that might block API requests
189+
- Try using a custom base URL if the default endpoint is blocked
190+
191+
## Support
192+
193+
For additional support:
194+
195+
- Visit the [ZenMux documentation](https://zenmux.ai/docs)
196+
- Contact ZenMux support through their dashboard
197+
- Check the [Kilo Code GitHub repository](https://github.com/kilocode/kilocode) for integration-specific issues

cli/src/config/mapper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ export function getModelIdForProvider(provider: ProviderConfig): string {
106106
return provider.apiModelId || ""
107107
case "openrouter":
108108
return provider.openRouterModelId || ""
109+
case "zenmux":
110+
return provider.zenmuxModelId || ""
109111
case "ollama":
110112
return provider.ollamaModelId || ""
111113
case "lmstudio":

cli/src/constants/providers/labels.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const PROVIDER_LABELS: Record<ProviderName, string> = {
1111
"openai-codex": "OpenAI - ChatGPT Plus/Pro",
1212
"openai-responses": "OpenAI Compatible (Responses)",
1313
openrouter: "OpenRouter",
14+
zenmux: "ZenMux",
1415
bedrock: "Amazon Bedrock",
1516
gemini: "Google Gemini",
1617
vertex: "GCP Vertex AI",

cli/src/constants/providers/models.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {
4646
minimaxModels,
4747
minimaxDefaultModelId,
4848
ovhCloudAiEndpointsDefaultModelId,
49+
zenmuxDefaultModelId,
4950
} from "@roo-code/types"
5051

5152
/**
@@ -64,6 +65,7 @@ export type RouterName =
6465
| "deepinfra"
6566
| "vercel-ai-gateway"
6667
| "ovhcloud"
68+
| "zenmux"
6769
| "nano-gpt"
6870

6971
/**
@@ -120,6 +122,7 @@ export type RouterModels = Record<RouterName, ModelRecord>
120122
export const PROVIDER_TO_ROUTER_NAME: Record<ProviderName, RouterName | null> = {
121123
kilocode: "kilocode",
122124
openrouter: "openrouter",
125+
zenmux: "zenmux", // kilocode_change
123126
ollama: "ollama",
124127
lmstudio: "lmstudio",
125128
litellm: "litellm",
@@ -165,7 +168,7 @@ export const PROVIDER_TO_ROUTER_NAME: Record<ProviderName, RouterName | null> =
165168
synthetic: null,
166169
"sap-ai-core": null,
167170
baseten: null,
168-
corethink: null
171+
corethink: null,
169172
}
170173

171174
/**
@@ -174,6 +177,7 @@ export const PROVIDER_TO_ROUTER_NAME: Record<ProviderName, RouterName | null> =
174177
export const PROVIDER_MODEL_FIELD: Record<ProviderName, string | null> = {
175178
kilocode: "kilocodeModel",
176179
openrouter: "openRouterModelId",
180+
zenmux: "zenmuxModelId", // kilocode_change
177181
ollama: "ollamaModelId",
178182
lmstudio: "lmStudioModelId",
179183
litellm: "litellmModelId",
@@ -219,7 +223,7 @@ export const PROVIDER_MODEL_FIELD: Record<ProviderName, string | null> = {
219223
synthetic: null,
220224
"sap-ai-core": "sapAiCoreModelId",
221225
baseten: null,
222-
corethink: null
226+
corethink: null,
223227
}
224228

225229
/**
@@ -285,6 +289,7 @@ export const DEFAULT_MODEL_IDS: Partial<Record<ProviderName, string>> = {
285289
zai: internationalZAiDefaultModelId,
286290
roo: rooDefaultModelId,
287291
ovhcloud: ovhCloudAiEndpointsDefaultModelId,
292+
zenmux: zenmuxDefaultModelId,
288293
}
289294

290295
/**
@@ -460,6 +465,8 @@ export function getModelIdKey(provider: ProviderName): string {
460465
return "vercelAiGatewayModelId"
461466
case "ovhcloud":
462467
return "ovhCloudAiEndpointsModelId"
468+
case "zenmux":
469+
return "zenmuxModelId"
463470
case "nano-gpt":
464471
return "nanoGptModelId"
465472
default:

cli/src/constants/providers/settings.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,25 @@ export const FIELD_REGISTRY: Record<string, FieldMetadata> = {
9191
placeholder: "Enter base URL (or leave empty for default)...",
9292
isOptional: true,
9393
},
94+
95+
// kilocode_change start - ZenMux fields
96+
zenmuxApiKey: {
97+
label: "API Key",
98+
type: "password",
99+
placeholder: "Enter ZenMux API key...",
100+
},
101+
zenmuxModelId: {
102+
label: "Model",
103+
type: "text",
104+
placeholder: "Enter model name...",
105+
},
106+
zenmuxBaseUrl: {
107+
label: "Base URL",
108+
type: "text",
109+
placeholder: "Enter base URL (or leave empty for default)...",
110+
isOptional: true,
111+
},
112+
// kilocode_change end
94113
openRouterProviderDataCollection: {
95114
label: "Provider Data Collection",
96115
type: "select",
@@ -791,6 +810,13 @@ export const getProviderSettings = (provider: ProviderName, config: ProviderSett
791810
createFieldConfig("openRouterBaseUrl", config, "Default"),
792811
]
793812

813+
case "zenmux": // kilocode_change
814+
return [
815+
createFieldConfig("zenmuxApiKey", config),
816+
createFieldConfig("zenmuxModelId", config, "openai/gpt-5"),
817+
createFieldConfig("zenmuxBaseUrl", config, "Default"),
818+
]
819+
794820
case "openai-native":
795821
return [
796822
createFieldConfig("openAiNativeApiKey", config),
@@ -1043,6 +1069,7 @@ export const PROVIDER_DEFAULT_MODELS: Record<ProviderName, string> = {
10431069
"openai-codex": "gpt-4o",
10441070
"openai-responses": "gpt-4o",
10451071
openrouter: "anthropic/claude-3-5-sonnet",
1072+
zenmux: "openai/gpt-5", // kilocode_change
10461073
bedrock: "anthropic.claude-3-5-sonnet-20241022-v2:0",
10471074
gemini: "gemini-1.5-pro-latest",
10481075
vertex: "claude-3-5-sonnet@20241022",

cli/src/constants/providers/validation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const PROVIDER_REQUIRED_FIELDS: Record<ProviderName, string[]> = {
1010
"openai-native": ["openAiNativeApiKey", "apiModelId"],
1111
"openai-codex": ["apiModelId"],
1212
openrouter: ["openRouterApiKey", "openRouterModelId"],
13+
zenmux: ["zenmuxApiKey", "zenmuxModelId"], // kilocode_change
1314
ollama: ["ollamaBaseUrl", "ollamaModelId"],
1415
lmstudio: ["lmStudioBaseUrl", "lmStudioModelId"],
1516
bedrock: ["awsRegion", "apiModelId"], // Auth fields handled in handleSpecialValidations (supports API key, profile, or direct credentials)

packages/core-schemas/src/config/provider.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,21 @@ export const openRouterProviderSchema = baseProviderSchema.extend({
8888
openRouterZdr: z.boolean().optional(),
8989
})
9090

91+
// kilocode_change start
92+
// ZenMux provider
93+
export const zenmuxProviderSchema = baseProviderSchema.extend({
94+
provider: z.literal("zenmux"),
95+
zenmuxModelId: z.string().optional(),
96+
zenmuxApiKey: z.string().optional(),
97+
zenmuxBaseUrl: z.string().optional(),
98+
zenmuxSpecificProvider: z.string().optional(),
99+
zenmuxUseMiddleOutTransform: z.boolean().optional(),
100+
zenmuxProviderDataCollection: z.enum(["allow", "deny"]).optional(),
101+
zenmuxProviderSort: z.enum(["price", "throughput", "latency"]).optional(),
102+
zenmuxZdr: z.boolean().optional(),
103+
})
104+
// kilocode_change end
105+
91106
// Ollama provider
92107
export const ollamaProviderSchema = baseProviderSchema.extend({
93108
provider: z.literal("ollama"),
@@ -407,6 +422,7 @@ export const providerConfigSchema = z.discriminatedUnion("provider", [
407422
openAIProviderSchema,
408423
openAIResponsesProviderSchema, // kilocode_change
409424
openRouterProviderSchema,
425+
zenmuxProviderSchema, // kilocode_change
410426
ollamaProviderSchema,
411427
lmStudioProviderSchema,
412428
glamaProviderSchema,
@@ -453,6 +469,7 @@ export type OpenAICodexProviderConfig = z.infer<typeof openAICodexProviderSchema
453469
export type OpenAIProviderConfig = z.infer<typeof openAIProviderSchema>
454470
export type OpenAIResponsesProviderConfig = z.infer<typeof openAIResponsesProviderSchema> // kilocode_change
455471
export type OpenRouterProviderConfig = z.infer<typeof openRouterProviderSchema>
472+
export type ZenmuxProviderConfig = z.infer<typeof zenmuxProviderSchema> // kilocode_change
456473
export type OllamaProviderConfig = z.infer<typeof ollamaProviderSchema>
457474
export type LMStudioProviderConfig = z.infer<typeof lmStudioProviderSchema>
458475
export type GlamaProviderConfig = z.infer<typeof glamaProviderSchema>

0 commit comments

Comments
 (0)