feat: UI-Verbesserungen und Model-Informationen in Kostenaufschlüsselung

- Vorgeschlagene Folgesuchen im UI nach oben verschoben
- Spalte "Modell" zur Kostenaufschlüsselungstabelle hinzugefügt
- Modellnamen für OpenRouter-API-Aufrufe (Rephrase, Rank, Final Summary) ergänzt
- Datenstruktur für Kostenaufschlüsselung um Modell-Information erweitert
This commit is contained in:
sebseb7
2026-04-05 01:03:04 +02:00
parent e0a602135a
commit 88015fbcae
2 changed files with 16 additions and 8 deletions

View File

@@ -569,6 +569,11 @@
<div class="error" id="error"></div>
<div class="results" id="results">
<div class="result-section">
<h2>💡 Vorgeschlagene Folgesuchen</h2>
<div class="suggested-searches" id="suggestedSearches"></div>
</div>
<div class="result-section">
<h2>📝 Antwort</h2>
<div class="answer" id="answer"></div>
@@ -579,10 +584,6 @@
<ul class="sources" id="sources"></ul>
</div>
<div class="result-section">
<h2>💡 Vorgeschlagene Folgesuchen</h2>
<div class="suggested-searches" id="suggestedSearches"></div>
</div>
<!-- Cost Breakdown Section -->
<div class="result-section">
@@ -594,6 +595,7 @@
<tr>
<th>#</th>
<th>Typ</th>
<th>Modell</th>
<th>Eingabe</th>
<th>Ausgabe</th>
<th>Kosten (USD)</th>
@@ -948,6 +950,7 @@
tr.innerHTML = `
<td>${item.index}</td>
<td>${item.type}</td>
<td>${item.model || '-'}</td>
<td>${item.prompt_tokens || '-'}</td>
<td>${item.completion_tokens || '-'}</td>
<td>${item.cost}</td>
@@ -956,7 +959,7 @@
});
} else {
const tr = document.createElement('tr');
tr.innerHTML = '<td colspan="5">Keine Kostendaten verfügbar</td>';
tr.innerHTML = '<td colspan="6">Keine Kostendaten verfügbar</td>';
costTableBody.appendChild(tr);
}

View File

@@ -89,6 +89,7 @@ function buildCostBreakdown(cost) {
cost.map((item, index) => ({
'#': index + 1,
Type: item.type,
Model: item.model || '-',
'Cost (USD)': `$${item.amount.toFixed(6)}`,
})),
);
@@ -99,6 +100,7 @@ function buildCostBreakdown(cost) {
const costBreakdown = cost.map((item, index) => ({
index: index + 1,
type: item.type,
model: item.model || '-',
prompt_tokens: item.prompt_tokens,
completion_tokens: item.completion_tokens,
cost: `$${item.amount.toFixed(6)}`,
@@ -128,7 +130,8 @@ export function createSearchService({ exa, openrouter, broadcast }) {
type:'openrouter_rephrase',
amount: rephraseResult.cost,
prompt_tokens: rephraseResult.prompt_tokens,
completion_tokens: rephraseResult.completion_tokens
completion_tokens: rephraseResult.completion_tokens,
model: 'openai/gpt-5.4-mini'
});
} catch (error) {
throw new SearchServiceError('Failed to generate summary', 500, error);
@@ -214,7 +217,8 @@ export function createSearchService({ exa, openrouter, broadcast }) {
type:'openrouter_rank',
amount: summaryResult.cost,
prompt_tokens: summaryResult.prompt_tokens,
completion_tokens: summaryResult.completion_tokens
completion_tokens: summaryResult.completion_tokens,
model: 'openai/gpt-oss-120b:nitro'
});
} catch (error) {
throw new SearchServiceError('Failed to generate summary', 500, error);
@@ -263,7 +267,8 @@ export function createSearchService({ exa, openrouter, broadcast }) {
type:'openrouter_final_summary',
amount: finalSummaryResult.cost,
prompt_tokens: finalSummaryResult.prompt_tokens,
completion_tokens: finalSummaryResult.completion_tokens
completion_tokens: finalSummaryResult.completion_tokens,
model: 'openai/gpt-oss-120b:nitro'
});
} catch (error) {
throw new SearchServiceError('Failed to generate final summary', 500, error);