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,
|
||||
taste: { styles: [], likes: [], avoid: [], notes: '', updated: 0 },
|
||||
streamEl: null,
|
||||
streamMeta: null,
|
||||
critiqueHopUsed: false,
|
||||
visionHopUsed: false,
|
||||
busyPhase: 'idle',
|
||||
@@ -1981,7 +1982,60 @@
|
||||
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');
|
||||
if (!box) {
|
||||
return null;
|
||||
@@ -1989,9 +2043,16 @@
|
||||
hideChatEmpty();
|
||||
const div = document.createElement('div');
|
||||
div.className = `sa-msg ${role}`;
|
||||
if (role === 'assistant') {
|
||||
mountAssistantMeta(div, meta);
|
||||
}
|
||||
const { prose, patch: extracted } = role === 'assistant' ? extractPatch(text) : { prose: text, patch: null };
|
||||
const finalPatch = patch || extracted;
|
||||
div.textContent = prose || text || '';
|
||||
if (role === 'assistant') {
|
||||
setAssistantBody(div, prose || text || '');
|
||||
} else {
|
||||
div.textContent = prose || text || '';
|
||||
}
|
||||
if (finalPatch) {
|
||||
const wrap = document.createElement('div');
|
||||
wrap.className = 'sa-patch';
|
||||
@@ -2009,7 +2070,7 @@
|
||||
return div;
|
||||
}
|
||||
|
||||
function beginStreamMessage() {
|
||||
function beginStreamMessage(meta) {
|
||||
const box = $('sa_messages');
|
||||
if (!box) {
|
||||
return null;
|
||||
@@ -2017,27 +2078,37 @@
|
||||
hideChatEmpty();
|
||||
const div = document.createElement('div');
|
||||
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.scrollTop = box.scrollHeight;
|
||||
state.streamEl = div;
|
||||
state.streamMeta = meta || null;
|
||||
return div;
|
||||
}
|
||||
|
||||
function appendStreamDelta(delta) {
|
||||
if (!state.streamEl) {
|
||||
beginStreamMessage();
|
||||
beginStreamMessage(state.streamMeta || undefined);
|
||||
}
|
||||
if (state.streamEl) {
|
||||
if (state.streamEl.classList.contains('sa-typing')) {
|
||||
state.streamEl.classList.remove('sa-typing');
|
||||
state.streamEl.textContent = '';
|
||||
setAssistantBody(state.streamEl, '');
|
||||
}
|
||||
state.gotDelta = true;
|
||||
if (state.busyPhase !== 'refining') {
|
||||
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');
|
||||
if (box) {
|
||||
box.scrollTop = box.scrollHeight;
|
||||
@@ -2047,14 +2118,18 @@
|
||||
|
||||
function finalizeStreamMessage(fullReply, civitaiResults) {
|
||||
const el = state.streamEl;
|
||||
const meta = state.streamMeta;
|
||||
state.streamEl = null;
|
||||
state.streamMeta = null;
|
||||
if (!el) {
|
||||
appendMessage('assistant', fullReply, null, civitaiResults);
|
||||
appendMessage('assistant', fullReply, null, civitaiResults, meta || undefined);
|
||||
return;
|
||||
}
|
||||
el.classList.remove('sa-streaming', 'sa-typing');
|
||||
mountAssistantMeta(el, meta || undefined);
|
||||
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) {
|
||||
const wrap = document.createElement('div');
|
||||
wrap.className = 'sa-patch';
|
||||
@@ -3294,6 +3369,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
const msgMeta = {
|
||||
persona: currentPersonaInfo(),
|
||||
pack,
|
||||
};
|
||||
state.history.push({ role: 'user', content: text });
|
||||
appendMessage('user', text);
|
||||
$('sa_input').value = '';
|
||||
@@ -3346,7 +3425,7 @@
|
||||
const finishOk = async (reply, civitaiResults) => {
|
||||
state.busy = false;
|
||||
setInterruptVisible(state.generating);
|
||||
state.history.push({ role: 'assistant', content: reply });
|
||||
state.history.push({ role: 'assistant', content: reply, persona, pack });
|
||||
stopBusyUi('Done');
|
||||
await handleReplySideEffects(reply, civitaiResults, {
|
||||
...opts,
|
||||
@@ -3362,15 +3441,16 @@
|
||||
if (state.streamEl) {
|
||||
state.streamEl.classList.remove('sa-streaming', 'sa-typing');
|
||||
state.streamEl.classList.add('error');
|
||||
state.streamEl.textContent = msg;
|
||||
setAssistantBody(state.streamEl, msg);
|
||||
state.streamEl = null;
|
||||
state.streamMeta = null;
|
||||
} else {
|
||||
appendMessage('error', msg);
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof makeWSRequest === 'function') {
|
||||
beginStreamMessage();
|
||||
beginStreamMessage(msgMeta);
|
||||
makeWSRequest(
|
||||
'AssistentChatWS',
|
||||
payload,
|
||||
@@ -3390,7 +3470,8 @@
|
||||
if (data.clear_stream) {
|
||||
if (state.streamEl) {
|
||||
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');
|
||||
return;
|
||||
@@ -3400,7 +3481,7 @@
|
||||
return;
|
||||
}
|
||||
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 || [];
|
||||
finalizeStreamMessage(reply, civitai);
|
||||
finishOk(reply, civitai);
|
||||
@@ -3413,6 +3494,7 @@
|
||||
if (state.streamEl) {
|
||||
state.streamEl.remove();
|
||||
state.streamEl = null;
|
||||
state.streamMeta = null;
|
||||
}
|
||||
genericRequest(
|
||||
'AssistentChat',
|
||||
@@ -3423,7 +3505,7 @@
|
||||
return;
|
||||
}
|
||||
const reply = data.reply || '';
|
||||
appendMessage('assistant', reply, null, data.civitai_results || []);
|
||||
appendMessage('assistant', reply, null, data.civitai_results || [], msgMeta);
|
||||
finishOk(reply, data.civitai_results || []);
|
||||
},
|
||||
0,
|
||||
@@ -3443,7 +3525,7 @@
|
||||
return;
|
||||
}
|
||||
const reply = data.reply || '';
|
||||
appendMessage('assistant', reply, null, data.civitai_results || []);
|
||||
appendMessage('assistant', reply, null, data.civitai_results || [], msgMeta);
|
||||
finishOk(reply, data.civitai_results || []);
|
||||
},
|
||||
0,
|
||||
|
||||
Reference in New Issue
Block a user