feat: add Featherless AI as a provider

- Add Featherless to provider names list
- Create Featherless model types with popular models
- Implement FeatherlessHandler using OpenAI-compatible API
- Add Featherless schema and configuration
- Wire up Featherless in API handler

Closes #7237
This commit is contained in:
Roo Code 2025-08-19 23:05:07 +00:00
parent 613abe08fc
commit 5cf78a4813
6 changed files with 112 additions and 0 deletions

View file

@ -48,6 +48,7 @@ export const providerNames = [
"fireworks",
"io-intelligence",
"roo",
"featherless",
] as const
export const providerNamesSchema = z.enum(providerNames)
@ -293,6 +294,10 @@ const rooSchema = apiModelIdProviderModelSchema.extend({
// No additional fields needed - uses cloud authentication
})
const featherlessSchema = apiModelIdProviderModelSchema.extend({
featherlessApiKey: z.string().optional(),
})
const defaultSchema = z.object({
apiProvider: z.undefined(),
})
@ -330,6 +335,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
fireworksSchema.merge(z.object({ apiProvider: z.literal("fireworks") })),
ioIntelligenceSchema.merge(z.object({ apiProvider: z.literal("io-intelligence") })),
rooSchema.merge(z.object({ apiProvider: z.literal("roo") })),
featherlessSchema.merge(z.object({ apiProvider: z.literal("featherless") })),
defaultSchema,
])
@ -367,6 +373,7 @@ export const providerSettingsSchema = z.object({
...fireworksSchema.shape,
...ioIntelligenceSchema.shape,
...rooSchema.shape,
...featherlessSchema.shape,
...codebaseIndexProviderSchema.shape,
})

View file

@ -0,0 +1,81 @@
import type { ModelInfo } from "../model.js"
// Featherless AI models - https://api.featherless.ai/v1/models
export type FeatherlessModelId = keyof typeof featherlessModels
export const featherlessDefaultModelId: FeatherlessModelId = "meta-llama/Meta-Llama-3.1-8B-Instruct"
export const featherlessModels = {
"meta-llama/Meta-Llama-3.1-8B-Instruct": {
maxTokens: 8192,
contextWindow: 131072,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.1,
outputPrice: 0.1,
description: "Meta's Llama 3.1 8B Instruct model with 128K context window",
},
"meta-llama/Meta-Llama-3.1-70B-Instruct": {
maxTokens: 8192,
contextWindow: 131072,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.4,
outputPrice: 0.4,
description: "Meta's Llama 3.1 70B Instruct model with 128K context window",
},
"meta-llama/Meta-Llama-3.1-405B-Instruct": {
maxTokens: 8192,
contextWindow: 131072,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 2.0,
outputPrice: 2.0,
description: "Meta's largest Llama 3.1 405B Instruct model with 128K context window",
},
"Qwen/Qwen2.5-72B-Instruct": {
maxTokens: 8192,
contextWindow: 131072,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.4,
outputPrice: 0.4,
description: "Alibaba's Qwen 2.5 72B Instruct model with 128K context window",
},
"mistralai/Mistral-7B-Instruct-v0.3": {
maxTokens: 8192,
contextWindow: 32768,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.1,
outputPrice: 0.1,
description: "Mistral's 7B Instruct v0.3 model with 32K context window",
},
"mistralai/Mixtral-8x7B-Instruct-v0.1": {
maxTokens: 8192,
contextWindow: 32768,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.3,
outputPrice: 0.3,
description: "Mistral's Mixtral 8x7B MoE Instruct model with 32K context window",
},
"deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B": {
maxTokens: 4096,
contextWindow: 131072,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.05,
outputPrice: 0.05,
description: "DeepSeek R1 Distill Qwen 1.5B model with 128K context window",
},
"moonshotai/Kimi-K2-Instruct": {
maxTokens: 16384,
contextWindow: 16384,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.3,
outputPrice: 0.3,
description: "Moonshot AI's Kimi K2 Instruct model with tool use support",
},
} as const satisfies Record<string, ModelInfo>

View file

@ -4,6 +4,7 @@ export * from "./cerebras.js"
export * from "./chutes.js"
export * from "./claude-code.js"
export * from "./deepseek.js"
export * from "./featherless.js"
export * from "./gemini.js"
export * from "./glama.js"
export * from "./groq.js"

View file

@ -24,6 +24,7 @@ import {
RequestyHandler,
HumanRelayHandler,
FakeAIHandler,
FeatherlessHandler,
XAIHandler,
GroqHandler,
HuggingFaceHandler,
@ -143,6 +144,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
return new IOIntelligenceHandler(options)
case "roo":
return new RooHandler(options)
case "featherless":
return new FeatherlessHandler(options)
default:
apiProvider satisfies "gemini-cli" | undefined
return new AnthropicHandler(options)

View file

@ -0,0 +1,19 @@
import { type FeatherlessModelId, featherlessDefaultModelId, featherlessModels } from "@roo-code/types"
import type { ApiHandlerOptions } from "../../shared/api"
import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider"
export class FeatherlessHandler extends BaseOpenAiCompatibleProvider<FeatherlessModelId> {
constructor(options: ApiHandlerOptions) {
super({
...options,
providerName: "Featherless",
baseURL: "https://api.featherless.ai/v1",
apiKey: options.featherlessApiKey,
defaultProviderModelId: featherlessDefaultModelId,
providerModels: featherlessModels,
defaultTemperature: 0.7,
})
}
}

View file

@ -8,6 +8,7 @@ export { DeepSeekHandler } from "./deepseek"
export { DoubaoHandler } from "./doubao"
export { MoonshotHandler } from "./moonshot"
export { FakeAIHandler } from "./fake-ai"
export { FeatherlessHandler } from "./featherless"
export { GeminiHandler } from "./gemini"
export { GlamaHandler } from "./glama"
export { GroqHandler } from "./groq"