mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-25 03:00:23 +00:00
feat(#524): add compress affordance to context ring tooltip
When context usage reaches 50% (yellow), a subtle hint button appears in the context ring tooltip suggesting /compress. At 75%+ (red), the hint intensifies with a warning style. Clicking the button pre-fills /compress into the composer and focuses it, so the user can add a focus topic or just hit send. No auto-fire — the user stays in control. - static/ui.js: conditional visibility + click handler in _syncCtxIndicator - static/index.html: ctxCompressBtn element inside ctxTooltip - static/style.css: muted button style, red variant for ctx-high - static/i18n.js: ctx_compress_hint / ctx_compress_action in all 7 locales Closes #524
This commit is contained in:
@@ -69,6 +69,8 @@ const LOCALES = {
|
||||
// commands.js
|
||||
cmd_clear: 'Clear conversation messages',
|
||||
cmd_compress: 'Manually compress conversation context (usage: /compress [focus topic])',
|
||||
ctx_compress_hint: 'Compress context to free up space →',
|
||||
ctx_compress_action: '⚠ Compress now to free context',
|
||||
cmd_compact_alias: 'Legacy alias for /compress',
|
||||
cmd_model: 'Switch model (e.g. /model gpt-4o)',
|
||||
cmd_workspace: 'Switch workspace by name',
|
||||
@@ -799,6 +801,8 @@ const LOCALES = {
|
||||
clarify_send: 'Отправить',
|
||||
cmd_compact_alias: 'Устаревший псевдоним для /compress',
|
||||
cmd_compress: 'Сжать контекст беседы (использование: /compress [тема])',
|
||||
ctx_compress_hint: 'Сжать контекст для освобождения места →',
|
||||
ctx_compress_action: '⚠ Сжать сейчас для освобождения контекста',
|
||||
command_label: 'Команда',
|
||||
compress_complete_label: 'Сжатие завершено',
|
||||
auto_compress_label: 'Автосжатие',
|
||||
@@ -1389,6 +1393,8 @@ const LOCALES = {
|
||||
cmd_help: 'Listar los comandos disponibles',
|
||||
cmd_clear: 'Borrar los mensajes de la conversación',
|
||||
cmd_compress: 'Comprimir manualmente el contexto de la conversación (uso: /compress [tema])',
|
||||
ctx_compress_hint: 'Comprimir contexto para liberar espacio →',
|
||||
ctx_compress_action: '⚠ Comprimir ahora para liberar contexto',
|
||||
cmd_compact_alias: 'Alias antiguo de /compress',
|
||||
cmd_compact: 'Comprimir contexto de la conversación',
|
||||
cmd_model: 'Cambiar de modelo (p. ej. /model gpt-4o)',
|
||||
@@ -2012,6 +2018,8 @@ const LOCALES = {
|
||||
archive_extracted: (n, c) => `${n} Datei(en) aus ${c} Archiv(en) entpackt`,
|
||||
cmd_clear: 'Konversationsverlauf löschen',
|
||||
cmd_compress: 'Kontext manuell komprimieren (Nutzung: /compress [Thema])',
|
||||
ctx_compress_hint: 'Kontext komprimieren um Platz zu schaffen →',
|
||||
ctx_compress_action: '⚠ Jetzt komprimieren um Kontext freizugeben',
|
||||
cmd_compact_alias: 'Alte Alias für /compress',
|
||||
cmd_model: 'Modell wechseln (z.B. /model gpt-4o)',
|
||||
cmd_workspace: 'Workspace nach Namen wechseln',
|
||||
@@ -2416,6 +2424,8 @@ const LOCALES = {
|
||||
cmd_help: '\u67e5\u770b\u53ef\u7528\u547d\u4ee4',
|
||||
cmd_clear: '\u6e05\u7a7a\u5f53\u524d\u5bf9\u8bdd\u6d88\u606f',
|
||||
cmd_compress: '\u624b\u52a8\u538b\u7f29\u5bf9\u8bdd\u4e0a\u4e0b\u6587\uff08\u7528\u6cd5\uff1a/compress [\u4e3b\u9898]\uff09',
|
||||
ctx_compress_hint: '\u538b\u7f29\u4e0a\u4e0b\u6587\u4ee5\u91ca\u653e\u7a7a\u95f4 →',
|
||||
ctx_compress_action: '\u26a0 \u7acb\u5373\u538b\u7f29\u4ee5\u91ca\u653e\u4e0a\u4e0b\u6587',
|
||||
cmd_compact_alias: '\u65e7\u522b\u540d\uff1a/compress',
|
||||
cmd_model: '\u5207\u6362\u6a21\u578b\uff08\u4f8b\u5982 /model gpt-4o\uff09',
|
||||
cmd_workspace: '\u6309\u540d\u79f0\u5207\u6362\u5de5\u4f5c\u533a',
|
||||
@@ -3033,6 +3043,8 @@ const LOCALES = {
|
||||
cmd_help: '\u67e5\u770b\u53ef\u7528\u547d\u4ee4',
|
||||
cmd_clear: '\u6e05\u7a7a\u7576\u524d\u5c0d\u8a71\u8a0a\u606f',
|
||||
cmd_compress: '\u624b\u52d5\u58d3\u7e2e\u5c0d\u8a71\u4e0a\u4e0b\u6587\uff08\u7528\u6cd5\uff1a/compress [\u4e3b\u984c]\uff09',
|
||||
ctx_compress_hint: '\u58d3\u7e2e\u4e0a\u4e0b\u6587\u4ee5\u91cb\u653e\u7a7a\u9593 →',
|
||||
ctx_compress_action: '\u26a0 \u7acb\u5373\u58d3\u7e2e\u4ee5\u91cb\u653e\u4e0a\u4e0b\u6587',
|
||||
cmd_compact_alias: '\u820a\u5225\u540d\uff1a/compress',
|
||||
cmd_model: '\u5207\u63db\u6a21\u578b\uff08\u4f8b\u5982 /model gpt-4o\uff09',
|
||||
cmd_workspace: '\u6309\u540d\u7a31\u5207\u63db\u5de5\u4f5c\u5340',
|
||||
@@ -3712,6 +3724,8 @@ const LOCALES = {
|
||||
// commands.js
|
||||
cmd_clear: '대화 메시지 지우기',
|
||||
cmd_compress: 'Manually compress conversation context (usage: /compress [focus topic])',
|
||||
ctx_compress_hint: '\ucee8\ud14d\uc2a4\ud2b8 \uc555\ucd95\ud558\uba70 \uacf5\uac04 \ud655\ubcf4 →',
|
||||
ctx_compress_action: '\u26a0 \uc9c0\uae08 \uc555\ucd95\ud558\uba70 \ucee8\ud14d\uc2a4\ud2b8 \ud655\ubcf4',
|
||||
cmd_compact_alias: 'Legacy alias for /compress',
|
||||
cmd_model: '모델 전환(예: /model gpt-4o)',
|
||||
cmd_workspace: '이름으로 워크스페이스 전환',
|
||||
|
||||
@@ -413,6 +413,9 @@
|
||||
<div class="ctx-tooltip-line" id="ctxTooltipTokens"></div>
|
||||
<div class="ctx-tooltip-line" id="ctxTooltipThreshold"></div>
|
||||
<div class="ctx-tooltip-line" id="ctxTooltipCost" style="display:none"></div>
|
||||
<div class="ctx-tooltip-compress" id="ctxTooltipCompress" style="display:none">
|
||||
<button class="ctx-compress-btn" id="ctxCompressBtn" type="button"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="bg-badge" id="bgBadge" style="display:none" title="Background tasks running">0</span>
|
||||
|
||||
@@ -726,6 +726,17 @@
|
||||
.ctx-indicator-wrap:hover .ctx-tooltip,.ctx-indicator-wrap:focus-within .ctx-tooltip{opacity:1;transform:translateY(0);}
|
||||
.ctx-tooltip-title{font-size:12px;font-weight:600;color:var(--text);margin-bottom:5px;}
|
||||
.ctx-tooltip-line+.ctx-tooltip-line{margin-top:3px;}
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
.ctx-tooltip-compress{margin-top:8px;padding-top:8px;border-top:1px solid var(--border2);}
|
||||
.ctx-compress-btn{width:100%;padding:6px 10px;border:1px solid var(--border2);border-radius:8px;background:rgba(255,255,255,.05);color:var(--text);font-size:11px;cursor:pointer;text-align:left;transition:background .15s,border-color .15s;}
|
||||
.ctx-compress-btn:hover{background:rgba(255,255,255,.1);border-color:var(--accent);}
|
||||
.ctx-indicator.ctx-high .ctx-compress-btn{border-color:var(--error);color:var(--error);}
|
||||
.ctx-indicator.ctx-high .ctx-compress-btn:hover{background:rgba(239,83,80,.12);}
|
||||
.cancel-btn{width:34px;height:34px;border-radius:50%;background:var(--error);border:none;color:#fff;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .15s,transform .15s,box-shadow .15s;box-shadow:0 2px 10px rgba(0,0,0,.18);}
|
||||
.cancel-btn:hover{background:var(--error);transform:scale(1.06);box-shadow:0 4px 14px rgba(0,0,0,.25);filter:brightness(1.1);}
|
||||
.cancel-btn:active{transform:scale(.96);}
|
||||
>>>>>>> 0a0513c (feat(#524): add compress affordance to context ring tooltip)
|
||||
.icon-btn{width:34px;height:34px;border-radius:8px;background:none;border:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:16px;transition:all .15s;}
|
||||
.icon-btn{opacity:.75;}
|
||||
.icon-btn:hover{background:rgba(255,255,255,.08);color:var(--text);opacity:1;}
|
||||
|
||||
@@ -641,6 +641,30 @@ function _syncCtxIndicator(usage){
|
||||
if(center) center.textContent=hasCtxWindow?String(pct):'\u00b7';
|
||||
el.classList.toggle('ctx-mid',pct>50&&pct<=75);
|
||||
el.classList.toggle('ctx-high',pct>75);
|
||||
// ── Compress affordance (#524) ──
|
||||
// Show a hint in the tooltip when context usage is high so users
|
||||
// discover /compress without having to know the slash command.
|
||||
const compressWrap=$('ctxTooltipCompress');
|
||||
const compressBtn=$('ctxCompressBtn');
|
||||
if(compressWrap&&compressBtn){
|
||||
if(pct>=75){
|
||||
compressWrap.style.display='';
|
||||
compressBtn.textContent=t('ctx_compress_action');
|
||||
compressBtn.onclick=function(){
|
||||
const ta=$('msg');
|
||||
if(ta){ta.value='/compress ';ta.focus();autoResize();}
|
||||
};
|
||||
}else if(pct>=50){
|
||||
compressWrap.style.display='';
|
||||
compressBtn.textContent=t('ctx_compress_hint');
|
||||
compressBtn.onclick=function(){
|
||||
const ta=$('msg');
|
||||
if(ta){ta.value='/compress ';ta.focus();autoResize();}
|
||||
};
|
||||
}else{
|
||||
compressWrap.style.display='none';
|
||||
}
|
||||
}
|
||||
let label=hasCtxWindow?`Context window ${pct}% used`:`${_fmtTokens(totalTok)} tokens used`;
|
||||
if(cost) label+=` \u00b7 $${cost<0.01?cost.toFixed(4):cost.toFixed(2)}`;
|
||||
el.setAttribute('aria-label',label);
|
||||
|
||||
Reference in New Issue
Block a user