fix(admin): LLM provider/model switching now reads DB overrides correctly

- get_llm_provider() now accepts provider + model args so DB overrides
  propagate through to all provider constructors (was always reading
  env vars, ignoring the admin UI selection)
- /test-llm replaced with lightweight ping (max_tokens=20) instead of
  running a full bill analysis; shows model name + reply, no truncation
- /api/settings/llm-models endpoint fetches available models live from
  each provider's API (OpenAI, Anthropic REST, Gemini, Ollama)
- Admin UI model picker dynamically populated from provider API;
  falls back to manual text input on error; Custom model name option kept
- Default Gemini model updated: gemini-1.5-pro → gemini-2.0-flash

Co-Authored-By: Jack Levy
This commit is contained in:
Jack Levy
2026-03-01 04:03:51 -05:00
parent 12a3eac48f
commit defc2c116d
6 changed files with 466 additions and 50 deletions

View File

@@ -9,6 +9,7 @@ import type {
MemberTrendScore,
MemberNewsArticle,
NewsArticle,
NotificationSettings,
PaginatedResponse,
SettingsData,
TrendScore,
@@ -111,6 +112,11 @@ export const searchAPI = {
apiClient.get<{ bills: Bill[]; members: Member[] }>("/api/search", { params: { q } }).then((r) => r.data),
};
export interface LLMModel {
id: string;
name: string;
}
// Settings
export const settingsAPI = {
get: () =>
@@ -119,6 +125,8 @@ export const settingsAPI = {
apiClient.put("/api/settings", { key, value }).then((r) => r.data),
testLLM: () =>
apiClient.post("/api/settings/test-llm").then((r) => r.data),
listModels: (provider: string) =>
apiClient.get<{ models: LLMModel[]; error?: string }>("/api/settings/llm-models", { params: { provider } }).then((r) => r.data),
};
export interface AdminUser {
@@ -139,6 +147,16 @@ export interface AnalysisStats {
remaining: number;
}
// Notifications
export const notificationsAPI = {
getSettings: () =>
apiClient.get<NotificationSettings>("/api/notifications/settings").then((r) => r.data),
updateSettings: (data: Partial<NotificationSettings>) =>
apiClient.put<NotificationSettings>("/api/notifications/settings", data).then((r) => r.data),
resetRssToken: () =>
apiClient.post<NotificationSettings>("/api/notifications/settings/rss-reset").then((r) => r.data),
};
// Admin
export const adminAPI = {
// Stats