Notice when the question is about their own machine
The other detector recognises named components, so its complement is unbounded; this one reads grammar instead, which is not.
This commit is contained in:
@@ -1909,6 +1909,19 @@
|
|||||||
AI_WEB_SEARCH_RESULTS=4
|
AI_WEB_SEARCH_RESULTS=4
|
||||||
AI_WEB_SEARCH_TIMEOUT=6
|
AI_WEB_SEARCH_TIMEOUT=6
|
||||||
|
|
||||||
|
# ━━━ AI Chat Caution ━━━
|
||||||
|
# General Chat cannot see this installation, and web search gives it confident-sounding material
|
||||||
|
# about the outside world. The danger is the overlap: a question about THIS machine, answered
|
||||||
|
# from a general page about Unraid, reads exactly like an answer about this machine.
|
||||||
|
#
|
||||||
|
# Detection is grammatical rather than topical — possessives, "this box", state questions, "what
|
||||||
|
# happened last night" — because the topics are unbounded and the grammar is not. When it fires,
|
||||||
|
# chat keeps its caution and defers instead of answering from the web.
|
||||||
|
#
|
||||||
|
# Pipe-separated extra phrases for what grammar misses: a nickname for the box, a share name,
|
||||||
|
# anything that in practice means "mine". Matched as literal text, not as patterns.
|
||||||
|
AI_CHAT_MY_SYSTEM_PHRASES=""
|
||||||
|
|
||||||
# ━━━ AI Conf Write Access ━━━
|
# ━━━ AI Conf Write Access ━━━
|
||||||
# Separate switch from AI_ENABLED, off by default, and an explicit key whitelist. Never paths,
|
# Separate switch from AI_ENABLED, off by default, and an explicit key whitelist. Never paths,
|
||||||
# never credentials, never a container name. An empty whitelist means no writes regardless of
|
# never credentials, never a container name. An empty whitelist means no writes regardless of
|
||||||
|
|||||||
@@ -855,7 +855,7 @@ if ($profile === 'chat' && vv_ai_chat_needs_varaverk($question)) {
|
|||||||
//
|
//
|
||||||
// Deterministic on both sides: this fires only when detection says there is nothing Varaverk in
|
// Deterministic on both sides: this fires only when detection says there is nothing Varaverk in
|
||||||
// the question, so the cautious branch above keeps every question it would have caught.
|
// the question, so the cautious branch above keeps every question it would have caught.
|
||||||
} elseif ($profile === 'chat' && $webHave) {
|
} elseif ($profile === 'chat' && $webHave && !vv_ai_asks_about_this_system($question)) {
|
||||||
// Removes a false prohibition. It does NOT classify the question, and the first version of
|
// Removes a false prohibition. It does NOT classify the question, and the first version of
|
||||||
// this did: it told the model that nothing named a Varaverk component so this was a question
|
// this did: it told the model that nothing named a Varaverk component so this was a question
|
||||||
// about the wider world. That inference is not the detector's to make. The detector finds
|
// about the wider world. That inference is not the detector's to make. The detector finds
|
||||||
|
|||||||
@@ -112,6 +112,58 @@ function vv_ai_chat_needs_varaverk(string $question): bool {
|
|||||||
|| vv_ai_resolve_run_target($question) !== '';
|
|| vv_ai_resolve_run_target($question) !== '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is the operator asking about THEIR OWN machine, without naming anything on it?
|
||||||
|
//
|
||||||
|
// A different axis from vv_ai_chat_needs_varaverk(), and the reason that one cannot be extended
|
||||||
|
// to cover this. That detector recognises Varaverk-shaped tokens — a .sh file, a SCREAMING_CASE
|
||||||
|
// key, a run target — so its complement is every question that names none, which is unbounded.
|
||||||
|
// "why is my array so slow tonight", "how much space do I have left" and "is everything healthy"
|
||||||
|
// are all about this machine and contain nothing to detect. Enumerating that class topic by topic
|
||||||
|
// is endless; the operator referring to their own system is not, because it is grammar rather
|
||||||
|
// than subject matter. Possessives, this-machine deictics, state questions and questions about
|
||||||
|
// what happened here cover most of it in about a dozen patterns.
|
||||||
|
//
|
||||||
|
// Used to decide when NOT to relax the chat profile's caution. Wrong in the safe direction: a
|
||||||
|
// false positive costs a redirect to a profile that can actually see the machine, a false
|
||||||
|
// negative risks a general web page answered as though it described this installation.
|
||||||
|
function vv_ai_asks_about_this_system(string $question): bool {
|
||||||
|
$q = ' ' . mb_strtolower(trim($question)) . ' ';
|
||||||
|
|
||||||
|
$builtin = [
|
||||||
|
// Theirs, or the box in front of them.
|
||||||
|
'/\b(my|our|mine)\b/',
|
||||||
|
'/\bthis (box|server|machine|system|install(ation)?|setup|rig|host|array|pool|cache|node)\b/',
|
||||||
|
// State of something here. "is everything healthy", "are the containers up".
|
||||||
|
'/\b(is|are|was|were)\b[^.?!]{0,40}\b(health(y|ier)?|ok|okay|fine|up|down|running|stopped|'
|
||||||
|
. 'slow|fast|full|empty|broken|failing|stuck|degraded|offline|online)\b/',
|
||||||
|
// What happened here, and when.
|
||||||
|
'/\bwhat (happened|went wrong|is (going on|happening))\b/',
|
||||||
|
'/\b(last night|this morning|yesterday|today|tonight|right now|currently|at the moment)\b/',
|
||||||
|
// Capacity and load, which are only ever about the machine being asked from.
|
||||||
|
'/\bhow (much|many)\b[^.?!]{0,30}\b(space|room|ram|memory|disk|storage|free|left|used)\b/',
|
||||||
|
'/\bdo i have\b/',
|
||||||
|
// Ownership of running things.
|
||||||
|
'/\b(my|the) (containers?|dockers?|shares?|disks?|drives?|pools?|arrays?)\b/',
|
||||||
|
];
|
||||||
|
foreach ($builtin as $re) if (preg_match($re, $q)) return true;
|
||||||
|
|
||||||
|
// Operator-supplied phrases, for the ones grammar does not reach — a nickname for the box, a
|
||||||
|
// share name, whatever turns up in practice. Pipe-separated rather than a conf array because
|
||||||
|
// vv_conf_vars() reads scalars and hands back "(" for an array, and this needs to be readable
|
||||||
|
// at question time from a settings field the operator can edit.
|
||||||
|
//
|
||||||
|
// Matched as literal text, never as patterns. The field is editable from the settings UI, and
|
||||||
|
// a regex arriving from there would run against every question asked.
|
||||||
|
$extra = trim((string) (vv_conf_vars()['AI_CHAT_MY_SYSTEM_PHRASES'] ?? ''));
|
||||||
|
if ($extra !== '') {
|
||||||
|
foreach (explode('|', $extra) as $phrase) {
|
||||||
|
$phrase = mb_strtolower(trim($phrase));
|
||||||
|
if ($phrase !== '' && mb_strpos($q, $phrase) !== false) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Asking for a script to be written, as opposed to asking about one that exists. The verb is
|
// Asking for a script to be written, as opposed to asking about one that exists. The verb is
|
||||||
// required: "what does arr_sync.sh do" names a script and wants documentation, "write me a script
|
// required: "what does arr_sync.sh do" names a script and wants documentation, "write me a script
|
||||||
// that does X" names none and wants code. Getting that backwards in either direction is the whole
|
// that does X" names none and wants code. Getting that backwards in either direction is the whole
|
||||||
|
|||||||
@@ -434,6 +434,16 @@ Saved into `host1.conf`, which does not need to be opened by hand.
|
|||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `HOST1_ZFS_REPORT_IGNORE_POOLS` | a list, one entry per line | in this section | — |
|
| `HOST1_ZFS_REPORT_IGNORE_POOLS` | a list, one entry per line | in this section | — |
|
||||||
|
|
||||||
|
## AI Chat Caution
|
||||||
|
|
||||||
|
Route: AI tab → Settings → Configuration → *AI Chat Caution*
|
||||||
|
|
||||||
|
Saved into `master.conf`, which does not need to be opened by hand.
|
||||||
|
|
||||||
|
| Setting | Control | Where | What it does |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `AI_CHAT_MY_SYSTEM_PHRASES` | a text box | in this section | Pipe-separated extra phrases for what grammar misses: a nickname for the box, a share name, anything that in practice means "mine". Matched as literal text, not as patterns. |
|
||||||
|
|
||||||
## AI Conf Write Access
|
## AI Conf Write Access
|
||||||
|
|
||||||
Route: AI tab → Settings → Configuration → *AI Conf Write Access*
|
Route: AI tab → Settings → Configuration → *AI Conf Write Access*
|
||||||
|
|||||||
Reference in New Issue
Block a user