token count for search
This commit is contained in:
@@ -289,6 +289,67 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Cost Breakdown Styles */
|
||||
.cost-breakdown-details {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.cost-breakdown-summary {
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
padding: 12px 15px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
border-left: 4px solid #667eea;
|
||||
transition: background 0.2s;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.cost-breakdown-summary:hover {
|
||||
background: #e9ecef;
|
||||
}
|
||||
|
||||
.cost-breakdown-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cost-breakdown-content {
|
||||
padding: 15px;
|
||||
margin-top: 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.cost-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.cost-table th,
|
||||
.cost-table td {
|
||||
padding: 10px 12px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.cost-table th {
|
||||
background: #f8f9fa;
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.cost-table tr:last-child td {
|
||||
border-bottom: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.cost-table tbody tr:hover {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.error {
|
||||
background: #fee;
|
||||
color: #c00;
|
||||
@@ -464,6 +525,7 @@
|
||||
<button class="example-btn" onclick="setExample('Wie ist die Lage im Iran?')">Lage im Iran</button>
|
||||
<button class="example-btn" onclick="setExample('Welche KI Modelle wurden in den letzten Tagen veröffentlicht?')">Neue KI-Modelle</button>
|
||||
<button class="example-btn" onclick="setExample('Wie ist das Wetter in Dresden?')">Wetter in Dresden</button>
|
||||
<button class="example-btn" onclick="setExample('Was ist neu in React 19.2?')">React 19.2</button>
|
||||
</div>
|
||||
|
||||
<div class="search-box">
|
||||
@@ -493,6 +555,29 @@
|
||||
<h2>🔗 Most Relevant Sources</h2>
|
||||
<ul class="sources" id="sources"></ul>
|
||||
</div>
|
||||
|
||||
<!-- Cost Breakdown Section -->
|
||||
<div class="result-section">
|
||||
<details class="cost-breakdown-details" id="costBreakdownDetails">
|
||||
<summary class="cost-breakdown-summary">💰 Cost Breakdown</summary>
|
||||
<div class="cost-breakdown-content">
|
||||
<table class="cost-table" id="costTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Type</th>
|
||||
<th>Input</th>
|
||||
<th>Output</th>
|
||||
<th>Cost (USD)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="costTableBody">
|
||||
<!-- Cost rows will be inserted here -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Log Panel -->
|
||||
@@ -531,6 +616,10 @@
|
||||
// SSE connection
|
||||
let eventSource = null;
|
||||
let logEntries = [];
|
||||
|
||||
// Clarification state
|
||||
let isAwaitingClarification = false;
|
||||
let clarificationData = null;
|
||||
|
||||
function connectToSSE() {
|
||||
eventSource = new EventSource('/stream');
|
||||
@@ -679,8 +768,109 @@
|
||||
searchBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function performSearchWithClarification(clarificationText) {
|
||||
if (!clarificationData || !clarificationData.originalQuestion) {
|
||||
showError('Clarification data not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading
|
||||
hideError();
|
||||
hideResults();
|
||||
showLoading();
|
||||
|
||||
try {
|
||||
const response = await fetch('/search', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
question: clarificationData.originalQuestion + ' ' + clarificationText,
|
||||
previousClarification: clarificationText,
|
||||
originalQuestion: clarificationData.originalQuestion
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Search failed');
|
||||
}
|
||||
|
||||
displayResults(data);
|
||||
} catch (err) {
|
||||
showError(err.message);
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
function displayResults(data) {
|
||||
// Check if clarification is needed
|
||||
if (data.clarificationNeeded) {
|
||||
isAwaitingClarification = true;
|
||||
clarificationData = {
|
||||
originalQuestion: data.originalQuestion
|
||||
};
|
||||
|
||||
// Show clarification prompt in the answer area
|
||||
answerEl.innerHTML = `
|
||||
<div style="background: #fff3cd; padding: 20px; border-radius: 8px; border-left: 4px solid #ffc107;">
|
||||
<p style="margin-bottom: 15px; font-weight: 600;">${data.fullAnswerHTMLSnippet}</p>
|
||||
<input
|
||||
type="text"
|
||||
id="clarificationInput"
|
||||
class="search-input"
|
||||
style="margin-bottom: 10px;"
|
||||
>
|
||||
<button
|
||||
class="search-btn"
|
||||
id="clarificationSubmitBtn"
|
||||
style="padding: 10px 20px; font-size: 1rem;"
|
||||
>
|
||||
Submit Clarification
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Clear sources since we're waiting for clarification
|
||||
sourcesEl.innerHTML = '<li>Waiting for clarification...</li>';
|
||||
|
||||
// Add event listener for clarification submission
|
||||
setTimeout(() => {
|
||||
const clarificationInput = document.getElementById('clarificationInput');
|
||||
const clarificationSubmitBtn = document.getElementById('clarificationSubmitBtn');
|
||||
|
||||
if (clarificationInput && clarificationSubmitBtn) {
|
||||
clarificationInput.focus();
|
||||
|
||||
const handleClarification = () => {
|
||||
const clarificationText = clarificationInput.value.trim();
|
||||
if (clarificationText) {
|
||||
// Search again with the clarification
|
||||
performSearchWithClarification(clarificationText);
|
||||
}
|
||||
};
|
||||
|
||||
clarificationSubmitBtn.addEventListener('click', handleClarification);
|
||||
clarificationInput.addEventListener('keypress', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
handleClarification();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
|
||||
showResults();
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset clarification state for normal results
|
||||
isAwaitingClarification = false;
|
||||
clarificationData = null;
|
||||
|
||||
// Display answer as HTML
|
||||
answerEl.innerHTML = data.fullAnswerHTMLSnippet || '<p>No answer generated</p>';
|
||||
|
||||
@@ -703,6 +893,27 @@
|
||||
sourcesEl.appendChild(li);
|
||||
}
|
||||
|
||||
// Display cost breakdown
|
||||
const costTableBody = document.getElementById('costTableBody');
|
||||
costTableBody.innerHTML = '';
|
||||
if (data.costBreakdown && data.costBreakdown.length > 0) {
|
||||
data.costBreakdown.forEach(item => {
|
||||
const tr = document.createElement('tr');
|
||||
tr.innerHTML = `
|
||||
<td>${item.index}</td>
|
||||
<td>${item.type}</td>
|
||||
<td>${item.prompt_tokens || '-'}</td>
|
||||
<td>${item.completion_tokens || '-'}</td>
|
||||
<td>${item.cost}</td>
|
||||
`;
|
||||
costTableBody.appendChild(tr);
|
||||
});
|
||||
} else {
|
||||
const tr = document.createElement('tr');
|
||||
tr.innerHTML = '<td colspan="5">No cost data available</td>';
|
||||
costTableBody.appendChild(tr);
|
||||
}
|
||||
|
||||
showResults();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user