Show persona and pack chips on assistant chat messages.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+98
-16
@@ -87,6 +87,7 @@
|
|||||||
inventoryFetchedAt: 0,
|
inventoryFetchedAt: 0,
|
||||||
taste: { styles: [], likes: [], avoid: [], notes: '', updated: 0 },
|
taste: { styles: [], likes: [], avoid: [], notes: '', updated: 0 },
|
||||||
streamEl: null,
|
streamEl: null,
|
||||||
|
streamMeta: null,
|
||||||
critiqueHopUsed: false,
|
critiqueHopUsed: false,
|
||||||
visionHopUsed: false,
|
visionHopUsed: false,
|
||||||
busyPhase: 'idle',
|
busyPhase: 'idle',
|
||||||
@@ -1981,7 +1982,60 @@
|
|||||||
await sendChat({ fromAutoCritique: true, forceSlotIds: [GEN_ID] });
|
await sendChat({ fromAutoCritique: true, forceSlotIds: [GEN_ID] });
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendMessage(role, text, patch, civitaiResults) {
|
function currentPersonaInfo() {
|
||||||
|
const id = ($('sa_persona')?.value || localStorage.getItem(LS_PERSONA) || 'neutral').trim() || 'neutral';
|
||||||
|
const known = (state.personas || []).find((p) => p && p.id === id);
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
title: (known && known.title) || ({
|
||||||
|
neutral: 'Нейтральный',
|
||||||
|
lewd: 'Пошляк',
|
||||||
|
aggressive: 'Агрессивный',
|
||||||
|
}[id] || id),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mountAssistantMeta(div, meta = {}) {
|
||||||
|
if (!div || div.querySelector('.sa-msg-meta')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const persona = meta.persona || currentPersonaInfo();
|
||||||
|
const pack = meta.pack || $('sa_pack')?.value || '';
|
||||||
|
div.dataset.persona = persona.id || 'neutral';
|
||||||
|
if (pack) {
|
||||||
|
div.dataset.pack = pack;
|
||||||
|
}
|
||||||
|
const row = document.createElement('div');
|
||||||
|
row.className = 'sa-msg-meta';
|
||||||
|
const chip = document.createElement('span');
|
||||||
|
chip.className = `sa-persona-mark sa-persona-${persona.id || 'neutral'}`;
|
||||||
|
chip.textContent = persona.title || persona.id;
|
||||||
|
chip.title = `Характер: ${persona.title || persona.id}${pack ? ` · режим ${pack}` : ''}`;
|
||||||
|
row.appendChild(chip);
|
||||||
|
if (pack && pack !== 'write_prompt') {
|
||||||
|
const packEl = document.createElement('span');
|
||||||
|
packEl.className = 'sa-pack-mark';
|
||||||
|
packEl.textContent = pack.replace(/_/g, ' ');
|
||||||
|
packEl.title = `Режим: ${pack}`;
|
||||||
|
row.appendChild(packEl);
|
||||||
|
}
|
||||||
|
div.insertBefore(row, div.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAssistantBody(div, text) {
|
||||||
|
if (!div) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let body = div.querySelector('.sa-msg-body');
|
||||||
|
if (!body) {
|
||||||
|
body = document.createElement('div');
|
||||||
|
body.className = 'sa-msg-body';
|
||||||
|
div.appendChild(body);
|
||||||
|
}
|
||||||
|
body.textContent = text || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendMessage(role, text, patch, civitaiResults, meta) {
|
||||||
const box = $('sa_messages');
|
const box = $('sa_messages');
|
||||||
if (!box) {
|
if (!box) {
|
||||||
return null;
|
return null;
|
||||||
@@ -1989,9 +2043,16 @@
|
|||||||
hideChatEmpty();
|
hideChatEmpty();
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.className = `sa-msg ${role}`;
|
div.className = `sa-msg ${role}`;
|
||||||
|
if (role === 'assistant') {
|
||||||
|
mountAssistantMeta(div, meta);
|
||||||
|
}
|
||||||
const { prose, patch: extracted } = role === 'assistant' ? extractPatch(text) : { prose: text, patch: null };
|
const { prose, patch: extracted } = role === 'assistant' ? extractPatch(text) : { prose: text, patch: null };
|
||||||
const finalPatch = patch || extracted;
|
const finalPatch = patch || extracted;
|
||||||
div.textContent = prose || text || '';
|
if (role === 'assistant') {
|
||||||
|
setAssistantBody(div, prose || text || '');
|
||||||
|
} else {
|
||||||
|
div.textContent = prose || text || '';
|
||||||
|
}
|
||||||
if (finalPatch) {
|
if (finalPatch) {
|
||||||
const wrap = document.createElement('div');
|
const wrap = document.createElement('div');
|
||||||
wrap.className = 'sa-patch';
|
wrap.className = 'sa-patch';
|
||||||
@@ -2009,7 +2070,7 @@
|
|||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginStreamMessage() {
|
function beginStreamMessage(meta) {
|
||||||
const box = $('sa_messages');
|
const box = $('sa_messages');
|
||||||
if (!box) {
|
if (!box) {
|
||||||
return null;
|
return null;
|
||||||
@@ -2017,27 +2078,37 @@
|
|||||||
hideChatEmpty();
|
hideChatEmpty();
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.className = 'sa-msg assistant sa-streaming sa-typing';
|
div.className = 'sa-msg assistant sa-streaming sa-typing';
|
||||||
div.innerHTML = '<span class="sa-dots" aria-hidden="true"><i></i><i></i><i></i></span><span class="sa-typing-label">Waiting for the model…</span>';
|
mountAssistantMeta(div, meta);
|
||||||
|
const body = document.createElement('div');
|
||||||
|
body.className = 'sa-msg-body';
|
||||||
|
body.innerHTML = '<span class="sa-dots" aria-hidden="true"><i></i><i></i><i></i></span><span class="sa-typing-label">Waiting for the model…</span>';
|
||||||
|
div.appendChild(body);
|
||||||
box.appendChild(div);
|
box.appendChild(div);
|
||||||
box.scrollTop = box.scrollHeight;
|
box.scrollTop = box.scrollHeight;
|
||||||
state.streamEl = div;
|
state.streamEl = div;
|
||||||
|
state.streamMeta = meta || null;
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendStreamDelta(delta) {
|
function appendStreamDelta(delta) {
|
||||||
if (!state.streamEl) {
|
if (!state.streamEl) {
|
||||||
beginStreamMessage();
|
beginStreamMessage(state.streamMeta || undefined);
|
||||||
}
|
}
|
||||||
if (state.streamEl) {
|
if (state.streamEl) {
|
||||||
if (state.streamEl.classList.contains('sa-typing')) {
|
if (state.streamEl.classList.contains('sa-typing')) {
|
||||||
state.streamEl.classList.remove('sa-typing');
|
state.streamEl.classList.remove('sa-typing');
|
||||||
state.streamEl.textContent = '';
|
setAssistantBody(state.streamEl, '');
|
||||||
}
|
}
|
||||||
state.gotDelta = true;
|
state.gotDelta = true;
|
||||||
if (state.busyPhase !== 'refining') {
|
if (state.busyPhase !== 'refining') {
|
||||||
setBusyPhase('streaming');
|
setBusyPhase('streaming');
|
||||||
}
|
}
|
||||||
state.streamEl.textContent += delta;
|
let body = state.streamEl.querySelector('.sa-msg-body');
|
||||||
|
if (!body) {
|
||||||
|
setAssistantBody(state.streamEl, '');
|
||||||
|
body = state.streamEl.querySelector('.sa-msg-body');
|
||||||
|
}
|
||||||
|
body.textContent += delta;
|
||||||
const box = $('sa_messages');
|
const box = $('sa_messages');
|
||||||
if (box) {
|
if (box) {
|
||||||
box.scrollTop = box.scrollHeight;
|
box.scrollTop = box.scrollHeight;
|
||||||
@@ -2047,14 +2118,18 @@
|
|||||||
|
|
||||||
function finalizeStreamMessage(fullReply, civitaiResults) {
|
function finalizeStreamMessage(fullReply, civitaiResults) {
|
||||||
const el = state.streamEl;
|
const el = state.streamEl;
|
||||||
|
const meta = state.streamMeta;
|
||||||
state.streamEl = null;
|
state.streamEl = null;
|
||||||
|
state.streamMeta = null;
|
||||||
if (!el) {
|
if (!el) {
|
||||||
appendMessage('assistant', fullReply, null, civitaiResults);
|
appendMessage('assistant', fullReply, null, civitaiResults, meta || undefined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
el.classList.remove('sa-streaming', 'sa-typing');
|
el.classList.remove('sa-streaming', 'sa-typing');
|
||||||
|
mountAssistantMeta(el, meta || undefined);
|
||||||
const { prose, patch } = extractPatch(fullReply);
|
const { prose, patch } = extractPatch(fullReply);
|
||||||
el.textContent = prose || fullReply || '';
|
setAssistantBody(el, prose || fullReply || '');
|
||||||
|
el.querySelectorAll('.sa-patch, .sa-civitai-list').forEach((n) => n.remove());
|
||||||
if (patch) {
|
if (patch) {
|
||||||
const wrap = document.createElement('div');
|
const wrap = document.createElement('div');
|
||||||
wrap.className = 'sa-patch';
|
wrap.className = 'sa-patch';
|
||||||
@@ -3294,6 +3369,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const msgMeta = {
|
||||||
|
persona: currentPersonaInfo(),
|
||||||
|
pack,
|
||||||
|
};
|
||||||
state.history.push({ role: 'user', content: text });
|
state.history.push({ role: 'user', content: text });
|
||||||
appendMessage('user', text);
|
appendMessage('user', text);
|
||||||
$('sa_input').value = '';
|
$('sa_input').value = '';
|
||||||
@@ -3346,7 +3425,7 @@
|
|||||||
const finishOk = async (reply, civitaiResults) => {
|
const finishOk = async (reply, civitaiResults) => {
|
||||||
state.busy = false;
|
state.busy = false;
|
||||||
setInterruptVisible(state.generating);
|
setInterruptVisible(state.generating);
|
||||||
state.history.push({ role: 'assistant', content: reply });
|
state.history.push({ role: 'assistant', content: reply, persona, pack });
|
||||||
stopBusyUi('Done');
|
stopBusyUi('Done');
|
||||||
await handleReplySideEffects(reply, civitaiResults, {
|
await handleReplySideEffects(reply, civitaiResults, {
|
||||||
...opts,
|
...opts,
|
||||||
@@ -3362,15 +3441,16 @@
|
|||||||
if (state.streamEl) {
|
if (state.streamEl) {
|
||||||
state.streamEl.classList.remove('sa-streaming', 'sa-typing');
|
state.streamEl.classList.remove('sa-streaming', 'sa-typing');
|
||||||
state.streamEl.classList.add('error');
|
state.streamEl.classList.add('error');
|
||||||
state.streamEl.textContent = msg;
|
setAssistantBody(state.streamEl, msg);
|
||||||
state.streamEl = null;
|
state.streamEl = null;
|
||||||
|
state.streamMeta = null;
|
||||||
} else {
|
} else {
|
||||||
appendMessage('error', msg);
|
appendMessage('error', msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof makeWSRequest === 'function') {
|
if (typeof makeWSRequest === 'function') {
|
||||||
beginStreamMessage();
|
beginStreamMessage(msgMeta);
|
||||||
makeWSRequest(
|
makeWSRequest(
|
||||||
'AssistentChatWS',
|
'AssistentChatWS',
|
||||||
payload,
|
payload,
|
||||||
@@ -3390,7 +3470,8 @@
|
|||||||
if (data.clear_stream) {
|
if (data.clear_stream) {
|
||||||
if (state.streamEl) {
|
if (state.streamEl) {
|
||||||
state.streamEl.classList.add('sa-typing');
|
state.streamEl.classList.add('sa-typing');
|
||||||
state.streamEl.innerHTML = '<span class="sa-dots" aria-hidden="true"><i></i><i></i><i></i></span><span class="sa-typing-label">Refining…</span>';
|
const body = state.streamEl.querySelector('.sa-msg-body') || state.streamEl;
|
||||||
|
body.innerHTML = '<span class="sa-dots" aria-hidden="true"><i></i><i></i><i></i></span><span class="sa-typing-label">Refining…</span>';
|
||||||
}
|
}
|
||||||
setBusyPhase('refining');
|
setBusyPhase('refining');
|
||||||
return;
|
return;
|
||||||
@@ -3400,7 +3481,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data.done || data.reply != null) {
|
if (data.done || data.reply != null) {
|
||||||
const reply = data.reply || (state.streamEl && state.streamEl.textContent) || '';
|
const reply = data.reply || (state.streamEl?.querySelector('.sa-msg-body')?.textContent) || '';
|
||||||
const civitai = data.civitai_results || [];
|
const civitai = data.civitai_results || [];
|
||||||
finalizeStreamMessage(reply, civitai);
|
finalizeStreamMessage(reply, civitai);
|
||||||
finishOk(reply, civitai);
|
finishOk(reply, civitai);
|
||||||
@@ -3413,6 +3494,7 @@
|
|||||||
if (state.streamEl) {
|
if (state.streamEl) {
|
||||||
state.streamEl.remove();
|
state.streamEl.remove();
|
||||||
state.streamEl = null;
|
state.streamEl = null;
|
||||||
|
state.streamMeta = null;
|
||||||
}
|
}
|
||||||
genericRequest(
|
genericRequest(
|
||||||
'AssistentChat',
|
'AssistentChat',
|
||||||
@@ -3423,7 +3505,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const reply = data.reply || '';
|
const reply = data.reply || '';
|
||||||
appendMessage('assistant', reply, null, data.civitai_results || []);
|
appendMessage('assistant', reply, null, data.civitai_results || [], msgMeta);
|
||||||
finishOk(reply, data.civitai_results || []);
|
finishOk(reply, data.civitai_results || []);
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
@@ -3443,7 +3525,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const reply = data.reply || '';
|
const reply = data.reply || '';
|
||||||
appendMessage('assistant', reply, null, data.civitai_results || []);
|
appendMessage('assistant', reply, null, data.civitai_results || [], msgMeta);
|
||||||
finishOk(reply, data.civitai_results || []);
|
finishOk(reply, data.civitai_results || []);
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
|
|||||||
Reference in New Issue
Block a user