Each assistant card remembers its own conversation instead of every card resuming the newest one

This commit is contained in:
Gmer4Lfe
2026-08-22 08:46:35 -04:00
parent e5f4ede3f2
commit 5d42a28d34
+22 -2
View File
@@ -943,6 +943,14 @@ vv_ai_profiles_script();
// Per instance, like the reasoning key beside it: the Monitor card and a tab's assistant are // Per instance, like the reasoning key beside it: the Monitor card and a tab's assistant are
// opened for different reasons and should not share one answer to "pick up where I left off". // opened for different reasons and should not share one answer to "pick up where I left off".
const RESUME_KEY = 'vvAiResume:' + P; const RESUME_KEY = 'vvAiResume:' + P;
// WHICH thread this card was last on, per card. The chat store is shared on purpose — a
// conversation started on the dashboard is the one you carry on in a tab — but "resume" was
// resolved as "the newest thread in this profile", and Fallback, Partnership and Monitor all
// pin the same profile. Opening any of them dragged all three onto whichever had been typed
// in last, so two cards could never hold two different conversations. The pool below is still
// the shared list; this only decides which of it this card comes back to.
const LAST_CHAT_KEY = 'vvAiLastChat:' + P;
const rememberChat = id => { try { id ? localStorage.setItem(LAST_CHAT_KEY, id) : localStorage.removeItem(LAST_CHAT_KEY); } catch (_) {} };
const seeThink = () => { const c = $('see-think'); return !!c && c.checked; }; const seeThink = () => { const c = $('see-think'); return !!c && c.checked; };
// Paths ride in data attributes rather than an onclick. They come out of the index, and a // Paths ride in data attributes rather than an onclick. They come out of the index, and a
@@ -1518,7 +1526,7 @@ vv_ai_profiles_script();
messages: JSON.stringify(messages), messages: JSON.stringify(messages),
}) }) }) })
.then(r => r.json()) .then(r => r.json())
.then(d => { if (d.ok) { chatId = d.id; onChats(chatId); } }) .then(d => { if (d.ok) { chatId = d.id; rememberChat(chatId); onChats(chatId); } })
.catch(e => vvFetchErr('save conversation', e)); .catch(e => vvFetchErr('save conversation', e));
} }
@@ -1598,6 +1606,7 @@ vv_ai_profiles_script();
// end would send the model an empty history for a transcript full of context. // end would send the model an empty history for a transcript full of context.
sendFrom = 0; sendFrom = 0;
chatId = c.id || ''; chatId = c.id || '';
rememberChat(chatId);
lastSources = []; lastSources = [];
if (PROFILES[c.profile]) applyProfile(c.profile); if (PROFILES[c.profile]) applyProfile(c.profile);
render(); render();
@@ -1607,6 +1616,9 @@ vv_ai_profiles_script();
function newChat() { function newChat() {
messages = []; sendFrom = 0; chatId = ''; lastSources = []; messages = []; sendFrom = 0; chatId = ''; lastSources = [];
// Forget, so New means new on the next visit too. Without this the card would reopen the
// thread the operator had just deliberately stepped away from.
rememberChat('');
reset(); reset();
onChats(''); onChats('');
} }
@@ -2119,7 +2131,15 @@ vv_ai_profiles_script();
const pool = want ? d.chats.filter(c => (c.profile || 'chat') === want) : d.chats; const pool = want ? d.chats.filter(c => (c.profile || 'chat') === want) : d.chats;
if (!pool.length) return; if (!pool.length) return;
const last = pool.slice().sort((a, b) => (b.updated || 0) - (a.updated || 0))[0]; // This card's own last thread first, and only if it is still in the pool — deleted
// elsewhere, or moved to a profile this card does not show, both mean it is not ours to
// reopen. Newest-in-pool remains the answer for a first visit and for that case, which is
// what every card did unconditionally before.
let want_id = '';
try { want_id = localStorage.getItem(LAST_CHAT_KEY) || ''; } catch (_) {}
const mine = want_id ? pool.find(c => c.id === want_id) : null;
const last = mine || pool.slice().sort((a, b) => (b.updated || 0) - (a.updated || 0))[0];
if (last) loadChat(last.id); if (last) loadChat(last.id);
}).catch(e => vvFetchErr('resume conversation', e)); }).catch(e => vvFetchErr('resume conversation', e));
} }