diff --git a/Plugin/unraid/README-unraid.md b/Plugin/unraid/README-unraid.md index 602b07a..2dd390c 100644 --- a/Plugin/unraid/README-unraid.md +++ b/Plugin/unraid/README-unraid.md @@ -121,16 +121,23 @@ soon a page notices the writer's update. > cache miss. A key added to the endpoint and not to the writer leaves its card loading forever > on every ordinary page load and working only on the request that happens to miss. -**One widget, rendered twice.** `include/ai_chat.php` owns the conversation surface — profile -bar, transcript, composer, source viewer, stored-chat list — and both the AI tab and the Monitor -tab's AI row construct it. Every id is composed from a prefix so instances can coexist, and each -tears down the previous holder of its prefix, because Unraid swaps tab content by AJAX without -unloading the old page's JavaScript. +**One widget, rendered three times.** `include/ai_chat.php` owns the conversation surface — +transcript, composer, profile and history pickers, source viewer, stored-chat list — and the AI +tab, the Monitor tab's AI row and the Scheduler's right-hand panel all construct it. Every id is +composed from a prefix so instances can coexist, and each tears down the previous holder of its +prefix, because Unraid swaps tab content by AJAX without unloading the old page's JavaScript. -The Scheduler tab's dock is deliberately *not* built on it: a one-line bar that follows the view -you have open, with its own scope chip, fix flow and incident capture, is a different component -that happens to share an endpoint. Folding it in would produce one widget with two personalities -and a mode flag choosing between them. +A placement chooses how much room it gets and which extra controls it needs. It does not choose +the shape: the control row is fixed everywhere — profile chip hard left, `⤢` `▾` `New` `Ask` hard +right — because a chat that rearranges itself per tab is three components wearing one name. + +The Scheduler panel was exactly that until it was folded in, and it proved the cost: a thread +there died on reload while the other two were saved, and its bar had drifted into a different +shape from the same control everywhere else. What was genuinely particular to it became options +rather than a second implementation — `scope` as a function for a subject that follows the open +view, `beforeSend` for the one reply that is recorded rather than asked, `think` for reasoning on +diagnosis only, and `setHeights()` for a placement sized as a share of a panel, which is not a +number that exists until layout has run. **Timezone.** `include/config.php` adopts Unraid's own `timeZone` from `ident.cfg` for the whole PHP layer. PHP here has no `date.timezone` and therefore ran in UTC while the server ran local, diff --git a/Plugin/unraid/include/ai.php b/Plugin/unraid/include/ai.php index 93569cc..314c7ed 100644 --- a/Plugin/unraid/include/ai.php +++ b/Plugin/unraid/include/ai.php @@ -90,7 +90,7 @@ require_once __DIR__ . '/config.php'; const VV_AI_KINDS = ['header', 'readme', 'manual', 'template', 'doc', 'ui']; // Profiles — what each one is, and what it is allowed to see and do. One table, in one file, -// read by everything: this endpoint, the worker, the shared chat include and the Scheduler dock. +// read by everything: this endpoint, the worker, and the shared chat include every page renders. // vv_ai_profile_can() and friends come from there. require_once __DIR__ . '/ai_profiles.php'; @@ -816,7 +816,7 @@ function vv_ai_token_stats(): array { return $out; } -// ── Scoped lookups for the WebGUI dock ─────────────────────────────────────────────────────── +// ── Scoped lookups for the Scheduler's assistant ────────────────────────────────────────────── // The tail of one named script's log, for the troubleshooting profile. vv_ai_recent_logs() // answers "is anything wrong anywhere"; this answers "why did THIS fail", which is a different @@ -1308,11 +1308,11 @@ function vv_ai_chat_save(string $id, string $profile, array $messages, string $s $prev = vv_ai_chat_read($id); $created = (int)($prev['created'] ?? time()); - // Scope travels with the conversation. A Scheduler dock thread is bound to what the operator - // had open — a script, a log, a conf key — and its turns carry log excerpts chosen for that + // Scope travels with the conversation. A Scheduler thread is bound to what the operator had + // open — a script, a log, a conf key — and its turns carry log excerpts chosen for that // thing. Storing the scope means reopening the thread anywhere restores the context it was // reasoned in, rather than silently continuing a troubleshooting conversation against - // whatever happens to be on screen. The isolation the dock enforces in memory becomes a + // whatever happens to be on screen. The isolation the page enforces in memory becomes a // property of the record instead of something lost the moment it is saved. $rec = [ 'id' => $id, diff --git a/Plugin/unraid/include/ai_profiles.php b/Plugin/unraid/include/ai_profiles.php index 04d25f7..52c8c78 100644 --- a/Plugin/unraid/include/ai_profiles.php +++ b/Plugin/unraid/include/ai_profiles.php @@ -2,7 +2,8 @@ // ═══════════════════════════════════════════════════════════════════════════════════════════════ // PURPOSE // The one definition of what an AI profile is. Every consumer — the endpoint, the worker, the -// shared chat include, the Scheduler dock — reads it from here instead of restating it. +// shared chat include and every page that renders it — reads it from here instead of +// restating it. // // WHY THIS EXISTS // A profile used to be defined in five places: history depth in api/ai.php, capabilities in @@ -187,9 +188,9 @@ function vv_ai_profiles_client(): array { // surfaces ask for it. Emitted as its own tag so any script block that consumes it stays pure // JavaScript and remains syntax-checkable outside PHP. // -// Both the shared chat include and the Scheduler dock call this. Before it existed the dock had -// its own literal `{ code: 'Code', troubleshoot: 'Troubleshoot' }` map, which is how a fourth -// copy of the profile list came to exist in the first place. +// The shared chat include calls this, as does any page emitting the registry ahead of it. Before +// it existed the Scheduler had its own literal `{ code: 'Code', troubleshoot: 'Troubleshoot' }` +// map, which is how a fourth copy of the profile list came to exist in the first place. function vv_ai_profiles_script(): void { static $done = false; if ($done) return; diff --git a/Plugin/unraid/pages/monitor.php b/Plugin/unraid/pages/monitor.php index b463473..8a8d04a 100644 --- a/Plugin/unraid/pages/monitor.php +++ b/Plugin/unraid/pages/monitor.php @@ -356,8 +356,9 @@ $_vv_doc_vars = array_merge(vv_conf_vars(), ['SCRIPTS_DIR' => SCRIPTS_DIR]); - +