Skip to content

Commit 32b4dba

Browse files
authored
Merge branch 'main' into fix(webapp)-bug-with-task-search
2 parents b670551 + 07a0e4a commit 32b4dba

18 files changed

Lines changed: 1170 additions & 67 deletions

File tree

.changeset/span-api-cached-cost.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/core": patch
3+
---
4+
5+
The run span API response now includes `cachedCost` and `cacheCreationCost` on the `ai` object, alongside the existing `inputCost` / `outputCost` / `totalCost`. `inputCost` reflects only the non-cached input, so these fields let you reconstruct the full cost breakdown for prompt-cached calls.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: fix
4+
---
5+
6+
LLM cost no longer double-counts cached input tokens. Prompt-cache reads and writes are now billed once at their cache rate instead of also being charged at the full input price, so cost and cache hit-rate figures on the AI metrics dashboard and Models page are accurate.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: feature
4+
---
5+
6+
The Models page now has a Your models tab showing your project's model usage (cost, calls, latency, prompt-cache savings, and trend sparklines over a selectable time range) alongside the full model library, ordered by provider relevance and release date. The AI metrics dashboard also gains a caching section with cache hit rate, cached tokens, and estimated savings.

apps/webapp/app/assets/icons/AiProviderIcons.tsx

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ export function LlamaIcon({ className }: IconProps) {
4646
xmlns="http://www.w3.org/2000/svg"
4747
>
4848
<path
49-
fill-rule="evenodd"
50-
clip-rule="evenodd"
49+
fillRule="evenodd"
50+
clipRule="evenodd"
5151
d="M3.4485 2C4.406 2 5.2065 2.466 6.1635 3.688L6.3045 3.5015C6.3995 3.3785 6.496 3.2595 6.5945 3.1465L6.751 2.9715C7.294 2.394 7.896 2 8.6125 2C9.249 2 9.847 2.2785 10.358 2.758L10.467 2.8645C11.332 3.747 11.9255 5.2195 11.9935 6.8775L11.999 7.0735L12 7.1985C12 7.949 11.86 8.578 11.591 9.0485L11.521 9.1635L11.467 9.24C11.3165 9.45 11.135 9.619 10.924 9.7445L10.7915 9.8155L10.748 9.8355C10.6986 9.85749 10.6482 9.87718 10.597 9.8945C10.3825 9.96542 10.1579 10.0006 9.932 9.9985C9.67 9.9985 9.434 9.965 9.213 9.891C8.906 9.789 8.6315 9.611 8.35 9.333L8.2365 9.2155C7.86 8.8095 7.4695 8.2275 6.99 7.4225L6.275 6.2175L6.003 5.77L5.12 7.335L4.9485 7.631C3.7985 9.578 3.1135 10 2.178 10C1.573 10 1.0755 9.79 0.71 9.409L0.626 9.317C0.384 9.0305 0.2075 8.6615 0.1045 8.2225L0.071 8.0625C0.0323456 7.84982 0.00961585 7.63456 0.003 7.4185L0 7.234C0.001 6.8615 0.03 6.489 0.087 6.119L0.137 5.8325C0.286 5.0675 0.551 4.3535 0.905 3.754L1.0095 3.584C1.598 2.669 2.404 2.0575 3.317 2.004L3.4485 2ZM3.432 3.3075L3.3315 3.3125C2.9165 3.354 2.5285 3.649 2.2055 4.101L2.1365 4.2005L2.1315 4.2095C1.7965 4.718 1.539 5.3985 1.4035 6.132L1.4015 6.143C1.33323 6.5148 1.29859 6.89199 1.298 7.27L1.299 7.364C1.301 7.454 1.3075 7.544 1.319 7.634L1.3405 7.7795C1.3865 8.031 1.469 8.2335 1.5835 8.3835L1.642 8.452C1.7935 8.6135 1.991 8.698 2.227 8.698C2.777 8.698 3.125 8.36 4.075 6.8775L5.1625 5.1775L5.3895 4.827L5.32 4.728C4.555 3.65 4.042 3.3075 3.432 3.3075ZM8.53 3.0315L8.442 3.035C8.1245 3.059 7.8305 3.2145 7.532 3.5015L7.434 3.6005C7.2145 3.8315 6.9905 4.1325 6.7505 4.504L6.8835 4.703C6.9735 4.84 7.0645 4.983 7.1585 5.132L7.305 5.3695L8.003 6.537L8.3505 7.094C8.642 7.557 8.8655 7.894 9.0545 8.135L9.161 8.266C9.302 8.429 9.4255 8.536 9.5495 8.6025L9.6005 8.6275C9.714 8.6775 9.829 8.6965 9.9595 8.6965C10.0475 8.6975 10.1345 8.685 10.2185 8.66C10.3875 8.608 10.5235 8.5 10.625 8.3415L10.6725 8.26L10.711 8.179C10.808 7.9495 10.856 7.649 10.856 7.2865L10.853 7.062C10.813 5.6265 10.384 4.376 9.753 3.663L9.665 3.5685C9.33 3.227 8.943 3.0315 8.53 3.0315Z"
5252
fill="currentColor"
5353
/>
@@ -58,10 +58,10 @@ export function LlamaIcon({ className }: IconProps) {
5858
export function DeepseekIcon({ className }: IconProps) {
5959
return (
6060
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
61-
<g clip-path="url(#clip0_20374_57805)">
61+
<g clipPath="url(#clip0_20374_57805)">
6262
<path
63-
fill-rule="evenodd"
64-
clip-rule="evenodd"
63+
fillRule="evenodd"
64+
clipRule="evenodd"
6565
d="M23.7479 4.48176C23.4939 4.35776 23.384 4.59476 23.236 4.71576C23.185 4.75476 23.142 4.80576 23.099 4.85176C22.727 5.24876 22.293 5.50876 21.726 5.47776C20.897 5.43176 20.189 5.69176 19.563 6.32576C19.43 5.54376 18.988 5.07776 18.316 4.77776C17.964 4.62176 17.608 4.46676 17.361 4.12776C17.189 3.88676 17.142 3.61776 17.056 3.35376C17.001 3.19376 16.946 3.03076 16.763 3.00376C16.563 2.97276 16.4849 3.13976 16.4069 3.27976C16.094 3.85176 15.9729 4.48176 15.9849 5.11976C16.0119 6.55576 16.618 7.69976 17.823 8.51276C17.96 8.60576 17.995 8.69976 17.952 8.83576C17.87 9.11576 17.772 9.38776 17.686 9.66876C17.631 9.84776 17.549 9.88576 17.357 9.80876C16.7082 9.52995 16.1189 9.12939 15.6209 8.62876C14.7639 7.80076 13.9899 6.88676 13.0239 6.17076C12.8001 6.00537 12.5703 5.84827 12.3349 5.69976C11.3499 4.74276 12.4649 3.95676 12.7229 3.86376C12.9929 3.76576 12.8159 3.43176 11.9439 3.43576C11.0719 3.43976 10.2739 3.73076 9.25695 4.11976C9.10582 4.17767 8.95033 4.22348 8.79195 4.25676C7.84158 4.07769 6.8696 4.0433 5.90895 4.15476C4.02395 4.36476 2.51895 5.25676 1.41195 6.77776C0.0819496 8.60576 -0.23105 10.6838 0.15195 12.8498C0.55495 15.1338 1.72095 17.0248 3.51195 18.5028C5.36995 20.0358 7.50895 20.7868 9.94995 20.6428C11.4319 20.5578 13.0829 20.3588 14.9439 18.7828C15.4139 19.0168 15.906 19.1098 16.724 19.1798C17.354 19.2388 17.96 19.1498 18.429 19.0518C19.164 18.8958 19.1129 18.2148 18.8479 18.0908C16.693 17.0868 17.166 17.4958 16.735 17.1648C17.831 15.8688 19.481 14.5228 20.127 10.1618C20.177 9.81476 20.134 9.59676 20.127 9.31676C20.123 9.14676 20.162 9.07976 20.357 9.06076C20.898 9.00463 21.4228 8.84327 21.902 8.58576C23.298 7.82276 23.862 6.57076 23.995 5.06876C24.015 4.83876 23.9909 4.60276 23.7479 4.48176ZM11.5809 17.9998C9.49195 16.3578 8.47895 15.8168 8.06095 15.8398C7.66895 15.8638 7.73995 16.3108 7.82595 16.6028C7.91595 16.8908 8.03295 17.0888 8.19695 17.3418C8.31095 17.5088 8.38895 17.7578 8.08395 17.9448C7.41095 18.3608 6.24195 17.8048 6.18695 17.7778C4.82595 16.9758 3.68695 15.9178 2.88595 14.4708C2.11195 13.0778 1.66195 11.5838 1.58795 9.98876C1.56795 9.60276 1.68095 9.46676 2.06495 9.39676C2.56906 9.30029 3.08558 9.28711 3.59395 9.35776C5.72595 9.66976 7.53995 10.6228 9.06195 12.1318C9.92995 12.9918 10.5869 14.0188 11.2639 15.0228C11.9839 16.0888 12.7579 17.1048 13.7439 17.9368C14.0919 18.2288 14.3689 18.4508 14.6349 18.6138C13.8329 18.7038 12.4949 18.7238 11.5809 17.9998ZM12.5809 11.5598C12.5808 11.5101 12.5927 11.4611 12.6157 11.4171C12.6387 11.373 12.672 11.3353 12.7129 11.307C12.7538 11.2787 12.8009 11.2609 12.8502 11.2549C12.8995 11.2489 12.9495 11.2551 12.9959 11.2728C13.0551 11.294 13.1062 11.3331 13.142 11.3848C13.1779 11.4364 13.1967 11.4979 13.1959 11.5608C13.1961 11.6014 13.1881 11.6416 13.1726 11.6791C13.157 11.7166 13.1341 11.7506 13.1053 11.7792C13.0764 11.8078 13.0422 11.8303 13.0045 11.8455C12.9669 11.8607 12.9266 11.8683 12.8859 11.8678C12.8457 11.8679 12.8057 11.86 12.7685 11.8445C12.7313 11.829 12.6976 11.8063 12.6693 11.7776C12.641 11.7489 12.6186 11.7149 12.6037 11.6775C12.5887 11.6401 12.5803 11.6 12.5809 11.5598ZM15.6909 13.1558C15.4909 13.2368 15.2919 13.3068 15.1009 13.3158C14.8136 13.3258 14.5316 13.236 14.3029 13.0618C14.0289 12.8318 13.8329 12.7038 13.7509 12.3038C13.7227 12.1083 13.7281 11.9094 13.7669 11.7158C13.8369 11.3888 13.7589 11.1788 13.5279 10.9888C13.3409 10.8328 13.1019 10.7898 12.8399 10.7898C12.7502 10.7845 12.6631 10.7578 12.5859 10.7118C12.4759 10.6578 12.3859 10.5218 12.4719 10.3538C12.4999 10.2998 12.6319 10.1678 12.6639 10.1438C13.0199 9.94176 13.4309 10.0078 13.8099 10.1598C14.1619 10.3038 14.4279 10.5678 14.8109 10.9418C15.2019 11.3928 15.2729 11.5178 15.4959 11.8558C15.6719 12.1208 15.8319 12.3928 15.9409 12.7038C16.0079 12.8988 15.9219 13.0578 15.6909 13.1558Z"
6666
fill="currentColor"
6767
/>
@@ -99,8 +99,8 @@ export function PerplexityIcon({ className }: IconProps) {
9999
return (
100100
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
101101
<path
102-
fill-rule="evenodd"
103-
clip-rule="evenodd"
102+
fillRule="evenodd"
103+
clipRule="evenodd"
104104
d="M18.4875 2V8.06H20.75V16.6833H18.3042V22L12.44 16.8383V21.9592H11.5308V16.8325L5.66 22V16.6125H3.25V7.99H5.65333V2L11.5308 7.41167V2.15833H12.4392V7.56667L18.4875 2ZM12.44 9.53667V15.6358L17.395 19.9975V14.0333L12.44 9.53667ZM11.5242 9.47L6.56917 13.9683V19.9975L11.5242 15.6358V9.47083V9.47ZM18.3042 15.7867H19.8408V8.9575H13.2167L18.3042 13.5742V15.7867ZM10.8192 8.88667H4.15833V15.7158H5.65833V13.5692L10.8183 8.88583L10.8192 8.88667ZM6.5625 4.06333V7.98833H10.825L6.5625 4.06333ZM17.5783 4.06333L13.3158 7.98833H17.5783V4.06333Z"
105105
fill="currentColor"
106106
/>
@@ -112,32 +112,32 @@ export function CerebrasIcon({ className }: IconProps) {
112112
return (
113113
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
114114
<path
115-
fill-rule="evenodd"
116-
clip-rule="evenodd"
115+
fillRule="evenodd"
116+
clipRule="evenodd"
117117
d="M11.6535 20.6834C10.4382 20.6834 9.28717 20.4401 8.23625 20.0036C6.66345 19.3453 5.31944 18.2433 4.36862 16.8551C3.4178 15.4669 2.86732 13.7997 2.86732 11.9964C2.86732 10.7943 3.11039 9.65655 3.56078 8.61182C4.22564 7.0519 5.3409 5.72809 6.7421 4.7907C8.1433 3.85331 9.83047 3.30948 11.6535 3.30948V2C10.2594 2 8.92972 2.27907 7.71437 2.78712C5.8985 3.54562 4.35432 4.81217 3.26767 6.40788C2.17386 8.00356 1.5376 9.92844 1.5376 11.9964C1.5376 13.3774 1.82356 14.6941 2.33114 15.8891C3.09609 17.6851 4.38291 19.2093 5.99144 20.2898C7.60713 21.3703 9.55167 22 11.6463 22V20.6834H11.6535Z"
118118
fill="currentColor"
119119
/>
120120
<path
121-
fill-rule="evenodd"
122-
clip-rule="evenodd"
121+
fillRule="evenodd"
122+
clipRule="evenodd"
123123
d="M7.14949 17.3272C6.32735 16.6403 5.71253 15.8102 5.2979 14.9014C4.88323 13.9927 4.66877 13.0124 4.66877 12.0249C4.66877 11.2378 4.8046 10.4506 5.06911 9.69931C5.34079 8.94794 5.74113 8.23241 6.29159 7.58122C6.9779 6.7655 7.81433 6.15012 8.72225 5.73508C9.63021 5.32005 10.6239 5.11254 11.6105 5.11254C12.3969 5.11254 13.1904 5.24849 13.9411 5.51325C14.6989 5.78516 15.4138 6.18588 16.0643 6.7297L16.9151 5.72077C16.143 5.07676 15.2851 4.59018 14.3843 4.27533C13.4835 3.95332 12.547 3.7959 11.6105 3.7959C10.4309 3.7959 9.25846 4.04634 8.17178 4.54009C7.08514 5.03382 6.09141 5.77087 5.27643 6.73687C4.62587 7.50967 4.14689 8.36119 3.82518 9.25563C3.50347 10.1501 3.34619 11.0875 3.34619 12.0249C3.34619 13.1984 3.59641 14.3719 4.08969 15.4524C4.58298 16.5329 5.32649 17.5276 6.29876 18.3362L7.14949 17.3272Z"
124124
fill="currentColor"
125125
/>
126126
<path
127-
fill-rule="evenodd"
128-
clip-rule="evenodd"
127+
fillRule="evenodd"
128+
clipRule="evenodd"
129129
d="M9.18714 16.4758C8.32211 16.0179 7.64298 15.3524 7.17829 14.5724C6.7136 13.7925 6.47052 12.8909 6.47052 11.9821C6.47052 11.1807 6.65641 10.3721 7.06388 9.62074C7.52144 8.75492 8.19345 8.08228 8.97983 7.6243C9.76624 7.1592 10.667 6.9159 11.5821 6.9159C12.3828 6.9159 13.1978 7.10194 13.9556 7.50269L14.5704 6.33631C13.6196 5.83541 12.5901 5.59212 11.5749 5.59927C10.424 5.59927 9.28725 5.90697 8.30069 6.48655C7.31412 7.06618 6.46339 7.92487 5.89146 9.00535C5.39101 9.95706 5.14795 10.9803 5.14795 11.9821C5.14795 13.127 5.45536 14.2576 6.04159 15.2379C6.62782 16.2254 7.48568 17.0626 8.57236 17.635L9.18714 16.4758Z"
130130
fill="currentColor"
131131
/>
132132
<path
133-
fill-rule="evenodd"
134-
clip-rule="evenodd"
133+
fillRule="evenodd"
134+
clipRule="evenodd"
135135
d="M11.6608 15.2165C11.2104 15.2165 10.7815 15.1235 10.3955 14.9589C9.80924 14.7156 9.31596 14.3005 8.96564 13.7782C8.61536 13.2558 8.40804 12.6333 8.40804 11.9606C8.40804 11.5098 8.50095 11.0805 8.66537 10.6941C8.90845 10.1145 9.32309 9.61359 9.84496 9.26297C10.3669 8.91235 10.9888 8.70484 11.6608 8.70484V7.38818C11.0317 7.38818 10.4312 7.517 9.88072 7.74597C9.05858 8.09659 8.36511 8.66905 7.87183 9.39892C7.37142 10.136 7.08545 11.0233 7.08545 11.9678C7.08545 12.5975 7.21412 13.1986 7.4429 13.7496C7.79322 14.5725 8.37228 15.2666 9.10147 15.7603C9.83067 16.2469 10.71 16.5331 11.6608 16.5331V15.2165Z"
136136
fill="currentColor"
137137
/>
138138
<path
139-
fill-rule="evenodd"
140-
clip-rule="evenodd"
139+
fillRule="evenodd"
140+
clipRule="evenodd"
141141
d="M12.7332 10.9234C12.5831 10.766 12.4187 10.6372 12.2542 10.5442C12.0898 10.4511 11.9183 10.401 11.7395 10.401C11.4965 10.401 11.2891 10.444 11.0961 10.5299C10.9102 10.6157 10.7458 10.7302 10.61 10.8805C10.4741 11.0236 10.374 11.1953 10.3026 11.3814C10.2311 11.5674 10.2025 11.7678 10.2025 11.9681C10.2025 12.1685 10.2382 12.3689 10.3026 12.5549C10.374 12.7409 10.4741 12.9127 10.61 13.0558C10.7458 13.1989 10.9031 13.3206 11.0961 13.4064C11.282 13.4923 11.4965 13.5352 11.7395 13.5352C11.9397 13.5352 12.1327 13.4923 12.3043 13.4136C12.4759 13.3277 12.626 13.2061 12.7475 13.0486L13.6197 13.986C13.491 14.1148 13.3409 14.2293 13.1693 14.3223C12.9978 14.4154 12.8262 14.4941 12.6546 14.5513C12.483 14.6086 12.3114 14.6515 12.1542 14.673C11.9969 14.7016 11.8539 14.7087 11.7395 14.7087C11.3463 14.7087 10.9746 14.6443 10.6314 14.5155C10.2811 14.3868 9.98084 14.2007 9.73064 13.9574C9.47326 13.7213 9.27311 13.4279 9.12298 13.0916C8.97285 12.7553 8.90137 12.376 8.90137 11.9681C8.90137 11.5531 8.97285 11.181 9.12298 10.8447C9.27311 10.5084 9.47326 10.2222 9.73064 9.97887C9.98801 9.74274 10.2883 9.55669 10.6314 9.42075C10.9817 9.29193 11.3535 9.22754 11.7395 9.22754C12.0755 9.22754 12.4115 9.29193 12.7475 9.42075C13.0835 9.54953 13.3838 9.7499 13.634 10.0218L12.7332 10.9234Z"
142142
fill="currentColor"
143143
/>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import {
2+
Bar,
3+
BarChart,
4+
ReferenceLine,
5+
ResponsiveContainer,
6+
Tooltip,
7+
YAxis,
8+
type TooltipProps,
9+
} from "recharts";
10+
import { cn } from "~/utils/cn";
11+
import { formatDateTime } from "./DateTime";
12+
import { Header3 } from "./Headers";
13+
import TooltipPortal from "./TooltipPortal";
14+
15+
type UsageDatum = { date: Date; count: number };
16+
17+
type UnitLabel = { singular: string; plural: string };
18+
19+
export type UsageSparklineProps = {
20+
/** Equal-width time buckets, oldest first. */
21+
data?: number[];
22+
/** Epoch ms of the first bucket's start. When omitted, the last bucket is anchored to now. */
23+
bucketStartMs?: number;
24+
/** Width of each bucket in ms. Defaults to one hour. */
25+
bucketIntervalMs?: number;
26+
/** Bar colour. Defaults to blue. */
27+
color?: string;
28+
/** Unit shown in the tooltip (e.g. calls, tokens). */
29+
unitLabel?: UnitLabel;
30+
/** Format the trailing total. Defaults to `toLocaleString`. */
31+
formatTotal?: (total: number) => string;
32+
/** Class for the trailing total label. */
33+
totalClassName?: string;
34+
};
35+
36+
/**
37+
* Inline 24h sparkline for list rows. Renders a small bar chart plus a trailing
38+
* total, or an em-dash when there's no data. Shared by the prompts and models
39+
* lists — keep it presentational (the caller supplies the zero-filled buckets).
40+
*/
41+
export function UsageSparkline({
42+
data,
43+
bucketStartMs,
44+
bucketIntervalMs,
45+
color = "#3B82F6",
46+
unitLabel = { singular: "call", plural: "calls" },
47+
formatTotal,
48+
totalClassName = "text-blue-400",
49+
}: UsageSparklineProps) {
50+
if (!data || data.every((v) => v === 0)) {
51+
return <span className="text-text-dimmed"></span>;
52+
}
53+
54+
const total = data.reduce((a, b) => a + b, 0);
55+
const max = Math.max(...data);
56+
57+
// Map each bucket to a dated point so the tooltip can show the window it
58+
// represents. Buckets are `intervalMs` wide; if the caller didn't pass the
59+
// first bucket's start, anchor the last bucket to now (hourly default).
60+
const intervalMs = bucketIntervalMs ?? 3600_000;
61+
const startMs = bucketStartMs ?? Date.now() - (data.length - 1) * intervalMs;
62+
const chartData: UsageDatum[] = data.map((count, i) => ({
63+
date: new Date(startMs + i * intervalMs),
64+
count,
65+
}));
66+
67+
return (
68+
<div className="flex items-start gap-2">
69+
<div className="h-6 w-[7rem] rounded-sm">
70+
<ResponsiveContainer width="100%" height="100%">
71+
<BarChart data={chartData} margin={{ top: 0, right: 0, left: 0, bottom: 0 }}>
72+
<YAxis domain={[0, max || 1]} hide />
73+
<Tooltip
74+
cursor={{ fill: "rgba(255, 255, 255, 0.06)" }}
75+
content={<UsageSparklineTooltip unitLabel={unitLabel} />}
76+
allowEscapeViewBox={{ x: true, y: true }}
77+
wrapperStyle={{ zIndex: 1000 }}
78+
animationDuration={0}
79+
/>
80+
<Bar
81+
dataKey="count"
82+
fill={color}
83+
strokeWidth={0}
84+
isAnimationActive={false}
85+
minPointSize={1}
86+
/>
87+
<ReferenceLine y={0} stroke="#2C3034" strokeWidth={1} />
88+
{max > 0 && (
89+
<ReferenceLine y={max} stroke="#4D525B" strokeDasharray="4 4" strokeWidth={1} />
90+
)}
91+
</BarChart>
92+
</ResponsiveContainer>
93+
</div>
94+
<span className={cn("-mt-1 text-xs tabular-nums", totalClassName)}>
95+
{formatTotal ? formatTotal(total) : total.toLocaleString()}
96+
</span>
97+
</div>
98+
);
99+
}
100+
101+
function UsageSparklineTooltip({
102+
active,
103+
payload,
104+
unitLabel,
105+
}: TooltipProps<number, string> & { unitLabel: UnitLabel }) {
106+
if (!active || !payload || payload.length === 0) return null;
107+
const entry = payload[0].payload as UsageDatum;
108+
const date = entry.date instanceof Date ? entry.date : new Date(entry.date);
109+
const formattedDate = formatDateTime(date, "UTC", [], false, true);
110+
return (
111+
<TooltipPortal active={active}>
112+
<div className="rounded-sm border border-grid-bright bg-background-dimmed px-3 py-2">
113+
<Header3 className="border-b border-b-charcoal-650 pb-2">{formattedDate}</Header3>
114+
<div className="mt-2 text-xs text-text-bright">
115+
<span className="tabular-nums">{entry.count.toLocaleString()}</span>{" "}
116+
<span className="text-text-dimmed">
117+
{entry.count === 1 ? unitLabel.singular : unitLabel.plural}
118+
</span>
119+
</div>
120+
</div>
121+
</TooltipPortal>
122+
);
123+
}

apps/webapp/app/components/runs/v3/SharedFilters.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,13 @@ export function TimeFilter({
375375
valueClassName,
376376
}: TimeFilterProps = {}) {
377377
const { value } = useSearchParams();
378-
const periodValue = period ?? value("period");
379-
const fromValue = from ?? value("from");
380-
const toValue = to ?? value("to");
378+
// In controlled mode (onValueChange provided) the caller owns all three values via local
379+
// state, so don't fall back to the URL — otherwise selecting a custom date range (which
380+
// sets period to undefined) would read the page-level URL period and override the range.
381+
const controlled = onValueChange !== undefined;
382+
const periodValue = controlled ? period : period ?? value("period");
383+
const fromValue = controlled ? from : from ?? value("from");
384+
const toValue = controlled ? to : to ?? value("to");
381385
const triggerRef = useRef<HTMLButtonElement>(null);
382386

383387
useShortcutKeys({

apps/webapp/app/components/runs/v3/ai/extractAISpanData.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ export function extractAISpanData(
110110
inputCost: num(triggerLlm.input_cost),
111111
outputCost: num(triggerLlm.output_cost),
112112
totalCost: num(triggerLlm.total_cost),
113+
cachedCost: num(triggerLlm.cached_cost),
114+
cacheCreationCost: num(triggerLlm.cache_creation_cost),
113115
responseText: isV7
114116
? extractGenAiAssistantText(gOutput.messages) || undefined
115117
: str(aiResponse.text) || undefined,

apps/webapp/app/components/runs/v3/ai/extractAISummarySpanData.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ export function extractAISummarySpanData(
108108
inputCost: num(triggerLlm.input_cost),
109109
outputCost: num(triggerLlm.output_cost),
110110
totalCost: num(triggerLlm.total_cost),
111+
cachedCost: num(triggerLlm.cached_cost),
112+
cacheCreationCost: num(triggerLlm.cache_creation_cost),
111113
responseText: str(aiResponse.text) || undefined,
112114
responseObject: str(aiResponse.object) || undefined,
113115
toolDefinitions: undefined,

apps/webapp/app/components/runs/v3/ai/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ export type AISpanData = {
104104
inputCost?: number;
105105
outputCost?: number;
106106
totalCost?: number;
107+
cachedCost?: number;
108+
cacheCreationCost?: number;
107109

108110
// Response text (final assistant output)
109111
responseText?: string;

0 commit comments

Comments
 (0)