feat: add cache token tracking and cache-aware cost calculation
Track cache_read_tokens and cache_write_tokens end-to-end: parse from provider responses (OpenAI, DeepSeek, Grok, Gemini), persist to SQLite, apply cache-aware pricing from the model registry, and surface in API responses and the dashboard. - Add cache fields to ProviderResponse, StreamUsage, RequestLog structs - Parse cached_tokens (OpenAI/Grok), prompt_cache_hit/miss (DeepSeek), cachedContentTokenCount (Gemini) from provider responses - Send stream_options.include_usage for streaming; capture real usage from final SSE chunk in AggregatingStream - ALTER TABLE migration for cache_read_tokens/cache_write_tokens columns - Cache-aware cost formula using registry cache_read/cache_write rates - Update Provider trait calculate_cost signature across all providers - Add cache_read_tokens/cache_write_tokens to Usage API response - Dashboard: cache hit rate card, cache columns in pricing and usage tables, cache token aggregation in SQL queries - Remove API debug panel and verbose console logging from api.js - Bump static asset cache-bust to v5
This commit is contained in:
@@ -184,21 +184,27 @@ class AnalyticsPage {
|
||||
if (!tableBody) return;
|
||||
|
||||
if (data.length === 0) {
|
||||
tableBody.innerHTML = '<tr><td colspan="7" class="text-center">No historical data found</td></tr>';
|
||||
tableBody.innerHTML = '<tr><td colspan="9" class="text-center">No historical data found</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
tableBody.innerHTML = data.map(row => `
|
||||
<tr>
|
||||
<td>${row.date}</td>
|
||||
<td><span class="badge-client">${row.client}</span></td>
|
||||
<td>${row.provider}</td>
|
||||
<td><code class="code-sm">${row.model}</code></td>
|
||||
<td>${row.requests.toLocaleString()}</td>
|
||||
<td>${window.api.formatNumber(row.tokens)}</td>
|
||||
<td>${window.api.formatCurrency(row.cost)}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
tableBody.innerHTML = data.map(row => {
|
||||
const cacheRead = row.cache_read_tokens || 0;
|
||||
const cacheWrite = row.cache_write_tokens || 0;
|
||||
return `
|
||||
<tr>
|
||||
<td>${row.date}</td>
|
||||
<td><span class="badge-client">${row.client}</span></td>
|
||||
<td>${row.provider}</td>
|
||||
<td><code class="code-sm">${row.model}</code></td>
|
||||
<td>${row.requests.toLocaleString()}</td>
|
||||
<td>${window.api.formatNumber(row.tokens)}</td>
|
||||
<td>${window.api.formatNumber(cacheRead)}</td>
|
||||
<td>${window.api.formatNumber(cacheWrite)}</td>
|
||||
<td>${window.api.formatCurrency(row.cost)}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
|
||||
Reference in New Issue
Block a user