diff --git a/config.py b/config.py
index abe364b..89e8086 100644
--- a/config.py
+++ b/config.py
@@ -9,7 +9,7 @@ import logging
log = logging.getLogger("caic")
-VERSION = "v0.17.16"
+VERSION = "v0.17.17"
OLLAMA_BASE = os.environ.get("OLLAMA_BASE", "http://localhost:11434")
LLAMA_SERVER_BASE = os.environ.get("LLAMA_SERVER_BASE", "http://192.168.50.108:8081")
SEARXNG_BASE = "http://localhost:8888"
diff --git a/templates/index.html b/templates/index.html
index 1e31e49..40d7a38 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -98,7 +98,7 @@ body { font-family: var(--font-body); background: var(--bg-primary); color: var(
.badge.off { border-color:rgba(255,51,85,0.3); color:var(--danger); background:rgba(255,51,85,0.08); }
.badge.admin { border-color:var(--border); color:var(--text-muted); }
.badge.admin:hover { border-color:var(--accent-dim); color:var(--accent); }
-.status-dot { width:6px; height:6px; border-radius:50%; background:var(--success); display:inline-block; flex-shrink:0; }
+.role-label .msg-time { color:var(--text-muted); font-weight:400; font-size:10px; margin-left:6px; }
.status-dot.offline { background:var(--danger); }
.status-dot.warning { background:var(--warning); }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} }
@@ -409,7 +409,7 @@ body { font-family: var(--font-body); background: var(--bg-primary); color: var(
${role}
${content ? renderMarkdown(content) : ''}
${role === 'assistant' ? '
' : ''}
`;
+ const now = new Date();
+ const timeStr = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
+ div.innerHTML = `${role}${role === 'user' ? ' ' + timeStr + '' : ''}
${content ? renderMarkdown(content) : ''}
${role === 'assistant' ? '
' : ''}
`;
if (afterEl) {
afterEl.parentNode.insertBefore(div, afterEl.nextSibling);
} else {
@@ -1499,6 +1501,26 @@ function addMessageToolbar(msgDiv) {
URL.revokeObjectURL(a.href);
};
toolbar.append(copyBtn, printBtn, saveBtn, sep());
+ if (!msgDiv.classList.contains('search-result')) {
+ const rating = { value: 0 };
+ const upBtn = document.createElement('button');
+ upBtn.innerHTML = '👍';
+ upBtn.title = 'Rate up';
+ upBtn.onclick = () => {
+ rating.value = rating.value === 1 ? 0 : 1;
+ upBtn.classList.toggle('active', rating.value === 1);
+ dnBtn.classList.toggle('active', false);
+ };
+ const dnBtn = document.createElement('button');
+ dnBtn.innerHTML = '👎';
+ dnBtn.title = 'Rate down';
+ dnBtn.onclick = () => {
+ rating.value = rating.value === -1 ? 0 : -1;
+ dnBtn.classList.toggle('active', rating.value === -1);
+ upBtn.classList.toggle('active', false);
+ };
+ toolbar.append(upBtn, dnBtn);
+ }
function sep() { const s = document.createElement('span'); s.className = 'sep'; return s; }
}
@@ -1525,6 +1547,7 @@ let historyDraft = '';
userInput.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = Math.min(this.scrollHeight, 200) + 'px'; });
userInput.addEventListener('keydown', e => {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); return; }
+ if (e.key === 'Enter' && e.shiftKey) { e.preventDefault(); sendSearch(); return; }
if (e.key === 'ArrowUp') {
e.preventDefault();
if (messageHistory.length === 0) return;