Give the wizard an assistant scoped to the step you are actually stuck on, so a first-run question can say "this" and mean something
This commit is contained in:
@@ -37,6 +37,12 @@
|
||||
// Step 2: auto-populate + guide + checklist.
|
||||
// master.conf pull (for partner servers) lives in the checklist, not here.
|
||||
|
||||
// The assistant is a bonus on this page, never a dependency: vv_ai_ui_on() is false on a node
|
||||
// with AI off or no model reachable, which is the normal state of the fresh install this wizard
|
||||
// exists to serve. The card simply is not rendered and setup proceeds exactly as before.
|
||||
require_once dirname(__DIR__) . '/include/ai_chat.php';
|
||||
if (vv_ai_ui_on()) vv_ai_chat_assets();
|
||||
|
||||
$detectedHostname = vv_get_hostname();
|
||||
|
||||
// ── Identity already on disk? ────────────────────────────────────────────────────────────────
|
||||
@@ -313,6 +319,21 @@ hr.vv-hr { border: none; border-top: 1px solid #1e1e1e; margin: 22px 0; }
|
||||
<div id="vv-onboard-panel"></div>
|
||||
<div id="vv-done-banner"></div>
|
||||
|
||||
<?php if (vv_ai_ui_on()): ?>
|
||||
<hr class="vv-hr">
|
||||
<div id="vv-su-ai-card">
|
||||
<?php vv_ai_chat_markup('vv-su-ai', [
|
||||
'profile' => 'varaverk',
|
||||
'compact' => true,
|
||||
'title' => 'Setup assistant',
|
||||
'height' => '260px',
|
||||
'tall' => '460px',
|
||||
'empty' => 'Stuck on a step? Ask what it wants and why — "what is the API key for", '
|
||||
. '"why does SSH need the other host", "what does populate actually do".',
|
||||
]); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="margin-top:18px;text-align:right;">
|
||||
<a href="#" id="vv-exit-link" onclick="vvGoNext(event)"
|
||||
style="font-size:11px;color:#3a3a3a;text-decoration:none;">Skip →</a>
|
||||
@@ -443,6 +464,7 @@ function vvShowStep2(redirect, apiKey) {
|
||||
_vvRedirect = redirect || '?tab=scheduler';
|
||||
document.getElementById('vv-step1').style.display = 'none';
|
||||
document.getElementById('vv-step2').style.display = 'block';
|
||||
vvSetupAiInit(); // card is visible now, so it can measure itself correctly
|
||||
if (apiKey && apiKey.ok) {
|
||||
const btn = document.getElementById('vv-key-btn');
|
||||
const status = document.getElementById('vv-key-status');
|
||||
@@ -676,6 +698,47 @@ function vvStartPhase2Watch(sinceMs) {
|
||||
_vvPartnerPoll = setInterval(check, 6000);
|
||||
}
|
||||
|
||||
// ── Setup assistant ───────────────────────────────────────────────────────────
|
||||
// Scoped to the step the operator is actually stuck on, so "what does this want" resolves without
|
||||
// them naming it. The worker turns a non-empty scope into a line saying what is open in the
|
||||
// WebGUI; the varaverk profile holds no scoped_log capability, so a checklist id never triggers a
|
||||
// log lookup and cannot produce a "log missing" note for something that was never a script.
|
||||
//
|
||||
// Re-read at send time, not captured: the checklist re-polls while the page is open and the step
|
||||
// they are on can change between opening the composer and pressing Ask.
|
||||
//
|
||||
// First not-ok, not-deferred item — deferred means "I have decided to skip this", which is not
|
||||
// where they are stuck. Falls back to the bare page when the list is clean or has not loaded.
|
||||
function vvSetupScope() {
|
||||
const d = _vvLastChecklist;
|
||||
if (!d || !Array.isArray(d.items)) return 'Setup';
|
||||
const stuck = d.items.find(i => !i.ok && !i.deferred);
|
||||
return stuck && stuck.id ? 'Setup/' + stuck.id : 'Setup';
|
||||
}
|
||||
|
||||
// Mounted when Step 2 is revealed, not at parse time. This is the only page where the card starts
|
||||
// inside a display:none block, and a chat that measured itself while hidden would come up wrong
|
||||
// with nothing to correct it — the component carries no resize observer. Idempotent because
|
||||
// vvShowStep2 is reachable more than once.
|
||||
let _vvSetupAiUp = false;
|
||||
function vvSetupAiInit() {
|
||||
if (_vvSetupAiUp) return;
|
||||
if (typeof VvAiChat !== 'function') return;
|
||||
if (!document.getElementById('vv-su-ai-chat')) return; // AI off — card was never rendered
|
||||
_vvSetupAiUp = true;
|
||||
VvAiChat({
|
||||
prefix: 'vv-su-ai',
|
||||
profile: 'varaverk',
|
||||
// Pinned, for the same reason the Partnership card pins it: resuming whatever thread was last
|
||||
// touched anywhere in the UI could land a first-run operator mid-way through someone else's
|
||||
// Scheduler conversation, on a card with no picker to get back from.
|
||||
resumeProfile: 'varaverk',
|
||||
scope: vvSetupScope,
|
||||
scopeLabel: 'Setup',
|
||||
empty: 'Stuck on a step? Ask what it wants and why.',
|
||||
});
|
||||
}
|
||||
|
||||
function vvLoadChecklist() {
|
||||
fetch('/plugins/varaverk/api/checklist.php?_=' + Date.now())
|
||||
.then(r => r.json()).then(d => {
|
||||
|
||||
Reference in New Issue
Block a user