Route definitional questions to the narrative docs, and tolerate misspelling
"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.
This commit is contained in:
@@ -107,6 +107,12 @@ $tRetrieve = 0.0;
|
|||||||
if ($profile === 'varaverk') {
|
if ($profile === 'varaverk') {
|
||||||
jw($jobFile, ['status' => 'retrieving']);
|
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);
|
$r = vv_ai_retrieve($question, $kind);
|
||||||
if (!$r['ok']) {
|
if (!$r['ok']) {
|
||||||
jw($jobFile, ['status' => 'error', 'error' => $r['error'] ?? 'retrieval failed']);
|
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
|
// ignore. Detection only ever makes the model MORE cautious, so a false positive costs a
|
||||||
// redirect rather than a wrong answer.
|
// redirect rather than a wrong answer.
|
||||||
if ($profile === 'chat'
|
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. "
|
$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. "
|
. "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 "
|
. "Say that plainly, point them at the Varaverk Assistant profile, and do not "
|
||||||
|
|||||||
@@ -453,6 +453,35 @@ function vv_ai_retrieve(string $query, string $kind = '', string $section = '',
|
|||||||
'scanned' => $d['scanned'] ?? 0];
|
'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 ───────────────────────────────────────────────────────────────────────────────────
|
// ── Memory ───────────────────────────────────────────────────────────────────────────────────
|
||||||
//
|
//
|
||||||
// A small operator-maintained file handed to the model at the start of every conversation.
|
// A small operator-maintained file handed to the model at the start of every conversation.
|
||||||
|
|||||||
Reference in New Issue
Block a user