Give the AI subsystem one profile table and one collection, read everywhere
This commit is contained in:
@@ -57,10 +57,16 @@
|
||||
// vv_ai_chat_list_markup($prefix) the stored-conversations list container
|
||||
//
|
||||
// DEPENDS ON
|
||||
// api/ai.php ask / poll / clear / chats / chat_get / chat_save / chat_delete
|
||||
// api/readscript.php source viewer contents
|
||||
// include/ai_profiles.php the profile registry, served to the browser rather than restated
|
||||
// api/ai.php ask / poll / clear / chats / chat_get / chat_save / chat_delete
|
||||
// api/readscript.php source viewer contents
|
||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
// Required directly, not assumed. The Monitor tab pulls this file in without include/ai.php,
|
||||
// so relying on something else having loaded the registry first works on the AI tab and fatals
|
||||
// on the dashboard.
|
||||
require_once __DIR__ . '/ai_profiles.php';
|
||||
|
||||
// Emitted once even if two instances are rendered. A second copy of the script would re-register
|
||||
// the factories harmlessly but would also install a second Escape handler and a second copy of
|
||||
// every keyframe, so the guard is cheaper than reasoning about whether it matters.
|
||||
@@ -145,18 +151,41 @@ function vv_ai_chat_assets(): void {
|
||||
.vv-ai-hint { font-size:10px; color:#3a3a3a; margin-left:auto; }
|
||||
|
||||
/* ── Compact form, for a chat living inside a Monitor card ──────────────── */
|
||||
/* Not a different component — the same markup with the chrome pulled in. The card supplies its
|
||||
own heading and border, so the transcript drops its own and the hint text goes away rather
|
||||
than wrapping to three lines at this width. */
|
||||
.vv-ai-c .vv-ai-chat { border:none; border-radius:0; padding:10px 2px; min-height:0; }
|
||||
/* Not a different component — the same markup with the chrome pulled in. The card supplies the
|
||||
heading and the border, so the transcript drops its own and the hint text goes away rather
|
||||
than wrapping to three lines at this width.
|
||||
|
||||
Surfaces are re-based on the card, not merely un-bordered. The standalone palette paints a
|
||||
#0b0b0b transcript because on the AI tab it sits on the page ground with nothing beside it
|
||||
to compare against; dropped into a .vv-card (#1e1e1e) that same fill reads as a hole cut in
|
||||
the card rather than as part of it. Transparent here, and the remaining controls move to the
|
||||
values the plugin already uses inside a card — .vv-btn-sm is #2a2a2a on #555 — so the whole
|
||||
thing reads as one object.
|
||||
|
||||
This is the second hardcoded dark palette in the plugin, which is exactly one too many. When
|
||||
theming happens it wants tokens (--vv-surface, --vv-line) defined once in varaverk.css, and
|
||||
this block becomes a token swap instead of a second set of literals. */
|
||||
.vv-ai-c .vv-ai-chat { border:none; border-radius:0; padding:10px 2px; min-height:0;
|
||||
background:transparent; }
|
||||
.vv-ai-c .vv-ai-empty { padding:26px 14px; }
|
||||
.vv-ai-c .vv-ai-composer { border:none; padding:8px 0 0; background:none; }
|
||||
.vv-ai-c .vv-ai-input { min-height:44px; font-size:12px; padding:7px; }
|
||||
.vv-ai-c .vv-ai-prof { padding:3px 9px; font-size:10px; }
|
||||
.vv-ai-c .vv-ai-input { min-height:44px; font-size:12px; padding:7px;
|
||||
background:#161616; border-color:#333; }
|
||||
.vv-ai-c .vv-ai-input:focus { border-color:#6495ed; }
|
||||
.vv-ai-c .vv-ai-prof { padding:3px 9px; font-size:10px; background:#2a2a2a;
|
||||
border-color:#555; color:#ccc; }
|
||||
.vv-ai-c .vv-ai-prof:hover { border-color:#888; color:#fff; }
|
||||
.vv-ai-c .vv-ai-prof.active { background:#152238; border-color:#4a7ab0; color:#9bd; }
|
||||
.vv-ai-c .vv-ai-prof-hint { display:none; }
|
||||
.vv-ai-c .vv-ai-hint { display:none; }
|
||||
.vv-ai-c .vv-ai-btn { padding:4px 11px; font-size:11px; }
|
||||
.vv-ai-c .vv-ai-btn.ghost { border-color:#555; color:#ccc; }
|
||||
.vv-ai-c .vv-ai-msg { margin-bottom:12px; }
|
||||
.vv-ai-c .vv-ai-think { background:#161616; border-left-color:#3a3a3a; }
|
||||
.vv-ai-c .vv-ai-body pre { background:#161616; border-color:#3a3a3a; }
|
||||
.vv-ai-c .vv-ai-body code { background:#2a2a2a; }
|
||||
.vv-ai-c .vv-ai-src { border-top-color:#333; }
|
||||
.vv-ai-c .vv-ai-switch { border-top-color:#333; }
|
||||
|
||||
/* ── Stored conversations ───────────────────────────────────────────────── */
|
||||
.vv-ai-clist { display:flex; flex-direction:column; gap:1px; }
|
||||
@@ -171,6 +200,14 @@ function vv_ai_chat_assets(): void {
|
||||
.vv-ai-crow-x { font-size:11px; color:#333; flex-shrink:0; padding:0 2px; visibility:hidden; }
|
||||
.vv-ai-crow:hover .vv-ai-crow-x { visibility:visible; }
|
||||
.vv-ai-crow-x:hover { color:#e57; }
|
||||
/* Hover lifts off the card rather than sinking into it. #141414 is a highlight against the AI
|
||||
tab's #0e0e0e panel and a shadow against a #1e1e1e card — the same value reads as the
|
||||
opposite gesture depending on what it sits on. */
|
||||
.vv-ai-c .vv-ai-crow:hover { background:#2a2a2a; }
|
||||
.vv-ai-c .vv-ai-crow-t { color:#ccc; }
|
||||
.vv-ai-c .vv-ai-crow-m { color:#666; }
|
||||
.vv-ai-c .vv-ai-crow-x { color:#666; }
|
||||
.vv-ai-c .vv-ai-none { color:#666; }
|
||||
.vv-ai-chead { display:flex; align-items:center; gap:8px; margin-bottom:5px; }
|
||||
|
||||
/* ── Source overlay ─────────────────────────────────────────────────────── */
|
||||
@@ -195,21 +232,21 @@ function vv_ai_chat_assets(): void {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// The profile registry, served rather than restated. This used to be a literal table in the
|
||||
// script below that had already drifted from the PHP — it knew three profiles where the server
|
||||
// knew four, which is why troubleshoot could not be offered here and the Scheduler dock had to
|
||||
// hand-roll its own labels.
|
||||
vv_ai_profiles_script();
|
||||
?>
|
||||
<script>
|
||||
(function () {
|
||||
const API = '/plugins/varaverk/api/ai.php';
|
||||
|
||||
// Server-side is the authority on retrieval depth and history; these are for the UI only, and
|
||||
// they must not drift from VV_AI_PROFILES in api/ai.php.
|
||||
const PROFILES = {
|
||||
varaverk: { label: 'Varaverk Assistant', turns: 3, kind: true,
|
||||
hint: 'Answers only from Varaverk\'s own docs, with sources. Says so when they don\'t cover it.' },
|
||||
chat: { label: 'General Chat', turns: 8, kind: false,
|
||||
hint: 'Ordinary conversation. Hands anything about this install to the assistant on its own.' },
|
||||
code: { label: 'Code Sketcher', turns: 4, kind: false,
|
||||
hint: 'Drafts short scripts for Custom Scripts. First drafts — test before trusting.' },
|
||||
};
|
||||
window.VvAiProfiles = PROFILES;
|
||||
// The server is the authority. It re-derives depth and capability on every request regardless
|
||||
// of what is here — these values draw buttons and decide whether to show the kind filter, they
|
||||
// do not make policy.
|
||||
const PROFILES = window.VvAiProfiles;
|
||||
|
||||
const esc = s => String(s == null ? '' : s)
|
||||
.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')
|
||||
@@ -678,9 +715,9 @@ function vv_ai_chat_markup(string $prefix, array $o = []): void {
|
||||
<div class="vv-ai-chatwrap<?= $compact ? ' vv-ai-c' : '' ?>" style="display:flex;flex-direction:column;gap:<?= $compact ? '4px' : '12px' ?>;min-width:0;">
|
||||
|
||||
<div class="vv-ai-profiles" id="<?= $p ?>-profiles">
|
||||
<?php foreach (['varaverk' => 'Varaverk Assistant', 'chat' => 'General Chat',
|
||||
'code' => 'Code Sketcher'] as $key => $label): ?>
|
||||
<button class="vv-ai-prof" data-prof="<?= $key ?>" type="button"><?= $label ?></button>
|
||||
<?php foreach (vv_ai_profiles_ui() as $key => $def): ?>
|
||||
<button class="vv-ai-prof" data-prof="<?= htmlspecialchars($key, ENT_QUOTES) ?>" type="button"
|
||||
title="<?= htmlspecialchars($def['hint'], ENT_QUOTES) ?>"><?= htmlspecialchars($def['label']) ?></button>
|
||||
<?php endforeach; ?>
|
||||
<span class="vv-ai-prof-hint" id="<?= $p ?>-prof-hint"></span>
|
||||
</div>
|
||||
@@ -705,9 +742,12 @@ function vv_ai_chat_markup(string $prefix, array $o = []): void {
|
||||
|
||||
// The stored-conversations container. Rendered separately from the chat because the two live in
|
||||
// different cards on Monitor and in different parts of the column on the AI tab.
|
||||
function vv_ai_chat_list_markup(string $prefix): void {
|
||||
//
|
||||
// Takes compact for the same reason the chat does: these rows are painted against whatever they
|
||||
// sit on, and a card and a panel are not the same ground.
|
||||
function vv_ai_chat_list_markup(string $prefix, bool $compact = false): void {
|
||||
$p = htmlspecialchars($prefix, ENT_QUOTES);
|
||||
?>
|
||||
<div id="<?= $p ?>-chats"><div class="vv-ai-none">loading…</div></div>
|
||||
<div id="<?= $p ?>-chats"<?= $compact ? ' class="vv-ai-c"' : '' ?>><div class="vv-ai-none">loading…</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user