mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
feat: add SiliconCloud provider support
- Add SiliconCloud provider implementation based on OpenAI-compatible API - Support multiple API endpoints (China, China-overseas, International) - Add model definitions with region-specific pricing - Integrate with UI settings and validation - Add i18n translations for SiliconCloud settings Closes #8550
This commit is contained in:
parent
5a3f911321
commit
2ba90bf30b
12 changed files with 472 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ import {
|
|||
qwenCodeModels,
|
||||
rooModels,
|
||||
sambaNovaModels,
|
||||
siliconCloudModels,
|
||||
vertexModels,
|
||||
vscodeLlmModels,
|
||||
xaiModels,
|
||||
|
|
@ -135,6 +136,7 @@ export const providerNames = [
|
|||
"qwen-code",
|
||||
"roo",
|
||||
"sambanova",
|
||||
"siliconcloud",
|
||||
"vertex",
|
||||
"xai",
|
||||
"zai",
|
||||
|
|
@ -377,6 +379,15 @@ const sambaNovaSchema = apiModelIdProviderModelSchema.extend({
|
|||
sambaNovaApiKey: z.string().optional(),
|
||||
})
|
||||
|
||||
export const siliconCloudApiLineSchema = z.enum(["china", "china-overseas", "international"])
|
||||
|
||||
export type SiliconCloudApiLine = z.infer<typeof siliconCloudApiLineSchema>
|
||||
|
||||
const siliconCloudSchema = apiModelIdProviderModelSchema.extend({
|
||||
siliconCloudApiKey: z.string().optional(),
|
||||
siliconCloudApiLine: siliconCloudApiLineSchema.optional(),
|
||||
})
|
||||
|
||||
export const zaiApiLineSchema = z.enum(["international_coding", "international", "china_coding", "china"])
|
||||
|
||||
export type ZaiApiLine = z.infer<typeof zaiApiLineSchema>
|
||||
|
|
@ -446,6 +457,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
|
|||
litellmSchema.merge(z.object({ apiProvider: z.literal("litellm") })),
|
||||
cerebrasSchema.merge(z.object({ apiProvider: z.literal("cerebras") })),
|
||||
sambaNovaSchema.merge(z.object({ apiProvider: z.literal("sambanova") })),
|
||||
siliconCloudSchema.merge(z.object({ apiProvider: z.literal("siliconcloud") })),
|
||||
zaiSchema.merge(z.object({ apiProvider: z.literal("zai") })),
|
||||
fireworksSchema.merge(z.object({ apiProvider: z.literal("fireworks") })),
|
||||
featherlessSchema.merge(z.object({ apiProvider: z.literal("featherless") })),
|
||||
|
|
@ -487,6 +499,7 @@ export const providerSettingsSchema = z.object({
|
|||
...litellmSchema.shape,
|
||||
...cerebrasSchema.shape,
|
||||
...sambaNovaSchema.shape,
|
||||
...siliconCloudSchema.shape,
|
||||
...zaiSchema.shape,
|
||||
...fireworksSchema.shape,
|
||||
...featherlessSchema.shape,
|
||||
|
|
@ -573,6 +586,7 @@ export const modelIdKeysByProvider: Record<TypicalProvider, ModelIdKey> = {
|
|||
huggingface: "huggingFaceModelId",
|
||||
cerebras: "apiModelId",
|
||||
sambanova: "apiModelId",
|
||||
siliconcloud: "apiModelId",
|
||||
zai: "apiModelId",
|
||||
fireworks: "apiModelId",
|
||||
featherless: "apiModelId",
|
||||
|
|
@ -683,6 +697,7 @@ export const MODELS_BY_PROVIDER: Record<
|
|||
label: "SambaNova",
|
||||
models: Object.keys(sambaNovaModels),
|
||||
},
|
||||
siliconcloud: { id: "siliconcloud", label: "SiliconCloud", models: Object.keys(siliconCloudModels) },
|
||||
vertex: {
|
||||
id: "vertex",
|
||||
label: "GCP Vertex AI",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export * from "./qwen-code.js"
|
|||
export * from "./requesty.js"
|
||||
export * from "./roo.js"
|
||||
export * from "./sambanova.js"
|
||||
export * from "./siliconcloud.js"
|
||||
export * from "./unbound.js"
|
||||
export * from "./vertex.js"
|
||||
export * from "./vscode-llm.js"
|
||||
|
|
|
|||
229
packages/types/src/providers/siliconcloud.ts
Normal file
229
packages/types/src/providers/siliconcloud.ts
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
import type { ModelInfo } from "../model.js"
|
||||
import type { SiliconCloudApiLine } from "../provider-settings.js"
|
||||
|
||||
export const siliconCloudDefaultModelId = "zai-org/GLM-4.6"
|
||||
|
||||
export const siliconCloudApiLineConfigs = {
|
||||
china: { name: "国内版", baseUrl: "https://api.siliconflow.cn/v1" },
|
||||
"china-overseas": { name: "国内版(海外访问)", baseUrl: "https://api-st.siliconflow.cn/v1" },
|
||||
international: { name: "国际版", baseUrl: "https://api.siliconflow.com/v1" },
|
||||
} satisfies Record<SiliconCloudApiLine, { name: string; baseUrl: string }>
|
||||
|
||||
const siliconCloudChinaModels: Record<string, ModelInfo> = {
|
||||
"Pro/deepseek-ai/DeepSeek-V3.1-Terminus": {
|
||||
contextWindow: 163840,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.14,
|
||||
outputPrice: 0.28,
|
||||
supportsReasoningBudget: true,
|
||||
},
|
||||
"zai-org/GLM-4.6": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
supportsReasoningBudget: true,
|
||||
},
|
||||
"Qwen/QwQ-32B-Preview": {
|
||||
contextWindow: 32768,
|
||||
maxTokens: 32768,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
supportsReasoningBudget: true,
|
||||
},
|
||||
"Qwen/Qwen2.5-Coder-32B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
},
|
||||
"deepseek-ai/DeepSeek-V2.5": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.14,
|
||||
outputPrice: 0.28,
|
||||
},
|
||||
"deepseek-ai/DeepSeek-Coder-V2-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.14,
|
||||
outputPrice: 0.28,
|
||||
},
|
||||
"Qwen/Qwen2.5-72B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.35,
|
||||
outputPrice: 1.4,
|
||||
},
|
||||
"meta-llama/Meta-Llama-3.1-70B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.35,
|
||||
outputPrice: 0.42,
|
||||
},
|
||||
"meta-llama/Meta-Llama-3.1-405B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 2.1,
|
||||
outputPrice: 2.1,
|
||||
},
|
||||
"google/gemma-2-27b-it": {
|
||||
contextWindow: 8192,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.14,
|
||||
outputPrice: 0.28,
|
||||
},
|
||||
"01-ai/Yi-1.5-34B-Chat-16K": {
|
||||
contextWindow: 16384,
|
||||
maxTokens: 4096,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.14,
|
||||
outputPrice: 0.84,
|
||||
},
|
||||
"internlm/internlm2_5-20b-chat": {
|
||||
contextWindow: 32768,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.14,
|
||||
outputPrice: 0.28,
|
||||
},
|
||||
}
|
||||
|
||||
const siliconCloudChinaOverseasModels: Record<string, ModelInfo> = {
|
||||
...siliconCloudChinaModels,
|
||||
}
|
||||
|
||||
const siliconCloudInternationalModels: Record<string, ModelInfo> = {
|
||||
"Pro/deepseek-ai/DeepSeek-V3.1-Terminus": {
|
||||
contextWindow: 163840,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.02,
|
||||
outputPrice: 0.04,
|
||||
supportsReasoningBudget: true,
|
||||
},
|
||||
"zai-org/GLM-4.6": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
supportsReasoningBudget: true,
|
||||
},
|
||||
"Qwen/QwQ-32B-Preview": {
|
||||
contextWindow: 32768,
|
||||
maxTokens: 32768,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
supportsReasoningBudget: true,
|
||||
},
|
||||
"Qwen/Qwen2.5-Coder-32B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
},
|
||||
"deepseek-ai/DeepSeek-V2.5": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.02,
|
||||
outputPrice: 0.04,
|
||||
},
|
||||
"deepseek-ai/DeepSeek-Coder-V2-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.02,
|
||||
outputPrice: 0.04,
|
||||
},
|
||||
"Qwen/Qwen2.5-72B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.05,
|
||||
outputPrice: 0.2,
|
||||
},
|
||||
"meta-llama/Meta-Llama-3.1-70B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.05,
|
||||
outputPrice: 0.06,
|
||||
},
|
||||
"meta-llama/Meta-Llama-3.1-405B-Instruct": {
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.3,
|
||||
outputPrice: 0.3,
|
||||
},
|
||||
"google/gemma-2-27b-it": {
|
||||
contextWindow: 8192,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.02,
|
||||
outputPrice: 0.04,
|
||||
},
|
||||
"01-ai/Yi-1.5-34B-Chat-16K": {
|
||||
contextWindow: 16384,
|
||||
maxTokens: 4096,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.02,
|
||||
outputPrice: 0.12,
|
||||
},
|
||||
"internlm/internlm2_5-20b-chat": {
|
||||
contextWindow: 32768,
|
||||
maxTokens: 8192,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
inputPrice: 0.02,
|
||||
outputPrice: 0.04,
|
||||
},
|
||||
}
|
||||
|
||||
export const siliconCloudModelsByApiLine = {
|
||||
china: siliconCloudChinaModels,
|
||||
"china-overseas": siliconCloudChinaOverseasModels,
|
||||
international: siliconCloudInternationalModels,
|
||||
} satisfies Record<SiliconCloudApiLine, Record<string, ModelInfo>>
|
||||
|
||||
// Export all models for the default list
|
||||
export const siliconCloudModels = siliconCloudChinaModels
|
||||
|
||||
export type SiliconCloudModelId = keyof typeof siliconCloudModels
|
||||
|
|
@ -32,6 +32,7 @@ import {
|
|||
ClaudeCodeHandler,
|
||||
QwenCodeHandler,
|
||||
SambaNovaHandler,
|
||||
SiliconCloudHandler,
|
||||
IOIntelligenceHandler,
|
||||
DoubaoHandler,
|
||||
ZAiHandler,
|
||||
|
|
@ -151,6 +152,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
|
|||
return new CerebrasHandler(options)
|
||||
case "sambanova":
|
||||
return new SambaNovaHandler(options)
|
||||
case "siliconcloud":
|
||||
return new SiliconCloudHandler(options)
|
||||
case "zai":
|
||||
return new ZAiHandler(options)
|
||||
case "fireworks":
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export { OpenRouterHandler } from "./openrouter"
|
|||
export { QwenCodeHandler } from "./qwen-code"
|
||||
export { RequestyHandler } from "./requesty"
|
||||
export { SambaNovaHandler } from "./sambanova"
|
||||
export { SiliconCloudHandler } from "./siliconcloud"
|
||||
export { UnboundHandler } from "./unbound"
|
||||
export { VertexHandler } from "./vertex"
|
||||
export { VsCodeLmHandler } from "./vscode-lm"
|
||||
|
|
|
|||
125
src/api/providers/siliconcloud.ts
Normal file
125
src/api/providers/siliconcloud.ts
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import OpenAI from "openai"
|
||||
|
||||
import {
|
||||
type SiliconCloudModelId,
|
||||
siliconCloudDefaultModelId,
|
||||
siliconCloudModelsByApiLine,
|
||||
siliconCloudApiLineConfigs,
|
||||
type SiliconCloudApiLine,
|
||||
} from "@roo-code/types"
|
||||
|
||||
import type { ApiHandlerOptions } from "../../shared/api"
|
||||
import { ApiStream } from "../transform/stream"
|
||||
import { convertToOpenAiMessages } from "../transform/openai-format"
|
||||
|
||||
import type { ApiHandlerCreateMessageMetadata, SingleCompletionHandler } from "../index"
|
||||
import { BaseProvider } from "./base-provider"
|
||||
import { DEFAULT_HEADERS } from "./constants"
|
||||
import { handleOpenAIError } from "./utils/openai-error-handler"
|
||||
|
||||
const SILICONCLOUD_DEFAULT_TEMPERATURE = 0
|
||||
|
||||
export class SiliconCloudHandler extends BaseProvider implements SingleCompletionHandler {
|
||||
private client: OpenAI
|
||||
private options: ApiHandlerOptions
|
||||
private apiLine: SiliconCloudApiLine
|
||||
private models: Record<string, any>
|
||||
|
||||
constructor(options: ApiHandlerOptions) {
|
||||
super()
|
||||
this.options = options
|
||||
this.apiLine = options.siliconCloudApiLine || "china"
|
||||
this.models = siliconCloudModelsByApiLine[this.apiLine]
|
||||
|
||||
const apiKey = options.siliconCloudApiKey
|
||||
if (!apiKey) {
|
||||
throw new Error("SiliconCloud API key is required")
|
||||
}
|
||||
|
||||
const config = siliconCloudApiLineConfigs[this.apiLine]
|
||||
this.client = new OpenAI({
|
||||
baseURL: config.baseUrl,
|
||||
apiKey,
|
||||
defaultHeaders: DEFAULT_HEADERS,
|
||||
})
|
||||
}
|
||||
|
||||
override getModel() {
|
||||
const id = (this.options.apiModelId as SiliconCloudModelId) || siliconCloudDefaultModelId
|
||||
const info = this.models[id] || this.models[siliconCloudDefaultModelId]
|
||||
return { id, info }
|
||||
}
|
||||
|
||||
override async *createMessage(
|
||||
systemPrompt: string,
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
metadata?: ApiHandlerCreateMessageMetadata,
|
||||
): ApiStream {
|
||||
const {
|
||||
id: model,
|
||||
info: { maxTokens: max_tokens, supportsReasoningBudget },
|
||||
} = this.getModel()
|
||||
|
||||
const temperature = this.options.modelTemperature ?? SILICONCLOUD_DEFAULT_TEMPERATURE
|
||||
|
||||
// Build the request parameters
|
||||
const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = {
|
||||
model,
|
||||
max_tokens,
|
||||
temperature,
|
||||
messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)],
|
||||
stream: true,
|
||||
stream_options: { include_usage: true },
|
||||
}
|
||||
|
||||
// Add SiliconCloud-specific reasoning parameters if the model supports it
|
||||
// Note: For now, we enable thinking by default for models that support it
|
||||
// In the future, this could be configurable via UI settings
|
||||
if (supportsReasoningBudget) {
|
||||
// SiliconCloud uses different parameter names than OpenAI
|
||||
;(params as any).enable_thinking = true
|
||||
// Default thinking budget could be added here if needed
|
||||
}
|
||||
|
||||
try {
|
||||
const stream = await this.client.chat.completions.create(params)
|
||||
|
||||
for await (const chunk of stream) {
|
||||
const delta = chunk.choices[0]?.delta
|
||||
|
||||
if (delta?.content) {
|
||||
yield {
|
||||
type: "text",
|
||||
text: delta.content,
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk.usage) {
|
||||
yield {
|
||||
type: "usage",
|
||||
inputTokens: chunk.usage.prompt_tokens || 0,
|
||||
outputTokens: chunk.usage.completion_tokens || 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw handleOpenAIError(error, "SiliconCloud")
|
||||
}
|
||||
}
|
||||
|
||||
async completePrompt(prompt: string): Promise<string> {
|
||||
const { id: modelId } = this.getModel()
|
||||
|
||||
try {
|
||||
const response = await this.client.chat.completions.create({
|
||||
model: modelId,
|
||||
messages: [{ role: "user", content: prompt }],
|
||||
})
|
||||
|
||||
return response.choices[0]?.message.content || ""
|
||||
} catch (error) {
|
||||
throw handleOpenAIError(error, "SiliconCloud")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -67,6 +67,7 @@ export class ProfileValidator {
|
|||
case "xai":
|
||||
case "groq":
|
||||
case "sambanova":
|
||||
case "siliconcloud":
|
||||
case "chutes":
|
||||
case "fireworks":
|
||||
case "featherless":
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
import { VSCodeDropdown, VSCodeOption, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
|
||||
import { useCallback } from "react"
|
||||
|
||||
import type { ProviderSettings } from "@roo-code/types"
|
||||
import { siliconCloudApiLineConfigs, siliconCloudApiLineSchema } from "@roo-code/types"
|
||||
|
||||
import { useAppTranslation } from "@src/i18n/TranslationContext"
|
||||
import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"
|
||||
|
||||
import { inputEventTransform } from "../transforms"
|
||||
import { cn } from "@src/lib/utils"
|
||||
|
||||
type SiliconCloudProps = {
|
||||
apiConfiguration: ProviderSettings
|
||||
setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void
|
||||
}
|
||||
|
||||
export const SiliconCloud = ({ apiConfiguration, setApiConfigurationField }: SiliconCloudProps) => {
|
||||
const { t } = useAppTranslation()
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
<K extends keyof ProviderSettings, E>(
|
||||
field: K,
|
||||
transform: (event: E) => ProviderSettings[K] = inputEventTransform,
|
||||
) =>
|
||||
(event: E | Event) => {
|
||||
setApiConfigurationField(field, transform(event as E))
|
||||
},
|
||||
[setApiConfigurationField],
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<label className="block font-medium mb-1">{t("settings:providers.siliconCloudEntrypoint")}</label>
|
||||
<VSCodeDropdown
|
||||
value={apiConfiguration.siliconCloudApiLine || "china"}
|
||||
onChange={handleInputChange("siliconCloudApiLine")}
|
||||
className={cn("w-full")}>
|
||||
{siliconCloudApiLineSchema.options.map((apiLine) => {
|
||||
const config = siliconCloudApiLineConfigs[apiLine]
|
||||
return (
|
||||
<VSCodeOption key={apiLine} value={apiLine} className="p-2">
|
||||
{config.name} ({config.baseUrl})
|
||||
</VSCodeOption>
|
||||
)
|
||||
})}
|
||||
</VSCodeDropdown>
|
||||
<div className="text-xs text-vscode-descriptionForeground mt-1">
|
||||
{t("settings:providers.siliconCloudEntrypointDescription")}
|
||||
</div>
|
||||
</div>
|
||||
<VSCodeTextField
|
||||
value={apiConfiguration?.siliconCloudApiKey || ""}
|
||||
type="password"
|
||||
onInput={handleInputChange("siliconCloudApiKey")}
|
||||
placeholder={t("settings:placeholders.apiKey")}
|
||||
className="w-full">
|
||||
<label className="block font-medium mb-1">{t("settings:providers.siliconCloudApiKey")}</label>
|
||||
</VSCodeTextField>
|
||||
<div className="text-sm text-vscode-descriptionForeground -mt-2">
|
||||
{t("settings:providers.apiKeyStorageNotice")}
|
||||
</div>
|
||||
{!apiConfiguration?.siliconCloudApiKey && (
|
||||
<VSCodeButtonLink href="https://siliconflow.cn/" appearance="secondary">
|
||||
{t("settings:providers.getSiliconCloudApiKey")}
|
||||
</VSCodeButtonLink>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -30,3 +30,4 @@ export { Fireworks } from "./Fireworks"
|
|||
export { Featherless } from "./Featherless"
|
||||
export { VercelAiGateway } from "./VercelAiGateway"
|
||||
export { DeepInfra } from "./DeepInfra"
|
||||
export { SiliconCloud } from "./SiliconCloud"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ import {
|
|||
claudeCodeModels,
|
||||
sambaNovaModels,
|
||||
sambaNovaDefaultModelId,
|
||||
siliconCloudDefaultModelId,
|
||||
siliconCloudModelsByApiLine,
|
||||
doubaoModels,
|
||||
doubaoDefaultModelId,
|
||||
internationalZAiDefaultModelId,
|
||||
|
|
@ -313,6 +315,13 @@ function getSelectedModel({
|
|||
const info = sambaNovaModels[id as keyof typeof sambaNovaModels]
|
||||
return { id, info }
|
||||
}
|
||||
case "siliconcloud": {
|
||||
const apiLine = apiConfiguration.siliconCloudApiLine || "china"
|
||||
const models = siliconCloudModelsByApiLine[apiLine]
|
||||
const id = apiConfiguration.apiModelId ?? siliconCloudDefaultModelId
|
||||
const info = models[id]
|
||||
return { id, info }
|
||||
}
|
||||
case "fireworks": {
|
||||
const id = apiConfiguration.apiModelId ?? fireworksDefaultModelId
|
||||
const info = fireworksModels[id as keyof typeof fireworksModels]
|
||||
|
|
|
|||
|
|
@ -288,6 +288,10 @@
|
|||
"getFireworksApiKey": "Get Fireworks API Key",
|
||||
"featherlessApiKey": "Featherless API Key",
|
||||
"getFeatherlessApiKey": "Get Featherless API Key",
|
||||
"siliconCloudApiKey": "SiliconCloud API Key",
|
||||
"getSiliconCloudApiKey": "Get SiliconCloud API Key",
|
||||
"siliconCloudEntrypoint": "SiliconCloud Entrypoint",
|
||||
"siliconCloudEntrypointDescription": "Please select the appropriate API entrypoint based on your location.",
|
||||
"ioIntelligenceApiKey": "IO Intelligence API Key",
|
||||
"ioIntelligenceApiKeyPlaceholder": "Enter your IO Intelligence API key",
|
||||
"getIoIntelligenceApiKey": "Get IO Intelligence API Key",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
isDynamicProvider,
|
||||
isFauxProvider,
|
||||
isCustomProvider,
|
||||
siliconCloudModelsByApiLine,
|
||||
} from "@roo-code/types"
|
||||
|
||||
import type { RouterModels } from "@roo/api"
|
||||
|
|
@ -156,6 +157,17 @@ function validateModelsAndKeysProvided(apiConfiguration: ProviderSettings): stri
|
|||
return i18next.t("settings:validation.apiKey")
|
||||
}
|
||||
break
|
||||
case "siliconcloud":
|
||||
if (!apiConfiguration.siliconCloudApiKey) {
|
||||
return i18next.t("settings:validation.apiKey")
|
||||
}
|
||||
if (apiConfiguration.siliconCloudApiLine) {
|
||||
const models = siliconCloudModelsByApiLine[apiConfiguration.siliconCloudApiLine]
|
||||
if (apiConfiguration.apiModelId && !models[apiConfiguration.apiModelId as keyof typeof models]) {
|
||||
return i18next.t("settings:validation.modelAvailability", { modelId: apiConfiguration.apiModelId })
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
return undefined
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue