-
Notifications
You must be signed in to change notification settings - Fork 307
Expand file tree
/
Copy pathUsageCounter.tsx
More file actions
99 lines (92 loc) · 2.99 KB
/
UsageCounter.tsx
File metadata and controls
99 lines (92 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import React from "react";
import { Card, Flex, HoverCard, Text } from "@radix-ui/themes";
import { ArrowDownIcon, ArrowUpIcon } from "@radix-ui/react-icons";
import { ScrollArea } from "../../ScrollArea";
import { calculateUsageInputTokens } from "../../../utils/calculateUsageInputTokens";
import type { Usage } from "../../../services/refact";
import styles from "./UsageCounter.module.css";
type UsageCounterProps = {
usage: Usage;
};
function formatNumber(num: number): string {
return num >= 1_000_000
? (num / 1_000_000).toFixed(1) + "M"
: num >= 1_000
? (num / 1_000).toFixed(2) + "k"
: num.toString();
}
const TokenDisplay: React.FC<{ label: string; value: number }> = ({
label,
value,
}) => (
<Flex align="center" justify="between" width="100%">
<Text size="1" weight="bold">
{label}
</Text>
<Text size="1">{value}</Text>
</Flex>
);
export const UsageCounter: React.FC<UsageCounterProps> = ({ usage }) => {
const inputTokens = calculateUsageInputTokens(usage, [
"prompt_tokens",
"cache_creation_input_tokens",
"cache_read_input_tokens",
]);
const outputTokens = calculateUsageInputTokens(usage, ["completion_tokens"]);
return (
<HoverCard.Root>
<HoverCard.Trigger>
<Card className={styles.usageCounterContainer}>
<Flex align="center">
<ArrowUpIcon width="12" height="12" />
<Text size="1">{formatNumber(inputTokens)}</Text>
</Flex>
<Flex align="center">
<ArrowDownIcon width="12" height="12" />
<Text size="1">{outputTokens}</Text>
</Flex>
</Card>
</HoverCard.Trigger>
<ScrollArea scrollbars="both" asChild>
<HoverCard.Content
size="1"
maxHeight="50vh"
maxWidth="90vw"
minWidth="300px"
avoidCollisions
align="end"
side="top"
>
<Flex direction="column" align="start" gap="2">
<Text size="2" mb="2">
Tokens spent per message:
</Text>
<TokenDisplay
label="Input tokens (in total):"
value={inputTokens}
/>
{usage.cache_read_input_tokens !== undefined && (
<TokenDisplay
label="Cache read input tokens:"
value={usage.cache_read_input_tokens}
/>
)}
{usage.cache_creation_input_tokens !== undefined && (
<TokenDisplay
label="Cache creation input tokens:"
value={usage.cache_creation_input_tokens}
/>
)}
<TokenDisplay label="Completion tokens:" value={outputTokens} />
{usage.completion_tokens_details && (
<TokenDisplay
label="Reasoning tokens:"
value={usage.completion_tokens_details.reasoning_tokens}
/>
)}
</Flex>
</HoverCard.Content>
</ScrollArea>
</HoverCard.Root>
);
};