Reduce AI costs: switch tagging to gpt-4o-mini, add custom base URL support
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled

- Change AI tagging to use AI_MODELS.QUICK (gpt-4o-mini) instead of gpt-4o for
  10-15x cost reduction on classification tasks
- Add openai_base_url system setting for OpenAI-compatible providers
  (OpenRouter, Groq, Together AI, local models)
- Reset OpenAI client singleton when API key, base URL, or model changes
- Add base URL field to AI settings form with provider examples

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt
2026-02-16 15:34:59 +01:00
parent f12c29103c
commit 014bb15890
5 changed files with 74 additions and 4 deletions

View File

@@ -187,7 +187,25 @@ async function getOpenAIApiKey(): Promise<string | null> {
}
/**
* Create OpenAI client instance
* Get custom base URL for OpenAI-compatible providers.
* Supports OpenRouter, Together AI, Groq, local models, etc.
* Set via Settings → AI or OPENAI_BASE_URL env var.
*/
async function getBaseURL(): Promise<string | undefined> {
try {
const setting = await prisma.systemSettings.findUnique({
where: { key: 'openai_base_url' },
})
return setting?.value || process.env.OPENAI_BASE_URL || undefined
} catch {
return process.env.OPENAI_BASE_URL || undefined
}
}
/**
* Create OpenAI client instance.
* Supports custom baseURL for OpenAI-compatible providers
* (OpenRouter, Groq, Together AI, local models, etc.)
*/
async function createOpenAIClient(): Promise<OpenAI | null> {
const apiKey = await getOpenAIApiKey()
@@ -197,8 +215,15 @@ async function createOpenAIClient(): Promise<OpenAI | null> {
return null
}
const baseURL = await getBaseURL()
if (baseURL) {
console.log(`[OpenAI] Using custom base URL: ${baseURL}`)
}
return new OpenAI({
apiKey,
...(baseURL ? { baseURL } : {}),
})
}
@@ -221,6 +246,15 @@ export async function getOpenAI(): Promise<OpenAI | null> {
return client
}
/**
* Reset the OpenAI client singleton (e.g., after settings change).
* Next call to getOpenAI() will create a fresh client.
*/
export function resetOpenAIClient(): void {
globalForOpenAI.openai = undefined
globalForOpenAI.openaiInitialized = false
}
/**
* Check if OpenAI is configured and available
*/