Skip to content
Closed
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
7 changes: 7 additions & 0 deletions packages/types/src/provider-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const providerNames = [
"fireworks",
"io-intelligence",
"roo",
"featherless",
] as const

export const providerNamesSchema = z.enum(providerNames)
Expand Down Expand Up @@ -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(),
})
Expand Down Expand Up @@ -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,
])

Expand Down Expand Up @@ -367,6 +373,7 @@ export const providerSettingsSchema = z.object({
...fireworksSchema.shape,
...ioIntelligenceSchema.shape,
...rooSchema.shape,
...featherlessSchema.shape,
...codebaseIndexProviderSchema.shape,
})

Expand Down
81 changes: 81 additions & 0 deletions packages/types/src/providers/featherless.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { ModelInfo } from "../model.js"

// Featherless AI models - https://api.featherless.ai/v1/models
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding the actual API documentation URL here for reference, not just the models endpoint. This would help future maintainers understand the API structure.

export type FeatherlessModelId = keyof typeof featherlessModels

export const featherlessDefaultModelId: FeatherlessModelId = "meta-llama/Meta-Llama-3.1-8B-Instruct"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we confirmed that all these model IDs are actually available through Featherless AI's API? It would be good to verify these against their API documentation or model list endpoint at https://api.featherless.ai/v1/models


export const featherlessModels = {
"meta-llama/Meta-Llama-3.1-8B-Instruct": {
maxTokens: 8192,
contextWindow: 131072,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.1,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pricing values here (0.1, 0.4, 2.0, etc.) appear to be placeholder values. Could we verify the actual pricing from Featherless AI's documentation? These rounded values might not reflect the actual per-token costs.

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>
1 change: 1 addition & 0 deletions packages/types/src/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
RequestyHandler,
HumanRelayHandler,
FakeAIHandler,
FeatherlessHandler,
XAIHandler,
GroqHandler,
HuggingFaceHandler,
Expand Down Expand Up @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions src/api/providers/featherless.ts
Original file line number Diff line number Diff line change
@@ -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({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the base class checks for apiKey, could we add a more specific error message for missing Featherless API key? Something like:

Suggested change
super({
if (!options.featherlessApiKey) {
throw new Error("Featherless API key is required")
}
super({
...options,
providerName: "Featherless",
baseURL: "https://api.featherless.ai/v1",
apiKey: options.featherlessApiKey,
defaultProviderModelId: featherlessDefaultModelId,
providerModels: featherlessModels,
defaultTemperature: 0.7,
})

...options,
providerName: "Featherless",
baseURL: "https://api.featherless.ai/v1",
apiKey: options.featherlessApiKey,
defaultProviderModelId: featherlessDefaultModelId,
providerModels: featherlessModels,
defaultTemperature: 0.7,
})
}
}
1 change: 1 addition & 0 deletions src/api/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading