From 452bf0e544eee974976e64851c7ee98472b6593f Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Mon, 3 Aug 2026 18:17:56 -0400 Subject: [PATCH] Route definitional questions to the narrative docs, and tolerate misspelling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "What is Varaverk" matched the PURPOSE intent, so retrieval returned every script's one-line purpose and the model answered that the context does not define the system — while README.md sat in the index unread. A definitional question with no explicit filter now goes to kind=readme. Varaverk is a coined word with no spell-check, so it arrives as varavrk, veraverk, varavek. Edit distance catches those without a pattern that needs extending per typo. This is search, not identity — a near-miss only widens a document search, unlike hostname resolution where it must never resolve. --- Plugin/unraid/Tools/ai_chat_worker.php | 9 +++++++- Plugin/unraid/include/ai.php | 29 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Plugin/unraid/Tools/ai_chat_worker.php b/Plugin/unraid/Tools/ai_chat_worker.php index 356647e..322a70b 100644 --- a/Plugin/unraid/Tools/ai_chat_worker.php +++ b/Plugin/unraid/Tools/ai_chat_worker.php @@ -107,6 +107,12 @@ $tRetrieve = 0.0; if ($profile === 'varaverk') { jw($jobFile, ['status' => 'retrieving']); + // A definitional question with no explicit filter goes to the narrative docs. Left alone, + // intent routing boosts PURPOSE and returns every script's one-line purpose, so the model + // reports that the context does not define Varaverk while README.md sits in the index + // unread. An explicit --kind from the user always wins. + if ($kind === '' && vv_ai_is_definitional($question)) $kind = 'readme'; + $r = vv_ai_retrieve($question, $kind); if (!$r['ok']) { jw($jobFile, ['status' => 'error', 'error' => $r['error'] ?? 'retrieval failed']); @@ -265,7 +271,8 @@ if ($diagBlock !== '') { // ignore. Detection only ever makes the model MORE cautious, so a false positive costs a // redirect rather than a wrong answer. if ($profile === 'chat' - && preg_match('/\b[\w.-]+\.sh\b|\b[A-Z][A-Z0-9]*(_[A-Z0-9]+)+\b|\bvaraverk\b/', $question)) { + && (vv_ai_mentions_varaverk($question) + || preg_match('/\b[\w.-]+\.sh\b|\b[A-Z][A-Z0-9]*(_[A-Z0-9]+)+\b/', $question))) { $system .= "NOTE: the operator's message appears to name a specific Varaverk component. " . "You cannot see the documentation in this mode, so you do not know what it does. " . "Say that plainly, point them at the Varaverk Assistant profile, and do not " diff --git a/Plugin/unraid/include/ai.php b/Plugin/unraid/include/ai.php index c0307cf..7f9c33e 100644 --- a/Plugin/unraid/include/ai.php +++ b/Plugin/unraid/include/ai.php @@ -453,6 +453,35 @@ function vv_ai_retrieve(string $query, string $kind = '', string $section = '', 'scanned' => $d['scanned'] ?? 0]; } +// ── Question shape ─────────────────────────────────────────────────────────────────────────── +// +// "Varaverk" is a coined word with no spell-check and an awkward keyboard shape, so it arrives +// misspelled often — varavrk, veraverk, varavek, varverk. Edit distance catches those without a +// hand-written pattern that would need extending every time a new typo appears. +// +// This is search, not identity. The rule against fuzzy hostname matching is about deciding which +// machine you are talking to, where a near-miss must never resolve; here a near-miss only widens +// a document search, and the cost of being wrong is a slightly odd set of passages. + +function vv_ai_mentions_varaverk(string $q): bool { + foreach (preg_split('/[^a-z0-9]+/i', mb_strtolower($q), -1, PREG_SPLIT_NO_EMPTY) as $w) { + if (strlen($w) < 5 || strlen($w) > 12) continue; // bound the comparison window + if ($w === 'varaverk' || levenshtein($w, 'varaverk') <= 2) return true; + } + return false; +} + +// "What is Varaverk", "explain varavrk", "whats this thing do". Intent routing boosts PURPOSE +// for these, which surfaces every script's one-line purpose and buries the top-level prose that +// actually defines the system — so the model answers that the context does not define it, while +// README.md sits in the index unread. +function vv_ai_is_definitional(string $q): bool { + if (!vv_ai_mentions_varaverk($q)) return false; + return (bool)preg_match( + '/\b(what\'?s?|whats|define|definition|describe|explain|overview|tell me about|' + . 'purpose of|point of|elevator|in a nutshell)\b/i', $q); +} + // ── Memory ─────────────────────────────────────────────────────────────────────────────────── // // A small operator-maintained file handed to the model at the start of every conversation.