diff --git a/chat/public/builder.js b/chat/public/builder.js index 232379f..bd61b0a 100644 --- a/chat/public/builder.js +++ b/chat/public/builder.js @@ -107,6 +107,13 @@ function updateBuildModeUI(modeOverride) { async function proceedWithBuild(planContent) { if (!planContent) return; pendingPlanContent = planContent; + + // Show model selector when build confirmation modal opens + // This allows user to choose their model before starting the build + if (el.modelSelectWrap) { + el.modelSelectWrap.style.display = 'inline-flex'; + } + if (el.confirmBuildModal) { el.confirmBuildModal.style.display = 'flex'; } else { diff --git a/chat/server.js b/chat/server.js index d09049a..d7c9067 100644 --- a/chat/server.js +++ b/chat/server.js @@ -8561,7 +8561,12 @@ async function sendOllamaChat({ messages, model }) { const payload = { model: targetModel, prompt }; - const res = await fetch(endpoint, { method: 'POST', headers, body: JSON.stringify(payload) }); + const res = await fetch(endpoint, { + method: 'POST', + headers, + body: JSON.stringify(payload), + signal: AbortSignal.timeout(30000) // 30 second timeout to prevent 504 gateway timeouts + }); if (!res.ok) { let detail = ''; try { detail = await res.text(); } catch (_) { } @@ -9708,6 +9713,14 @@ function classifyProviderError(error, provider) { userError: [400, 413], notFound: 404 }, + ollama: { + transient: [500, 502, 503, 504, 529], + rateLimit: 429, + auth: 401, + permission: 403, + userError: [400], + notFound: 404 + }, default: { transient: [500, 502, 503, 529], rateLimit: 429,