Skip to content

Commit e668169

Browse files
committed
feat: Add conversation context token counter
- Add contextTokens to ApiMetrics interface - Calculate context size using last API request's tokens - Display context token count in TaskHeader below total tokens - Use exact token counts instead of character estimation This helps users track the total size of their conversation context, which is useful for managing context window limits.
1 parent 86d4a10 commit e668169

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

src/shared/getApiMetrics.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ interface ApiMetrics {
66
totalCacheWrites?: number
77
totalCacheReads?: number
88
totalCost: number
9+
contextTokens: number // Total tokens in conversation (last message's tokensIn + tokensOut)
910
}
1011

1112
/**
@@ -32,8 +33,14 @@ export function getApiMetrics(messages: ClineMessage[]): ApiMetrics {
3233
totalCacheWrites: undefined,
3334
totalCacheReads: undefined,
3435
totalCost: 0,
36+
contextTokens: 0,
3537
}
3638

39+
// Find the last api_req_started message to get the context size
40+
const lastApiReq = [...messages]
41+
.reverse()
42+
.find((message) => message.type === "say" && message.say === "api_req_started" && message.text)
43+
3744
messages.forEach((message) => {
3845
if (message.type === "say" && message.say === "api_req_started" && message.text) {
3946
try {
@@ -55,6 +62,11 @@ export function getApiMetrics(messages: ClineMessage[]): ApiMetrics {
5562
if (typeof cost === "number") {
5663
result.totalCost += cost
5764
}
65+
66+
// If this is the last api request, use its tokens for context size
67+
if (message === lastApiReq) {
68+
result.contextTokens = (tokensIn || 0) + (tokensOut || 0)
69+
}
5870
} catch (error) {
5971
console.error("Error parsing JSON:", error)
6072
}

webview-ui/src/components/chat/ChatView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
915915
cacheWrites={apiMetrics.totalCacheWrites}
916916
cacheReads={apiMetrics.totalCacheReads}
917917
totalCost={apiMetrics.totalCost}
918+
contextTokens={apiMetrics.contextTokens}
918919
onClose={handleTaskCloseButtonClick}
919920
/>
920921
) : (

webview-ui/src/components/chat/TaskHeader.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ interface TaskHeaderProps {
1616
cacheWrites?: number
1717
cacheReads?: number
1818
totalCost: number
19+
contextTokens: number
1920
onClose: () => void
2021
}
2122

@@ -27,6 +28,7 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
2728
cacheWrites,
2829
cacheReads,
2930
totalCost,
31+
contextTokens,
3032
onClose,
3133
}) => {
3234
const { apiConfiguration } = useExtensionState()
@@ -272,6 +274,13 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
272274
{!isCostAvailable && <ExportButton />}
273275
</div>
274276

277+
<div style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" }}>
278+
<span style={{ fontWeight: "bold" }}>Context:</span>
279+
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
280+
{formatLargeNumber(contextTokens || 0)}
281+
</span>
282+
</div>
283+
275284
{shouldShowPromptCacheInfo && (cacheReads !== undefined || cacheWrites !== undefined) && (
276285
<div style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" }}>
277286
<span style={{ fontWeight: "bold" }}>Cache:</span>

0 commit comments

Comments
 (0)