From 25c8c39ba6bcf13c0c2adebac1140256a26f3dcf Mon Sep 17 00:00:00 2001 From: BOHA Date: Mon, 8 Jun 2026 21:26:54 +0200 Subject: [PATCH] feat(odin): scope to invoice processing only (guard general chat) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Odin currently advertises general Q&A via the /chat path, which burns API credits on open-ended questions. Guard it: a text-only message makes NO AI call — it gets a canned reply telling the user to attach an invoice. The invoice path (attachments → extract) is unchanged. Removing the guard re-enables the general /chat path for a later phase. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/admin/components/odin/OdinChat.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/admin/components/odin/OdinChat.tsx b/src/admin/components/odin/OdinChat.tsx index 5e71e0c..b3e72ab 100644 --- a/src/admin/components/odin/OdinChat.tsx +++ b/src/admin/components/odin/OdinChat.tsx @@ -208,6 +208,24 @@ export default function OdinChat() { const files = attachments.map((a) => a.file); if (!text && files.length === 0) return; + // Guard: Odin is scoped to invoice processing only (for now). A text-only + // message makes NO AI call — it gets a canned reply locally, so open-ended + // chat can't burn API credits. The invoice path (attachments) runs normally. + // (Removing this guard re-enables the general /chat path below for Phase 2.) + if (files.length === 0) { + setTurns((t) => [ + ...t, + { role: "user", content: text }, + { + role: "assistant", + content: + "Momentálně umím zpracovat pouze přijaté faktury. Přiložte prosím fakturu (PDF) a já z ní načtu údaje k uložení.", + }, + ]); + setInput(""); + return; + } + setBusy(true); const prevTurns = turns;