diff --git a/core/control-plane/schema.ts b/core/control-plane/schema.ts index 02901bda2fb..c39c16dac8a 100644 --- a/core/control-plane/schema.ts +++ b/core/control-plane/schema.ts @@ -20,6 +20,7 @@ const modelDescriptionSchema = z.object({ "nebius", "siliconflow", "tensorix", + "forge", "scaleway", "watsonx", ]), @@ -94,6 +95,7 @@ const embeddingsProviderSchema = z.object({ "nebius", "siliconflow", "tensorix", + "forge", "scaleway", "watsonx", ]), diff --git a/core/llm/llms/Forge.ts b/core/llm/llms/Forge.ts new file mode 100644 index 00000000000..42680ed2320 --- /dev/null +++ b/core/llm/llms/Forge.ts @@ -0,0 +1,14 @@ +import OpenAI from "./OpenAI.js"; + +import type { LLMOptions } from "../../index.js"; + +class Forge extends OpenAI { + static providerName = "forge"; + static defaultOptions: Partial = { + apiBase: "https://api.voxell.ai/v1/", + model: "forge-pro", + maxEmbeddingBatchSize: 128, + }; +} + +export default Forge; diff --git a/core/llm/llms/index.ts b/core/llm/llms/index.ts index 453b2d90cd8..2f6c0e2b51c 100644 --- a/core/llm/llms/index.ts +++ b/core/llm/llms/index.ts @@ -23,6 +23,7 @@ import Deepseek from "./Deepseek"; import Docker from "./Docker"; import Fireworks from "./Fireworks"; import Flowise from "./Flowise"; +import Forge from "./Forge"; import FunctionNetwork from "./FunctionNetwork"; import Gemini from "./Gemini"; import Groq from "./Groq"; @@ -101,6 +102,7 @@ export const LLMClasses = [ SageMaker, DeepInfra, Flowise, + Forge, Groq, Fireworks, NCompass, diff --git a/docs/customize/model-providers/more/forge.mdx b/docs/customize/model-providers/more/forge.mdx new file mode 100644 index 00000000000..577cbb0d811 --- /dev/null +++ b/docs/customize/model-providers/more/forge.mdx @@ -0,0 +1,45 @@ +--- +title: "Forge" +description: "Configure Forge with Continue to use OpenAI-compatible text embeddings from Voxell" +--- + +[Forge](https://voxell.ai) is an OpenAI-compatible embeddings API from Voxell. It is embeddings-only and exposes models at multiple dimensionalities: `forge-turbo` (1024d), `forge-pro` (2560d, default), and `forge-ultra-4k` (4096d). OpenAI model aliases are also accepted, and the `dimensions` parameter is supported. + + + You can get an API key from [voxell.ai](https://voxell.ai). + + +## Embeddings Model + +We recommend configuring **forge-pro** as your embeddings model. + + + + ```yaml title="config.yaml" + name: My Config + version: 0.0.1 + schema: v1 + + models: + - name: Forge Pro + provider: forge + model: forge-pro + apiKey: + roles: + - embed + ``` + + + ```json title="config.json" + { + "embeddingsProvider": { + "provider": "forge", + "model": "forge-pro", + "apiKey": "" + } + } + ``` + + + +[View the source](https://github.com/continuedev/continue/blob/main/core/llm/llms/Forge.ts) diff --git a/docs/docs.json b/docs/docs.json index 8556401ffc6..9c364ed039d 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -172,6 +172,7 @@ "customize/model-providers/more/clawrouter", "customize/model-providers/more/deepseek", "customize/model-providers/more/deepinfra", + "customize/model-providers/more/forge", "customize/model-providers/more/groq", "customize/model-providers/more/llamacpp", "customize/model-providers/more/llamastack", diff --git a/gui/src/pages/AddNewModel/configs/providers.ts b/gui/src/pages/AddNewModel/configs/providers.ts index 82f1e15c7a0..bbade33feb4 100644 --- a/gui/src/pages/AddNewModel/configs/providers.ts +++ b/gui/src/pages/AddNewModel/configs/providers.ts @@ -1271,6 +1271,26 @@ To get started, [register](https://dataplatform.cloud.ibm.com/registration/stepo packages: [{ ...models.AUTODETECT }], apiKeyUrl: "https://app.tensorix.ai", }, + forge: { + title: "Forge", + provider: "forge", + description: + "Forge is an OpenAI-compatible embeddings API from Voxell, offering high-dimensional text embedding models.", + longDescription: + "Forge provides OpenAI-compatible text embeddings. To get started, create an account and get an API key at [voxell.ai](https://voxell.ai). Available models include `forge-turbo` (1024d), `forge-pro` (2560d), and `forge-ultra-4k` (4096d).", + tags: [ModelProviderTags.RequiresApiKey], + collectInputFor: [ + { + inputType: "text", + key: "apiKey", + label: "API Key", + placeholder: "Enter your Forge API key", + required: true, + }, + ], + packages: [{ ...models.AUTODETECT }], + apiKeyUrl: "https://voxell.ai", + }, venice: { title: "Venice", provider: "venice", diff --git a/packages/config-types/src/index.ts b/packages/config-types/src/index.ts index 8561500e662..3cd4bdde30f 100644 --- a/packages/config-types/src/index.ts +++ b/packages/config-types/src/index.ts @@ -60,6 +60,7 @@ export const modelDescriptionSchema = z.object({ "continue-proxy", "nebius", "scaleway", + "forge", "watsonx", "minimax", ]), @@ -115,6 +116,7 @@ export const embeddingsProviderSchema = z.object({ "continue-proxy", "nebius", "scaleway", + "forge", "watsonx", ]), apiBase: z.string().optional(), diff --git a/packages/llm-info/src/index.ts b/packages/llm-info/src/index.ts index 0ea14a5ab47..a7419be4be9 100644 --- a/packages/llm-info/src/index.ts +++ b/packages/llm-info/src/index.ts @@ -3,6 +3,7 @@ import { Azure } from "./providers/azure.js"; import { Bedrock } from "./providers/bedrock.js"; import { Cohere } from "./providers/cohere.js"; import { CometAPI } from "./providers/cometapi.js"; +import { Forge } from "./providers/forge.js"; import { Gemini } from "./providers/gemini.js"; import { Inception } from "./providers/inception.js"; import { MiniMax } from "./providers/minimax.js"; @@ -27,6 +28,7 @@ export const allModelProviders: ModelProvider[] = [ Bedrock, Cohere, CometAPI, + Forge, Inception, MiniMax, xAI, diff --git a/packages/llm-info/src/providers/forge.ts b/packages/llm-info/src/providers/forge.ts new file mode 100644 index 00000000000..0a0822fed4f --- /dev/null +++ b/packages/llm-info/src/providers/forge.ts @@ -0,0 +1,23 @@ +import { ModelProvider } from "../types.js"; + +export const Forge: ModelProvider = { + models: [ + { + model: "forge-turbo", + displayName: "Forge Turbo", + recommendedFor: ["embed"], + }, + { + model: "forge-pro", + displayName: "Forge Pro", + recommendedFor: ["embed"], + }, + { + model: "forge-ultra-4k", + displayName: "Forge Ultra 4K", + recommendedFor: ["embed"], + }, + ], + id: "forge", + displayName: "Forge", +}; diff --git a/packages/openai-adapters/src/index.ts b/packages/openai-adapters/src/index.ts index c9eb4da00fa..69589f7704f 100644 --- a/packages/openai-adapters/src/index.ts +++ b/packages/openai-adapters/src/index.ts @@ -178,6 +178,8 @@ export function constructLlmApi(config: LLMConfig): BaseLlmApi | undefined { return openAICompatible("https://api.function.network/v1/", config); case "tensorix": return openAICompatible("https://api.tensorix.ai/v1/", config); + case "forge": + return openAICompatible("https://api.voxell.ai/v1/", config); case "openrouter": return new OpenRouterApi(config); case "clawrouter": diff --git a/packages/openai-adapters/src/test/main.test.ts b/packages/openai-adapters/src/test/main.test.ts index 8a10c8b727f..ad5a0bcf500 100644 --- a/packages/openai-adapters/src/test/main.test.ts +++ b/packages/openai-adapters/src/test/main.test.ts @@ -254,6 +254,25 @@ describe("Configuration", () => { ); }); + it("should configure Forge OpenAI client with correct apiBase and apiKey", () => { + const forge = constructLlmApi({ + provider: "forge", + apiKey: "sk-xxx", + }); + + expect((forge as OpenAIApi).openai.baseURL).toBe( + "https://api.voxell.ai/v1/", + ); + expect((forge as OpenAIApi).openai.apiKey).toBe("sk-xxx"); + + const forge2 = constructLlmApi({ + provider: "forge", + apiKey: "sk-xxx", + apiBase: "https://api.example.com", + }); + expect((forge2 as OpenAIApi).openai.baseURL).toBe("https://api.example.com"); + }); + it("should configure Azure OpenAI client with root URL and trailing slash", () => { const azure = constructLlmApi({ provider: "azure", diff --git a/packages/openai-adapters/src/types.ts b/packages/openai-adapters/src/types.ts index 3b324b0ac6b..7c7f629144b 100644 --- a/packages/openai-adapters/src/types.ts +++ b/packages/openai-adapters/src/types.ts @@ -60,6 +60,7 @@ export const OpenAIConfigSchema = BasePlusConfig.extend({ z.literal("zAI"), z.literal("scaleway"), z.literal("tensorix"), + z.literal("forge"), z.literal("ncompass"), z.literal("relace"), z.literal("huggingface-inference-api"),