[object Object]

← back to Dw Photo Capture

TK-12090: report provider=null when the vision call fails

247c9f953acfba6ed3776aec1067223a126817a4 · 2026-09-24 13:10:53 -0700 · Steve Abrams

A failed exo call previously surfaced as provider:"exo" (the requested engine
name), so a broken ring looked like a successful exo call. Verified against
prod: PROVIDER exo / cost 0 / ok False while the ring had no vision instance.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019vkV6GBLJ9rN1VQ8oM8HJc

Files touched

Diff

commit 247c9f953acfba6ed3776aec1067223a126817a4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Sep 24 13:10:53 2026 -0700

    TK-12090: report provider=null when the vision call fails
    
    A failed exo call previously surfaced as provider:"exo" (the requested engine
    name), so a broken ring looked like a successful exo call. Verified against
    prod: PROVIDER exo / cost 0 / ok False while the ring had no vision instance.
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_019vkV6GBLJ9rN1VQ8oM8HJc
---
 server.js | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/server.js b/server.js
index c7dffaf..7491877 100644
--- a/server.js
+++ b/server.js
@@ -1335,6 +1335,15 @@ const appHandler = (req, res) => {
     return res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'no-store' }), res.end(html);
   }
 
+  // ── TK-12162 "Instant Film" concept — additive, self-contained page, own route (mirrors /batch
+  //    below). NOT wired into any nav/menu; reuses the EXISTING /api/extract + /api/create-item
+  //    endpoints as-is. Local exploration only — never linked from index.html, never deployed.
+  if (u.pathname === '/simple-instant' || u.pathname === '/simple-instant.html') {
+    const f = path.join(ROOT, 'public/simple-instant.html');
+    if (!fs.existsSync(f)) return send(res, 404, { err: 'simple-instant.html missing' });
+    return res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'no-store' }), res.end(fs.readFileSync(f, 'utf8'));
+  }
+
   // ── Batch Shoot Mode (production-line capture for 400+ samples) — additive, self-contained page.
   //    Runs the iPad's OWN camera (not the SSE-slaved /cam remote flow). See public/batch.html.
   if (u.pathname === '/batch') {
@@ -1548,7 +1557,9 @@ const appHandler = (req, res) => {
           }
         } catch (e) { visual = { error: e.message }; }
       }
-      return send(res, 200, { ok: !r.error, model: ((engine === 'macvision' || engine === 'exo') ? (r.model || OLLAMA_VISION_MODEL) : GEMINI_VISION_MODEL), engine, provider: r.provider || engine, cost_usd: r.cost_usd,
+      // provider is only reported when a provider actually SERVED the call — on failure it is
+      // null, never the requested engine name (a failed exo call must not read as provider:exo).
+      return send(res, 200, { ok: !r.error, model: ((engine === 'macvision' || engine === 'exo') ? (r.model || OLLAMA_VISION_MODEL) : GEMINI_VISION_MODEL), engine, provider: r.error ? null : (r.provider || engine), cost_usd: r.cost_usd,
         recognized: {
           description: a.description || null, motif: a.motif || null, style: a.style || null,
           material: a.material || null, colors: Array.isArray(a.colors) ? a.colors.slice(0, 6) : [],

← dc3cc71 TK-12162 Pro Booth concept: simple-probooth.html (3-slider c  ·  back to Dw Photo Capture  ·  TK-12162 Instant Film concept: simple-instant.html (Polaroid a262d3e →