fix(gateway-ui): preserve assistant overrides and bust stale cache

This commit is contained in:
William Valentin
2026-02-19 08:55:41 -08:00
parent 682154d9ec
commit 9799859eca
3 changed files with 39 additions and 12 deletions
+36 -7
View File
@@ -11,6 +11,8 @@ let _dashboardClient = null;
let _lastPlaybookRollbackPatches = null; let _lastPlaybookRollbackPatches = null;
let _lastBriefingTestAt = null; let _lastBriefingTestAt = null;
let _assistantSaveState = null; let _assistantSaveState = null;
let _lastAssistantConfig = null;
let _assistantManualOverrides = new Set();
function formatUptime(seconds) { function formatUptime(seconds) {
const d = Math.floor(seconds / 86400); const d = Math.floor(seconds / 86400);
@@ -77,7 +79,7 @@ function getAssistantStateSnapshot(configData) {
function buildPlaybookPatches(playbook) { function buildPlaybookPatches(playbook) {
if (playbook === 'executive') { if (playbook === 'executive') {
return { const patches = {
'automation.delivery_mode': 'announce', 'automation.delivery_mode': 'announce',
'automation.daily_briefing.enabled': true, 'automation.daily_briefing.enabled': true,
'memory.daily_log.enabled': true, 'memory.daily_log.enabled': true,
@@ -87,9 +89,13 @@ function buildPlaybookPatches(playbook) {
'tts.enabled_channels': [], 'tts.enabled_channels': [],
'server.queue.mode': 'interrupt', 'server.queue.mode': 'interrupt',
}; };
for (const key of _assistantManualOverrides) {
delete patches[key];
}
return patches;
} }
if (playbook === 'operator') { if (playbook === 'operator') {
return { const patches = {
'automation.delivery_mode': 'announce', 'automation.delivery_mode': 'announce',
'automation.daily_briefing.enabled': true, 'automation.daily_briefing.enabled': true,
'memory.daily_log.enabled': true, 'memory.daily_log.enabled': true,
@@ -98,8 +104,12 @@ function buildPlaybookPatches(playbook) {
'tts.enabled': false, 'tts.enabled': false,
'server.queue.mode': 'steer_backlog', 'server.queue.mode': 'steer_backlog',
}; };
for (const key of _assistantManualOverrides) {
delete patches[key];
}
return patches;
} }
return { const patches = {
'automation.delivery_mode': 'shared_session', 'automation.delivery_mode': 'shared_session',
'automation.daily_briefing.enabled': false, 'automation.daily_briefing.enabled': false,
'memory.daily_log.enabled': false, 'memory.daily_log.enabled': false,
@@ -108,6 +118,10 @@ function buildPlaybookPatches(playbook) {
'tts.enabled': false, 'tts.enabled': false,
'server.queue.mode': 'collect', 'server.queue.mode': 'collect',
}; };
for (const key of _assistantManualOverrides) {
delete patches[key];
}
return patches;
} }
function buildRollbackPatchesFromSnapshot(snapshot) { function buildRollbackPatchesFromSnapshot(snapshot) {
@@ -792,14 +806,19 @@ function updateAssistantHealth(configData) {
let patches = null; let patches = null;
if (action === 'toggle-announce') { if (action === 'toggle-announce') {
patches = { 'automation.delivery_mode': announce ? 'shared_session' : 'announce' }; patches = { 'automation.delivery_mode': announce ? 'shared_session' : 'announce' };
_assistantManualOverrides.add('automation.delivery_mode');
} else if (action === 'toggle-daily-briefing') { } else if (action === 'toggle-daily-briefing') {
patches = { 'automation.daily_briefing.enabled': !dailyBriefing }; patches = { 'automation.daily_briefing.enabled': !dailyBriefing };
_assistantManualOverrides.add('automation.daily_briefing.enabled');
} else if (action === 'toggle-memory-daily') { } else if (action === 'toggle-memory-daily') {
patches = { 'memory.daily_log.enabled': !memoryDaily }; patches = { 'memory.daily_log.enabled': !memoryDaily };
_assistantManualOverrides.add('memory.daily_log.enabled');
} else if (action === 'toggle-memory-proactive') { } else if (action === 'toggle-memory-proactive') {
patches = { 'memory.proactive_extract.enabled': !memoryProactive }; patches = { 'memory.proactive_extract.enabled': !memoryProactive };
_assistantManualOverrides.add('memory.proactive_extract.enabled');
} else if (action === 'toggle-tts') { } else if (action === 'toggle-tts') {
patches = { 'tts.enabled': !ttsEnabled }; patches = { 'tts.enabled': !ttsEnabled };
_assistantManualOverrides.add('tts.enabled');
} else if (action === 'test-daily-briefing') { } else if (action === 'test-daily-briefing') {
await triggerDailyBriefingTest(briefingName, statusEl); await triggerDailyBriefingTest(briefingName, statusEl);
} else if (action === 'playbook-executive') { } else if (action === 'playbook-executive') {
@@ -836,6 +855,7 @@ function updateAssistantHealth(configData) {
'automation.daily_briefing.output.peer': peer, 'automation.daily_briefing.output.peer': peer,
'automation.daily_briefing.enabled': true, 'automation.daily_briefing.enabled': true,
}; };
_assistantManualOverrides.add('automation.daily_briefing.enabled');
} }
if (!patches) {return;} if (!patches) {return;}
await applyAssistantPatch(patches, statusEl); await applyAssistantPatch(patches, statusEl);
@@ -845,8 +865,13 @@ function updateAssistantHealth(configData) {
updateServices(refreshed.services); updateServices(refreshed.services);
updateSessionAnalytics(refreshed.sessionAnalytics); updateSessionAnalytics(refreshed.sessionAnalytics);
updateContextHealth(refreshed.contextUsage); updateContextHealth(refreshed.contextUsage);
// Capture status message before re-render destroys the DOM element // Only re-render assistant controls from a confirmed config snapshot.
updateAssistantHealth(refreshed.config); if (refreshed.config) {
_lastAssistantConfig = refreshed.config;
updateAssistantHealth(_lastAssistantConfig);
} else if (_lastAssistantConfig) {
updateAssistantHealth(_lastAssistantConfig);
}
} }
}); });
}); });
@@ -980,7 +1005,8 @@ async function loadDashboard(el, client) {
updateContextHealth(slow.contextUsage); updateContextHealth(slow.contextUsage);
} }
if (slow?.config) { if (slow?.config) {
updateAssistantHealth(slow.config); _lastAssistantConfig = slow.config;
updateAssistantHealth(_lastAssistantConfig);
} }
// Fast refresh: 3 seconds for metrics, events, requests // Fast refresh: 3 seconds for metrics, events, requests
@@ -1012,7 +1038,8 @@ async function loadDashboard(el, client) {
updateContextHealth(data.contextUsage); updateContextHealth(data.contextUsage);
} }
if (data.config) { if (data.config) {
updateAssistantHealth(data.config); _lastAssistantConfig = data.config;
updateAssistantHealth(_lastAssistantConfig);
} }
}, 10000); }, 10000);
} }
@@ -1037,5 +1064,7 @@ export const DashboardPage = {
_lastPlaybookRollbackPatches = null; _lastPlaybookRollbackPatches = null;
_lastBriefingTestAt = null; _lastBriefingTestAt = null;
_assistantSaveState = null; _assistantSaveState = null;
_lastAssistantConfig = null;
_assistantManualOverrides = new Set();
}, },
}; };
+2 -4
View File
@@ -74,10 +74,8 @@
color: white; color: white;
} }
/* ---------- Hidden utility ---------- */ /* Tailwind provides .hidden natively — do NOT re-declare here.
.hidden { An !important rule would conflict with responsive overrides (md:flex). */
display: none !important;
}
/* ---------- Links ---------- */ /* ---------- Links ---------- */
a { a {
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE_NAME = 'flynn-webchat-v3'; const CACHE_NAME = 'flynn-webchat-v5';
const token = new URL(self.location.href).searchParams.get('token'); const token = new URL(self.location.href).searchParams.get('token');
const withToken = (path) => { const withToken = (path) => {
if (!token) { if (!token) {