From 2ad10ba0396337803badf8e027449e36d5221f05 Mon Sep 17 00:00:00 2001 From: Will Chen Date: Sat, 26 Apr 2025 08:52:08 -0700 Subject: [PATCH] Support LLM gateway with Dyad API key (#23) * Do not make API key input (password) - hurts usability * Support LLM gateway (and add GPT 4.1 mini model) * Show Dyad Pro button * Fix to use auto (not dyad) for detecting dyad pro * Fix description of gpt 4.1-mini --- src/app/TitleBar.tsx | 18 +++++++++++++++ .../settings/ProviderSettingsPage.tsx | 1 - src/constants/models.ts | 17 +++++++++----- src/ipc/utils/get_model_client.ts | 22 +++++++++++++++++-- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/app/TitleBar.tsx b/src/app/TitleBar.tsx index 3930bda..f9e39f8 100644 --- a/src/app/TitleBar.tsx +++ b/src/app/TitleBar.tsx @@ -6,6 +6,7 @@ import { useSettings } from "@/hooks/useSettings"; import { Button } from "@/components/ui/button"; // @ts-ignore import logo from "../../assets/logo_transparent.png"; +import { providerSettingsRoute } from "@/routes/settings/providers/$provider"; export const TitleBar = () => { const [selectedAppId] = useAtom(selectedAppIdAtom); @@ -25,6 +26,8 @@ export const TitleBar = () => { } }; + const isDyadPro = !!settings?.providerSettings?.auto?.apiKey?.value; + return (
@@ -39,6 +42,21 @@ export const TitleBar = () => { > {displayText} + {isDyadPro && ( + + )}
); }; diff --git a/src/components/settings/ProviderSettingsPage.tsx b/src/components/settings/ProviderSettingsPage.tsx index 9571712..9fabff1 100644 --- a/src/components/settings/ProviderSettingsPage.tsx +++ b/src/components/settings/ProviderSettingsPage.tsx @@ -273,7 +273,6 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
setApiKeyInput(e.target.value)} diff --git a/src/constants/models.ts b/src/constants/models.ts index 0c83b51..c85d9a1 100644 --- a/src/constants/models.ts +++ b/src/constants/models.ts @@ -14,6 +14,11 @@ export const MODEL_OPTIONS: Record = { displayName: "GPT 4.1", description: "OpenAI's flagship model", }, + { + name: "gpt-4.1-mini", + displayName: "GPT 4.1 Mini", + description: "OpenAI's lightweight, but intelligent model", + }, { name: "o3-mini", displayName: "o3 mini", @@ -55,40 +60,40 @@ export const MODEL_OPTIONS: Record = { export const PROVIDERS: Record< RegularModelProvider, { - name: string; displayName: string; hasFreeTier?: boolean; websiteUrl?: string; + gatewayPrefix: string; } > = { openai: { - name: "openai", displayName: "OpenAI", hasFreeTier: false, websiteUrl: "https://platform.openai.com/api-keys", + gatewayPrefix: "", }, anthropic: { - name: "anthropic", displayName: "Anthropic", hasFreeTier: false, websiteUrl: "https://console.anthropic.com/settings/keys", + gatewayPrefix: "anthropic/", }, google: { - name: "google", displayName: "Google", hasFreeTier: true, websiteUrl: "https://aistudio.google.com/app/apikey", + gatewayPrefix: "gemini/", }, openrouter: { - name: "openrouter", displayName: "OpenRouter", hasFreeTier: true, websiteUrl: "https://openrouter.ai/settings/keys", + gatewayPrefix: "openrouter/", }, auto: { - name: "auto", displayName: "Dyad", websiteUrl: "https://academy.dyad.sh/settings", + gatewayPrefix: "", }, }; diff --git a/src/ipc/utils/get_model_client.ts b/src/ipc/utils/get_model_client.ts index 4f089c4..b7aa77b 100644 --- a/src/ipc/utils/get_model_client.ts +++ b/src/ipc/utils/get_model_client.ts @@ -1,12 +1,19 @@ -import { createOpenAI } from "@ai-sdk/openai"; +import { createOpenAI, OpenAIProvider } from "@ai-sdk/openai"; import { createGoogleGenerativeAI as createGoogle } from "@ai-sdk/google"; import { createAnthropic } from "@ai-sdk/anthropic"; import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { createOllama } from "ollama-ai-provider"; import type { LargeLanguageModel, UserSettings } from "../../lib/schemas"; -import { PROVIDER_TO_ENV_VAR, AUTO_MODELS } from "../../constants/models"; +import { + PROVIDER_TO_ENV_VAR, + AUTO_MODELS, + PROVIDERS, +} from "../../constants/models"; import { getEnvVar } from "./read_env"; +import log from "electron-log"; + +const logger = log.scope("getModelClient"); export function getModelClient( model: LargeLanguageModel, settings: UserSettings @@ -38,6 +45,17 @@ export function getModelClient( throw new Error("No API keys available for any model in AUTO_MODELS"); } + const dyadApiKey = settings.providerSettings?.auto?.apiKey?.value; + if (dyadApiKey) { + const provider = createOpenAI({ + apiKey: dyadApiKey, + baseURL: "https://llm-gateway.dyad.sh/v1", + }); + const providerInfo = PROVIDERS[model.provider as keyof typeof PROVIDERS]; + logger.info("Using Dyad Pro API key"); + return provider(`${providerInfo.gatewayPrefix}${model.name}`); + } + const apiKey = settings.providerSettings?.[model.provider]?.apiKey?.value || getEnvVar(PROVIDER_TO_ENV_VAR[model.provider]);