Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions cli/docs/PROVIDER_CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ This guide provides detailed information on how to configure each provider in Ki
- [Virtual Quota Fallback](#virtual-quota-fallback)
- [Human Relay](#human-relay)
- [Fake AI](#fake-ai)
- [OVHcloud AI Endpoints](#ovhcloud-ai-endpoints)

## Introduction

Expand Down Expand Up @@ -1322,6 +1323,41 @@ Fake AI provider for testing and development.

---

### OVHcloud AI Endpoints

OVHcloud AI Endpoints inference provider.

**Description**: Use OVHcloud leading cloud computing for accessing various open-source models, with GDPR compliance and data sovreignty.

**Required Field**:

- `ovhCloudAiEndpointsModelId` (text): Model identifier (default: `gpt-oss-120b`)

**Optional Field**:

- `ovhCloudAiEndpointsApiKey` (password): Your OVHcloud AI Endpoints API key
If you do not provide the API key, you can use our service for free with a rate limit.

**Example Configuration**:

```json
{
"id": "default",
"provider": "ovhcloud",
"ovhCloudAiEndpointsApiKey": "your-api-key", // optional
"ovhCloudAiEndpointsModelId": "gpt-oss-120b"
}
```

**Default Model**: `gpt-oss-120b`

**Notes**:

- Get your API key from https://ovh.com/manager in `Public Cloud > AI & Machine Learning` section, then in `AI Endpoints`.
- You can browse our [catalog](https://www.ovhcloud.com/en/public-cloud/ai-endpoints/catalog/) to discover all of our models.

---

## Additional Resources

- [Kilo Code Documentation](https://docs.kilocode.com/)
Expand Down
2 changes: 2 additions & 0 deletions cli/src/commands/__tests__/model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ describe("/model command", () => {
"io-intelligence": {},
deepinfra: {},
"vercel-ai-gateway": {},
ovhcloud: {},
}

const mockProvider: ProviderConfig = {
Expand Down Expand Up @@ -404,6 +405,7 @@ describe("/model command", () => {
"io-intelligence": {},
deepinfra: {},
"vercel-ai-gateway": {},
ovhcloud: {},
}
mockContext.args = ["list"]

Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ async function ensureRouterModels(context: any): Promise<boolean> {
"deepinfra",
"io-intelligence",
"vercel-ai-gateway",
"ovhcloud",
].includes(routerName)

if (!needsRouterModels) {
Expand Down
2 changes: 2 additions & 0 deletions cli/src/config/mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ function getModelIdForProvider(provider: ProviderConfig): string {
return provider.vercelAiGatewayModelId || ""
case "io-intelligence":
return provider.ioIntelligenceModelId || ""
case "ovhcloud":
return provider.ovhCloudAiEndpointsModelId || ""
default:
return provider.apiModelId || provider.modelId || ""
}
Expand Down
45 changes: 44 additions & 1 deletion cli/src/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@
"vercel-ai-gateway",
"virtual-quota-fallback",
"human-relay",
"fake-ai"
"fake-ai",
"ovhcloud"
]
}
},
Expand Down Expand Up @@ -2065,6 +2066,48 @@
}
}
}
},
{
"if": {
"properties": { "provider": { "const": "ovhcloud" } }
},
"then": {
"properties": {
"ovhCloudAiEndpointsApiKey": {
"type": "string",
"description": "OVHcloud AI Endpoints API key"
},
"ovhCloudAiEndpointsModelId": {
"type": "string",
"description": "OVHcloud AI Endpoints model ID"
}
}
}
},
{
"if": {
"properties": { "provider": { "const": "ovhcloud" } }
},
"then": {
"properties": {
"ovhCloudAiEndpointsApiKey": { "type": "string" }
},
"required": []
}
},
{
"if": {
"properties": {
"provider": { "const": "ovhcloud" },
"ovhCloudAiEndpointsModelId": { "type": "string", "minLength": 1 }
},
"required": ["ovhCloudAiEndpointsModelId"]
},
"then": {
"properties": {
"ovhCloudAiEndpointsModelId": { "minLength": 1 }
}
}
}
]
}
Expand Down
1 change: 1 addition & 0 deletions cli/src/constants/providers/__tests__/models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ describe("Static Provider Models", () => {
"io-intelligence": {},
deepinfra: {},
"vercel-ai-gateway": {},
ovhcloud: {},
}

it("should return router models for openrouter provider", () => {
Expand Down
1 change: 1 addition & 0 deletions cli/src/constants/providers/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const PROVIDER_LABELS: Record<ProviderName, string> = {
"virtual-quota-fallback": "Virtual Quota Fallback",
"human-relay": "Human Relay",
"fake-ai": "Fake AI",
ovhcloud: "OVHcloud AI Endpoints",
}

/**
Expand Down
7 changes: 7 additions & 0 deletions cli/src/constants/providers/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
claudeCodeDefaultModelId,
geminiCliModels,
geminiCliDefaultModelId,
ovhCloudAiEndpointsDefaultModelId,
} from "@roo-code/types"

/**
Expand All @@ -62,6 +63,7 @@ export type RouterName =
| "io-intelligence"
| "deepinfra"
| "vercel-ai-gateway"
| "ovhcloud"

/**
* ModelInfo interface - mirrors the one from packages/types/src/model.ts
Expand Down Expand Up @@ -105,6 +107,7 @@ export const PROVIDER_TO_ROUTER_NAME: Record<ProviderName, RouterName | null> =
deepinfra: "deepinfra",
"io-intelligence": "io-intelligence",
"vercel-ai-gateway": "vercel-ai-gateway",
ovhcloud: "ovhcloud",
// Providers without dynamic model support
anthropic: null,
bedrock: null,
Expand Down Expand Up @@ -150,6 +153,7 @@ export const PROVIDER_MODEL_FIELD: Record<ProviderName, string | null> = {
deepinfra: "deepInfraModelId",
"io-intelligence": "ioIntelligenceModelId",
"vercel-ai-gateway": "vercelAiGatewayModelId",
ovhcloud: "ovhCloudAiEndpointsModelId",
// Providers without dynamic model support
anthropic: null,
bedrock: null,
Expand Down Expand Up @@ -242,6 +246,7 @@ export const DEFAULT_MODEL_IDS: Partial<Record<ProviderName, string>> = {
zai: internationalZAiDefaultModelId,
roo: rooDefaultModelId,
"gemini-cli": geminiCliDefaultModelId,
ovhcloud: ovhCloudAiEndpointsDefaultModelId,
}

/**
Expand Down Expand Up @@ -413,6 +418,8 @@ export function getModelIdKey(provider: ProviderName): string {
return "ioIntelligenceModelId"
case "vercel-ai-gateway":
return "vercelAiGatewayModelId"
case "ovhcloud":
return "ovhCloudAiEndpointsModelId"
default:
return "apiModelId"
}
Expand Down
19 changes: 19 additions & 0 deletions cli/src/constants/providers/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,18 @@ export const FIELD_REGISTRY: Record<string, FieldMetadata> = {
placeholder: "Enter model ID...",
},

// OVHcloud AI Endpoints fields
ovhCloudAiEndpointsApiKey: {
label: "API Key",
type: "password",
placeholder: "Enter OVHcloud AI Endpoints API key...",
},
ovhCloudAiEndpointsModelId: {
label: "Model ID",
type: "text",
placeholder: "Enter model ID...",
},

// Virtual Quota Fallback fields
profiles: {
label: "Profiles Configuration",
Expand Down Expand Up @@ -779,6 +791,12 @@ export const getProviderSettings = (provider: ProviderName, config: ProviderSett
},
]

case "ovhcloud":
return [
createFieldConfig("ovhCloudAiEndpointsApiKey", config),
createFieldConfig("ovhCloudAiEndpointsModelId", config, "gpt-oss-120b"),
]

default:
return []
}
Expand Down Expand Up @@ -826,6 +844,7 @@ export const PROVIDER_DEFAULT_MODELS: Record<ProviderName, string> = {
"virtual-quota-fallback": "gpt-4o",
"human-relay": "human",
"fake-ai": "fake-model",
ovhcloud: "gpt-oss-120b",
}

/**
Expand Down
1 change: 1 addition & 0 deletions cli/src/constants/providers/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const PROVIDER_REQUIRED_FIELDS: Record<ProviderName, string[]> = {
"vercel-ai-gateway": ["vercelAiGatewayApiKey", "vercelAiGatewayModelId"],
"human-relay": ["apiModelId"],
"fake-ai": ["apiModelId"],
ovhcloud: ["ovhCloudAiEndpointsModelId"],
// Special cases handled separately in handleSpecialValidations
vertex: [], // Has special validation logic (either/or fields)
"vscode-lm": [], // Has nested object validation
Expand Down
5 changes: 5 additions & 0 deletions cli/src/types/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export type ProviderName =
| "io-intelligence"
| "roo"
| "vercel-ai-gateway"
| "ovhcloud"

// Provider Settings Entry for profile metadata
export interface ProviderSettingsEntry {
Expand Down Expand Up @@ -320,6 +321,10 @@ export interface ProviderSettings {
vercelAiGatewayApiKey?: string
vercelAiGatewayModelId?: string

// OVHcloud AI Endpoints
ovhCloudAiEndpointsApiKey?: string
ovhCloudAiEndpointsModelId?: string

// Allow additional fields for extensibility
[key: string]: any
}
Expand Down
6 changes: 6 additions & 0 deletions cli/src/utils/__tests__/providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ describe("getSelectedModelId", () => {
expect(result).toBe("litellm-model-1")
})

it("should return correct model for OVHcloud AI Endpoints provider", () => {
const apiConfig = { ovhCloudAiEndpointsModelId: "ovhcloud-model" }
const result = getSelectedModelId("ovhcloud", apiConfig)
expect(result).toBe("ovhcloud-model")
})

it("should return 'unknown' when model field is not set", () => {
const apiConfig = { someOtherField: "value" }
const result = getSelectedModelId("kilocode", apiConfig)
Expand Down