Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit 91d500e

Browse files
committed
feat: add Kyma API as built-in provider
Kyma API (kymaapi.com) is an OpenAI-compatible LLM gateway with 20+ open-source models, free credits on signup, and pay-per-token billing. - Add KymaHandler extending BaseOpenAiCompatibleProvider - Register 8 top models (qwen-3.6-plus, deepseek-v3/r1, kimi-k2.5, gemma-4-31b, llama-3.3-70b, qwen-3-32b, minimax-m2.5) - Add kymaApiKey to provider settings schema and secret storage - Add Kyma settings UI component with API key input - Wire into buildApiHandler switch, PROVIDERS list, and model config
1 parent 7adbfec commit 91d500e

15 files changed

Lines changed: 203 additions & 0 deletions

File tree

packages/types/src/global-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ export const SECRET_STATE_KEYS = [
276276
"codebaseIndexVercelAiGatewayApiKey",
277277
"codebaseIndexOpenRouterApiKey",
278278
"sambaNovaApiKey",
279+
"kymaApiKey",
279280
"zaiApiKey",
280281
"fireworksApiKey",
281282
"vercelAiGatewayApiKey",

packages/types/src/provider-settings.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
xaiModels,
2121
internationalZAiModels,
2222
minimaxModels,
23+
kymaModels,
2324
} from "./providers/index.js"
2425

2526
/**
@@ -125,6 +126,7 @@ export const providerNames = [
125126
"qwen-code",
126127
"roo",
127128
"sambanova",
129+
"kyma",
128130
"vertex",
129131
"xai",
130132
"zai",
@@ -363,6 +365,10 @@ const sambaNovaSchema = apiModelIdProviderModelSchema.extend({
363365
sambaNovaApiKey: z.string().optional(),
364366
})
365367

368+
const kymaSchema = apiModelIdProviderModelSchema.extend({
369+
kymaApiKey: z.string().optional(),
370+
})
371+
366372
export const zaiApiLineSchema = z.enum(["international_coding", "china_coding", "international_api", "china_api"])
367373

368374
export type ZaiApiLine = z.infer<typeof zaiApiLineSchema>
@@ -423,6 +429,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
423429
basetenSchema.merge(z.object({ apiProvider: z.literal("baseten") })),
424430
litellmSchema.merge(z.object({ apiProvider: z.literal("litellm") })),
425431
sambaNovaSchema.merge(z.object({ apiProvider: z.literal("sambanova") })),
432+
kymaSchema.merge(z.object({ apiProvider: z.literal("kyma") })),
426433
zaiSchema.merge(z.object({ apiProvider: z.literal("zai") })),
427434
fireworksSchema.merge(z.object({ apiProvider: z.literal("fireworks") })),
428435
qwenCodeSchema.merge(z.object({ apiProvider: z.literal("qwen-code") })),
@@ -457,6 +464,7 @@ export const providerSettingsSchema = z.object({
457464
...basetenSchema.shape,
458465
...litellmSchema.shape,
459466
...sambaNovaSchema.shape,
467+
...kymaSchema.shape,
460468
...zaiSchema.shape,
461469
...fireworksSchema.shape,
462470
...qwenCodeSchema.shape,
@@ -533,6 +541,7 @@ export const modelIdKeysByProvider: Record<TypicalProvider, ModelIdKey> = {
533541
baseten: "apiModelId",
534542
litellm: "litellmModelId",
535543
sambanova: "apiModelId",
544+
kyma: "apiModelId",
536545
zai: "apiModelId",
537546
fireworks: "apiModelId",
538547
roo: "apiModelId",
@@ -633,6 +642,11 @@ export const MODELS_BY_PROVIDER: Record<
633642
label: "SambaNova",
634643
models: Object.keys(sambaNovaModels),
635644
},
645+
kyma: {
646+
id: "kyma",
647+
label: "Kyma API",
648+
models: Object.keys(kymaModels),
649+
},
636650
vertex: {
637651
id: "vertex",
638652
label: "GCP Vertex AI",

packages/types/src/providers/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export * from "./xai.js"
2525
export * from "./vercel-ai-gateway.js"
2626
export * from "./zai.js"
2727
export * from "./minimax.js"
28+
export * from "./kyma.js"
2829

2930
import { anthropicDefaultModelId } from "./anthropic.js"
3031
import { basetenDefaultModelId } from "./baseten.js"
@@ -49,6 +50,7 @@ import { xaiDefaultModelId } from "./xai.js"
4950
import { vercelAiGatewayDefaultModelId } from "./vercel-ai-gateway.js"
5051
import { internationalZAiDefaultModelId, mainlandZAiDefaultModelId } from "./zai.js"
5152
import { minimaxDefaultModelId } from "./minimax.js"
53+
import { kymaDefaultModelId } from "./kyma.js"
5254

5355
// Import the ProviderName type from provider-settings to avoid duplication
5456
import type { ProviderName } from "../provider-settings.js"
@@ -115,6 +117,8 @@ export function getProviderDefaultModelId(
115117
return unboundDefaultModelId
116118
case "vercel-ai-gateway":
117119
return vercelAiGatewayDefaultModelId
120+
case "kyma":
121+
return kymaDefaultModelId
118122
case "anthropic":
119123
case "gemini-cli":
120124
case "fake-ai":
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import type { ModelInfo } from "../model.js"
2+
3+
// https://kymaapi.com — OpenAI-compatible LLM gateway with 20+ open-source models
4+
export type KymaModelId =
5+
| "qwen-3.6-plus"
6+
| "deepseek-v3"
7+
| "deepseek-r1"
8+
| "kimi-k2.5"
9+
| "gemma-4-31b"
10+
| "llama-3.3-70b"
11+
| "qwen-3-32b"
12+
| "minimax-m2.5"
13+
14+
export const kymaDefaultModelId: KymaModelId = "qwen-3.6-plus"
15+
16+
export const kymaModels = {
17+
"qwen-3.6-plus": {
18+
maxTokens: 8192,
19+
contextWindow: 128000,
20+
supportsImages: false,
21+
supportsPromptCache: false,
22+
inputPrice: 0.4,
23+
outputPrice: 1.6,
24+
description: "Qwen 3.6 Plus — top-tier open model, best overall quality.",
25+
},
26+
"deepseek-v3": {
27+
maxTokens: 8192,
28+
contextWindow: 128000,
29+
supportsImages: false,
30+
supportsPromptCache: true,
31+
inputPrice: 0.26,
32+
outputPrice: 0.38,
33+
description: "DeepSeek V3 — GPT-4-class coding and reasoning at very low cost.",
34+
},
35+
"deepseek-r1": {
36+
maxTokens: 8192,
37+
contextWindow: 128000,
38+
supportsImages: false,
39+
supportsPromptCache: false,
40+
inputPrice: 0.5,
41+
outputPrice: 2.18,
42+
description: "DeepSeek R1 — strong open reasoning model, 96% cheaper than o1.",
43+
},
44+
"kimi-k2.5": {
45+
maxTokens: 8192,
46+
contextWindow: 131072,
47+
supportsImages: true,
48+
supportsPromptCache: false,
49+
inputPrice: 1.0,
50+
outputPrice: 3.0,
51+
description: "Kimi K2.5 — multimodal agentic model optimized for tool use.",
52+
},
53+
"gemma-4-31b": {
54+
maxTokens: 8192,
55+
contextWindow: 131072,
56+
supportsImages: true,
57+
supportsPromptCache: false,
58+
inputPrice: 0.0,
59+
outputPrice: 0.0,
60+
description: "Gemma 4 31B — Google's latest multimodal open model, free tier.",
61+
},
62+
"llama-3.3-70b": {
63+
maxTokens: 8192,
64+
contextWindow: 131072,
65+
supportsImages: false,
66+
supportsPromptCache: false,
67+
inputPrice: 0.23,
68+
outputPrice: 0.4,
69+
description: "Llama 3.3 70B — most popular open model, great balance of speed and quality.",
70+
},
71+
"qwen-3-32b": {
72+
maxTokens: 8192,
73+
contextWindow: 131072,
74+
supportsImages: false,
75+
supportsPromptCache: false,
76+
inputPrice: 0.2,
77+
outputPrice: 0.6,
78+
description: "Qwen 3 32B — top coding model, fast and accurate.",
79+
},
80+
"minimax-m2.5": {
81+
maxTokens: 8192,
82+
contextWindow: 131072,
83+
supportsImages: false,
84+
supportsPromptCache: false,
85+
inputPrice: 0.8,
86+
outputPrice: 2.0,
87+
description: "MiniMax M2.5 — SWE-bench 80.2%, strong coding and agentic tasks.",
88+
},
89+
} as const satisfies Record<string, ModelInfo>

src/api/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
VercelAiGatewayHandler,
3535
MiniMaxHandler,
3636
BasetenHandler,
37+
KymaHandler,
3738
} from "./providers"
3839
import { NativeOllamaHandler } from "./providers/native-ollama"
3940

@@ -177,6 +178,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
177178
return new MiniMaxHandler(options)
178179
case "baseten":
179180
return new BasetenHandler(options)
181+
case "kyma":
182+
return new KymaHandler(options)
180183
case "poe":
181184
return new PoeHandler(options)
182185
default:

src/api/providers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ export { RooHandler } from "./roo"
2828
export { VercelAiGatewayHandler } from "./vercel-ai-gateway"
2929
export { MiniMaxHandler } from "./minimax"
3030
export { BasetenHandler } from "./baseten"
31+
export { KymaHandler } from "./kyma"

src/api/providers/kyma.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { type KymaModelId, kymaDefaultModelId, kymaModels } from "@roo-code/types"
2+
3+
import type { ApiHandlerOptions } from "../../shared/api"
4+
5+
import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider"
6+
7+
export class KymaHandler extends BaseOpenAiCompatibleProvider<KymaModelId> {
8+
constructor(options: ApiHandlerOptions) {
9+
super({
10+
...options,
11+
providerName: "Kyma API",
12+
baseURL: "https://kymaapi.com/v1",
13+
apiKey: options.kymaApiKey,
14+
defaultProviderModelId: kymaDefaultModelId,
15+
providerModels: kymaModels,
16+
})
17+
}
18+
}

src/shared/ProfileValidator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export class ProfileValidator {
6262
case "deepseek":
6363
case "xai":
6464
case "sambanova":
65+
case "kyma":
6566
case "fireworks":
6667
return profile.apiModelId
6768
case "litellm":

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
bedrockDefaultModelId,
2727
vertexDefaultModelId,
2828
sambaNovaDefaultModelId,
29+
kymaDefaultModelId,
2930
internationalZAiDefaultModelId,
3031
mainlandZAiDefaultModelId,
3132
fireworksDefaultModelId,
@@ -94,6 +95,7 @@ import {
9495
Fireworks,
9596
VercelAiGateway,
9697
MiniMax,
98+
Kyma,
9799
} from "./providers"
98100

99101
import { MODELS_BY_PROVIDER, PROVIDERS } from "./constants"
@@ -352,6 +354,7 @@ const ApiOptions = ({
352354
bedrock: { field: "apiModelId", default: bedrockDefaultModelId },
353355
vertex: { field: "apiModelId", default: vertexDefaultModelId },
354356
sambanova: { field: "apiModelId", default: sambaNovaDefaultModelId },
357+
kyma: { field: "apiModelId", default: kymaDefaultModelId },
355358
zai: {
356359
field: "apiModelId",
357360
default:
@@ -686,6 +689,10 @@ const ApiOptions = ({
686689
/>
687690
)}
688691

692+
{selectedProvider === "kyma" && (
693+
<Kyma apiConfiguration={apiConfiguration} setApiConfigurationField={setApiConfigurationField} />
694+
)}
695+
689696
{selectedProvider === "zai" && (
690697
<ZAi apiConfiguration={apiConfiguration} setApiConfigurationField={setApiConfigurationField} />
691698
)}

webview-ui/src/components/settings/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
fireworksModels,
1818
minimaxModels,
1919
basetenModels,
20+
kymaModels,
2021
} from "@roo-code/types"
2122

2223
export const MODELS_BY_PROVIDER: Partial<Record<ProviderName, Record<string, ModelInfo>>> = {
@@ -32,6 +33,7 @@ export const MODELS_BY_PROVIDER: Partial<Record<ProviderName, Record<string, Mod
3233
vertex: vertexModels,
3334
xai: xaiModels,
3435
sambanova: sambaNovaModels,
36+
kyma: kymaModels,
3537
zai: internationalZAiModels,
3638
fireworks: fireworksModels,
3739
minimax: minimaxModels,
@@ -58,6 +60,7 @@ export const PROVIDERS = [
5860
{ value: "xai", label: "xAI (Grok)", proxy: false },
5961
{ value: "litellm", label: "LiteLLM", proxy: true },
6062
{ value: "sambanova", label: "SambaNova", proxy: false },
63+
{ value: "kyma", label: "Kyma API", proxy: false },
6164
{ value: "zai", label: "Z.ai", proxy: false },
6265
{ value: "fireworks", label: "Fireworks AI", proxy: false },
6366
{ value: "roo", label: "Roo Code Router", proxy: false },

0 commit comments

Comments
 (0)