chore: version up to 2.80.35 and package with experience memory
This commit is contained in:
+52
-4
@@ -257,6 +257,37 @@
|
||||
});
|
||||
}
|
||||
|
||||
// ── "Record a lesson?" prompt (after a rollback / rejected change / repeated complaint) ──
|
||||
function renderLessonCandidate(v) {
|
||||
const t = v && v.trigger;
|
||||
const titleText = t === 'rejected'
|
||||
? '⚠ 방금 변경을 거부하셨네요 — 같은 실수를 반복하지 않게 교훈으로 기록할까요?'
|
||||
: t === 'qa-feedback'
|
||||
? '⚠ 같은 문제가 반복되는 것 같습니다 — 교훈으로 기록해두면 다음 작업 전에 자동으로 체크합니다.'
|
||||
: '⚠ 방금 작업이 롤백됐습니다 — 같은 실수를 반복하지 않게 교훈으로 기록할까요?';
|
||||
const reasonLine = v && v.reason ? `<div class="lc-reason">사유: ${escAttr(String(v.reason))}</div>` : '';
|
||||
// Reuse the active (or last) assistant bubble as the anchor; fall back to appending to the chat.
|
||||
let anchor = streamBody && streamBody._parent;
|
||||
if (!anchor) { const all = chat.querySelectorAll('.msg.msg-ai'); anchor = all[all.length - 1]; }
|
||||
const old = (anchor || chat).querySelector('.lesson-candidate-box');
|
||||
if (old) old.remove();
|
||||
const box = document.createElement('div');
|
||||
box.className = 'lesson-candidate-box';
|
||||
box.innerHTML =
|
||||
`<div class="lc-title">${escAttr(titleText)}</div>` +
|
||||
reasonLine +
|
||||
`<div class="lc-btns"><button class="lc-rec">📝 교훈 기록</button><button class="lc-skip">무시</button></div>`;
|
||||
box.querySelector('.lc-rec').onclick = () => { vscode.postMessage({ type: 'createLessonFromConversation' }); box.remove(); };
|
||||
box.querySelector('.lc-skip').onclick = () => box.remove();
|
||||
if (anchor) {
|
||||
const actions = anchor.querySelector('.msg-actions');
|
||||
if (actions) anchor.insertBefore(box, actions); else anchor.appendChild(box);
|
||||
} else {
|
||||
chat.appendChild(box);
|
||||
}
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
}
|
||||
|
||||
// ── Per-answer "scope used" footer ──────────────────────────────────
|
||||
const MEMORY_LAYER_LABELS = {
|
||||
'long-term-memory': '장기기억',
|
||||
@@ -278,7 +309,8 @@
|
||||
footer.className = 'msg-scope-footer';
|
||||
const files = Array.isArray(v.usedBrainFiles) ? v.usedBrainFiles : [];
|
||||
const layers = (Array.isArray(v.usedMemoryLayers) ? v.usedMemoryLayers : []).map(s => MEMORY_LAYER_LABELS[s] || s);
|
||||
if (files.length === 0 && layers.length === 0) {
|
||||
const lessons = Array.isArray(v.lessonFiles) ? v.lessonFiles : [];
|
||||
if (files.length === 0 && layers.length === 0 && lessons.length === 0) {
|
||||
footer.innerHTML = `<span class="scope-link" data-act="map" title="에이전트↔지식 매핑 편집">🔎 참조 지식 없음</span> <span class="scope-dim">— 모델 자체 지식으로 답변</span>`;
|
||||
} else {
|
||||
const dirs = Array.from(new Set(files.map(dirOf)));
|
||||
@@ -287,18 +319,31 @@
|
||||
scopeLabel = v.configuredFolders.join(', ');
|
||||
} else if (dirs.length) {
|
||||
scopeLabel = dirs.slice(0, 4).join(', ') + (dirs.length > 4 ? ` 외 ${dirs.length - 4}` : '');
|
||||
} else if (files.length === 0) {
|
||||
scopeLabel = '브레인 파일 없음';
|
||||
} else {
|
||||
scopeLabel = '전체 브레인';
|
||||
}
|
||||
const agentTag = v.agentName ? `[${escAttr(v.agentName)}] ` : '';
|
||||
const fileTag = files.length ? ` <span class="scope-dim">· 파일 ${files.length}</span>` : '';
|
||||
const layerTag = layers.length ? ` <span class="scope-dim">· 메모리 ${escAttr(layers.join('·'))}</span>` : '';
|
||||
const lessonTag = lessons.length ? ` <span class="scope-lesson" data-act="lessons" title="${escAttr('적용된 교훈 (클릭 → 교훈 관리):\n' + lessons.join('\n'))}">· ⚠ 교훈 ${lessons.length}</span>` : '';
|
||||
const titleAttr = files.length ? `사용된 브레인 파일:\n${files.join('\n')}` : '에이전트↔지식 매핑 편집';
|
||||
footer.innerHTML = `<span class="scope-link" data-act="map" title="${escAttr(titleAttr)}">🔎 참조: ${agentTag}${escAttr(scopeLabel)}</span>${fileTag}${layerTag}`;
|
||||
footer.innerHTML = `<span class="scope-link" data-act="map" title="${escAttr(titleAttr)}">🔎 참조: ${agentTag}${escAttr(scopeLabel)}</span>${fileTag}${lessonTag}${layerTag}`;
|
||||
}
|
||||
// Non-blocking flag: lesson Prevention-Checklist items the answer doesn't visibly address.
|
||||
const unaddressed = Array.isArray(v.unaddressedChecklist) ? v.unaddressedChecklist : [];
|
||||
if (unaddressed.length) {
|
||||
const list = unaddressed.map(it => `· ${escAttr(it)}`).join('<br>');
|
||||
const w = document.createElement('div');
|
||||
w.className = 'scope-unaddressed';
|
||||
w.innerHTML = `⚠ 답변에서 안 보이는 교훈 체크리스트 항목:<br>${list}`;
|
||||
footer.appendChild(w);
|
||||
}
|
||||
footer.addEventListener('click', e => {
|
||||
const t = e.target;
|
||||
if (t && t.dataset && t.dataset.act === 'map') vscode.postMessage({ type: 'editKnowledgeMap' });
|
||||
const act = e.target && e.target.dataset && e.target.dataset.act;
|
||||
if (act === 'map') vscode.postMessage({ type: 'editKnowledgeMap' });
|
||||
else if (act === 'lessons') vscode.postMessage({ type: 'manageLessons' });
|
||||
});
|
||||
const actions = target.querySelector('.msg-actions');
|
||||
if (actions) target.insertBefore(footer, actions); else target.appendChild(footer);
|
||||
@@ -587,6 +632,9 @@
|
||||
renderScopeFooter(target, msg.value || {});
|
||||
break;
|
||||
}
|
||||
case 'lessonCandidate':
|
||||
renderLessonCandidate(msg.value || {});
|
||||
break;
|
||||
case 'autoContinue':
|
||||
statusLabel.innerText = msg.value; thinkingBar.classList.add('active');
|
||||
if (msg.value.includes('Analyzing')) setStep('analyze');
|
||||
|
||||
Reference in New Issue
Block a user