Reload Ollama models on URL change, pre-select current model

- /api/ollama-models accepts optional url query param to query a different endpoint
- Frontend fetches models on load and on Ollama URL blur
- Keeps current model selected if available, otherwise selects first in list
- Shows loading indicator while fetching
This commit is contained in:
Oliver Hofmann 2026-04-28 09:07:53 +02:00
parent f22bad6496
commit 94368670b7
2 changed files with 34 additions and 7 deletions

View File

@ -112,8 +112,12 @@ async def update_settings(
return settings
@app.get("/api/ollama-models")
async def get_ollama_models(db: Session = Depends(get_db), _ = Depends(require_admin_auth)):
ollama_url = crud.get_setting(db, "ollama_url", "http://localhost:11434")
async def get_ollama_models(
url: str = None,
db: Session = Depends(get_db),
_ = Depends(require_admin_auth),
):
ollama_url = url or crud.get_setting(db, "ollama_url", "http://localhost:11434")
try:
async with httpx.AsyncClient(timeout=5.0) as client:
response = await client.get(f"{ollama_url}/api/tags")

View File

@ -51,20 +51,40 @@ const EMPTY_KEY_FORM = {
function SettingsSection({ password }) {
const [settings, setSettings] = useState(null);
const [availableModels, setAvailableModels] = useState([]);
const [modelsLoading, setModelsLoading] = useState(false);
const [proxyEndpoint, setProxyEndpoint] = useState(null);
const [saved, setSaved] = useState(false);
const [error, setError] = useState(null);
const fetchModels = async (url, currentModel) => {
setModelsLoading(true);
try {
const res = await axios.get('/api/ollama-models', {
headers: authHeaders(password),
params: url ? { url } : {},
});
const models = res.data.models;
setAvailableModels(models);
if (models.length > 0 && !models.includes(currentModel)) {
setSettings(s => ({ ...s, default_model: models[0] }));
}
} catch {
setAvailableModels([]);
} finally {
setModelsLoading(false);
}
};
useEffect(() => {
const headers = authHeaders(password);
Promise.all([
axios.get('/api/settings', { headers }),
axios.get('/api/ollama-models', { headers }),
axios.get('/api/proxy-info', { headers }),
]).then(([settingsRes, modelsRes, proxyRes]) => {
setSettings(settingsRes.data);
setAvailableModels(modelsRes.data.models);
]).then(([settingsRes, proxyRes]) => {
const s = settingsRes.data;
setSettings(s);
setProxyEndpoint(proxyRes.data.endpoint);
fetchModels(s.ollama_url, s.default_model);
}).catch(() => setError('Einstellungen konnten nicht geladen werden.'));
}, []);
@ -100,13 +120,16 @@ function SettingsSection({ password }) {
type="url"
value={settings.ollama_url}
onChange={(e) => setSettings({ ...settings, ollama_url: e.target.value })}
onBlur={(e) => fetchModels(e.target.value, settings.default_model)}
placeholder="http://localhost:11434"
required
/>
</div>
<div className="settings-row">
<label>Standard-Modell</label>
{availableModels.length > 0 ? (
{modelsLoading ? (
<span className="settings-value">Lade Modelle</span>
) : availableModels.length > 0 ? (
<select
value={settings.default_model}
onChange={(e) => setSettings({ ...settings, default_model: e.target.value })}