diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 884337767fe..ab7cd499750 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -32,6 +32,7 @@ export const providerNames = [ "groq", "chutes", "litellm", + "sambanova", ] as const export const providerNamesSchema = z.enum(providerNames) @@ -229,6 +230,10 @@ const litellmSchema = baseProviderSettingsSchema.extend({ litellmModelId: z.string().optional(), }) +const sambaNovaSchema = apiModelIdProviderModelSchema.extend({ + sambaNovaApiKey: z.string().optional(), +}) + const defaultSchema = z.object({ apiProvider: z.undefined(), }) @@ -258,6 +263,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv groqSchema.merge(z.object({ apiProvider: z.literal("groq") })), chutesSchema.merge(z.object({ apiProvider: z.literal("chutes") })), litellmSchema.merge(z.object({ apiProvider: z.literal("litellm") })), + sambaNovaSchema.merge(z.object({ apiProvider: z.literal("sambanova") })), defaultSchema, ]) @@ -287,6 +293,7 @@ export const providerSettingsSchema = z.object({ ...groqSchema.shape, ...chutesSchema.shape, ...litellmSchema.shape, + ...sambaNovaSchema.shape, ...codebaseIndexProviderSchema.shape, }) diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index e4e506b8a7b..d560e6c1f9f 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -14,6 +14,7 @@ export * from "./ollama.js" export * from "./openai.js" export * from "./openrouter.js" export * from "./requesty.js" +export * from "./sambanova.js" export * from "./unbound.js" export * from "./vertex.js" export * from "./vscode-llm.js" diff --git a/packages/types/src/providers/sambanova.ts b/packages/types/src/providers/sambanova.ts new file mode 100644 index 00000000000..dc23618f4e1 --- /dev/null +++ b/packages/types/src/providers/sambanova.ts @@ -0,0 +1,141 @@ +import type { ModelInfo } from "../model.js" + +// https://docs.sambanova.ai/cloud/docs/get-started/supported-models +export type SambaNovaModelId = + | "Meta-Llama-3.1-8B-Instruct" + | "Meta-Llama-3.1-70B-Instruct" + | "Meta-Llama-3.1-405B-Instruct" + | "Meta-Llama-3.2-1B-Instruct" + | "Meta-Llama-3.2-3B-Instruct" + | "Meta-Llama-3.3-70B-Instruct" + | "Llama-3.2-11B-Vision-Instruct" + | "Llama-3.2-90B-Vision-Instruct" + | "QwQ-32B-Preview" + | "Qwen2.5-72B-Instruct" + | "Qwen2.5-Coder-32B-Instruct" + | "deepseek-r1" + | "deepseek-r1-distill-llama-70b" + +export const sambaNovaDefaultModelId: SambaNovaModelId = "Meta-Llama-3.3-70B-Instruct" + +export const sambaNovaModels = { + "Meta-Llama-3.1-8B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.2, + description: "Meta Llama 3.1 8B Instruct model with 128K context window.", + }, + "Meta-Llama-3.1-70B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.64, + outputPrice: 0.8, + description: "Meta Llama 3.1 70B Instruct model with 128K context window.", + }, + "Meta-Llama-3.1-405B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 3.0, + outputPrice: 15.0, + description: "Meta Llama 3.1 405B Instruct model with 128K context window.", + }, + "Meta-Llama-3.2-1B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.04, + outputPrice: 0.04, + description: "Meta Llama 3.2 1B Instruct model with 128K context window.", + }, + "Meta-Llama-3.2-3B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.06, + outputPrice: 0.06, + description: "Meta Llama 3.2 3B Instruct model with 128K context window.", + }, + "Meta-Llama-3.3-70B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.64, + outputPrice: 0.8, + description: "Meta Llama 3.3 70B Instruct model with 128K context window.", + }, + "Llama-3.2-11B-Vision-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0.18, + outputPrice: 0.2, + description: "Meta Llama 3.2 11B Vision Instruct model with image support.", + }, + "Llama-3.2-90B-Vision-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0.9, + outputPrice: 1.1, + description: "Meta Llama 3.2 90B Vision Instruct model with image support.", + }, + "QwQ-32B-Preview": { + maxTokens: 32768, + contextWindow: 32768, + supportsImages: false, + supportsPromptCache: false, + supportsReasoningBudget: true, + inputPrice: 0.15, + outputPrice: 0.15, + description: "Alibaba QwQ 32B Preview reasoning model.", + }, + "Qwen2.5-72B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.59, + outputPrice: 0.79, + description: "Alibaba Qwen 2.5 72B Instruct model with 128K context window.", + }, + "Qwen2.5-Coder-32B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.29, + outputPrice: 0.39, + description: "Alibaba Qwen 2.5 Coder 32B Instruct model optimized for coding tasks.", + }, + "deepseek-r1": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + supportsReasoningBudget: true, + inputPrice: 0.55, + outputPrice: 2.19, + description: "DeepSeek R1 reasoning model with 128K context window.", + }, + "deepseek-r1-distill-llama-70b": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.27, + outputPrice: 1.08, + description: "DeepSeek R1 distilled Llama 70B model with 128K context window.", + }, +} as const satisfies Record diff --git a/src/api/index.ts b/src/api/index.ts index 4598a711b2a..f4558e1d39b 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -29,6 +29,7 @@ import { ChutesHandler, LiteLLMHandler, ClaudeCodeHandler, + SambaNovaHandler, } from "./providers" export interface SingleCompletionHandler { @@ -112,6 +113,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler { return new ChutesHandler(options) case "litellm": return new LiteLLMHandler(options) + case "sambanova": + return new SambaNovaHandler(options) default: apiProvider satisfies "gemini-cli" | undefined return new AnthropicHandler(options) diff --git a/src/api/providers/__tests__/sambanova.spec.ts b/src/api/providers/__tests__/sambanova.spec.ts new file mode 100644 index 00000000000..a1ecbe6e13c --- /dev/null +++ b/src/api/providers/__tests__/sambanova.spec.ts @@ -0,0 +1,163 @@ +import { describe, it, expect, vi, beforeEach } from "vitest" +import OpenAI from "openai" +import { Anthropic } from "@anthropic-ai/sdk" + +import { type SambaNovaModelId, sambaNovaModels } from "@roo-code/types" + +import { SambaNovaHandler } from "../sambanova" + +// Mock OpenAI +vi.mock("openai", () => { + const mockCreate = vi.fn() + return { + default: vi.fn(() => ({ + chat: { + completions: { + create: mockCreate, + }, + }, + })), + } +}) + +describe("SambaNovaHandler", () => { + let handler: SambaNovaHandler + let mockCreate: any + + beforeEach(() => { + vi.clearAllMocks() + mockCreate = (OpenAI as unknown as any)().chat.completions.create + handler = new SambaNovaHandler({ sambaNovaApiKey: "test-sambanova-api-key" }) + }) + + it("should use the correct SambaNova base URL", () => { + new SambaNovaHandler({ sambaNovaApiKey: "test-sambanova-api-key" }) + expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ baseURL: "https://api.sambanova.ai/v1" })) + }) + + it("should use the provided API key", () => { + const sambaNovaApiKey = "test-sambanova-api-key" + new SambaNovaHandler({ sambaNovaApiKey }) + expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ apiKey: sambaNovaApiKey })) + }) + + it("should throw an error if API key is not provided", () => { + expect(() => new SambaNovaHandler({} as any)).toThrow("API key is required") + }) + + it("should use the specified model when provided", () => { + const testModelId: SambaNovaModelId = "Meta-Llama-3.3-70B-Instruct" + const handlerWithModel = new SambaNovaHandler({ + apiModelId: testModelId, + sambaNovaApiKey: "test-sambanova-api-key", + }) + const model = handlerWithModel.getModel() + expect(model.id).toBe(testModelId) + expect(model.info).toEqual(sambaNovaModels[testModelId]) + }) + + it("should use the default model when no model is specified", () => { + const model = handler.getModel() + expect(model.id).toBe("Meta-Llama-3.3-70B-Instruct") + expect(model.info).toEqual(sambaNovaModels["Meta-Llama-3.3-70B-Instruct"]) + }) + + describe("createMessage", () => { + it("should create a streaming chat completion with correct parameters", async () => { + const systemPrompt = "You are a helpful assistant" + const messages: Anthropic.Messages.MessageParam[] = [ + { + role: "user", + content: "Hello", + }, + ] + + mockCreate.mockImplementation(() => { + const chunks = [ + { + choices: [{ delta: { content: "Hi there!" } }], + }, + { + choices: [{ delta: {} }], + usage: { prompt_tokens: 10, completion_tokens: 5 }, + }, + ] + + return { + [Symbol.asyncIterator]: async function* () { + for (const chunk of chunks) { + yield chunk + } + }, + } + }) + + const stream = handler.createMessage(systemPrompt, messages) + const results = [] + for await (const chunk of stream) { + results.push(chunk) + } + + expect(mockCreate).toHaveBeenCalledWith( + expect.objectContaining({ + model: "Meta-Llama-3.3-70B-Instruct", + max_tokens: 8192, + temperature: 0.7, + messages: [ + { role: "system", content: systemPrompt }, + { role: "user", content: "Hello" }, + ], + stream: true, + stream_options: { include_usage: true }, + }), + ) + + expect(results).toEqual([ + { type: "text", text: "Hi there!" }, + { type: "usage", inputTokens: 10, outputTokens: 5 }, + ]) + }) + }) + + describe("completePrompt", () => { + it("should complete a prompt successfully", async () => { + const prompt = "Test prompt" + const expectedResponse = "Test response" + + mockCreate.mockResolvedValue({ + choices: [{ message: { content: expectedResponse } }], + }) + + const result = await handler.completePrompt(prompt) + + expect(mockCreate).toHaveBeenCalledWith({ + model: "Meta-Llama-3.3-70B-Instruct", + messages: [{ role: "user", content: prompt }], + }) + expect(result).toBe(expectedResponse) + }) + + it("should handle errors properly", async () => { + const prompt = "Test prompt" + const errorMessage = "API Error" + + mockCreate.mockRejectedValue(new Error(errorMessage)) + + await expect(handler.completePrompt(prompt)).rejects.toThrow(`SambaNova completion error: ${errorMessage}`) + }) + }) + + describe("model selection", () => { + it.each(Object.keys(sambaNovaModels) as SambaNovaModelId[])("should correctly handle model %s", (modelId) => { + const modelInfo = sambaNovaModels[modelId] + const handlerWithModel = new SambaNovaHandler({ + apiModelId: modelId, + sambaNovaApiKey: "test-sambanova-api-key", + }) + + const model = handlerWithModel.getModel() + expect(model.id).toBe(modelId) + expect(model.info).toEqual(modelInfo) + }) + }) +}) diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index 89d4c203adf..7e514236269 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -18,6 +18,7 @@ export { OpenAiNativeHandler } from "./openai-native" export { OpenAiHandler } from "./openai" export { OpenRouterHandler } from "./openrouter" export { RequestyHandler } from "./requesty" +export { SambaNovaHandler } from "./sambanova" export { UnboundHandler } from "./unbound" export { VertexHandler } from "./vertex" export { VsCodeLmHandler } from "./vscode-lm" diff --git a/src/api/providers/sambanova.ts b/src/api/providers/sambanova.ts new file mode 100644 index 00000000000..a15bc125776 --- /dev/null +++ b/src/api/providers/sambanova.ts @@ -0,0 +1,19 @@ +import { type SambaNovaModelId, sambaNovaDefaultModelId, sambaNovaModels } from "@roo-code/types" + +import type { ApiHandlerOptions } from "../../shared/api" + +import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider" + +export class SambaNovaHandler extends BaseOpenAiCompatibleProvider { + constructor(options: ApiHandlerOptions) { + super({ + ...options, + providerName: "SambaNova", + baseURL: "https://api.sambanova.ai/v1", + apiKey: options.sambaNovaApiKey, + defaultProviderModelId: sambaNovaDefaultModelId, + providerModels: sambaNovaModels, + defaultTemperature: 0.7, + }) + } +} diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 6c6c621956c..dfd3fab714d 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -25,6 +25,7 @@ import { chutesDefaultModelId, bedrockDefaultModelId, vertexDefaultModelId, + sambaNovaDefaultModelId, } from "@roo-code/types" import { vscode } from "@src/utils/vscode" @@ -68,6 +69,7 @@ import { OpenAICompatible, OpenRouter, Requesty, + SambaNova, Unbound, Vertex, VSCodeLM, @@ -296,6 +298,7 @@ const ApiOptions = ({ chutes: { field: "apiModelId", default: chutesDefaultModelId }, bedrock: { field: "apiModelId", default: bedrockDefaultModelId }, vertex: { field: "apiModelId", default: vertexDefaultModelId }, + sambanova: { field: "apiModelId", default: sambaNovaDefaultModelId }, openai: { field: "openAiModelId" }, ollama: { field: "ollamaModelId" }, lmstudio: { field: "lmStudioModelId" }, @@ -500,6 +503,10 @@ const ApiOptions = ({ /> )} + {selectedProvider === "sambanova" && ( + + )} + {selectedProvider === "human-relay" && ( <>
diff --git a/webview-ui/src/components/settings/constants.ts b/webview-ui/src/components/settings/constants.ts index 1140e4c0bcf..b68390339c9 100644 --- a/webview-ui/src/components/settings/constants.ts +++ b/webview-ui/src/components/settings/constants.ts @@ -13,6 +13,7 @@ import { xaiModels, groqModels, chutesModels, + sambaNovaModels, } from "@roo-code/types" export const MODELS_BY_PROVIDER: Partial>> = { @@ -28,6 +29,7 @@ export const MODELS_BY_PROVIDER: Partial a.label.localeCompare(b.label)) diff --git a/webview-ui/src/components/settings/providers/SambaNova.tsx b/webview-ui/src/components/settings/providers/SambaNova.tsx new file mode 100644 index 00000000000..4f4158bc9b5 --- /dev/null +++ b/webview-ui/src/components/settings/providers/SambaNova.tsx @@ -0,0 +1,50 @@ +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 SambaNovaProps = { + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void +} + +export const SambaNova = ({ apiConfiguration, setApiConfigurationField }: SambaNovaProps) => { + 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 ( + <> + + + +
+ {t("settings:providers.apiKeyStorageNotice")} +
+ {!apiConfiguration?.sambaNovaApiKey && ( + + {t("settings:providers.getSambaNovaApiKey")} + + )} + + ) +} diff --git a/webview-ui/src/components/settings/providers/index.ts b/webview-ui/src/components/settings/providers/index.ts index 54974f7200b..e2e460c657b 100644 --- a/webview-ui/src/components/settings/providers/index.ts +++ b/webview-ui/src/components/settings/providers/index.ts @@ -14,6 +14,7 @@ export { OpenAI } from "./OpenAI" export { OpenAICompatible } from "./OpenAICompatible" export { OpenRouter } from "./OpenRouter" export { Requesty } from "./Requesty" +export { SambaNova } from "./SambaNova" export { Unbound } from "./Unbound" export { Vertex } from "./Vertex" export { VSCodeLM } from "./VSCodeLM" diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 928ebb42f46..5c181fe4f49 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -34,6 +34,8 @@ import { litellmDefaultModelId, claudeCodeDefaultModelId, claudeCodeModels, + sambaNovaModels, + sambaNovaDefaultModelId, } from "@roo-code/types" import type { RouterModels } from "@roo/api" @@ -214,6 +216,11 @@ function getSelectedModel({ const info = claudeCodeModels[id as keyof typeof claudeCodeModels] return { id, info: { ...openAiModelInfoSaneDefaults, ...info } } } + case "sambanova": { + const id = apiConfiguration.apiModelId ?? sambaNovaDefaultModelId + const info = sambaNovaModels[id as keyof typeof sambaNovaModels] + return { id, info } + } // case "anthropic": // case "human-relay": // case "fake-ai": diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index cf17a6f919d..a9a72f132f5 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Clau API de Gemini", "getGroqApiKey": "Obtenir clau API de Groq", "groqApiKey": "Clau API de Groq", + "getSambaNovaApiKey": "Obtenir clau API de SambaNova", + "sambaNovaApiKey": "Clau API de SambaNova", "getGeminiApiKey": "Obtenir clau API de Gemini", "openAiApiKey": "Clau API d'OpenAI", "apiKey": "Clau API", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 20ffaec5252..1226255a6bf 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API-Schlüssel", "getGroqApiKey": "Groq API-Schlüssel erhalten", "groqApiKey": "Groq API-Schlüssel", + "getSambaNovaApiKey": "SambaNova API-Schlüssel erhalten", + "sambaNovaApiKey": "SambaNova API-Schlüssel", "getGeminiApiKey": "Gemini API-Schlüssel erhalten", "openAiApiKey": "OpenAI API-Schlüssel", "apiKey": "API-Schlüssel", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 4a826bddab4..5393990b80a 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API Key", "getGroqApiKey": "Get Groq API Key", "groqApiKey": "Groq API Key", + "getSambaNovaApiKey": "Get SambaNova API Key", + "sambaNovaApiKey": "SambaNova API Key", "getGeminiApiKey": "Get Gemini API Key", "openAiApiKey": "OpenAI API Key", "apiKey": "API Key", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 4c4f24bb0f9..9e43480a609 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Clave API de Gemini", "getGroqApiKey": "Obtener clave API de Groq", "groqApiKey": "Clave API de Groq", + "getSambaNovaApiKey": "Obtener clave API de SambaNova", + "sambaNovaApiKey": "Clave API de SambaNova", "getGeminiApiKey": "Obtener clave API de Gemini", "openAiApiKey": "Clave API de OpenAI", "apiKey": "Clave API", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 6e7a964694b..fcc017ec3a7 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Clé API Gemini", "getGroqApiKey": "Obtenir la clé API Groq", "groqApiKey": "Clé API Groq", + "getSambaNovaApiKey": "Obtenir la clé API SambaNova", + "sambaNovaApiKey": "Clé API SambaNova", "getGeminiApiKey": "Obtenir la clé API Gemini", "openAiApiKey": "Clé API OpenAI", "apiKey": "Clé API", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index ca255ca44ee..040f0a10427 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API कुंजी", "getGroqApiKey": "Groq API कुंजी प्राप्त करें", "groqApiKey": "Groq API कुंजी", + "getSambaNovaApiKey": "SambaNova API कुंजी प्राप्त करें", + "sambaNovaApiKey": "SambaNova API कुंजी", "getGeminiApiKey": "Gemini API कुंजी प्राप्त करें", "openAiApiKey": "OpenAI API कुंजी", "apiKey": "API कुंजी", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 0bff5ef4a17..991708dec8a 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -263,6 +263,8 @@ "geminiApiKey": "Gemini API Key", "getGroqApiKey": "Dapatkan Groq API Key", "groqApiKey": "Groq API Key", + "getSambaNovaApiKey": "Dapatkan SambaNova API Key", + "sambaNovaApiKey": "SambaNova API Key", "getGeminiApiKey": "Dapatkan Gemini API Key", "openAiApiKey": "OpenAI API Key", "apiKey": "API Key", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index e5cd37a1106..000b70dab4c 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Chiave API Gemini", "getGroqApiKey": "Ottieni chiave API Groq", "groqApiKey": "Chiave API Groq", + "getSambaNovaApiKey": "Ottieni chiave API SambaNova", + "sambaNovaApiKey": "Chiave API SambaNova", "getGeminiApiKey": "Ottieni chiave API Gemini", "openAiApiKey": "Chiave API OpenAI", "apiKey": "Chiave API", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index e32fac776a9..832e651ec59 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini APIキー", "getGroqApiKey": "Groq APIキーを取得", "groqApiKey": "Groq APIキー", + "getSambaNovaApiKey": "SambaNova APIキーを取得", + "sambaNovaApiKey": "SambaNova APIキー", "getGeminiApiKey": "Gemini APIキーを取得", "openAiApiKey": "OpenAI APIキー", "apiKey": "APIキー", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index f48860b0aeb..b1b22958075 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API 키", "getGroqApiKey": "Groq API 키 받기", "groqApiKey": "Groq API 키", + "getSambaNovaApiKey": "SambaNova API 키 받기", + "sambaNovaApiKey": "SambaNova API 키", "getGeminiApiKey": "Gemini API 키 받기", "apiKey": "API 키", "openAiApiKey": "OpenAI API 키", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index bf6e65c995d..341188f472c 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API-sleutel", "getGroqApiKey": "Groq API-sleutel ophalen", "groqApiKey": "Groq API-sleutel", + "getSambaNovaApiKey": "SambaNova API-sleutel ophalen", + "sambaNovaApiKey": "SambaNova API-sleutel", "getGeminiApiKey": "Gemini API-sleutel ophalen", "apiKey": "API-sleutel", "openAiApiKey": "OpenAI API-sleutel", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index d42e4f51a99..779aa69880c 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Klucz API Gemini", "getGroqApiKey": "Uzyskaj klucz API Groq", "groqApiKey": "Klucz API Groq", + "getSambaNovaApiKey": "Uzyskaj klucz API SambaNova", + "sambaNovaApiKey": "Klucz API SambaNova", "getGeminiApiKey": "Uzyskaj klucz API Gemini", "apiKey": "Klucz API", "openAiApiKey": "Klucz API OpenAI", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 924542cf096..1d20c589d85 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Chave de API Gemini", "getGroqApiKey": "Obter chave de API Groq", "groqApiKey": "Chave de API Groq", + "getSambaNovaApiKey": "Obter chave de API SambaNova", + "sambaNovaApiKey": "Chave de API SambaNova", "getGeminiApiKey": "Obter chave de API Gemini", "apiKey": "Chave de API", "openAiApiKey": "Chave de API OpenAI", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index cf719b09769..67a3fa7195e 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API-ключ", "getGroqApiKey": "Получить Groq API-ключ", "groqApiKey": "Groq API-ключ", + "getSambaNovaApiKey": "Получить SambaNova API-ключ", + "sambaNovaApiKey": "SambaNova API-ключ", "getGeminiApiKey": "Получить Gemini API-ключ", "apiKey": "API-ключ", "openAiApiKey": "OpenAI API-ключ", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index fc8fc9c6775..44170cc2f9f 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API Anahtarı", "getGroqApiKey": "Groq API Anahtarı Al", "groqApiKey": "Groq API Anahtarı", + "getSambaNovaApiKey": "SambaNova API Anahtarı Al", + "sambaNovaApiKey": "SambaNova API Anahtarı", "getGeminiApiKey": "Gemini API Anahtarı Al", "openAiApiKey": "OpenAI API Anahtarı", "apiKey": "API Anahtarı", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 7d3e2803ad7..891e3deb845 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Khóa API Gemini", "getGroqApiKey": "Lấy khóa API Groq", "groqApiKey": "Khóa API Groq", + "getSambaNovaApiKey": "Lấy khóa API SambaNova", + "sambaNovaApiKey": "Khóa API SambaNova", "getGeminiApiKey": "Lấy khóa API Gemini", "openAiApiKey": "Khóa API OpenAI", "apiKey": "Khóa API", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index eae71ac706f..c470bbf579c 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API 密钥", "getGroqApiKey": "获取 Groq API 密钥", "groqApiKey": "Groq API 密钥", + "getSambaNovaApiKey": "获取 SambaNova API 密钥", + "sambaNovaApiKey": "SambaNova API 密钥", "getGeminiApiKey": "获取 Gemini API 密钥", "openAiApiKey": "OpenAI API 密钥", "apiKey": "API 密钥", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 420ece916e6..f8c0f835fc1 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -259,6 +259,8 @@ "geminiApiKey": "Gemini API 金鑰", "getGroqApiKey": "取得 Groq API 金鑰", "groqApiKey": "Groq API 金鑰", + "getSambaNovaApiKey": "取得 SambaNova API 金鑰", + "sambaNovaApiKey": "SambaNova API 金鑰", "getGeminiApiKey": "取得 Gemini API 金鑰", "openAiApiKey": "OpenAI API 金鑰", "apiKey": "API 金鑰",