Skip to content

Commit 7338f66

Browse files
committed
feat(webapp): add prompt-cache metrics to the prompt detail page
The prompt detail Metrics tab now shows a Cached tokens total, a cache hit-rate-over-time chart, and a cached-tokens-over-time chart, matching the model detail page. Avg input cost and input cost per 1k now include the cache-read and cache-creation cost lines so they reflect total input spend rather than the fresh-input cost alone.
1 parent e7a728f commit 7338f66

1 file changed

Lines changed: 56 additions & 3 deletions

File tree

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,7 +1626,7 @@ function MetricsTab({
16261626
return (
16271627
<div className="space-y-3">
16281628
{/* Summary big numbers */}
1629-
<div className="grid grid-cols-4 gap-3">
1629+
<div className="grid grid-cols-5 gap-3">
16301630
<div className="h-44">
16311631
<MetricWidget
16321632
widgetKey={`prompt-${prompt.slug}-generations`}
@@ -1659,7 +1659,7 @@ function MetricsTab({
16591659
<MetricWidget
16601660
widgetKey={`prompt-${prompt.slug}-cost`}
16611661
title="Avg input cost"
1662-
query={`SELECT avg(input_cost) AS avg_cost FROM llm_metrics WHERE 1=1`}
1662+
query={`SELECT avg(input_cost + cached_read_cost + cache_creation_cost) AS avg_cost FROM llm_metrics WHERE 1=1`}
16631663
config={{
16641664
type: "bignumber",
16651665
column: "avg_cost",
@@ -1684,6 +1684,20 @@ function MetricsTab({
16841684
{...widgetProps}
16851685
/>
16861686
</div>
1687+
<div className="h-44">
1688+
<MetricWidget
1689+
widgetKey={`prompt-${prompt.slug}-cached-tokens`}
1690+
title="Cached tokens"
1691+
query={`SELECT sum(cached_read_tokens) AS cached_tokens FROM llm_metrics WHERE 1=1`}
1692+
config={{
1693+
type: "bignumber",
1694+
column: "cached_tokens",
1695+
aggregation: "sum",
1696+
abbreviate: true,
1697+
}}
1698+
{...widgetProps}
1699+
/>
1700+
</div>
16871701
</div>
16881702

16891703
{/* Version performance */}
@@ -1808,7 +1822,7 @@ function VersionPerformanceSection({
18081822
<MetricWidget
18091823
widgetKey={`prompt-${promptSlug}-perf-input-cost`}
18101824
title="Input cost per 1k tokens (p50 / p95)"
1811-
query={`SELECT timeBucket(), prettyFormat(quantile(0.5)(input_cost / input_tokens * 1000), 'costInDollars') AS p50, prettyFormat(quantile(0.95)(input_cost / input_tokens * 1000), 'costInDollars') AS p95 FROM llm_metrics WHERE input_tokens > 0 GROUP BY timeBucket ORDER BY timeBucket`}
1825+
query={`SELECT timeBucket(), prettyFormat(quantile(0.5)((input_cost + cached_read_cost + cache_creation_cost) / input_tokens * 1000), 'costInDollars') AS p50, prettyFormat(quantile(0.95)((input_cost + cached_read_cost + cache_creation_cost) / input_tokens * 1000), 'costInDollars') AS p95 FROM llm_metrics WHERE input_tokens > 0 GROUP BY timeBucket ORDER BY timeBucket`}
18121826
config={{
18131827
type: "chart",
18141828
chartType: "line",
@@ -1862,6 +1876,45 @@ function VersionPerformanceSection({
18621876
{...widgetProps}
18631877
/>
18641878
</div>
1879+
{/* Row 4: Caching */}
1880+
<div className="h-96">
1881+
<MetricWidget
1882+
widgetKey={`prompt-${promptSlug}-perf-cache-hit`}
1883+
title="Cache hit rate over time"
1884+
query={`SELECT timeBucket(), round(ifNull(sum(cached_read_tokens) * 100.0 / nullIf(sum(input_tokens), 0), 0), 1) AS cache_hit_pct FROM llm_metrics WHERE 1=1 GROUP BY timeBucket ORDER BY timeBucket`}
1885+
config={{
1886+
type: "chart",
1887+
chartType: "line",
1888+
xAxisColumn: "timebucket",
1889+
yAxisColumns: ["cache_hit_pct"],
1890+
groupByColumn: null,
1891+
stacked: false,
1892+
sortByColumn: null,
1893+
sortDirection: "asc",
1894+
aggregation: "avg",
1895+
}}
1896+
{...widgetProps}
1897+
/>
1898+
</div>
1899+
<div className="h-96">
1900+
<MetricWidget
1901+
widgetKey={`prompt-${promptSlug}-perf-cached-tokens`}
1902+
title="Cached tokens over time"
1903+
query={`SELECT timeBucket(), sum(cached_read_tokens) AS cache_reads, sum(cache_creation_tokens) AS cache_writes FROM llm_metrics WHERE 1=1 GROUP BY timeBucket ORDER BY timeBucket`}
1904+
config={{
1905+
type: "chart",
1906+
chartType: "bar",
1907+
xAxisColumn: "timebucket",
1908+
yAxisColumns: ["cache_reads", "cache_writes"],
1909+
groupByColumn: null,
1910+
stacked: true,
1911+
sortByColumn: null,
1912+
sortDirection: "asc",
1913+
aggregation: "sum",
1914+
}}
1915+
{...widgetProps}
1916+
/>
1917+
</div>
18651918
</div>
18661919

18671920
<div className="h-48">

0 commit comments

Comments
 (0)