PageSourceSearch

https://radreport.com.br/assets/AICostsPage-Si8WM_Fl.js

js radreport.com.br collected 2026-09-24 14:37:43 UTC 12,467 bytes, 2 lines download raw bytes

1import{j as s}from"./vendor-query-skQMsM6X.js";import{r as u}from"./vendor-react-DyYvSSk1.js";import{u as es,a as ts,b as as,c as os,d as rs}from"./useAICosts-C_r0_VXt.js";import{aJ as ls,p as A,at as f,au as b,av as v,ax as p,ab as is}from"./index-BGwtrXIa.js";import{T as P,a as z,b as C,c as i,d as H,e as l}from"./table-DnRDtd-j.js";import{D as cs,$ as ns,I as ds,bS as ms,aC as us,U as J,r as V,d as W}from"./vendor-ui-CCmu0bzQ.js";import{R as D,X as O,Y as R,T as L,y as X,B as xs,z as hs}from"./generateCategoricalChart-BxE9pWj9.js";import{A as js,a as $}from"./AreaChart-Dc-mtYEU.js";import{C as F}from"./CartesianGrid-OCksdiBu.js";import{B as _s}from"./BarChart-BW7VrK2B.js";import{P as fs,a as ps}from"./PieChart-FGAAL4ST.js";import{L as gs}from"./LineChart-O6kn5cs0.js";import{L as Ns}from"./Line-B3-42a0o.js";import"./vendor-supabase-BfoV2C50.js";const ys=[{value:"24h",label:"24h"},{value:"7d",label:"7 dias"},{value:"30d",label:"30 dias"},{value:"90d",label:"90 dias"}],bs=[{value:"all",label:"Todas"},{value:"user",label:"Usuário"},{value:"admin",label:"Admin"},{value:"system",label:"Sistema"}],x={user:"hsl(217 91% 60%)",admin:"hsl(30 80% 55%)",system:"hsl(220 9% 46%)"};function Y(o){if(!o)return null;const j=o==="user"?"Usuário":o==="admin"?"Admin":"Sistema",n=o==="admin"?V:o==="system"?W:J;return s.jsxs(is,{variant:"outline",className:"gap-1 text-[10px] font-normal",children:[s.jsx(n,{className:"h-3 w-3"}),j]})}const U=o=>`$${(Number(o)||0).toLocaleString("en-US",{minimumFractionDigits:4,maximumFractionDigits:4})}`,_=o=>`$${(Number(o)||0).toLocaleString("en-US",{minimumFractionDigits:6,maximumFractionDigits:6})}`,m=o=>(Number(o)||0).toLocaleString("pt-BR"),G=["hsl(217 91% 60%)","hsl(160 60% 45%)","hsl(30 80% 55%)","hsl(280 60% 60%)","hsl(0 70% 55%)","hsl(195 65% 50%)","hsl(45 90% 55%)","hsl(330 65% 55%)"];function Fs(){const[o,j]=u.useState("7d"),[n,g]=u.useState("all"),h=es(o,n),k=ts(o,n),I=as(o,n),K=os(n),w=rs(o),N=u.useMemo(()=>{const e=h.data||[];let t=0,a=0,r=0,c=0,d=0;for(const S of e)t+=Number(S.sum_cost_usd)||0,a+=S.executions||0,r+=Number(S.sum_in)||0,c+=Number(S.sum_out)||0,d+=Number(S.sum_cached)||0;return{cost:t,calls:a,tin:r,tout:c,tcached:d,avg:a>0?t/a:0}},[h.data]),q=u.useMemo(()=>{const e=new Map;for(const t of h.data||[]){const a=e.get(t.feature)||{feature:t.feature,executions:0,sum_cost_usd:0,sum_in:0,sum_out:0,sum_cached:0};a.executions+=t.executions,a.sum_cost_usd+=Number(t.sum_cost_usd)||0,a.sum_in+=Number(t.sum_in)||0,a.sum_out+=Number(t.sum_out)||0,a.sum_cached+=Number(t.sum_cached)||0,e.set(t.feature,a)}return Array.from(e.values()).sort((t,a)=>a.sum_cost_usd-t.sum_cost_usd)},[h.data]),E=u.useMemo(()=>{const e=new Map;for(const t of k.data||[]){const a=t.model_api_name||"unknown",r=e.get(a)||{model:a,provider:t.provider,executions:0,sum_cost_usd:0,sum_in:0,sum_out:0,sum_cached:0};r.executions+=t.executions,r.sum_cost_usd+=Number(t.sum_cost_usd)||0,r.sum_in+=Number(t.sum_in)||0,r.sum_out+=Number(t.sum_out)||0,r.sum_cached+=Number(t.sum_cached)||0,e.set(a,r)}return Array.from(e.values()).sort((t,a)=>a.sum_cost_usd-t.sum_cost_usd)},[k.data]),Q=u.useMemo(()=>{const e=new Map;for(const t of h.data||[])e.set(t.day,(e.get(t.day)||0)+(Number(t.sum_cost_usd)||0));return Array.from(e.entries()).map(([t,a])=>({day:t,cost:a})).sort((t,a)=>t.day.localeCompare(a.day))},[h.data]),T=u.useMemo(()=>{const e=new Map;for(const t of I.data||[]){const a=`${t.feature}|${t.caller_kind}|${t.model_api_name}`,r=e.get(a)||{feature:t.feature,caller_kind:t.caller_kind,model:t.model_api_name,provider:t.provider,executions:0,sum_in:0,sum_out:0,sum_cached:0,sum_cost_usd:0};r.executions+=t.executions,r.sum_in+=Number(t.sum_in)||0,r.sum_out+=Number(t.sum_out)||0,r.sum_cached+=Number(t.sum_cached)||0,r.sum_cost_usd+=Number(t.sum_cost_usd)||0,e.set(a,r)}return Array.from(e.values()).sort((t,a)=>a.sum_cost_usd-t.sum_cost_usd)},[I.data]),Z=u.useMemo(()=>{const e=new Map;for(const t of w.data||[]){const a=e.get(t.day)||{day:t.day,user:0,admin:0,system:0};a[t.caller_kind]=(a[t.caller_kind]||0)+(Number(t.sum_cost_usd)||0),e.set(t.day,a)}return Array.from(e.values()).sort((t,a)=>t.day.localeCompare(a.day))},[w.data]),y=u.useMemo(()=>{let e=0,t=0,a=0;for(const c of w.data||[])c.caller_kind==="user"?e+=Number(c.sum_c
1ost_usd)||0:c.caller_kind==="admin"?t+=Number(c.sum_cost_usd)||0:c.caller_kind==="system"&&(a+=Number(c.sum_cost_usd)||0);const r=e+t+a;return{user:e,admin:t,system:a,total:r}},[w.data]),ss=()=>{const t=[["feature","caller_kind","model","provider","executions","tokens_input","tokens_output","tokens_cached","cost_usd"].join(",")];for(const d of T)t.push([d.feature,d.caller_kind,d.model,d.provider??"",d.executions,d.sum_in,d.sum_out,d.sum_cached,d.sum_cost_usd].join(","));const a=new Blob([t.join(`
2`)],{type:"text/csv"}),r=URL.createObjectURL(a),c=document.createElement("a");c.href=r,c.download=`ai-costs-${o}-${new Date().toISOString().slice(0,10)}.csv`,c.click(),URL.revokeObjectURL(r)};return s.jsx(ls,{children:s.jsxs("div",{className:"space-y-6",children:[s.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[s.jsxs("div",{children:[s.jsx("h1",{className:"text-2xl font-semibold tracking-tight",children:"Custos LLM"}),s.jsx("p",{className:"text-sm text-muted-foreground",children:"Custo REAL em USD por feature e modelo. Tokens exatos retornados pelo provider; nenhuma estimativa."})]}),s.jsxs("div",{className:"flex items-center gap-2",children:[ys.map(e=>s.jsx(A,{variant:o===e.value?"default":"outline",size:"sm",onClick:()=>j(e.value),children:e.label},e.value)),s.jsxs(A,{variant:"outline",size:"sm",onClick:ss,children:[s.jsx(cs,{className:"h-4 w-4 mr-1"}),"CSV"]})]})]}),s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[s.jsx("span",{className:"text-xs text-muted-foreground font-mono",children:"Origem:"}),bs.map(e=>s.jsx(A,{variant:n===e.value?"default":"outline",size:"sm",onClick:()=>g(e.value),children:e.label},e.value))]}),s.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4",children:[s.jsx(M,{icon:s.jsx(ns,{className:"h-4 w-4"}),label:"Custo total",value:U(N.cost)}),s.jsx(M,{icon:s.jsx(ds,{className:"h-4 w-4"}),label:"Chamadas LLM",value:m(N.calls)}),s.jsx(M,{icon:s.jsx(ms,{className:"h-4 w-4"}),label:"Tokens (in / out / cached)",value:`${m(N.tin)} / ${m(N.tout)} / ${m(N.tcached)}`,small:!0}),s.jsx(M,{icon:s.jsx(us,{className:"h-4 w-4"}),label:"Custo médio / chamada",value:_(N.avg)})]}),s.jsxs(f,{children:[s.jsx(b,{children:s.jsx(v,{className:"text-base",children:"Custo por origem (período)"})}),s.jsxs(p,{children:[s.jsxs("div",{className:"grid grid-cols-3 gap-4 mb-4",children:[s.jsx(B,{label:"Usuário",icon:s.jsx(J,{className:"h-4 w-4"}),value:y.user,total:y.total,color:x.user}),s.jsx(B,{label:"Admin",icon:s.jsx(V,{className:"h-4 w-4"}),value:y.admin,total:y.total,color:x.admin}),s.jsx(B,{label:"Sistema",icon:s.jsx(W,{className:"h-4 w-4"}),value:y.system,total:y.total,color:x.system})]}),s.jsx(D,{width:"100%",height:240,children:s.jsxs(js,{data:Z,children:[s.jsx(F,{strokeDasharray:"3 3",opacity:.3}),s.jsx(O,{dataKey:"day"}),s.jsx(R,{tickFormatter:e=>U(e)}),s.jsx(L,{formatter:e=>_(e)}),s.jsx(X,{wrapperStyle:{fontSize:11}}),s.jsx($,{type:"monotone",dataKey:"user",stackId:"1",stroke:x.user,fill:x.user,fillOpacity:.6,name:"Usuário"}),s.jsx($,{type:"monotone",dataKey:"admin",stackId:"1",stroke:x.admin,fill:x.admin,fillOpacity:.6,name:"Admin"}),s.jsx($,{type:"monotone",dataKey:"system",stackId:"1",stroke:x.system,fill:x.system,fillOpacity:.6,name:"Sistema"})]})})]})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[s.jsxs(f,{children:[s.jsx(b,{children:s.jsx(v,{className:"text-base",children:"Custo por feature (USD)"})}),s.jsx(p,{children:s.jsx(D,{width:"100%",height:300,children:s.jsxs(_s,{data:q.slice(0,15),layout:"vertical",margin:{left:80},children:[s.jsx(F,{strokeDasharray:"3 3",opacity:.3}),s.jsx(O,{type:"number",tickFormatter:e=>U(e)}),s.jsx(R,{type:"category",dataKey:"feature",width:170,tick:{fontSize:11}}),s.jsx(L,{formatter:e=>_(e)}),s.jsx(xs,{dataKey:"sum_cost_usd",fill:"hsl(217 91% 60%)"})]})})})]}),s.jsxs(f,{children:[s.jsx(b,{children:s.jsx(v,{className:"text-base",children:"Distribuição por modelo"})}),s.jsx(p,{children:s.jsx(D,{width:"100%",height:300,children:s.jsxs(fs,{children:[s.jsx(ps,{data:E.slice(0,8),dataKey:"sum_cost_usd",nameKey:"model",cx:"50%",cy:"50%",outerRadius:100,label:e=>e.model.slice(0,18),children:E.slice(0,8).map((e,t)=>s.jsx(hs,{fill:G[t%G.length]},t))}),s.jsx(L,{formatter:e=>_(e)}),s.jsx(X,{wrapperStyle:{fontSize:11}})]})})})]})]}),s.jsxs(f,{children:[s.jsx(b,{children:s.jsx(v,{className:"text-base",children:"Custo diário (USD)"})}),s.jsx(p,{children:s.jsx(D,{width:"100%",height:260,children:s.jsxs(gs,{data:Q,children:[s.jsx(F,{strokeDasharray:"3 3",opacity:.3}),s.jsx(O,{dataKey:"day"}),s.jsx(R,{tickFormatter:e=>U(e)}),s.jsx(L,{formatter:e=>_(e)}),s.jsx(Ns,{type:"monotone",dataKey:"cost",stroke:"hsl(217 91% 60%)",strokeWidth:2,dot:!1})]})})})]}),s.jsxs(f,{children:[s.jsx(b,{children:s.jsx(v,{className:"text-base",children:"Detalhamento por feature × modelo"})}),s.jsx(p,{children:s.jsx("div",{className:"overflow-x-auto",children:s.jsxs(P,{children:[s.jsx(z,{children:s.jsxs(C,{children:[s.jsx(i,{children:"Feature"}),s.jsx(i,{children:"Origem"}),s.jsx(i,{children:"Modelo"}),s.jsx(i,{children:"Provider"}),s.jsx(i,{className:"text-right",children:"Chamadas"}),s.jsx(i,{className:"text-right",children:"In"}),s.jsx(i,{className:"text-right",children:"Out"}),s.jsx(i,{className:"text-right",children:"Cached"}),s.jsx(i,{className:"text-right",children:"Custo USD"})]})}
2),s.jsxs(H,{children:[T.map((e,t)=>s.jsxs(C,{children:[s.jsx(l,{className:"font-mono text-xs",children:e.feature}),s.jsx(l,{children:Y(e.caller_kind)}),s.jsx(l,{className:"font-mono text-xs",children:e.model}),s.jsx(l,{className:"text-xs",children:e.provider||"-"}),s.jsx(l,{className:"text-right",children:m(e.executions)}),s.jsx(l,{className:"text-right",children:m(e.sum_in)}),s.jsx(l,{className:"text-right",children:m(e.sum_out)}),s.jsx(l,{className:"text-right text-muted-foreground",children:m(e.sum_cached)}),s.jsx(l,{className:"text-right font-mono",children:_(e.sum_cost_usd)})]},t)),T.length===0&&s.jsx(C,{children:s.jsx(l,{colSpan:9,className:"text-center text-muted-foreground py-8",children:"Sem dados no período. O log começa a popular após o próximo deploy."})})]})]})})})]}),s.jsxs(f,{children:[s.jsx(b,{children:s.jsx(v,{className:"text-base",children:"Top 20 usuários (últimos 30 dias)"})}),s.jsx(p,{children:s.jsx("div",{className:"overflow-x-auto",children:s.jsxs(P,{children:[s.jsx(z,{children:s.jsxs(C,{children:[s.jsx(i,{children:"User ID"}),s.jsx(i,{children:"Origem"}),s.jsx(i,{className:"text-right",children:"Chamadas"}),s.jsx(i,{className:"text-right",children:"Tokens in"}),s.jsx(i,{className:"text-right",children:"Tokens out"}),s.jsx(i,{className:"text-right",children:"Custo USD"})]})}),s.jsxs(H,{children:[(K.data||[]).map(e=>s.jsxs(C,{children:[s.jsx(l,{className:"font-mono text-xs",children:e.user_id}),s.jsx(l,{children:Y(e.caller_kind)}),s.jsx(l,{className:"text-right",children:m(e.executions)}),s.jsx(l,{className:"text-right",children:m(e.sum_in)}),s.jsx(l,{className:"text-right",children:m(e.sum_out)}),s.jsx(l,{className:"text-right font-mono",children:_(e.sum_cost_usd)})]},`${e.user_id}-${e.caller_kind}`)),(K.data||[]).length===0&&s.jsx(C,{children:s.jsx(l,{colSpan:6,className:"text-center text-muted-foreground py-8",children:"Sem dados."})})]})]})})})]})]})})}function M({icon:o,label:j,value:n,small:g}){return s.jsx(f,{children:s.jsxs(p,{className:"p-4",children:[s.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground text-xs font-mono mb-1",children:[o,j]}),s.jsx("div",{className:g?"text-base font-semibold font-mono":"text-2xl font-semibold font-mono",children:n})]})})}function B({label:o,icon:j,value:n,total:g,color:h}){const k=g>0?n/g*100:0;return s.jsxs("div",{className:"rounded-lg border p-3",children:[s.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground text-xs font-mono mb-1",children:[j,o]}),s.jsxs("div",{className:"text-xl font-semibold font-mono",style:{color:h},children:["$",n.toLocaleString("en-US",{minimumFractionDigits:4,maximumFractionDigits:4})]}),s.jsxs("div",{className:"text-xs text-muted-foreground font-mono",children:[k.toFixed(1),"% do período"]})]})}export{Fs as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.