diff --git a/config.py b/config.py index ba71e8c..ec9ef98 100644 --- a/config.py +++ b/config.py @@ -9,7 +9,7 @@ import logging log = logging.getLogger("jarvischat") -VERSION = "v1.8.7" +VERSION = "v1.8.8" 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 63c86cb..d640301 100644 --- a/templates/index.html +++ b/templates/index.html @@ -157,6 +157,12 @@ body { font-family: var(--font-body); background: var(--bg-primary); color: var( .perplexity-badge.low { background:rgba(46,204,113,0.15); border:1px solid rgba(46,204,113,0.3); color:var(--success); } .perplexity-badge.medium { background:rgba(243,156,18,0.15); border:1px solid rgba(243,156,18,0.3); color:var(--warning); } .perplexity-badge.high { background:rgba(231,76,60,0.15); border:1px solid rgba(231,76,60,0.3); color:var(--danger); } + +.ttr-badge { display:inline-block; padding:2px 8px; border-radius:10px; font-family:var(--font-mono); font-size:10px; margin-left:8px; } +.ttr-badge.low { background:rgba(46,204,113,0.15); border:1px solid rgba(46,204,113,0.3); color:var(--success); } +.ttr-badge.medium { background:rgba(243,156,18,0.15); border:1px solid rgba(243,156,18,0.3); color:var(--warning); } +.ttr-badge.high { background:rgba(231,76,60,0.15); border:1px solid rgba(231,76,60,0.3); color:var(--danger); } +.ttr-badge.search { background:rgba(230,126,34,0.15); border:1px solid rgba(230,126,34,0.3); color:#e67e22; } .tps-badge { display:inline-block; padding:2px 8px; border-radius:10px; font-family:var(--font-mono); font-size:10px; margin-left:8px; background:rgba(72,181,224,0.15); border:1px solid rgba(72,181,224,0.3); color:var(--accent); } .input-area { padding:16px 20px; border-top:1px solid var(--border); background:var(--bg-secondary); } @@ -1057,6 +1063,8 @@ async function sendSearch() { const textEl = assistantDiv.querySelector('.text'); textEl.innerHTML = '
Searching the web...
'; setStreamingState(true); + const ttrStart = performance.now(); + let ttr = 0; try { abortController = new AbortController(); const resp = await authFetch('/api/search', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ conversation_id: currentConvId, query, model }), signal: abortController.signal }); @@ -1078,7 +1086,7 @@ async function sendSearch() { if (data.error) { textEl.textContent = 'Error: ' + data.error; setStreamingState(false); return; } if (data.conversation_id && !currentConvId) { currentConvId = data.conversation_id; await loadConversations(); } if (data.search_results) { textEl.innerHTML = '
🔍 Found ' + data.search_results + ' results, summarizing...
'; } - if (data.token) { if (firstToken) { textEl.innerHTML = ''; firstToken = false; } fullText += data.token; textEl.innerHTML = renderMarkdown(fullText); scrollToBottom(); } + if (data.token) { if (firstToken) { textEl.innerHTML = ''; firstToken = false; ttr = performance.now() - ttrStart; } fullText += data.token; textEl.innerHTML = renderMarkdown(fullText); scrollToBottom(); } if (data.raw_results) { let rawHtml = '
🔍 View raw search results (' + data.raw_results.length + ')