From 053748564f038d3870f9b0790bb18be49478b73b Mon Sep 17 00:00:00 2001 From: Aditya Gupta Date: Thu, 9 Jul 2026 19:02:42 +0530 Subject: [PATCH] refactor: Decouple model from provider --- apps/gui/src/app/config/page.tsx | 18 ++++++++++-- apps/gui/src/app/play/actions.ts | 6 ++-- apps/gui/src/lib/provider-manager.ts | 33 ++++++++++++++-------- packages/llm/src/llm.ts | 1 + packages/llm/src/providers/google-genai.ts | 4 +-- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/apps/gui/src/app/config/page.tsx b/apps/gui/src/app/config/page.tsx index f87ce26..7be8fd1 100644 --- a/apps/gui/src/app/config/page.tsx +++ b/apps/gui/src/app/config/page.tsx @@ -31,6 +31,7 @@ export default function ConfigPage() { const [editName, setEditName] = useState(""); const [editProvider, setEditProvider] = useState("google-genai"); const [editKey, setEditKey] = useState(""); + const [editModel, setEditModel] = useState("gemini-2.5-flash"); const [editIsActive, setEditIsActive] = useState(false); useEffect(() => { @@ -38,6 +39,7 @@ export default function ConfigPage() { setEditName(""); setEditProvider("google-genai"); setEditKey(""); + setEditModel("gemini-2.5-flash"); setEditIsActive(false); } else { const inst = instances.find((i) => i.id === selectedInstanceId); @@ -45,6 +47,7 @@ export default function ConfigPage() { setEditName(inst.name); setEditProvider(inst.providerName); setEditKey(""); + setEditModel(inst.modelName || "gemini-2.5-flash"); setEditIsActive(inst.isActive); } } @@ -104,13 +107,13 @@ export default function ConfigPage() { setLoading(false); return; } - const created = await createProviderInstance(editName, editProvider, editKey); + const created = await createProviderInstance(editName, editProvider, editKey, editModel || undefined); if (editIsActive) { await setActiveProviderInstance(created.id); } setSelectedInstanceId(created.id); } else { - await updateProviderInstance(selectedInstanceId, editName, editProvider, editKey || undefined); + await updateProviderInstance(selectedInstanceId, editName, editProvider, editKey || undefined, editModel || undefined); if (editIsActive) { await setActiveProviderInstance(selectedInstanceId); } @@ -251,6 +254,17 @@ export default function ConfigPage() { /> +
+ + setEditModel(e.target.value)} + placeholder="e.g. gemini-2.5-flash, gemini-2.5-pro" + /> +
+
{ - return ProviderManager.create(name, providerName, apiKey); + return ProviderManager.create(name, providerName, apiKey, modelName); } export async function deleteProviderInstance(id: string): Promise { @@ -259,8 +260,9 @@ export async function updateProviderInstance( name: string, providerName: string, apiKey?: string, + modelName?: string, ): Promise { - ProviderManager.update(id, name, providerName, apiKey); + ProviderManager.update(id, name, providerName, apiKey, modelName); } export async function getProviderMappings(): Promise> { diff --git a/apps/gui/src/lib/provider-manager.ts b/apps/gui/src/lib/provider-manager.ts index 9eac049..54e441c 100644 --- a/apps/gui/src/lib/provider-manager.ts +++ b/apps/gui/src/lib/provider-manager.ts @@ -19,9 +19,16 @@ function getSettingsDb() { name TEXT NOT NULL, providerName TEXT NOT NULL, apiKey TEXT NOT NULL, - isActive INTEGER NOT NULL DEFAULT 0 + isActive INTEGER NOT NULL DEFAULT 0, + modelName TEXT ) `).run(); + + try { + db.prepare(`ALTER TABLE provider_instances ADD COLUMN modelName TEXT`).run(); + } catch { + // ignore + } return db; } @@ -36,6 +43,7 @@ export class ProviderManager { providerName: string; apiKey: string; isActive: number; + modelName?: string; }[]; return rows.map((r) => ({ id: r.id, @@ -43,13 +51,14 @@ export class ProviderManager { providerName: r.providerName, apiKey: r.apiKey, isActive: r.isActive === 1, + modelName: r.modelName || undefined, })); } finally { db.close(); } } - static create(name: string, providerName: string, apiKey: string): LLMProviderInstance { + static create(name: string, providerName: string, apiKey: string, modelName?: string): LLMProviderInstance { const db = getSettingsDb(); try { const id = "provider-" + Date.now(); @@ -57,11 +66,11 @@ export class ProviderManager { const isActive = activeCount.count === 0 ? 1 : 0; db.prepare(` - INSERT INTO provider_instances (id, name, providerName, apiKey, isActive) - VALUES (?, ?, ?, ?, ?) - `).run(id, name, providerName, apiKey, isActive); + INSERT INTO provider_instances (id, name, providerName, apiKey, isActive, modelName) + VALUES (?, ?, ?, ?, ?, ?) + `).run(id, name, providerName, apiKey, isActive, modelName || null); - return { id, name, providerName, apiKey, isActive: isActive === 1 }; + return { id, name, providerName, apiKey, isActive: isActive === 1, modelName }; } finally { db.close(); } @@ -94,21 +103,21 @@ export class ProviderManager { } } - static update(id: string, name: string, providerName: string, apiKey?: string): void { + static update(id: string, name: string, providerName: string, apiKey?: string, modelName?: string): void { const db = getSettingsDb(); try { if (apiKey && apiKey.trim()) { db.prepare(` UPDATE provider_instances - SET name = ?, providerName = ?, apiKey = ? + SET name = ?, providerName = ?, apiKey = ?, modelName = ? WHERE id = ? - `).run(name, providerName, apiKey, id); + `).run(name, providerName, apiKey, modelName || null, id); } else { db.prepare(` UPDATE provider_instances - SET name = ?, providerName = ? + SET name = ?, providerName = ?, modelName = ? WHERE id = ? - `).run(name, providerName, id); + `).run(name, providerName, modelName || null, id); } } finally { db.close(); @@ -124,6 +133,7 @@ export class ProviderManager { providerName: string; apiKey: string; isActive: number; + modelName?: string; } | undefined; if (!row) return null; return { @@ -132,6 +142,7 @@ export class ProviderManager { providerName: row.providerName, apiKey: row.apiKey, isActive: true, + modelName: row.modelName || undefined, }; } finally { db.close(); diff --git a/packages/llm/src/llm.ts b/packages/llm/src/llm.ts index 7c2550a..8e65d2c 100644 --- a/packages/llm/src/llm.ts +++ b/packages/llm/src/llm.ts @@ -43,4 +43,5 @@ export interface LLMProviderInstance { providerName: string; apiKey: string; isActive: boolean; + modelName?: string; } diff --git a/packages/llm/src/providers/google-genai.ts b/packages/llm/src/providers/google-genai.ts index 94faef9..83bff43 100644 --- a/packages/llm/src/providers/google-genai.ts +++ b/packages/llm/src/providers/google-genai.ts @@ -8,14 +8,14 @@ export class GeminiProvider implements ILLMProvider { private model: ChatGoogleGenerativeAI; lastCalls: LLMCallRecord[] = []; - constructor(apiKey?: string) { + constructor(apiKey?: string, modelName?: string) { const key = apiKey || llmConfig.GOOGLE_API_KEY; if (!key) { throw new Error("GOOGLE_API_KEY is required to initialize GeminiProvider"); } this.model = new ChatGoogleGenerativeAI({ apiKey: key, - model: "gemini-2.5-flash", + model: modelName || "gemini-2.5-flash", }); }