102 lines
2.4 KiB
TypeScript
102 lines
2.4 KiB
TypeScript
|
|
/** Token cost card sub-component for WorkItemDetailPanel. */
|
||
|
|
|
||
|
|
import type { AgentCostEntry, TokenCostResponse } from "../api/client";
|
||
|
|
|
||
|
|
/** Renders the "Token Cost" card in the detail panel. */
|
||
|
|
export function TokenCostSection({
|
||
|
|
tokenCost,
|
||
|
|
}: {
|
||
|
|
tokenCost: TokenCostResponse | null;
|
||
|
|
}) {
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
data-testid="token-cost-section"
|
||
|
|
style={{
|
||
|
|
border: "1px solid #2a2a2a",
|
||
|
|
borderRadius: "8px",
|
||
|
|
padding: "10px 12px",
|
||
|
|
background: "#161616",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<div
|
||
|
|
style={{
|
||
|
|
fontWeight: 600,
|
||
|
|
fontSize: "0.8em",
|
||
|
|
color: "#555",
|
||
|
|
marginBottom: "8px",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
Token Cost
|
||
|
|
</div>
|
||
|
|
{tokenCost && tokenCost.agents.length > 0 ? (
|
||
|
|
<div data-testid="token-cost-content">
|
||
|
|
<div
|
||
|
|
style={{
|
||
|
|
fontSize: "0.75em",
|
||
|
|
color: "#888",
|
||
|
|
marginBottom: "8px",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
Total:{" "}
|
||
|
|
<span data-testid="token-cost-total" style={{ color: "#ccc" }}>
|
||
|
|
${tokenCost.total_cost_usd.toFixed(6)}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
{tokenCost.agents.map((agent: AgentCostEntry) => (
|
||
|
|
<div
|
||
|
|
key={agent.agent_name}
|
||
|
|
data-testid={`token-cost-agent-${agent.agent_name}`}
|
||
|
|
style={{
|
||
|
|
fontSize: "0.75em",
|
||
|
|
color: "#888",
|
||
|
|
padding: "4px 0",
|
||
|
|
borderTop: "1px solid #222",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<div
|
||
|
|
style={{
|
||
|
|
display: "flex",
|
||
|
|
justifyContent: "space-between",
|
||
|
|
marginBottom: "2px",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<span style={{ color: "#ccc", fontWeight: 600 }}>
|
||
|
|
{agent.agent_name}
|
||
|
|
{agent.model ? (
|
||
|
|
<span
|
||
|
|
style={{ color: "#666", fontWeight: 400 }}
|
||
|
|
>{` (${agent.model})`}</span>
|
||
|
|
) : null}
|
||
|
|
</span>
|
||
|
|
<span style={{ color: "#aaa" }}>
|
||
|
|
${agent.total_cost_usd.toFixed(6)}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div style={{ color: "#555" }}>
|
||
|
|
in {agent.input_tokens.toLocaleString()} / out{" "}
|
||
|
|
{agent.output_tokens.toLocaleString()}
|
||
|
|
{(agent.cache_creation_input_tokens > 0 ||
|
||
|
|
agent.cache_read_input_tokens > 0) && (
|
||
|
|
<>
|
||
|
|
{" "}
|
||
|
|
/ cache +
|
||
|
|
{agent.cache_creation_input_tokens.toLocaleString()}{" "}
|
||
|
|
read {agent.cache_read_input_tokens.toLocaleString()}
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
) : (
|
||
|
|
<div
|
||
|
|
data-testid="token-cost-empty"
|
||
|
|
style={{ fontSize: "0.75em", color: "#444" }}
|
||
|
|
>
|
||
|
|
No token data recorded
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|