Files
vas3k-TaxHacker/models/settings.ts
MaxP 8bcbf403d5 feat: add OpenAI Compatible LLM provider for local models (#81)
Support Ollama, LM Studio, vLLM, and any OpenAI-compatible API
  via a configurable base URL. Reuses ChatOpenAI with custom baseURL,
  no new dependencies. Local models use direct JSON parsing instead
  of withStructuredOutput since many don't support function calling.

Co-authored-by: FasterOP <7832832+mmplisskin@useres.noreply.github.com>
2026-03-31 10:43:58 +02:00

76 lines
2.3 KiB
TypeScript

import { prisma } from "@/lib/db"
import { PROVIDERS } from "@/lib/llm-providers"
import { cache } from "react"
import { LLMProvider } from "@/ai/providers/llmProvider"
export type SettingsMap = Record<string, string>
/**
* Helper to extract LLM provider settings from SettingsMap.
*/
export function getLLMSettings(settings: SettingsMap) {
const priorities = (settings.llm_providers || "openai,google,mistral,openai_compatible").split(",").map(p => p.trim()).filter(Boolean)
const providers = priorities.map((provider) => {
if (provider === "openai") {
return {
provider: provider as LLMProvider,
apiKey: settings.openai_api_key || "",
model: settings.openai_model_name || PROVIDERS[0]['defaultModelName'],
}
}
if (provider === "google") {
return {
provider: provider as LLMProvider,
apiKey: settings.google_api_key || "",
model: settings.google_model_name || PROVIDERS[1]['defaultModelName'],
}
}
if (provider === "mistral") {
return {
provider: provider as LLMProvider,
apiKey: settings.mistral_api_key || "",
model: settings.mistral_model_name || PROVIDERS[2]['defaultModelName'],
}
}
if (provider === "openai_compatible") {
const providerMeta = PROVIDERS.find(p => p.key === "openai_compatible")
return {
provider: provider as LLMProvider,
apiKey: settings.openai_compatible_api_key || "",
model: settings.openai_compatible_model_name || "",
baseUrl: settings.openai_compatible_base_url || providerMeta?.defaultBaseUrl || "",
}
}
return null
}).filter((provider): provider is NonNullable<typeof provider> => provider !== null)
return {
providers,
}
}
export const getSettings = cache(async (userId: string): Promise<SettingsMap> => {
const settings = await prisma.setting.findMany({
where: { userId },
})
return settings.reduce((acc, setting) => {
acc[setting.code] = setting.value || ""
return acc
}, {} as SettingsMap)
})
export const updateSettings = cache(async (userId: string, code: string, value: string | undefined) => {
return await prisma.setting.upsert({
where: { userId_code: { code, userId } },
update: { value },
create: {
code,
value,
name: code,
userId,
},
})
})