diff --git a/core/llm/autodetect.ts b/core/llm/autodetect.ts index c8511554b8b..62bc6947396 100644 --- a/core/llm/autodetect.ts +++ b/core/llm/autodetect.ts @@ -70,6 +70,7 @@ const PROVIDER_HANDLES_TEMPLATING: string[] = [ "minimax", "groq", "gemini", + "saygm", "docker", "nous", "zAI", diff --git a/core/llm/llms/Saygm.ts b/core/llm/llms/Saygm.ts new file mode 100644 index 00000000000..3e727276fbf --- /dev/null +++ b/core/llm/llms/Saygm.ts @@ -0,0 +1,39 @@ +import { ChatCompletionCreateParams } from "openai/resources/index"; + +import { LLMOptions } from "../../index.js"; +import { osModelsEditPrompt } from "../templates/edit.js"; + +import OpenAI from "./OpenAI.js"; + +class Saygm extends OpenAI { + static providerName = "saygm"; + + static defaultOptions: Partial = { + apiBase: "https://api.saygm.com/v1/", + model: "gpt-5.4", + promptTemplates: { + edit: osModelsEditPrompt, + }, + useLegacyCompletionsEndpoint: false, + }; + + protected modifyChatBody( + body: ChatCompletionCreateParams, + ): ChatCompletionCreateParams { + const modified = super.modifyChatBody(body); + if ( + modified.model === "gpt-5.6-sol" && + Array.isArray(modified.tools) && + modified.tools.length > 0 + ) { + ( + modified as Omit & { + reasoning_effort?: string; + } + ).reasoning_effort = "none"; + } + return modified; + } +} + +export default Saygm; diff --git a/core/llm/llms/index.ts b/core/llm/llms/index.ts index 4978f0617f2..2d54e27f711 100644 --- a/core/llm/llms/index.ts +++ b/core/llm/llms/index.ts @@ -25,6 +25,7 @@ import Fireworks from "./Fireworks"; import Flowise from "./Flowise"; import FunctionNetwork from "./FunctionNetwork"; import Gemini from "./Gemini"; +import Saygm from "./Saygm"; import Groq from "./Groq"; import HuggingFaceInferenceAPI from "./HuggingFaceInferenceAPI"; import HuggingFaceTEIEmbeddingsProvider from "./HuggingFaceTEI"; @@ -76,6 +77,7 @@ export const LLMClasses = [ CometAPI, FunctionNetwork, Gemini, + Saygm, Llamafile, Moonshot, Ollama, diff --git a/docs/customize/model-providers/more/saygm.mdx b/docs/customize/model-providers/more/saygm.mdx new file mode 100644 index 00000000000..1f2f0e83075 --- /dev/null +++ b/docs/customize/model-providers/more/saygm.mdx @@ -0,0 +1,106 @@ +--- +title: "SayGM" +description: "Configure SayGM's frontier models (GPT-5.x, o-series) with Continue. SayGM is a decentralized inference subnet on Bittensor serving OpenAI-compatible models." +--- + +[SayGM](https://saygm.com) is a decentralized inference subnet on Bittensor that serves frontier OpenAI models (GPT-5.x, o-series) over an OpenAI-compatible API at `https://api.saygm.com/v1`. + +## Configuration + +To use SayGM models, you need to: + +1. Sign up at [saygm.com](https://saygm.com) and get an API key (a `gm_live_...` token) +2. Add the following configuration: + + + + ```yaml title="config.yaml" + name: My Config + version: 0.0.1 + schema: v1 + + models: + - name: GPT-5.6 Sol + provider: saygm + model: gpt-5.6-sol + apiKey: + ``` + + + ```json title="config.json" + { + "models": [ + { + "title": "GPT-5.6 Sol", + "provider": "saygm", + "model": "gpt-5.6-sol", + "apiKey": "" + } + ] + } + ``` + + + +## Available Models + +SayGM currently serves the following OpenAI-chat-compatible models (all with a 1M token context window): + +- `gpt-5.6-sol`: latest frontier reasoning model +- `gpt-5.6-terra`: mid-tier frontier model +- `gpt-5.6-luna`: fast frontier model +- `gpt-5.5`: frontier reasoning model +- `gpt-5.4`: flagship reasoning model +- `gpt-5.4-mini`: compact frontier model +- `gpt-5.4-nano`: smallest gpt-5.4 model +- `o3`: full o3 reasoning model +- `o4-mini`: compact o-series reasoning model + +SayGM also serves Claude models and `gpt-5.5-pro`, but those require the Anthropic / OpenAI Responses wire protocols respectively, which Continue does not expose for the `saygm` provider. + +## Configuration Options + +| Option | Description | Default | +| --------- | ----------------- | ----------------------------- | +| `apiKey` | SayGM API key | Required | +| `apiBase` | API base URL | `https://api.saygm.com/v1/` | +| `model` | Model name to use | `gpt-5.4` | + +## Example + +Here's a complete configuration example: + + + + ```yaml title="config.yaml" + name: My Config + version: 0.0.1 + schema: v1 + + models: + - name: GPT-5.6 Sol + provider: saygm + model: gpt-5.6-sol + apiKey: + defaultCompletionOptions: + maxTokens: 128000 + ``` + + + ```json title="config.json" + { + "models": [ + { + "title": "GPT-5.6 Sol", + "provider": "saygm", + "model": "gpt-5.6-sol", + "apiKey": "", + "completionOptions": { + "maxTokens": 128000 + } + } + ] + } + ``` + + diff --git a/gui/public/logos/saygm.svg b/gui/public/logos/saygm.svg new file mode 100644 index 00000000000..a7f15946624 --- /dev/null +++ b/gui/public/logos/saygm.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/src/pages/AddNewModel/configs/models.ts b/gui/src/pages/AddNewModel/configs/models.ts index 7065248d68f..b4dd403a2ea 100644 --- a/gui/src/pages/AddNewModel/configs/models.ts +++ b/gui/src/pages/AddNewModel/configs/models.ts @@ -2306,6 +2306,132 @@ export const models: { [key: string]: ModelPackage } = { icon: "openai.png", isOpenSource: false, }, + saygmGpt5_4: { + title: "GPT-5.4", + description: + "Frontier reasoning model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "gpt-5.4", + contextLength: 1_000_000, + completionOptions: { maxTokens: 128_000 }, + title: "GPT-5.4", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmGpt5_4Mini: { + title: "GPT-5.4 Mini", + description: + "Fast frontier model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "gpt-5.4-mini", + contextLength: 1_000_000, + completionOptions: { maxTokens: 128_000 }, + title: "GPT-5.4 Mini", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmGpt5_4Nano: { + title: "GPT-5.4 Nano", + description: + "Smallest gpt-5.4 model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "gpt-5.4-nano", + contextLength: 1_000_000, + completionOptions: { maxTokens: 128_000 }, + title: "GPT-5.4 Nano", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmGpt5_5: { + title: "GPT-5.5", + description: + "Frontier reasoning model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "gpt-5.5", + contextLength: 1_000_000, + completionOptions: { maxTokens: 128_000 }, + title: "GPT-5.5", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmGpt5_6Sol: { + title: "GPT-5.6 Sol", + description: + "Latest frontier reasoning model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "gpt-5.6-sol", + contextLength: 1_000_000, + completionOptions: { maxTokens: 128_000 }, + title: "GPT-5.6 Sol", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmGpt5_6Luna: { + title: "GPT-5.6 Luna", + description: + "Compact frontier model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "gpt-5.6-luna", + contextLength: 1_000_000, + completionOptions: { maxTokens: 128_000 }, + title: "GPT-5.6 Luna", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmGpt5_6Terra: { + title: "GPT-5.6 Terra", + description: + "Mid-tier frontier model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "gpt-5.6-terra", + contextLength: 1_000_000, + completionOptions: { maxTokens: 128_000 }, + title: "GPT-5.6 Terra", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmO3: { + title: "o3", + description: + "Full o3 reasoning model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "o3", + contextLength: 1_000_000, + completionOptions: { maxTokens: 100_000 }, + title: "o3", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, + saygmO4Mini: { + title: "o4 Mini", + description: + "Compact o-series reasoning model served on the SayGM inference subnet (Bittensor), 1M context.", + params: { + model: "o4-mini", + contextLength: 1_000_000, + completionOptions: { maxTokens: 100_000 }, + title: "o4 Mini", + }, + providerOptions: ["saygm"], + icon: "saygm.svg", + isOpenSource: false, + }, gemini25Flash: { title: "Gemini 2.5 Flash", description: diff --git a/gui/src/pages/AddNewModel/configs/providers.ts b/gui/src/pages/AddNewModel/configs/providers.ts index 9e2aba08c5c..12e4ca0ca90 100644 --- a/gui/src/pages/AddNewModel/configs/providers.ts +++ b/gui/src/pages/AddNewModel/configs/providers.ts @@ -266,6 +266,37 @@ export const providers: Partial> = { ], apiKeyUrl: "https://z.ai/manage-apikey/apikey-list", }, + saygm: { + title: "SayGM", + provider: "saygm", + description: + "Frontier models (GPT-5.x, o-series) served by the SayGM inference subnet on Bittensor", + longDescription: `[SayGM](https://saygm.com) is a decentralized inference subnet on Bittensor serving frontier models over an OpenAI-compatible API. Sign up at [saygm.com](https://saygm.com) to create an API key.`, + icon: "saygm.svg", + tags: [ModelProviderTags.RequiresApiKey], + collectInputFor: [ + { + inputType: "text", + key: "apiKey", + label: "API Key", + placeholder: "Enter your SayGM API key", + required: true, + }, + ...completionParamsInputsConfigs, + ], + packages: [ + models.saygmGpt5_6Sol, + models.saygmGpt5_6Terra, + models.saygmGpt5_6Luna, + models.saygmGpt5_5, + models.saygmGpt5_4, + models.saygmGpt5_4Mini, + models.saygmGpt5_4Nano, + models.saygmO3, + models.saygmO4Mini, + ], + apiKeyUrl: "https://saygm.com", + }, "function-network": { title: "Function Network", provider: "function-network", diff --git a/packages/llm-info/src/index.ts b/packages/llm-info/src/index.ts index 0ea14a5ab47..bbd3a5e9f53 100644 --- a/packages/llm-info/src/index.ts +++ b/packages/llm-info/src/index.ts @@ -4,6 +4,7 @@ import { Bedrock } from "./providers/bedrock.js"; import { Cohere } from "./providers/cohere.js"; import { CometAPI } from "./providers/cometapi.js"; import { Gemini } from "./providers/gemini.js"; +import { Saygm } from "./providers/saygm.js"; import { Inception } from "./providers/inception.js"; import { MiniMax } from "./providers/minimax.js"; import { Mistral } from "./providers/mistral.js"; @@ -18,6 +19,7 @@ import { LlmInfoWithProvider, ModelProvider, UseCase } from "./types.js"; export const allModelProviders: ModelProvider[] = [ OpenAi, Gemini, + Saygm, Anthropic, Mistral, Voyage, diff --git a/packages/llm-info/src/providers/saygm.ts b/packages/llm-info/src/providers/saygm.ts new file mode 100644 index 00000000000..607f61656e8 --- /dev/null +++ b/packages/llm-info/src/providers/saygm.ts @@ -0,0 +1,71 @@ +import { ModelProvider } from "../types.js"; + +export const Saygm: ModelProvider = { + id: "saygm", + displayName: "SayGM", + models: [ + { + model: "gpt-5.4", + displayName: "GPT-5.4", + contextLength: 1000000, + maxCompletionTokens: 128000, + recommendedFor: ["chat"], + }, + { + model: "gpt-5.4-mini", + displayName: "GPT-5.4 Mini", + contextLength: 1000000, + maxCompletionTokens: 128000, + recommendedFor: ["chat"], + }, + { + model: "gpt-5.4-nano", + displayName: "GPT-5.4 Nano", + contextLength: 1000000, + maxCompletionTokens: 128000, + recommendedFor: ["chat"], + }, + { + model: "gpt-5.5", + displayName: "GPT-5.5", + contextLength: 1000000, + maxCompletionTokens: 128000, + recommendedFor: ["chat"], + }, + { + model: "gpt-5.6-sol", + displayName: "GPT-5.6 Sol", + contextLength: 1000000, + maxCompletionTokens: 128000, + recommendedFor: ["chat"], + }, + { + model: "gpt-5.6-luna", + displayName: "GPT-5.6 Luna", + contextLength: 1000000, + maxCompletionTokens: 128000, + recommendedFor: ["chat"], + }, + { + model: "gpt-5.6-terra", + displayName: "GPT-5.6 Terra", + contextLength: 1000000, + maxCompletionTokens: 128000, + recommendedFor: ["chat"], + }, + { + model: "o3", + displayName: "o3", + contextLength: 1000000, + maxCompletionTokens: 100000, + recommendedFor: ["chat"], + }, + { + model: "o4-mini", + displayName: "o4 Mini", + contextLength: 1000000, + maxCompletionTokens: 100000, + recommendedFor: ["chat"], + }, + ], +}; diff --git a/packages/openai-adapters/src/index.ts b/packages/openai-adapters/src/index.ts index 52fb2d33a0c..e8bf3316ed4 100644 --- a/packages/openai-adapters/src/index.ts +++ b/packages/openai-adapters/src/index.ts @@ -131,6 +131,8 @@ export function constructLlmApi(config: LLMConfig): BaseLlmApi | undefined { return openAICompatible("https://api.x.ai/v1/", config); case "zAI": return openAICompatible("https://api.z.ai/api/paas/v4/", config); + case "saygm": + return openAICompatible("https://api.saygm.com/v1/", config); case "voyage": return openAICompatible("https://api.voyageai.com/v1/", config); case "mistral": diff --git a/packages/openai-adapters/src/types.ts b/packages/openai-adapters/src/types.ts index 14b9512f75b..209986f1b4e 100644 --- a/packages/openai-adapters/src/types.ts +++ b/packages/openai-adapters/src/types.ts @@ -58,6 +58,7 @@ export const OpenAIConfigSchema = BasePlusConfig.extend({ z.literal("vllm"), z.literal("xAI"), z.literal("zAI"), + z.literal("saygm"), z.literal("scaleway"), z.literal("tensorix"), z.literal("ncompass"),