diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index a66aae08a24..05fa228ebf5 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -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", "chinaOverseas", "international"]) + +export type SiliconCloudApiLine = z.infer + +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 @@ -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 = { 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", diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index 21e43aaa99a..16cb4e532eb 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -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" diff --git a/packages/types/src/providers/siliconcloud.ts b/packages/types/src/providers/siliconcloud.ts new file mode 100644 index 00000000000..5431266d97a --- /dev/null +++ b/packages/types/src/providers/siliconcloud.ts @@ -0,0 +1,175 @@ +import type { ModelInfo } from "../model.js" +import { SiliconCloudApiLine } from "../provider-settings.js" + +export const siliconCloudDefaultModelId = "zai-org/GLM-4.6" +export const siliconCloudDefaultApiLine: SiliconCloudApiLine = "china" + +export const siliconCloudApiLineConfigs = { + china: { baseUrl: "https://api.siliconflow.cn/v1" }, + chinaOverseas: { baseUrl: "https://api-st.siliconflow.cn/v1" }, + international: { baseUrl: "https://api.siliconflow.com/v1" }, +} satisfies Record + +const siliconCloudChinaModels: Record = { + "Pro/deepseek-ai/DeepSeek-V3.1-Terminus": { + contextWindow: 163840, + inputPrice: 0.56, + outputPrice: 2.25, + description: + "DeepSeek-V3.1-Terminus 是由深度求索(DeepSeek)发布的 V3.1 模型的更新版本,定位为混合智能体大语言模型。此次更新在保持模型原有能力的基础上,专注于修复用户反馈的问题并提升稳定性。它显著改善了语言一致性,减少了中英文混用和异常字符的出现。模型集成了“思考模式”(Thinking Mode)和“非思考模式”(Non-thinking Mode),用户可通过聊天模板灵活切换以适应不同任务。作为一个重要的优化,V3.1-Terminus 增强了代码智能体(Code Agent)和搜索智能体(Search Agent)的性能,使其在工具调用和执行多步复杂任务方面更加可靠", + supportsPromptCache: false, + supportsReasoningBudget: true, + maxTokens: 163840, + }, + "Pro/moonshotai/Kimi-K2-Instruct-0905": { + contextWindow: 262144, + inputPrice: 0.56, + outputPrice: 2.25, + description: + "Kimi K2-Instruct-0905 是 Kimi K2 最新、最强大的版本。它是一款顶尖的混合专家(MoE)语言模型,拥有 1 万亿的总参数和 320 亿的激活参数。该模型的主要特性包括:增强的智能体编码智能,在公开基准测试和真实世界的编码智能体任务中表现出显著的性能提升;改进的前端编码体验,在前端编程的美观性和实用性方面均有进步", + supportsPromptCache: false, + }, + "zai-org/GLM-4.6": { + contextWindow: 202752, + inputPrice: 0.49, + outputPrice: 1.97, + description: + "与 GLM-4.5 相比,GLM-4.6 带来了多项关键改进。其上下文窗口从 128K 扩展到 200K tokens,使模型能够处理更复杂的智能体任务。模型在代码基准测试中取得了更高的分数,并在 Claude Code、Cline、Roo Code 和 Kilo Code 等应用中展现了更强的真实世界性能,包括在生成视觉效果精致的前端页面方面有所改进。GLM-4.6 在推理性能上表现出明显提升,并支持在推理过程中使用工具,从而带来了更强的综合能力。它在工具使用和基于搜索的智能体方面表现更强,并且能更有效地集成到智能体框架中。在写作方面,该模型在风格和可读性上更符合人类偏好,并在角色扮演场景中表现得更自然", + supportsPromptCache: false, + supportsReasoningBudget: true, + maxTokens: 202752, + }, + "deepseek-ai/DeepSeek-V3.1-Terminus": { + contextWindow: 163840, + inputPrice: 0.56, + outputPrice: 2.25, + description: + "DeepSeek-V3.1-Terminus 是由深度求索(DeepSeek)发布的 V3.1 模型的更新版本,定位为混合智能体大语言模型。此次更新在保持模型原有能力的基础上,专注于修复用户反馈的问题并提升稳定性。它显著改善了语言一致性,减少了中英文混用和异常字符的出现。模型集成了“思考模式”(Thinking Mode)和“非思考模式”(Non-thinking Mode),用户可通过聊天模板灵活切换以适应不同任务。作为一个重要的优化,V3.1-Terminus 增强了代码智能体(Code Agent)和搜索智能体(Search Agent)的性能,使其在工具调用和执行多步复杂任务方面更加可靠", + supportsPromptCache: false, + supportsReasoningBudget: true, + maxTokens: 163840, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + contextWindow: 262144, + inputPrice: 0.56, + outputPrice: 2.25, + description: + "Kimi K2-Instruct-0905 是 Kimi K2 最新、最强大的版本。它是一款顶尖的混合专家(MoE)语言模型,拥有 1 万亿的总参数和 320 亿的激活参数。该模型的主要特性包括:增强的智能体编码智能,在公开基准测试和真实世界的编码智能体任务中表现出显著的性能提升;改进的前端编码体验,在前端编程的美观性和实用性方面均有进步", + supportsPromptCache: false, + }, + "zai-org/GLM-4.5": { + contextWindow: 131072, + inputPrice: 0.49, + outputPrice: 1.97, + description: + "GLM-4.5 是一款专为智能体应用打造的基础模型,使用了混合专家(Mixture-of-Experts)架构。在工具调用、网页浏览、软件工程、前端编程领域进行了深度优化,支持无缝接入 Claude Code、Roo Code 等代码智能体中使用。GLM-4.5 采用混合推理模式,可以适应复杂推理和日常使用等多种应用场景", + supportsPromptCache: false, + supportsReasoningBudget: true, + maxTokens: 131072, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct": { + contextWindow: 262144, + inputPrice: 1.12, + outputPrice: 2.25, + description: + "Qwen3-Coder-480B-A35B-Instruct 是由阿里巴巴发布的、迄今为止最具代理(Agentic)能力的代码模型。它是一个拥有 4800 亿总参数和 350 亿激活参数的混合专家(MoE)模型,在效率和性能之间取得了平衡。该模型原生支持 256K(约 26 万) tokens 的上下文长度,并可通过 YaRN 等外推方法扩展至 100 万 tokens,使其能够处理大规模代码库和复杂的编程任务。Qwen3-Coder 专为代理式编码工作流设计,不仅能生成代码,还能与开发工具和环境自主交互,以解决复杂的编程问题。在多个编码和代理任务的基准测试中,该模型在开源模型中取得了顶尖水平,其性能可与 Claude Sonnet 4 等领先模型相媲美。此外,阿里还开源了配套的命令行工具 Qwen Code,以充分释放其强大的代理编程能力", + supportsPromptCache: false, + }, + "Pro/deepseek-ai/DeepSeek-R1": { + contextWindow: 163840, + inputPrice: 0.56, + outputPrice: 2.25, + description: + "DeepSeek-R1-0528 是一款强化学习(RL)驱动的推理模型,解决了模型中的重复性和可读性问题。在 RL 之前,DeepSeek-R1 引入了冷启动数据,进一步优化了推理性能。它在数学、代码和推理任务中与 OpenAI-o1 表现相当,并且通过精心设计的训练方法,提升了整体效果", + supportsPromptCache: false, + }, + "deepseek-ai/DeepSeek-R1": { + contextWindow: 163840, + inputPrice: 0.56, + outputPrice: 2.25, + description: + "DeepSeek-R1-0528 是一款强化学习(RL)驱动的推理模型,解决了模型中的重复性和可读性问题。在 RL 之前,DeepSeek-R1 引入了冷启动数据,进一步优化了推理性能。它在数学、代码和推理任务中与 OpenAI-o1 表现相当,并且通过精心设计的训练方法,提升了整体效果", + supportsPromptCache: false, + }, + "Qwen/Qwen3-Next-80B-A3B-Instruct": { + contextWindow: 262144, + inputPrice: 0.14, + outputPrice: 0.56, + description: + "Qwen3-Next-80B-A3B-Instruct 是由阿里巴巴通义千问团队发布的下一代基础模型。它基于全新的 Qwen3-Next 架构,旨在实现极致的训练和推理效率。该模型采用了创新的混合注意力机制(Gated DeltaNet 和 Gated Attention)、高稀疏度混合专家(MoE)结构以及多项训练稳定性优化。作为一个拥有 800 亿总参数的稀疏模型,它在推理时仅需激活约 30 亿参数,从而大幅降低了计算成本,并在处理超过 32K tokens 的长上下文任务时,推理吞吐量比 Qwen3-32B 模型高出 10 倍以上。此模型为指令微调版本,专为通用任务设计,不支持思维链(Thinking)模式。在性能上,它与通义千问的旗舰模型 Qwen3-235B 在部分基准测试中表现相当,尤其在超长上下文任务中展现出明显优势", + supportsPromptCache: false, + }, +} + +const siliconCloudInternationalModels: Record = { + "zai-org/GLM-4.6": { + ...siliconCloudChinaModels["zai-org/GLM-4.6"]!, + inputPrice: 0.5, + outputPrice: 1.9, + description: + "Compared with GLM-4.5, GLM-4.6 brings several key improvements. Its context window is expanded from 128K to 200K tokens, enabling the model to handle more complex agentic tasks. The model achieves higher scores on code benchmarks and demonstrates better real-world performance in applications such as Claude Code, Cline, Roo Code and Kilo Code, including improvements in generating visually polished front-end pages. GLM-4.6 shows a clear improvement in reasoning performance and supports tool use during inference, leading to stronger overall capability. It also exhibits stronger performance in tool using and search-based agents, and integrates more effectively within agent frameworks. For writing, it better aligns with human preferences in style and readability, and performs more naturally in role-playing scenarios", + }, + "deepseek-ai/DeepSeek-V3.1-Terminus": { + ...siliconCloudChinaModels["deepseek-ai/DeepSeek-V3.1-Terminus"]!, + inputPrice: 0.27, + outputPrice: 1, + description: + "DeepSeek-V3.1-Terminus is an updated version of the V3.1 model from DeepSeek, positioned as a hybrid, agent-oriented large language model. This update maintains the model's original capabilities while focusing on addressing user-reported issues and improving stability. It significantly enhances language consistency, reducing instances of mixed Chinese-English text and abnormal characters. The model integrates both a 'Thinking Mode' for complex, multi-step reasoning and a 'Non-thinking Mode' for direct, quick responses, switchable via the chat template. As a key enhancement, V3.1-Terminus features improved performance for its Code Agent and Search Agent, making it more reliable for tool use and executing complex, multi-step tasks", + }, + "moonshotai/Kimi-K2-Instruct-0905": { + ...siliconCloudChinaModels["moonshotai/Kimi-K2-Instruct-0905"]!, + inputPrice: 0.4, + outputPrice: 2, + description: + "Kimi K2-Instruct-0905 is the latest, most capable version of Kimi K2. It is a state-of-the-art mixture-of-experts (MoE) language model, featuring 32 billion activated parameters and a total of 1 trillion parameters. Key features include enhanced agentic coding intelligence, with the model demonstrating significant improvements on public benchmarks and real-world coding agent tasks; an improved frontend coding experience, offering advancements in both the aesthetics and practicality of frontend programming", + }, + "zai-org/GLM-4.5": { + ...siliconCloudChinaModels["zai-org/GLM-4.5"]!, + inputPrice: 0.4, + outputPrice: 2, + description: + "GLM-4.5 is a foundational model specifically designed for AI agent applications, built on a Mixture-of-Experts (MoE) architecture. It has been extensively optimized for tool use, web browsing, software development, and front-end development, enabling seamless integration with coding agents such as Claude Code and Roo Code. GLM-4.5 employs a hybrid reasoning approach, allowing it to adapt effectively to a wide range of application scenarios—from complex reasoning tasks to everyday use cases", + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct": { + ...siliconCloudChinaModels["Qwen/Qwen3-Coder-480B-A35B-Instruct"]!, + inputPrice: 0.25, + outputPrice: 1, + description: + "Qwen3-Coder-480B-A35B-Instruct is the most agentic code model released by Alibaba to date. It is a Mixture-of-Experts (MoE) model with 480 billion total parameters and 35 billion activated parameters, balancing efficiency and performance. The model natively supports a 256K (approximately 262,144) token context length, which can be extended up to 1 million tokens using extrapolation methods like YaRN, enabling it to handle repository-scale codebases and complex programming tasks. Qwen3-Coder is specifically designed for agentic coding workflows, where it not only generates code but also autonomously interacts with developer tools and environments to solve complex problems. It has achieved state-of-the-art results among open models on various coding and agentic benchmarks, with performance comparable to leading models like Claude Sonnet 4. Alongside the model, Alibaba has also open-sourced Qwen Code, a command-line tool designed to fully unleash its powerful agentic coding capabilities", + }, + "deepseek-ai/DeepSeek-R1": { + ...siliconCloudChinaModels["deepseek-ai/DeepSeek-R1"]!, + inputPrice: 0.5, + outputPrice: 2.18, + description: + "DeepSeek-R1-0528 is a reasoning model powered by reinforcement learning (RL) that addresses the issues of repetition and readability. Prior to RL, DeepSeek-R1 incorporated cold-start data to further optimize its reasoning performance. It achieves performance comparable to OpenAI-o1 across math, code, and reasoning tasks, and through carefully designed training methods, it has enhanced overall effectiveness", + }, + "Qwen/Qwen3-Next-80B-A3B-Instruct": { + ...siliconCloudChinaModels["Qwen/Qwen3-Next-80B-A3B-Instruct"]!, + inputPrice: 0.14, + outputPrice: 1.4, + description: + "Qwen3-Next-80B-A3B-Instruct is a next-generation foundation model released by Alibaba's Qwen team. It is built on the new Qwen3-Next architecture, designed for ultimate training and inference efficiency. The model incorporates innovative features such as a Hybrid Attention mechanism (Gated DeltaNet and Gated Attention), a High-Sparsity Mixture-of-Experts (MoE) structure, and various stability optimizations. As an 80-billion-parameter sparse model, it activates only about 3 billion parameters per token during inference, which significantly reduces computational costs and delivers over 10 times higher throughput than the Qwen3-32B model for long-context tasks exceeding 32K tokens. This is an instruction-tuned version optimized for general-purpose tasks and does not support 'thinking' mode. In terms of performance, it is comparable to Qwen's flagship model, Qwen3-235B, on certain benchmarks, showing significant advantages in ultra-long-context scenarios", + }, + "openai/gpt-oss-120b": { + contextWindow: 131072, + inputPrice: 0.05, + outputPrice: 0.45, + description: + "gpt-oss-120b is OpenAI’s open-weight large language model with ~117B parameters (5.1B active), using a Mixture-of-Experts (MoE) design and MXFP4 quantization to run on a single 80 GB GPU. It delivers o4-mini-level or better performance in reasoning, coding, health, and math benchmarks, with full Chain-of-Thought (CoT), tool use, and Apache 2.0-licensed commercial deployment support.", + supportsPromptCache: false, + }, +} + +export const siliconCloudModelsByApiLine = { + china: siliconCloudChinaModels, + chinaOverseas: siliconCloudChinaModels, + international: siliconCloudInternationalModels, +} as const satisfies Record> + +export const siliconCloudModels = { + ...siliconCloudInternationalModels, + ...siliconCloudChinaModels, +} as const satisfies Record + +export type SiliconCloudModel = keyof typeof siliconCloudModels diff --git a/src/api/index.ts b/src/api/index.ts index ac009676762..ae4a0a9f810 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -40,6 +40,7 @@ import { FeatherlessHandler, VercelAiGatewayHandler, DeepInfraHandler, + SiliconCloudHandler, } from "./providers" import { NativeOllamaHandler } from "./providers/native-ollama" @@ -165,6 +166,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler { return new FeatherlessHandler(options) case "vercel-ai-gateway": return new VercelAiGatewayHandler(options) + case "siliconcloud": + return new SiliconCloudHandler(options) default: apiProvider satisfies "gemini-cli" | undefined return new AnthropicHandler(options) diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index 85d877b6bc7..41130f6980b 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -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" diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index aebe671712a..8e30a56736a 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -31,8 +31,8 @@ import { handleOpenAIError } from "./utils/openai-error-handler" // compatible with the OpenAI API. We can also rename it to `OpenAIHandler`. export class OpenAiHandler extends BaseProvider implements SingleCompletionHandler { protected options: ApiHandlerOptions - private client: OpenAI - private readonly providerName = "OpenAI" + protected client: OpenAI + protected readonly providerName = "OpenAI" constructor(options: ApiHandlerOptions) { super() diff --git a/src/api/providers/siliconcloud.ts b/src/api/providers/siliconcloud.ts new file mode 100644 index 00000000000..e85ea14e480 --- /dev/null +++ b/src/api/providers/siliconcloud.ts @@ -0,0 +1,114 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" + +import { + siliconCloudApiLineConfigs, + siliconCloudDefaultModelId, + siliconCloudDefaultApiLine, + siliconCloudModelsByApiLine, +} from "@roo-code/types" + +import { type ApiHandlerOptions } from "../../shared/api" +import { type ApiStream } from "../transform/stream" +import { convertToOpenAiMessages } from "../transform/openai-format" +import { handleOpenAIError } from "./utils/openai-error-handler" +import { ApiHandlerCreateMessageMetadata } from ".." +import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider" + +export class SiliconCloudHandler extends BaseOpenAiCompatibleProvider { + constructor(options: ApiHandlerOptions) { + const apiLine = options.siliconCloudApiLine || siliconCloudDefaultApiLine + const baseURL = siliconCloudApiLineConfigs[apiLine].baseUrl + const providerModels = siliconCloudModelsByApiLine[apiLine] + + super({ + ...options, + providerName: "SiliconCloud", + baseURL, + apiKey: options.siliconCloudApiKey, + defaultProviderModelId: siliconCloudDefaultModelId, + providerModels, + defaultTemperature: 0, + }) + } + + protected override createStream( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + metadata?: ApiHandlerCreateMessageMetadata, + requestOptions?: OpenAI.RequestOptions, + ) { + const { + id: model, + info: { maxTokens: max_tokens, supportsReasoningBudget }, + } = this.getModel() + + const temperature = this.options.modelTemperature ?? this.defaultTemperature + + const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = { + model, + max_tokens, + temperature, + messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + stream: true, + stream_options: { include_usage: true }, + } + + if (supportsReasoningBudget) { + if (this.options.enableReasoningEffort) { + // @ts-ignore + params.enable_thinking = true + } + + if (this.options.modelMaxThinkingTokens) { + // @ts-ignore + params.thinking_budget = this.options.modelMaxThinkingTokens + } + } + + try { + return this.client.chat.completions.create(params, requestOptions) + } catch (error) { + throw handleOpenAIError(error, this.providerName) + } + } + + override async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + metadata?: ApiHandlerCreateMessageMetadata, + ): ApiStream { + const stream = await this.createStream(systemPrompt, messages, metadata) + let lastUsage: OpenAI.CompletionUsage | undefined + + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta ?? {} + + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + + if ("reasoning_content" in delta && delta.reasoning_content) { + yield { + type: "reasoning", + text: (delta.reasoning_content as string | undefined) || "", + } + } + + if (chunk.usage) { + lastUsage = chunk.usage + } + } + + if (lastUsage) { + yield { + type: "usage", + inputTokens: lastUsage.prompt_tokens || 0, + outputTokens: lastUsage.completion_tokens || 0, + } + } + } +} diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 66f389f81c1..b28dfacdc62 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -77,6 +77,7 @@ export interface ExtensionMessage { | "listApiConfig" | "routerModels" | "openAiModels" + | "siliconCloudModels" | "ollamaModels" | "lmStudioModels" | "vsCodeLmModels" @@ -152,6 +153,7 @@ export interface ExtensionMessage { clineMessage?: ClineMessage routerModels?: RouterModels openAiModels?: string[] + siliconCloudModels?: string[] ollamaModels?: ModelRecord lmStudioModels?: ModelRecord vsCodeLmModels?: { vendor?: string; family?: string; version?: string; id?: string }[] diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 4142796b668..bdfa874b915 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -37,6 +37,8 @@ import { rooDefaultModelId, vercelAiGatewayDefaultModelId, deepInfraDefaultModelId, + siliconCloudDefaultModelId, + siliconCloudDefaultApiLine, } from "@roo-code/types" import { vscode } from "@src/utils/vscode" @@ -95,9 +97,10 @@ import { Featherless, VercelAiGateway, DeepInfra, + SiliconCloud, } from "./providers" -import { MODELS_BY_PROVIDER, PROVIDERS } from "./constants" +import { MODELS_BY_PROVIDER, PROVIDERS, SILICON_CLOUD_MODELS_BY_API_LINE } from "./constants" import { inputEventTransform, noTransform } from "./transforms" import { ModelInfoView } from "./ModelInfoView" import { ApiErrorMessage } from "./ApiErrorMessage" @@ -258,7 +261,12 @@ const ApiOptions = ({ }, [apiConfiguration, routerModels, organizationAllowList, setErrorMessage]) const selectedProviderModels = useMemo(() => { - const models = MODELS_BY_PROVIDER[selectedProvider] + let models = MODELS_BY_PROVIDER[selectedProvider] + + if (selectedProvider === "siliconcloud") { + const apiLine = apiConfiguration.siliconCloudApiLine || siliconCloudDefaultApiLine + models = SILICON_CLOUD_MODELS_BY_API_LINE[apiLine] + } if (!models) return [] const filteredModels = filterModels(models, selectedProvider, organizationAllowList) @@ -280,7 +288,7 @@ const ApiOptions = ({ : [] return availableModels - }, [selectedProvider, organizationAllowList, selectedModelId]) + }, [selectedProvider, organizationAllowList, selectedModelId, apiConfiguration.siliconCloudApiLine]) const onProviderChange = useCallback( (value: ProviderName) => { @@ -354,6 +362,7 @@ const ApiOptions = ({ "io-intelligence": { field: "ioIntelligenceModelId", default: ioIntelligenceDefaultModelId }, roo: { field: "apiModelId", default: rooDefaultModelId }, "vercel-ai-gateway": { field: "vercelAiGatewayModelId", default: vercelAiGatewayDefaultModelId }, + siliconcloud: { field: "apiModelId", default: siliconCloudDefaultModelId }, openai: { field: "openAiModelId" }, ollama: { field: "ollamaModelId" }, lmstudio: { field: "lmStudioModelId" }, @@ -514,6 +523,10 @@ const ApiOptions = ({ /> )} + {selectedProvider === "siliconcloud" && ( + + )} + {selectedProvider === "anthropic" && ( )} diff --git a/webview-ui/src/components/settings/constants.ts b/webview-ui/src/components/settings/constants.ts index ae336730ff5..3922b4ad2c6 100644 --- a/webview-ui/src/components/settings/constants.ts +++ b/webview-ui/src/components/settings/constants.ts @@ -21,6 +21,8 @@ import { fireworksModels, rooModels, featherlessModels, + siliconCloudModels, + siliconCloudModelsByApiLine, } from "@roo-code/types" export const MODELS_BY_PROVIDER: Partial>> = { @@ -44,8 +46,11 @@ export const MODELS_BY_PROVIDER: Partial a.label.localeCompare(b.label)) diff --git a/webview-ui/src/components/settings/providers/SiliconCloud.tsx b/webview-ui/src/components/settings/providers/SiliconCloud.tsx new file mode 100644 index 00000000000..ce4a4d91b3c --- /dev/null +++ b/webview-ui/src/components/settings/providers/SiliconCloud.tsx @@ -0,0 +1,80 @@ +import { useCallback } from "react" +import { VSCodeTextField, VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react" + +import { + type ProviderSettings, + siliconCloudApiLineSchema, + siliconCloudApiLineConfigs, + siliconCloudDefaultApiLine, +} from "@roo-code/types" + +import { useAppTranslation } from "@src/i18n/TranslationContext" +import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" + +import { inputEventTransform } from "../transforms" + +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( + ( + field: K, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, + ) => + (event: E | Event) => { + setApiConfigurationField(field, transform(event as E)) + }, + [setApiConfigurationField], + ) + + return ( + <> +
+ + + {siliconCloudApiLineSchema.options.map((apiLine) => { + const config = siliconCloudApiLineConfigs[apiLine] + return ( + + {t(`settings:providers.siliconcloud.apiLineConfigs.${apiLine}`)} ({config.baseUrl}) + + ) + })} + +
+ {t("settings:providers.siliconcloud.entrypointDescription")} +
+
+ + + +
+ {t("settings:providers.apiKeyStorageNotice")} +
+ {!apiConfiguration?.siliconCloudApiKey && ( + + {t("settings:providers.siliconcloud.getApiKey")} + + )} + + ) +} diff --git a/webview-ui/src/components/settings/providers/index.ts b/webview-ui/src/components/settings/providers/index.ts index fe0e6cecf96..b47d9d96d98 100644 --- a/webview-ui/src/components/settings/providers/index.ts +++ b/webview-ui/src/components/settings/providers/index.ts @@ -30,3 +30,4 @@ export { Fireworks } from "./Fireworks" export { Featherless } from "./Featherless" export { VercelAiGateway } from "./VercelAiGateway" export { DeepInfra } from "./DeepInfra" +export { SiliconCloud } from "./SiliconCloud" diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 0d0514b4d66..154a02d35bf 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -38,6 +38,9 @@ import { claudeCodeModels, sambaNovaModels, sambaNovaDefaultModelId, + siliconCloudDefaultModelId, + siliconCloudModelsByApiLine, + siliconCloudDefaultApiLine, doubaoModels, doubaoDefaultModelId, internationalZAiDefaultModelId, @@ -313,6 +316,13 @@ function getSelectedModel({ const info = sambaNovaModels[id as keyof typeof sambaNovaModels] return { id, info } } + case "siliconcloud": { + const apiLine = apiConfiguration.siliconCloudApiLine || siliconCloudDefaultApiLine + 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] diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 611159069b2..2b87b266425 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Obtenir clau API de Fireworks", "featherlessApiKey": "Clau API de Featherless", "getFeatherlessApiKey": "Obtenir clau API de Featherless", + "siliconcloud": { + "apiKey": "Clau API de SiliconCloud", + "getApiKey": "Obtenir clau API de SiliconCloud", + "entrypoint": "Regió de servei de SiliconCloud", + "entrypointDescription": "Selecciona la regió de servei adequada segons la teva ubicació.", + "apiLineConfigs": { + "china": "Nacional", + "chinaOverseas": "Nacional (Accés des de l'estranger)", + "international": "Internacional" + } + }, "ioIntelligenceApiKey": "Clau API d'IO Intelligence", "ioIntelligenceApiKeyPlaceholder": "Introdueix la teva clau d'API de IO Intelligence", "getIoIntelligenceApiKey": "Obtenir clau API d'IO Intelligence", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 00827751b0f..44f25d27cbf 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -290,6 +290,17 @@ "getIoIntelligenceApiKey": "IO Intelligence API-Schlüssel erhalten", "deepSeekApiKey": "DeepSeek API-Schlüssel", "getDeepSeekApiKey": "DeepSeek API-Schlüssel erhalten", + "siliconcloud": { + "apiKey": "SiliconCloud API-Schlüssel", + "getApiKey": "SiliconCloud API-Schlüssel erhalten", + "entrypoint": "SiliconCloud-Serviceregion", + "entrypointDescription": "Wähle die passende Serviceregion basierend auf deinem Standort.", + "apiLineConfigs": { + "china": "Inland", + "chinaOverseas": "Inland (Zugriff aus dem Ausland)", + "international": "International" + } + }, "moonshotApiKey": "Moonshot API-Schlüssel", "getMoonshotApiKey": "Moonshot API-Schlüssel erhalten", "moonshotBaseUrl": "Moonshot-Einstiegspunkt", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index dfccc49cc4c..134e2d27b91 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -288,6 +288,17 @@ "getFireworksApiKey": "Get Fireworks API Key", "featherlessApiKey": "Featherless API Key", "getFeatherlessApiKey": "Get Featherless API Key", + "siliconcloud": { + "apiKey": "SiliconCloud API Key", + "getApiKey": "Get SiliconCloud API Key", + "entrypoint": "SiliconCloud Service Region", + "entrypointDescription": "Please select the appropriate service region based on your location.", + "apiLineConfigs": { + "china": "Domestic", + "chinaOverseas": "Domestic (Overseas Access)", + "international": "International" + } + }, "ioIntelligenceApiKey": "IO Intelligence API Key", "ioIntelligenceApiKeyPlaceholder": "Enter your IO Intelligence API key", "getIoIntelligenceApiKey": "Get IO Intelligence API Key", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index c1271df8274..744b8d6353d 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -387,6 +387,17 @@ "description": "Ollama le permite ejecutar modelos localmente en su computadora. Para obtener instrucciones sobre cómo comenzar, consulte la guía de inicio rápido.", "warning": "Nota: Roo Code utiliza prompts complejos y funciona mejor con modelos Claude. Los modelos menos capaces pueden no funcionar como se espera." }, + "siliconcloud": { + "apiKey": "Clave API de SiliconCloud", + "getApiKey": "Obtener clave API de SiliconCloud", + "entrypoint": "Región de servicio de SiliconCloud", + "entrypointDescription": "Por favor, seleccione la región de servicio apropiada según su ubicación.", + "apiLineConfigs": { + "china": "Nacional", + "chinaOverseas": "Nacional (Acceso desde el extranjero)", + "international": "Internacional" + } + }, "unboundApiKey": "Clave API de Unbound", "getUnboundApiKey": "Obtener clave API de Unbound", "unboundRefreshModelsSuccess": "¡Lista de modelos actualizada! Ahora puede seleccionar entre los últimos modelos.", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index abcf401d640..4034c945936 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -324,6 +324,17 @@ "getMistralApiKey": "Obtenir la clé API Mistral / Codestral", "codestralBaseUrl": "URL de base Codestral (Optionnel)", "codestralBaseUrlDesc": "Définir une URL alternative pour le modèle Codestral.", + "siliconcloud": { + "apiKey": "Clé API SiliconCloud", + "getApiKey": "Obtenir la clé API SiliconCloud", + "entrypoint": "Région de service SiliconCloud", + "entrypointDescription": "Sélectionnez la région de service appropriée en fonction de votre localisation.", + "apiLineConfigs": { + "china": "National", + "chinaOverseas": "National (Accès depuis l'étranger)", + "international": "International" + } + }, "xaiApiKey": "Clé API xAI", "getXaiApiKey": "Obtenir la clé API xAI", "litellmApiKey": "Clé API LiteLLM", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 975e35411ee..6f07633f264 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Fireworks API कुंजी प्राप्त करें", "featherlessApiKey": "Featherless API कुंजी", "getFeatherlessApiKey": "Featherless API कुंजी प्राप्त करें", + "siliconcloud": { + "apiKey": "SiliconCloud API कुंजी", + "getApiKey": "SiliconCloud API कुंजी प्राप्त करें", + "entrypoint": "SiliconCloud सेवा क्षेत्र", + "entrypointDescription": "कृपया अपने स्थान के आधार पर उपयुक्त सेवा क्षेत्र चुनें।", + "apiLineConfigs": { + "china": "घरेलू", + "chinaOverseas": "घरेलू (विदेश से पहुंच)", + "international": "अंतर्राष्ट्रीय" + } + }, "ioIntelligenceApiKey": "IO Intelligence API कुंजी", "ioIntelligenceApiKeyPlaceholder": "अपना आईओ इंटेलिजेंस एपीआई कुंजी दर्ज करें", "getIoIntelligenceApiKey": "IO Intelligence API कुंजी प्राप्त करें", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index aa2c1172119..66f19021e66 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -287,6 +287,17 @@ "getFireworksApiKey": "Dapatkan Fireworks API Key", "featherlessApiKey": "Featherless API Key", "getFeatherlessApiKey": "Dapatkan Featherless API Key", + "siliconcloud": { + "apiKey": "SiliconCloud API Key", + "getApiKey": "Dapatkan SiliconCloud API Key", + "entrypoint": "Wilayah Layanan SiliconCloud", + "entrypointDescription": "Silakan pilih wilayah layanan yang sesuai berdasarkan lokasi kamu.", + "apiLineConfigs": { + "china": "Domestik", + "chinaOverseas": "Domestik (Akses dari Luar Negeri)", + "international": "Internasional" + } + }, "ioIntelligenceApiKey": "IO Intelligence API Key", "ioIntelligenceApiKeyPlaceholder": "Masukkan kunci API IO Intelligence Anda", "getIoIntelligenceApiKey": "Dapatkan IO Intelligence API Key", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 6f2e06bb8fd..0e2be95dd81 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Ottieni chiave API Fireworks", "featherlessApiKey": "Chiave API Featherless", "getFeatherlessApiKey": "Ottieni chiave API Featherless", + "siliconcloud": { + "apiKey": "Chiave API SiliconCloud", + "getApiKey": "Ottieni chiave API SiliconCloud", + "entrypoint": "Regione di servizio SiliconCloud", + "entrypointDescription": "Seleziona la regione di servizio appropriata in base alla tua posizione.", + "apiLineConfigs": { + "china": "Nazionale", + "chinaOverseas": "Nazionale (Accesso dall'estero)", + "international": "Internazionale" + } + }, "ioIntelligenceApiKey": "Chiave API IO Intelligence", "ioIntelligenceApiKeyPlaceholder": "Inserisci la tua chiave API IO Intelligence", "getIoIntelligenceApiKey": "Ottieni chiave API IO Intelligence", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index cc1ea09317e..5e0a670f593 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Fireworks APIキーを取得", "featherlessApiKey": "Featherless APIキー", "getFeatherlessApiKey": "Featherless APIキーを取得", + "siliconcloud": { + "apiKey": "SiliconCloud APIキー", + "getApiKey": "SiliconCloud APIキーを取得", + "entrypoint": "SiliconCloud サービスリージョン", + "entrypointDescription": "お住まいの地域に応じて適切なサービスリージョンを選択してください。", + "apiLineConfigs": { + "china": "国内版", + "chinaOverseas": "国内版(海外アクセス)", + "international": "国際版" + } + }, "ioIntelligenceApiKey": "IO Intelligence APIキー", "ioIntelligenceApiKeyPlaceholder": "IO Intelligence APIキーを入力してください", "getIoIntelligenceApiKey": "IO Intelligence APIキーを取得", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 61539cfc4d9..ec3ea578c47 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Fireworks API 키 받기", "featherlessApiKey": "Featherless API 키", "getFeatherlessApiKey": "Featherless API 키 받기", + "siliconcloud": { + "apiKey": "SiliconCloud API 키", + "getApiKey": "SiliconCloud API 키 받기", + "entrypoint": "SiliconCloud 서비스 지역", + "entrypointDescription": "위치에 따라 적절한 서비스 지역을 선택하세요.", + "apiLineConfigs": { + "china": "국내판", + "chinaOverseas": "국내판 (해외 접속)", + "international": "국제판" + } + }, "ioIntelligenceApiKey": "IO Intelligence API 키", "ioIntelligenceApiKeyPlaceholder": "IO Intelligence API 키를 입력하세요", "getIoIntelligenceApiKey": "IO Intelligence API 키 받기", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 41ee3e5910b..62df8a72b9f 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Fireworks API-sleutel ophalen", "featherlessApiKey": "Featherless API-sleutel", "getFeatherlessApiKey": "Featherless API-sleutel ophalen", + "siliconcloud": { + "apiKey": "SiliconCloud API-sleutel", + "getApiKey": "SiliconCloud API-sleutel ophalen", + "entrypoint": "SiliconCloud-serviceregio", + "entrypointDescription": "Selecteer de juiste serviceregio op basis van je locatie.", + "apiLineConfigs": { + "china": "Binnenlands", + "chinaOverseas": "Binnenlands (Toegang vanuit het buitenland)", + "international": "Internationaal" + } + }, "ioIntelligenceApiKey": "IO Intelligence API-sleutel", "ioIntelligenceApiKeyPlaceholder": "Voer je IO Intelligence API-sleutel in", "getIoIntelligenceApiKey": "IO Intelligence API-sleutel ophalen", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 6862d6f7edd..0e1a363bafd 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Uzyskaj klucz API Fireworks", "featherlessApiKey": "Klucz API Featherless", "getFeatherlessApiKey": "Uzyskaj klucz API Featherless", + "siliconcloud": { + "apiKey": "Klucz API SiliconCloud", + "getApiKey": "Uzyskaj klucz API SiliconCloud", + "entrypoint": "Region usługi SiliconCloud", + "entrypointDescription": "Wybierz odpowiedni region usługi w zależności od twojej lokalizacji.", + "apiLineConfigs": { + "china": "Krajowa", + "chinaOverseas": "Krajowa (Dostęp z zagranicy)", + "international": "Międzynarodowa" + } + }, "ioIntelligenceApiKey": "Klucz API IO Intelligence", "ioIntelligenceApiKeyPlaceholder": "Wprowadź swój klucz API IO Intelligence", "getIoIntelligenceApiKey": "Uzyskaj klucz API IO Intelligence", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index b8184777acf..2b778d7ef64 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Obter chave de API Fireworks", "featherlessApiKey": "Chave de API Featherless", "getFeatherlessApiKey": "Obter chave de API Featherless", + "siliconcloud": { + "apiKey": "Chave de API SiliconCloud", + "getApiKey": "Obter chave de API SiliconCloud", + "entrypoint": "Região de serviço SiliconCloud", + "entrypointDescription": "Selecione a região de serviço apropriada com base na sua localização.", + "apiLineConfigs": { + "china": "Nacional", + "chinaOverseas": "Nacional (Acesso do exterior)", + "international": "Internacional" + } + }, "ioIntelligenceApiKey": "Chave de API IO Intelligence", "ioIntelligenceApiKeyPlaceholder": "Insira sua chave de API da IO Intelligence", "getIoIntelligenceApiKey": "Obter chave de API IO Intelligence", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index bcbd72089a4..a2d0a0e7e31 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Получить Fireworks API-ключ", "featherlessApiKey": "Featherless API-ключ", "getFeatherlessApiKey": "Получить Featherless API-ключ", + "siliconcloud": { + "apiKey": "SiliconCloud API-ключ", + "getApiKey": "Получить SiliconCloud API-ключ", + "entrypoint": "Регион сервиса SiliconCloud", + "entrypointDescription": "Выбери подходящий регион сервиса в зависимости от твоего местоположения.", + "apiLineConfigs": { + "china": "Национальная", + "chinaOverseas": "Национальная (Доступ из-за рубежа)", + "international": "Международная" + } + }, "ioIntelligenceApiKey": "IO Intelligence API-ключ", "ioIntelligenceApiKeyPlaceholder": "Введите свой ключ API IO Intelligence", "getIoIntelligenceApiKey": "Получить IO Intelligence API-ключ", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 4ac28f47d2f..7350b4aafff 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Fireworks API Anahtarı Al", "featherlessApiKey": "Featherless API Anahtarı", "getFeatherlessApiKey": "Featherless API Anahtarı Al", + "siliconcloud": { + "apiKey": "SiliconCloud API Anahtarı", + "getApiKey": "SiliconCloud API Anahtarı Al", + "entrypoint": "SiliconCloud Hizmet Bölgesi", + "entrypointDescription": "Konumuna göre uygun hizmet bölgesini seç.", + "apiLineConfigs": { + "china": "Ulusal", + "chinaOverseas": "Ulusal (Yurtdışından Erişim)", + "international": "Uluslararası" + } + }, "ioIntelligenceApiKey": "IO Intelligence API Anahtarı", "ioIntelligenceApiKeyPlaceholder": "IO Intelligence API anahtarınızı girin", "getIoIntelligenceApiKey": "IO Intelligence API Anahtarı Al", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 4303325d068..8be46260679 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "Lấy khóa API Fireworks", "featherlessApiKey": "Khóa API Featherless", "getFeatherlessApiKey": "Lấy khóa API Featherless", + "siliconcloud": { + "apiKey": "Khóa API SiliconCloud", + "getApiKey": "Lấy khóa API SiliconCloud", + "entrypoint": "Khu vực dịch vụ SiliconCloud", + "entrypointDescription": "Vui lòng chọn khu vực dịch vụ phù hợp dựa trên vị trí của bạn.", + "apiLineConfigs": { + "china": "Trong nước", + "chinaOverseas": "Trong nước (Truy cập từ nước ngoài)", + "international": "Quốc tế" + } + }, "ioIntelligenceApiKey": "Khóa API IO Intelligence", "ioIntelligenceApiKeyPlaceholder": "Nhập khóa API IO Intelligence của bạn", "getIoIntelligenceApiKey": "Lấy khóa API IO Intelligence", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index f574106f456..7c6effb0dd6 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "获取 Fireworks API 密钥", "featherlessApiKey": "Featherless API 密钥", "getFeatherlessApiKey": "获取 Featherless API 密钥", + "siliconcloud": { + "apiKey": "SiliconCloud API 密钥", + "getApiKey": "获取 SiliconCloud API 密钥", + "entrypoint": "SiliconCloud 服务站点", + "entrypointDescription": "请根据您的所在区域选择合适的服务站点。", + "apiLineConfigs": { + "china": "国内版", + "chinaOverseas": "国内版(海外访问)", + "international": "国际版" + } + }, "ioIntelligenceApiKey": "IO Intelligence API 密钥", "ioIntelligenceApiKeyPlaceholder": "输入您的 IO Intelligence API 密钥", "getIoIntelligenceApiKey": "获取 IO Intelligence API 密钥", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 67e8c43b60a..bbcd06708ba 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -283,6 +283,17 @@ "getFireworksApiKey": "取得 Fireworks API 金鑰", "featherlessApiKey": "Featherless API 金鑰", "getFeatherlessApiKey": "取得 Featherless API 金鑰", + "siliconcloud": { + "apiKey": "SiliconCloud API 金鑰", + "getApiKey": "取得 SiliconCloud API 金鑰", + "entrypoint": "SiliconCloud 服務站點", + "entrypointDescription": "請根據您的所在區域選擇合適的服務站點。", + "apiLineConfigs": { + "china": "國內版", + "chinaOverseas": "國內版(海外存取)", + "international": "國際版" + } + }, "ioIntelligenceApiKey": "IO Intelligence API 金鑰", "ioIntelligenceApiKeyPlaceholder": "輸入您的 IO Intelligence API 金鑰", "getIoIntelligenceApiKey": "取得 IO Intelligence API 金鑰", diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index d15f82e4caf..c1b347dc871 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -9,6 +9,8 @@ import { isDynamicProvider, isFauxProvider, isCustomProvider, + siliconCloudModelsByApiLine, + siliconCloudDefaultApiLine, } from "@roo-code/types" import type { RouterModels } from "@roo/api" @@ -156,6 +158,17 @@ function validateModelsAndKeysProvided(apiConfiguration: ProviderSettings): stri return i18next.t("settings:validation.apiKey") } break + case "siliconcloud": { + if (!apiConfiguration.siliconCloudApiKey) { + return i18next.t("settings:validation.apiKey") + } + const apiLine = apiConfiguration.siliconCloudApiLine || siliconCloudDefaultApiLine + const models = siliconCloudModelsByApiLine[apiLine] + if (apiConfiguration.apiModelId && !models[apiConfiguration.apiModelId as keyof typeof models]) { + return i18next.t("settings:validation.modelAvailability", { modelId: apiConfiguration.apiModelId }) + } + break + } } return undefined