fix: Ollama base URL not read from per-purpose config keys in Docker + i18n for all locales
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 44s

The admin form saves Ollama URLs as OLLAMA_BASE_URL_TAGS/EMBEDDING/CHAT,
but the factory only read OLLAMA_BASE_URL — causing 500 errors in Docker
where no localhost fallback exists.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-30 19:26:45 +02:00
parent a482aaaad6
commit 07f8a60b69
15 changed files with 15895 additions and 15455 deletions

View File

@@ -5,8 +5,8 @@ import { AIProvider } from './types';
type ProviderType = 'ollama' | 'openai' | 'custom' | 'deepseek' | 'openrouter';
function createOllamaProvider(config: Record<string, string>, modelName: string, embeddingModelName: string): OllamaProvider {
let baseUrl = config?.OLLAMA_BASE_URL || process.env.OLLAMA_BASE_URL
function createOllamaProvider(config: Record<string, string>, modelName: string, embeddingModelName: string, baseUrlOverride?: string): OllamaProvider {
let baseUrl = baseUrlOverride || config?.OLLAMA_BASE_URL || process.env.OLLAMA_BASE_URL
// Only use localhost as fallback for local development (not in Docker)
if (!baseUrl && process.env.NODE_ENV !== 'production') {
@@ -62,10 +62,10 @@ function createOpenRouterProvider(config: Record<string, string>, modelName: str
return new CustomOpenAIProvider(apiKey, 'https://openrouter.ai/api/v1', modelName, embeddingModelName);
}
function getProviderInstance(providerType: ProviderType, config: Record<string, string>, modelName: string, embeddingModelName: string): AIProvider {
function getProviderInstance(providerType: ProviderType, config: Record<string, string>, modelName: string, embeddingModelName: string, ollamaBaseUrl?: string): AIProvider {
switch (providerType) {
case 'ollama':
return createOllamaProvider(config, modelName, embeddingModelName);
return createOllamaProvider(config, modelName, embeddingModelName, ollamaBaseUrl);
case 'openai':
return createOpenAIProvider(config, modelName, embeddingModelName);
case 'custom':
@@ -75,7 +75,7 @@ function getProviderInstance(providerType: ProviderType, config: Record<string,
case 'openrouter':
return createOpenRouterProvider(config, modelName, embeddingModelName);
default:
return createOllamaProvider(config, modelName, embeddingModelName);
return createOllamaProvider(config, modelName, embeddingModelName, ollamaBaseUrl);
}
}
@@ -102,8 +102,9 @@ export function getTagsProvider(config?: Record<string, string>): AIProvider {
const provider = providerType.toLowerCase() as ProviderType;
const modelName = config?.AI_MODEL_TAGS || process.env.AI_MODEL_TAGS || 'granite4:latest';
const embeddingModelName = config?.AI_MODEL_EMBEDDING || process.env.AI_MODEL_EMBEDDING || 'embeddinggemma:latest';
const ollamaBaseUrl = config?.OLLAMA_BASE_URL_TAGS || config?.OLLAMA_BASE_URL;
return getProviderInstance(provider, config || {}, modelName, embeddingModelName);
return getProviderInstance(provider, config || {}, modelName, embeddingModelName, ollamaBaseUrl);
}
export function getEmbeddingsProvider(config?: Record<string, string>): AIProvider {
@@ -129,8 +130,9 @@ export function getEmbeddingsProvider(config?: Record<string, string>): AIProvid
const provider = providerType.toLowerCase() as ProviderType;
const modelName = config?.AI_MODEL_TAGS || process.env.AI_MODEL_TAGS || 'granite4:latest';
const embeddingModelName = config?.AI_MODEL_EMBEDDING || process.env.AI_MODEL_EMBEDDING || 'embeddinggemma:latest';
const ollamaBaseUrl = config?.OLLAMA_BASE_URL_EMBEDDING || config?.OLLAMA_BASE_URL;
return getProviderInstance(provider, config || {}, modelName, embeddingModelName);
return getProviderInstance(provider, config || {}, modelName, embeddingModelName, ollamaBaseUrl);
}
export function getAIProvider(config?: Record<string, string>): AIProvider {
@@ -167,6 +169,7 @@ export function getChatProvider(config?: Record<string, string>): AIProvider {
'granite4:latest'
);
const embeddingModelName = config?.AI_MODEL_EMBEDDING || process.env.AI_MODEL_EMBEDDING || 'embeddinggemma:latest';
const ollamaBaseUrl = config?.OLLAMA_BASE_URL_CHAT || config?.OLLAMA_BASE_URL_TAGS || config?.OLLAMA_BASE_URL_EMBEDDING || config?.OLLAMA_BASE_URL;
return getProviderInstance(provider, config || {}, modelName, embeddingModelName);
return getProviderInstance(provider, config || {}, modelName, embeddingModelName, ollamaBaseUrl);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff