← back to Wallco Ai
admin/inspiration/generate: actionable 503 when Ollama is unreachable + OLLAMA_HOST fallback
77613994bd487b17f3aa63e088b4190bb9336971 · 2026-05-19 14:30:38 -0700 · SteveStudio2
Was failing silently as a generic 500 on prod because the default Ollama URL (192.168.1.133:11434) is Mac1's LAN address — not routable from Kamatera. Now: explicit OLLAMA_URL wins, then OLLAMA_HOST, then the LAN fallback; the fetch is wrapped so the browser sees the URL tried + the fix hint instead of a bare 500.
Files touched
Diff
commit 77613994bd487b17f3aa63e088b4190bb9336971
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date: Tue May 19 14:30:38 2026 -0700
admin/inspiration/generate: actionable 503 when Ollama is unreachable + OLLAMA_HOST fallback
Was failing silently as a generic 500 on prod because the default Ollama URL (192.168.1.133:11434) is Mac1's LAN address — not routable from Kamatera. Now: explicit OLLAMA_URL wins, then OLLAMA_HOST, then the LAN fallback; the fetch is wrapped so the browser sees the URL tried + the fix hint instead of a bare 500.
---
src/admin.js | 45 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 34 insertions(+), 11 deletions(-)
diff --git a/src/admin.js b/src/admin.js
index b0ccbc8..c6ded1a 100644
--- a/src/admin.js
+++ b/src/admin.js
@@ -412,17 +412,40 @@ function mount(app) {
].join('\n');
const userMsg = `Aesthetic inspiration (names only):\n${scrubbedList}\n\nReturn a JSON array of 3 prompts.`;
- const ollamaUrl = process.env.OLLAMA_URL || 'http://192.168.1.133:11434';
- const ollResp = await fetch(`${ollamaUrl}/api/chat`, {
- method: 'POST', headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- model: process.env.OLLAMA_MODEL || 'qwen3:14b',
- messages: [{ role: 'system', content: sys }, { role: 'user', content: userMsg }],
- stream: false, options: { temperature: 0.7 }
- }),
- signal: AbortSignal.timeout(60_000)
- });
- const ollText = (await ollResp.json()).message?.content || '';
+ // Ollama URL — explicit OLLAMA_URL wins; else OLLAMA_HOST (host:port form
+ // used by the Mac1→Kamatera Tailscale bridge convention); else fall back to
+ // Mac1's LAN address, which prod CANNOT reach — so prod must set one of
+ // OLLAMA_URL / OLLAMA_HOST in wallco-ai/.env or the try/catch below fires
+ // with an actionable error (no more generic 500 on "Generate 3 originals").
+ const ollamaUrl = process.env.OLLAMA_URL
+ || (process.env.OLLAMA_HOST ? `http://${String(process.env.OLLAMA_HOST).replace(/^https?:\/\//, '')}` : null)
+ || 'http://192.168.1.133:11434';
+
+ let ollText;
+ try {
+ const ollResp = await fetch(`${ollamaUrl}/api/chat`, {
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ model: process.env.OLLAMA_MODEL || 'qwen3:14b',
+ messages: [{ role: 'system', content: sys }, { role: 'user', content: userMsg }],
+ stream: false, options: { temperature: 0.7 }
+ }),
+ signal: AbortSignal.timeout(60_000)
+ });
+ if (!ollResp.ok) {
+ return res.status(503).json({
+ error: 'ollama_http_error', status: ollResp.status, url: ollamaUrl,
+ });
+ }
+ ollText = (await ollResp.json()).message?.content || '';
+ } catch (e) {
+ return res.status(503).json({
+ error: 'ollama_unreachable',
+ url: ollamaUrl,
+ reason: String(e.message || e).slice(0, 200),
+ hint: 'Set OLLAMA_URL (or OLLAMA_HOST) in wallco-ai/.env. For prod use the Mac1→Kamatera Tailscale bridge: OLLAMA_URL=http://100.65.187.120:11435',
+ });
+ }
let prompts = [];
try {
const m = ollText.match(/\[\s*"[\s\S]*?"\s*\]/);
← 48f6b40 Fuzzy-design cull pipeline: Gemini classifier + viewer + app
·
back to Wallco Ai
·
/design page: show full palette as paint chips + paint strip b6b1b00 →