diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 44626273b5..03bbe9640a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -38,6 +38,7 @@ body: - OpenAI Compatible - OpenRouter - Requesty + - SambaNova - Unbound - VS Code Language Model API - xAI (Grok) diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts index d5e76eccea..0e8e40add2 100644 --- a/packages/types/src/global-settings.ts +++ b/packages/types/src/global-settings.ts @@ -185,6 +185,7 @@ export const SECRET_STATE_KEYS = [ "codebaseIndexGeminiApiKey", "codebaseIndexMistralApiKey", "huggingFaceApiKey", + "sambaNovaApiKey", ] as const satisfies readonly (keyof ProviderSettings)[] export type SecretState = Pick diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 4322b9f550..ff76a2df5c 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -33,6 +33,7 @@ export const providerNames = [ "chutes", "litellm", "huggingface", + "sambanova", ] as const export const providerNamesSchema = z.enum(providerNames) @@ -240,6 +241,10 @@ const litellmSchema = baseProviderSettingsSchema.extend({ litellmModelId: z.string().optional(), }) +const sambaNovaSchema = apiModelIdProviderModelSchema.extend({ + sambaNovaApiKey: z.string().optional(), +}) + const defaultSchema = z.object({ apiProvider: z.undefined(), }) @@ -270,6 +275,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv huggingFaceSchema.merge(z.object({ apiProvider: z.literal("huggingface") })), 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, ]) @@ -300,6 +306,7 @@ export const providerSettingsSchema = z.object({ ...huggingFaceSchema.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 f5061f152c..2e9a2a74a2 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -15,6 +15,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 0000000000..bed143f6e5 --- /dev/null +++ b/packages/types/src/providers/sambanova.ts @@ -0,0 +1,90 @@ +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.3-70B-Instruct" + | "DeepSeek-R1" + | "DeepSeek-V3-0324" + | "DeepSeek-R1-Distill-Llama-70B" + | "Llama-4-Maverick-17B-128E-Instruct" + | "Llama-3.3-Swallow-70B-Instruct-v0.4" + | "Qwen3-32B" + +export const sambaNovaDefaultModelId: SambaNovaModelId = "Meta-Llama-3.3-70B-Instruct" + +export const sambaNovaModels = { + "Meta-Llama-3.1-8B-Instruct": { + maxTokens: 8192, + contextWindow: 16384, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.2, + description: "Meta Llama 3.1 8B Instruct model with 16K context window.", + }, + "Meta-Llama-3.3-70B-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.6, + outputPrice: 1.2, + description: "Meta Llama 3.3 70B Instruct model with 128K context window.", + }, + "DeepSeek-R1": { + maxTokens: 8192, + contextWindow: 32768, + supportsImages: false, + supportsPromptCache: false, + supportsReasoningBudget: true, + inputPrice: 5.0, + outputPrice: 7.0, + description: "DeepSeek R1 reasoning model with 32K context window.", + }, + "DeepSeek-V3-0324": { + maxTokens: 8192, + contextWindow: 32768, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 3.0, + outputPrice: 4.5, + description: "DeepSeek V3 model with 32K context window.", + }, + "DeepSeek-R1-Distill-Llama-70B": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.7, + outputPrice: 1.4, + description: "DeepSeek R1 distilled Llama 70B model with 128K context window.", + }, + "Llama-4-Maverick-17B-128E-Instruct": { + maxTokens: 8192, + contextWindow: 131072, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0.63, + outputPrice: 1.8, + description: "Meta Llama 4 Maverick 17B 128E Instruct model with 128K context window.", + }, + "Llama-3.3-Swallow-70B-Instruct-v0.4": { + maxTokens: 8192, + contextWindow: 16384, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.6, + outputPrice: 1.2, + description: "Tokyotech Llama 3.3 Swallow 70B Instruct v0.4 model with 16K context window.", + }, + "Qwen3-32B": { + maxTokens: 8192, + contextWindow: 8192, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.4, + outputPrice: 0.8, + description: "Alibaba Qwen 3 32B model with 8K context window.", + }, +} as const satisfies Record diff --git a/src/api/index.ts b/src/api/index.ts index bda390848c..1e9d2f6e59 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -30,6 +30,7 @@ import { ChutesHandler, LiteLLMHandler, ClaudeCodeHandler, + SambaNovaHandler, } from "./providers" export interface SingleCompletionHandler { @@ -115,6 +116,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 0000000000..cd0e4a1989 --- /dev/null +++ b/src/api/providers/__tests__/sambanova.spec.ts @@ -0,0 +1,154 @@ +// npx vitest run src/api/providers/__tests__/sambanova.spec.ts + +// Mock vscode first to avoid import errors +vitest.mock("vscode", () => ({})) + +import OpenAI from "openai" +import { Anthropic } from "@anthropic-ai/sdk" + +import { type SambaNovaModelId, sambaNovaDefaultModelId, sambaNovaModels } from "@roo-code/types" + +import { SambaNovaHandler } from "../sambanova" + +vitest.mock("openai", () => { + const createMock = vitest.fn() + return { + default: vitest.fn(() => ({ chat: { completions: { create: createMock } } })), + } +}) + +describe("SambaNovaHandler", () => { + let handler: SambaNovaHandler + let mockCreate: any + + beforeEach(() => { + vitest.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 return default model when no model is specified", () => { + const model = handler.getModel() + expect(model.id).toBe(sambaNovaDefaultModelId) + expect(model.info).toEqual(sambaNovaModels[sambaNovaDefaultModelId]) + }) + + it("should return specified model when valid model is 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("completePrompt method should return text from SambaNova API", async () => { + const expectedResponse = "This is a test response from SambaNova" + mockCreate.mockResolvedValueOnce({ choices: [{ message: { content: expectedResponse } }] }) + const result = await handler.completePrompt("test prompt") + expect(result).toBe(expectedResponse) + }) + + it("should handle errors in completePrompt", async () => { + const errorMessage = "SambaNova API error" + mockCreate.mockRejectedValueOnce(new Error(errorMessage)) + await expect(handler.completePrompt("test prompt")).rejects.toThrow( + `SambaNova completion error: ${errorMessage}`, + ) + }) + + it("createMessage should yield text content from stream", async () => { + const testContent = "This is test content from SambaNova stream" + + mockCreate.mockImplementationOnce(() => { + return { + [Symbol.asyncIterator]: () => ({ + next: vitest + .fn() + .mockResolvedValueOnce({ + done: false, + value: { choices: [{ delta: { content: testContent } }] }, + }) + .mockResolvedValueOnce({ done: true }), + }), + } + }) + + const stream = handler.createMessage("system prompt", []) + const firstChunk = await stream.next() + + expect(firstChunk.done).toBe(false) + expect(firstChunk.value).toEqual({ type: "text", text: testContent }) + }) + + it("createMessage should yield usage data from stream", async () => { + mockCreate.mockImplementationOnce(() => { + return { + [Symbol.asyncIterator]: () => ({ + next: vitest + .fn() + .mockResolvedValueOnce({ + done: false, + value: { choices: [{ delta: {} }], usage: { prompt_tokens: 10, completion_tokens: 20 } }, + }) + .mockResolvedValueOnce({ done: true }), + }), + } + }) + + const stream = handler.createMessage("system prompt", []) + const firstChunk = await stream.next() + + expect(firstChunk.done).toBe(false) + expect(firstChunk.value).toEqual({ type: "usage", inputTokens: 10, outputTokens: 20 }) + }) + + it("createMessage should pass correct parameters to SambaNova client", async () => { + const modelId: SambaNovaModelId = "Meta-Llama-3.3-70B-Instruct" + const modelInfo = sambaNovaModels[modelId] + const handlerWithModel = new SambaNovaHandler({ + apiModelId: modelId, + sambaNovaApiKey: "test-sambanova-api-key", + }) + + mockCreate.mockImplementationOnce(() => { + return { + [Symbol.asyncIterator]: () => ({ + async next() { + return { done: true } + }, + }), + } + }) + + const systemPrompt = "Test system prompt for SambaNova" + const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Test message for SambaNova" }] + + const messageGenerator = handlerWithModel.createMessage(systemPrompt, messages) + await messageGenerator.next() + + expect(mockCreate).toHaveBeenCalledWith( + expect.objectContaining({ + model: modelId, + max_tokens: modelInfo.maxTokens, + temperature: 0.7, + messages: expect.arrayContaining([{ role: "system", content: systemPrompt }]), + stream: true, + stream_options: { include_usage: true }, + }), + ) + }) +}) diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index 1cefd0616b..e49dc55c76 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -19,6 +19,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 0000000000..a15bc12577 --- /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/src/shared/ProfileValidator.ts b/src/shared/ProfileValidator.ts index 9fc527c15a..2ebf9bb3ab 100644 --- a/src/shared/ProfileValidator.ts +++ b/src/shared/ProfileValidator.ts @@ -65,6 +65,7 @@ export class ProfileValidator { case "deepseek": case "xai": case "groq": + case "sambanova": case "chutes": return profile.apiModelId case "litellm": diff --git a/src/shared/__tests__/ProfileValidator.spec.ts b/src/shared/__tests__/ProfileValidator.spec.ts index 896968ff7c..7ece0d8bf8 100644 --- a/src/shared/__tests__/ProfileValidator.spec.ts +++ b/src/shared/__tests__/ProfileValidator.spec.ts @@ -192,6 +192,7 @@ describe("ProfileValidator", () => { "xai", "groq", "chutes", + "sambanova", ] apiModelProviders.forEach((provider) => { diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 38d2ceebd3..10d01d097e 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" @@ -69,6 +70,7 @@ import { OpenAICompatible, OpenRouter, Requesty, + SambaNova, Unbound, Vertex, VSCodeLM, @@ -297,6 +299,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" }, @@ -505,6 +508,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 995f591034..7d07e41f46 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 0000000000..9202f8d06e --- /dev/null +++ b/webview-ui/src/components/settings/providers/SambaNova.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 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 6c6fdddaee..957edb7992 100644 --- a/webview-ui/src/components/settings/providers/index.ts +++ b/webview-ui/src/components/settings/providers/index.ts @@ -15,6 +15,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 8dceb6e117..a6b76fbd7c 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" @@ -224,6 +226,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 aed9413f27..06317599ea 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", "getHuggingFaceApiKey": "Obtenir clau API de Hugging Face", "huggingFaceApiKey": "Clau API de Hugging Face", "huggingFaceModelId": "ID del model", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 36970cb920..ace5c3fc15 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", "getHuggingFaceApiKey": "Hugging Face API-Schlüssel erhalten", "huggingFaceApiKey": "Hugging Face API-Schlüssel", "huggingFaceModelId": "Modell-ID", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index cd83190326..5695491994 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", "getHuggingFaceApiKey": "Get Hugging Face API Key", "huggingFaceApiKey": "Hugging Face API Key", "huggingFaceModelId": "Model ID", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index fbee37507d..5af4862d77 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", "getHuggingFaceApiKey": "Obtener clave API de Hugging Face", "huggingFaceApiKey": "Clave API de Hugging Face", "huggingFaceModelId": "ID del modelo", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index ce3e2526de..27f911c20c 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", "getHuggingFaceApiKey": "Obtenir la clé API Hugging Face", "huggingFaceApiKey": "Clé API Hugging Face", "huggingFaceModelId": "ID du modèle", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 9fe2ca57b5..a133e31a3f 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 कुंजी", "getHuggingFaceApiKey": "Hugging Face API कुंजी प्राप्त करें", "huggingFaceApiKey": "Hugging Face API कुंजी", "huggingFaceModelId": "मॉडल ID", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 82a10a05f4..e4a3f67c16 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", "getHuggingFaceApiKey": "Dapatkan Kunci API Hugging Face", "huggingFaceApiKey": "Kunci API Hugging Face", "huggingFaceModelId": "ID Model", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index f5c12b5c75..4fe1f04977 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", "getHuggingFaceApiKey": "Ottieni chiave API Hugging Face", "huggingFaceApiKey": "Chiave API Hugging Face", "huggingFaceModelId": "ID modello", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index f91dc6a174..34d8f29a00 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キー", "getHuggingFaceApiKey": "Hugging Face APIキーを取得", "huggingFaceApiKey": "Hugging Face APIキー", "huggingFaceModelId": "モデルID", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index f1f4347887..e4d843c752 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 키 받기", "getHuggingFaceApiKey": "Hugging Face API 키 받기", "huggingFaceApiKey": "Hugging Face API 키", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 07f86818a2..28e8252a4b 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", "getHuggingFaceApiKey": "Hugging Face API-sleutel ophalen", "huggingFaceApiKey": "Hugging Face API-sleutel", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index b787d85a81..3409749114 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", "getHuggingFaceApiKey": "Uzyskaj klucz API Hugging Face", "huggingFaceApiKey": "Klucz API Hugging Face", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index e35df63d15..0d6ce84daf 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", "getHuggingFaceApiKey": "Obter chave de API Hugging Face", "huggingFaceApiKey": "Chave de API Hugging Face", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 1a0d533792..b36bf4e2db 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-ключ", "getHuggingFaceApiKey": "Получить Hugging Face API-ключ", "huggingFaceApiKey": "Hugging Face API-ключ", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index c05beb0eb3..ddc37200ad 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ı", "getHuggingFaceApiKey": "Hugging Face API Anahtarı Al", "huggingFaceApiKey": "Hugging Face API Anahtarı", "huggingFaceModelId": "Model ID", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 016079f0cc..5e1b589b66 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", "getHuggingFaceApiKey": "Lấy Khóa API Hugging Face", "huggingFaceApiKey": "Khóa API Hugging Face", "huggingFaceModelId": "ID Mô hình", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 7a4bd26fb8..0ac1519682 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 密钥", "getHuggingFaceApiKey": "获取 Hugging Face API 密钥", "huggingFaceApiKey": "Hugging Face API 密钥", "huggingFaceModelId": "模型 ID", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index b3d57e998a..5bd9a1c96b 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 金鑰", "getHuggingFaceApiKey": "取得 Hugging Face API 金鑰", "huggingFaceApiKey": "Hugging Face API 金鑰", "huggingFaceModelId": "模型 ID",