ソースを参照

Support new LLM provider: Doubao (#6345)

Co-authored-by: Daniel Riccio <[email protected]>
AntiMoron 5 ヶ月 前
コミット
4b45a4e7f2
29 ファイル変更244 行追加0 行削除
  1. 8 0
      packages/types/src/provider-settings.ts
  2. 44 0
      packages/types/src/providers/doubao.ts
  3. 1 0
      packages/types/src/providers/index.ts
  4. 3 0
      src/api/index.ts
  5. 81 0
      src/api/providers/doubao.ts
  6. 1 0
      src/api/providers/index.ts
  7. 7 0
      webview-ui/src/components/settings/ApiOptions.tsx
  8. 3 0
      webview-ui/src/components/settings/constants.ts
  9. 52 0
      webview-ui/src/components/settings/providers/Doubao.tsx
  10. 1 0
      webview-ui/src/components/settings/providers/index.ts
  11. 7 0
      webview-ui/src/components/ui/hooks/useSelectedModel.ts
  12. 2 0
      webview-ui/src/i18n/locales/ca/settings.json
  13. 2 0
      webview-ui/src/i18n/locales/de/settings.json
  14. 2 0
      webview-ui/src/i18n/locales/en/settings.json
  15. 2 0
      webview-ui/src/i18n/locales/es/settings.json
  16. 2 0
      webview-ui/src/i18n/locales/fr/settings.json
  17. 2 0
      webview-ui/src/i18n/locales/hi/settings.json
  18. 2 0
      webview-ui/src/i18n/locales/id/settings.json
  19. 2 0
      webview-ui/src/i18n/locales/it/settings.json
  20. 2 0
      webview-ui/src/i18n/locales/ja/settings.json
  21. 2 0
      webview-ui/src/i18n/locales/ko/settings.json
  22. 2 0
      webview-ui/src/i18n/locales/nl/settings.json
  23. 2 0
      webview-ui/src/i18n/locales/pl/settings.json
  24. 2 0
      webview-ui/src/i18n/locales/pt-BR/settings.json
  25. 2 0
      webview-ui/src/i18n/locales/ru/settings.json
  26. 2 0
      webview-ui/src/i18n/locales/tr/settings.json
  27. 2 0
      webview-ui/src/i18n/locales/vi/settings.json
  28. 2 0
      webview-ui/src/i18n/locales/zh-CN/settings.json
  29. 2 0
      webview-ui/src/i18n/locales/zh-TW/settings.json

+ 8 - 0
packages/types/src/provider-settings.ts

@@ -24,6 +24,7 @@ export const providerNames = [
 	"mistral",
 	"moonshot",
 	"deepseek",
+	"doubao",
 	"unbound",
 	"requesty",
 	"human-relay",
@@ -194,6 +195,11 @@ const deepSeekSchema = apiModelIdProviderModelSchema.extend({
 	deepSeekApiKey: z.string().optional(),
 })
 
+const doubaoSchema = apiModelIdProviderModelSchema.extend({
+	doubaoBaseUrl: z.string().optional(),
+	doubaoApiKey: z.string().optional(),
+})
+
 const moonshotSchema = apiModelIdProviderModelSchema.extend({
 	moonshotBaseUrl: z
 		.union([z.literal("https://api.moonshot.ai/v1"), z.literal("https://api.moonshot.cn/v1")])
@@ -266,6 +272,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
 	openAiNativeSchema.merge(z.object({ apiProvider: z.literal("openai-native") })),
 	mistralSchema.merge(z.object({ apiProvider: z.literal("mistral") })),
 	deepSeekSchema.merge(z.object({ apiProvider: z.literal("deepseek") })),
+	doubaoSchema.merge(z.object({ apiProvider: z.literal("doubao") })),
 	moonshotSchema.merge(z.object({ apiProvider: z.literal("moonshot") })),
 	unboundSchema.merge(z.object({ apiProvider: z.literal("unbound") })),
 	requestySchema.merge(z.object({ apiProvider: z.literal("requesty") })),
@@ -297,6 +304,7 @@ export const providerSettingsSchema = z.object({
 	...openAiNativeSchema.shape,
 	...mistralSchema.shape,
 	...deepSeekSchema.shape,
+	...doubaoSchema.shape,
 	...moonshotSchema.shape,
 	...unboundSchema.shape,
 	...requestySchema.shape,

+ 44 - 0
packages/types/src/providers/doubao.ts

@@ -0,0 +1,44 @@
+import type { ModelInfo } from "../model.js"
+
+export const doubaoDefaultModelId = "doubao-seed-1-6-250615"
+
+export const doubaoModels = {
+	"doubao-seed-1-6-250615": {
+		maxTokens: 32_768,
+		contextWindow: 128_000,
+		supportsImages: true,
+		supportsPromptCache: true,
+		inputPrice: 0.0001, // $0.0001 per million tokens (cache miss)
+		outputPrice: 0.0004, // $0.0004 per million tokens
+		cacheWritesPrice: 0.0001, // $0.0001 per million tokens (cache miss)
+		cacheReadsPrice: 0.00002, // $0.00002 per million tokens (cache hit)
+		description: `Doubao Seed 1.6 is a powerful model designed for high-performance tasks with extensive context handling.`,
+	},
+	"doubao-seed-1-6-thinking-250715": {
+		maxTokens: 32_768,
+		contextWindow: 128_000,
+		supportsImages: true,
+		supportsPromptCache: true,
+		inputPrice: 0.0002, // $0.0002 per million tokens
+		outputPrice: 0.0008, // $0.0008 per million tokens
+		cacheWritesPrice: 0.0002, // $0.0002 per million
+		cacheReadsPrice: 0.00004, // $0.00004 per million tokens (cache hit)
+		description: `Doubao Seed 1.6 Thinking is optimized for reasoning tasks, providing enhanced performance in complex problem-solving scenarios.`,
+	},
+	"doubao-seed-1-6-flash-250715": {
+		maxTokens: 32_768,
+		contextWindow: 128_000,
+		supportsImages: true,
+		supportsPromptCache: true,
+		inputPrice: 0.00015, // $0.00015 per million tokens
+		outputPrice: 0.0006, // $0.0006 per million tokens
+		cacheWritesPrice: 0.00015, // $0.00015 per million
+		cacheReadsPrice: 0.00003, // $0.00003 per million tokens (cache hit)
+		description: `Doubao Seed 1.6 Flash is tailored for speed and efficiency, making it ideal for applications requiring rapid responses.`,
+	},
+} as const satisfies Record<string, ModelInfo>
+
+export const doubaoDefaultModelInfo: ModelInfo = doubaoModels[doubaoDefaultModelId]
+
+export const DOUBAO_API_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3"
+export const DOUBAO_API_CHAT_PATH = "/chat/completions"

+ 1 - 0
packages/types/src/providers/index.ts

@@ -20,3 +20,4 @@ export * from "./unbound.js"
 export * from "./vertex.js"
 export * from "./vscode-llm.js"
 export * from "./xai.js"
+export * from "./doubao.js"

+ 3 - 0
src/api/index.ts

@@ -31,6 +31,7 @@ import {
 	LiteLLMHandler,
 	ClaudeCodeHandler,
 	SambaNovaHandler,
+	DoubaoHandler,
 } from "./providers"
 
 export interface SingleCompletionHandler {
@@ -92,6 +93,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
 			return new OpenAiNativeHandler(options)
 		case "deepseek":
 			return new DeepSeekHandler(options)
+		case "doubao":
+			return new DoubaoHandler(options)
 		case "moonshot":
 			return new MoonshotHandler(options)
 		case "vscode-lm":

+ 81 - 0
src/api/providers/doubao.ts

@@ -0,0 +1,81 @@
+import { OpenAiHandler } from "./openai"
+import type { ApiHandlerOptions } from "../../shared/api"
+import { DOUBAO_API_BASE_URL, doubaoDefaultModelId, doubaoModels } from "@roo-code/types"
+import { getModelParams } from "../transform/model-params"
+import { ApiStreamUsageChunk } from "../transform/stream"
+
+// Core types for Doubao API
+interface ChatCompletionMessageParam {
+	role: "system" | "user" | "assistant" | "developer"
+	content:
+		| string
+		| Array<{
+				type: "text" | "image_url"
+				text?: string
+				image_url?: { url: string }
+		  }>
+}
+
+interface ChatCompletionParams {
+	model: string
+	messages: ChatCompletionMessageParam[]
+	temperature?: number
+	stream?: boolean
+	stream_options?: { include_usage: boolean }
+	max_completion_tokens?: number
+}
+
+interface ChatCompletion {
+	choices: Array<{
+		message: {
+			content: string
+		}
+	}>
+	usage?: {
+		prompt_tokens: number
+		completion_tokens: number
+	}
+}
+
+interface ChatCompletionChunk {
+	choices: Array<{
+		delta: {
+			content?: string
+		}
+	}>
+	usage?: {
+		prompt_tokens: number
+		completion_tokens: number
+	}
+}
+
+export class DoubaoHandler extends OpenAiHandler {
+	constructor(options: ApiHandlerOptions) {
+		super({
+			...options,
+			openAiApiKey: options.doubaoApiKey ?? "not-provided",
+			openAiModelId: options.apiModelId ?? doubaoDefaultModelId,
+			openAiBaseUrl: options.doubaoBaseUrl ?? DOUBAO_API_BASE_URL,
+			openAiStreamingEnabled: true,
+			includeMaxTokens: true,
+		})
+	}
+
+	override getModel() {
+		const id = this.options.apiModelId ?? doubaoDefaultModelId
+		const info = doubaoModels[id as keyof typeof doubaoModels] || doubaoModels[doubaoDefaultModelId]
+		const params = getModelParams({ format: "openai", modelId: id, model: info, settings: this.options })
+		return { id, info, ...params }
+	}
+
+	// Override to handle Doubao's usage metrics, including caching.
+	protected override processUsageMetrics(usage: any): ApiStreamUsageChunk {
+		return {
+			type: "usage",
+			inputTokens: usage?.prompt_tokens || 0,
+			outputTokens: usage?.completion_tokens || 0,
+			cacheWriteTokens: usage?.prompt_tokens_details?.cache_miss_tokens,
+			cacheReadTokens: usage?.prompt_tokens_details?.cached_tokens,
+		}
+	}
+}

+ 1 - 0
src/api/providers/index.ts

@@ -4,6 +4,7 @@ export { AwsBedrockHandler } from "./bedrock"
 export { ChutesHandler } from "./chutes"
 export { ClaudeCodeHandler } from "./claude-code"
 export { DeepSeekHandler } from "./deepseek"
+export { DoubaoHandler } from "./doubao"
 export { MoonshotHandler } from "./moonshot"
 export { FakeAIHandler } from "./fake-ai"
 export { GeminiHandler } from "./gemini"

+ 7 - 0
webview-ui/src/components/settings/ApiOptions.tsx

@@ -15,6 +15,7 @@ import {
 	litellmDefaultModelId,
 	openAiNativeDefaultModelId,
 	anthropicDefaultModelId,
+	doubaoDefaultModelId,
 	claudeCodeDefaultModelId,
 	geminiDefaultModelId,
 	deepSeekDefaultModelId,
@@ -57,6 +58,7 @@ import {
 	Chutes,
 	ClaudeCode,
 	DeepSeek,
+	Doubao,
 	Gemini,
 	Glama,
 	Groq,
@@ -292,6 +294,7 @@ const ApiOptions = ({
 				"openai-native": { field: "apiModelId", default: openAiNativeDefaultModelId },
 				gemini: { field: "apiModelId", default: geminiDefaultModelId },
 				deepseek: { field: "apiModelId", default: deepSeekDefaultModelId },
+				doubao: { field: "apiModelId", default: doubaoDefaultModelId },
 				moonshot: { field: "apiModelId", default: moonshotDefaultModelId },
 				mistral: { field: "apiModelId", default: mistralDefaultModelId },
 				xai: { field: "apiModelId", default: xaiDefaultModelId },
@@ -475,6 +478,10 @@ const ApiOptions = ({
 				<DeepSeek apiConfiguration={apiConfiguration} setApiConfigurationField={setApiConfigurationField} />
 			)}
 
+			{selectedProvider === "doubao" && (
+				<Doubao apiConfiguration={apiConfiguration} setApiConfigurationField={setApiConfigurationField} />
+			)}
+
 			{selectedProvider === "moonshot" && (
 				<Moonshot apiConfiguration={apiConfiguration} setApiConfigurationField={setApiConfigurationField} />
 			)}

+ 3 - 0
webview-ui/src/components/settings/constants.ts

@@ -14,6 +14,7 @@ import {
 	groqModels,
 	chutesModels,
 	sambaNovaModels,
+	doubaoModels,
 } from "@roo-code/types"
 
 export const MODELS_BY_PROVIDER: Partial<Record<ProviderName, Record<string, ModelInfo>>> = {
@@ -21,6 +22,7 @@ export const MODELS_BY_PROVIDER: Partial<Record<ProviderName, Record<string, Mod
 	"claude-code": claudeCodeModels,
 	bedrock: bedrockModels,
 	deepseek: deepSeekModels,
+	doubao: doubaoModels,
 	moonshot: moonshotModels,
 	gemini: geminiModels,
 	mistral: mistralModels,
@@ -37,6 +39,7 @@ export const PROVIDERS = [
 	{ value: "anthropic", label: "Anthropic" },
 	{ value: "claude-code", label: "Claude Code" },
 	{ value: "gemini", label: "Google Gemini" },
+	{ value: "doubao", label: "Doubao" },
 	{ value: "deepseek", label: "DeepSeek" },
 	{ value: "moonshot", label: "Moonshot" },
 	{ value: "openai-native", label: "OpenAI" },

+ 52 - 0
webview-ui/src/components/settings/providers/Doubao.tsx

@@ -0,0 +1,52 @@
+import { useCallback } from "react"
+import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
+
+import type { ProviderSettings } from "@roo-code/types"
+
+import { useAppTranslation } from "@src/i18n/TranslationContext"
+import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"
+
+import { inputEventTransform } from "../transforms"
+
+type DoubaoProps = {
+	apiConfiguration: ProviderSettings
+	setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void
+}
+
+export const Doubao = ({ apiConfiguration, setApiConfigurationField }: DoubaoProps) => {
+	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 (
+		<>
+			<VSCodeTextField
+				value={apiConfiguration?.doubaoApiKey || ""}
+				type="password"
+				onInput={handleInputChange("doubaoApiKey")}
+				placeholder={t("settings:placeholders.apiKey")}
+				className="w-full">
+				<label className="block font-medium mb-1">{t("settings:providers.doubaoApiKey")}</label>
+			</VSCodeTextField>
+			<div className="text-sm text-vscode-descriptionForeground -mt-2">
+				{t("settings:providers.apiKeyStorageNotice")}
+			</div>
+			{!apiConfiguration?.doubaoApiKey && (
+				<VSCodeButtonLink
+					href="https://www.volcengine.com/experience/ark?model=doubao-1-5-thinking-vision-pro-250428"
+					appearance="secondary">
+					{t("settings:providers.getDoubaoApiKey")}
+				</VSCodeButtonLink>
+			)}
+		</>
+	)
+}

+ 1 - 0
webview-ui/src/components/settings/providers/index.ts

@@ -3,6 +3,7 @@ export { Bedrock } from "./Bedrock"
 export { Chutes } from "./Chutes"
 export { ClaudeCode } from "./ClaudeCode"
 export { DeepSeek } from "./DeepSeek"
+export { Doubao } from "./Doubao"
 export { Gemini } from "./Gemini"
 export { Glama } from "./Glama"
 export { Groq } from "./Groq"

+ 7 - 0
webview-ui/src/components/ui/hooks/useSelectedModel.ts

@@ -36,6 +36,8 @@ import {
 	claudeCodeModels,
 	sambaNovaModels,
 	sambaNovaDefaultModelId,
+	doubaoModels,
+	doubaoDefaultModelId,
 } from "@roo-code/types"
 
 import type { RouterModels } from "@roo/api"
@@ -176,6 +178,11 @@ function getSelectedModel({
 			const info = deepSeekModels[id as keyof typeof deepSeekModels]
 			return { id, info }
 		}
+		case "doubao": {
+			const id = apiConfiguration.apiModelId ?? doubaoDefaultModelId
+			const info = doubaoModels[id as keyof typeof doubaoModels]
+			return { id, info }
+		}
 		case "moonshot": {
 			const id = apiConfiguration.apiModelId ?? moonshotDefaultModelId
 			const info = moonshotModels[id as keyof typeof moonshotModels]

+ 2 - 0
webview-ui/src/i18n/locales/ca/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Obtenir clau API de Chutes",
 		"deepSeekApiKey": "Clau API de DeepSeek",
 		"getDeepSeekApiKey": "Obtenir clau API de DeepSeek",
+		"doubaoApiKey": "Clau API de Doubao",
+		"getDoubaoApiKey": "Obtenir clau API de Doubao",
 		"moonshotApiKey": "Clau API de Moonshot",
 		"getMoonshotApiKey": "Obtenir clau API de Moonshot",
 		"moonshotBaseUrl": "Punt d'entrada de Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/de/settings.json

@@ -225,6 +225,8 @@
 		"awsCustomArnDesc": "Stellen Sie sicher, dass die Region in der ARN mit Ihrer oben ausgewählten AWS-Region übereinstimmt.",
 		"openRouterApiKey": "OpenRouter API-Schlüssel",
 		"getOpenRouterApiKey": "OpenRouter API-Schlüssel erhalten",
+		"doubaoApiKey": "Doubao API-Schlüssel",
+		"getDoubaoApiKey": "Doubao API-Schlüssel erhalten",
 		"apiKeyStorageNotice": "API-Schlüssel werden sicher im VSCode Secret Storage gespeichert",
 		"glamaApiKey": "Glama API-Schlüssel",
 		"getGlamaApiKey": "Glama API-Schlüssel erhalten",

+ 2 - 0
webview-ui/src/i18n/locales/en/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Get Chutes API Key",
 		"deepSeekApiKey": "DeepSeek API Key",
 		"getDeepSeekApiKey": "Get DeepSeek API Key",
+		"doubaoApiKey": "Doubao API Key",
+		"getDoubaoApiKey": "Get Doubao API Key",
 		"moonshotApiKey": "Moonshot API Key",
 		"getMoonshotApiKey": "Get Moonshot API Key",
 		"moonshotBaseUrl": "Moonshot Entrypoint",

+ 2 - 0
webview-ui/src/i18n/locales/es/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Obtener clave API de Chutes",
 		"deepSeekApiKey": "Clave API de DeepSeek",
 		"getDeepSeekApiKey": "Obtener clave API de DeepSeek",
+		"doubaoApiKey": "Clave API de Doubao",
+		"getDoubaoApiKey": "Obtener clave API de Doubao",
 		"moonshotApiKey": "Clave API de Moonshot",
 		"getMoonshotApiKey": "Obtener clave API de Moonshot",
 		"moonshotBaseUrl": "Punto de entrada de Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/fr/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Obtenir la clé API Chutes",
 		"deepSeekApiKey": "Clé API DeepSeek",
 		"getDeepSeekApiKey": "Obtenir la clé API DeepSeek",
+		"doubaoApiKey": "Clé API Doubao",
+		"getDoubaoApiKey": "Obtenir la clé API Doubao",
 		"moonshotApiKey": "Clé API Moonshot",
 		"getMoonshotApiKey": "Obtenir la clé API Moonshot",
 		"moonshotBaseUrl": "Point d'entrée Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/hi/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Chutes API कुंजी प्राप्त करें",
 		"deepSeekApiKey": "DeepSeek API कुंजी",
 		"getDeepSeekApiKey": "DeepSeek API कुंजी प्राप्त करें",
+		"doubaoApiKey": "डौबाओ API कुंजी",
+		"getDoubaoApiKey": "डौबाओ API कुंजी प्राप्त करें",
 		"moonshotApiKey": "Moonshot API कुंजी",
 		"getMoonshotApiKey": "Moonshot API कुंजी प्राप्त करें",
 		"moonshotBaseUrl": "Moonshot प्रवेश बिंदु",

+ 2 - 0
webview-ui/src/i18n/locales/id/settings.json

@@ -257,6 +257,8 @@
 		"getChutesApiKey": "Dapatkan Chutes API Key",
 		"deepSeekApiKey": "DeepSeek API Key",
 		"getDeepSeekApiKey": "Dapatkan DeepSeek API Key",
+		"doubaoApiKey": "Kunci API Doubao",
+		"getDoubaoApiKey": "Dapatkan Kunci API Doubao",
 		"moonshotApiKey": "Kunci API Moonshot",
 		"getMoonshotApiKey": "Dapatkan Kunci API Moonshot",
 		"moonshotBaseUrl": "Titik Masuk Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/it/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Ottieni chiave API Chutes",
 		"deepSeekApiKey": "Chiave API DeepSeek",
 		"getDeepSeekApiKey": "Ottieni chiave API DeepSeek",
+		"doubaoApiKey": "Chiave API Doubao",
+		"getDoubaoApiKey": "Ottieni chiave API Doubao",
 		"moonshotApiKey": "Chiave API Moonshot",
 		"getMoonshotApiKey": "Ottieni chiave API Moonshot",
 		"moonshotBaseUrl": "Punto di ingresso Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/ja/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Chutes APIキーを取得",
 		"deepSeekApiKey": "DeepSeek APIキー",
 		"getDeepSeekApiKey": "DeepSeek APIキーを取得",
+		"doubaoApiKey": "Doubao APIキー",
+		"getDoubaoApiKey": "Doubao APIキーを取得",
 		"moonshotApiKey": "Moonshot APIキー",
 		"getMoonshotApiKey": "Moonshot APIキーを取得",
 		"moonshotBaseUrl": "Moonshot エントリーポイント",

+ 2 - 0
webview-ui/src/i18n/locales/ko/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Chutes API 키 받기",
 		"deepSeekApiKey": "DeepSeek API 키",
 		"getDeepSeekApiKey": "DeepSeek API 키 받기",
+		"doubaoApiKey": "Doubao API 키",
+		"getDoubaoApiKey": "Doubao API 키 받기",
 		"moonshotApiKey": "Moonshot API 키",
 		"getMoonshotApiKey": "Moonshot API 키 받기",
 		"moonshotBaseUrl": "Moonshot 엔트리포인트",

+ 2 - 0
webview-ui/src/i18n/locales/nl/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Chutes API-sleutel ophalen",
 		"deepSeekApiKey": "DeepSeek API-sleutel",
 		"getDeepSeekApiKey": "DeepSeek API-sleutel ophalen",
+		"doubaoApiKey": "Doubao API-sleutel",
+		"getDoubaoApiKey": "Doubao API-sleutel ophalen",
 		"moonshotApiKey": "Moonshot API-sleutel",
 		"getMoonshotApiKey": "Moonshot API-sleutel ophalen",
 		"moonshotBaseUrl": "Moonshot-ingangspunt",

+ 2 - 0
webview-ui/src/i18n/locales/pl/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Uzyskaj klucz API Chutes",
 		"deepSeekApiKey": "Klucz API DeepSeek",
 		"getDeepSeekApiKey": "Uzyskaj klucz API DeepSeek",
+		"doubaoApiKey": "Klucz API Doubao",
+		"getDoubaoApiKey": "Uzyskaj klucz API Doubao",
 		"moonshotApiKey": "Klucz API Moonshot",
 		"getMoonshotApiKey": "Uzyskaj klucz API Moonshot",
 		"moonshotBaseUrl": "Punkt wejścia Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/pt-BR/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Obter chave de API Chutes",
 		"deepSeekApiKey": "Chave de API DeepSeek",
 		"getDeepSeekApiKey": "Obter chave de API DeepSeek",
+		"doubaoApiKey": "Chave de API Doubao",
+		"getDoubaoApiKey": "Obter chave de API Doubao",
 		"moonshotApiKey": "Chave de API Moonshot",
 		"getMoonshotApiKey": "Obter chave de API Moonshot",
 		"moonshotBaseUrl": "Ponto de entrada Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/ru/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Получить Chutes API-ключ",
 		"deepSeekApiKey": "DeepSeek API-ключ",
 		"getDeepSeekApiKey": "Получить DeepSeek API-ключ",
+		"doubaoApiKey": "Doubao API-ключ",
+		"getDoubaoApiKey": "Получить Doubao API-ключ",
 		"moonshotApiKey": "Moonshot API-ключ",
 		"getMoonshotApiKey": "Получить Moonshot API-ключ",
 		"moonshotBaseUrl": "Точка входа Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/tr/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Chutes API Anahtarı Al",
 		"deepSeekApiKey": "DeepSeek API Anahtarı",
 		"getDeepSeekApiKey": "DeepSeek API Anahtarı Al",
+		"doubaoApiKey": "Doubao API Anahtarı",
+		"getDoubaoApiKey": "Doubao API Anahtarı Al",
 		"moonshotApiKey": "Moonshot API Anahtarı",
 		"getMoonshotApiKey": "Moonshot API Anahtarı Al",
 		"moonshotBaseUrl": "Moonshot Giriş Noktası",

+ 2 - 0
webview-ui/src/i18n/locales/vi/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "Lấy khóa API Chutes",
 		"deepSeekApiKey": "Khóa API DeepSeek",
 		"getDeepSeekApiKey": "Lấy khóa API DeepSeek",
+		"doubaoApiKey": "Khóa API Doubao",
+		"getDoubaoApiKey": "Lấy khóa API Doubao",
 		"moonshotApiKey": "Khóa API Moonshot",
 		"getMoonshotApiKey": "Lấy khóa API Moonshot",
 		"moonshotBaseUrl": "Điểm vào Moonshot",

+ 2 - 0
webview-ui/src/i18n/locales/zh-CN/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "获取 Chutes API 密钥",
 		"deepSeekApiKey": "DeepSeek API 密钥",
 		"getDeepSeekApiKey": "获取 DeepSeek API 密钥",
+		"doubaoApiKey": "豆包 API 密钥",
+		"getDoubaoApiKey": "获取豆包 API 密钥",
 		"moonshotApiKey": "Moonshot API 密钥",
 		"getMoonshotApiKey": "获取 Moonshot API 密钥",
 		"moonshotBaseUrl": "Moonshot 服务站点",

+ 2 - 0
webview-ui/src/i18n/locales/zh-TW/settings.json

@@ -253,6 +253,8 @@
 		"getChutesApiKey": "取得 Chutes API 金鑰",
 		"deepSeekApiKey": "DeepSeek API 金鑰",
 		"getDeepSeekApiKey": "取得 DeepSeek API 金鑰",
+		"doubaoApiKey": "豆包 API 金鑰",
+		"getDoubaoApiKey": "取得豆包 API 金鑰",
 		"moonshotApiKey": "Moonshot API 金鑰",
 		"getMoonshotApiKey": "取得 Moonshot API 金鑰",
 		"moonshotBaseUrl": "Moonshot 服務站點",