Skip to content

Commit ea6dc7c

Browse files
committed
feat(ui): add context window percentage to task header
Display the percentage of total context window used alongside token count in the task header. This helps users better understand their context usage relative to the model's capacity. Implementation details: - Retrieve model's context window size from normalized API configuration - Calculate percentage of context window used based on current context tokens - Display percentage in parentheses next to token count (e.g. "40,000 (20%)") - Default to context window size of 1 if model info is unavailable - Format numbers with commas for better readability
1 parent f7cf08c commit ea6dc7c

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

src/core/Cline.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3043,7 +3043,11 @@ export class Cline {
30433043

30443044
// Add context tokens information
30453045
const { contextTokens } = getApiMetrics(this.clineMessages)
3046-
details += `\n\n# Current Context Size (Tokens)\n${contextTokens ? contextTokens.toLocaleString() : "(Not available)"}`
3046+
const modelInfo = this.api.getModel().info
3047+
const contextWindow = modelInfo.contextWindow
3048+
const contextPercentage =
3049+
contextTokens && contextWindow ? Math.round((contextTokens / contextWindow) * 100) : undefined
3050+
details += `\n\n# Current Context Size (Tokens)\n${contextTokens ? `${contextTokens.toLocaleString()} (${contextPercentage}%)` : "(Not available)"}`
30473051

30483052
// Add current mode and any mode-specific warnings
30493053
const { mode, customModes } = (await this.providerRef.deref()?.getState()) ?? {}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { vscode } from "../../utils/vscode"
77
import Thumbnails from "../common/Thumbnails"
88
import { mentionRegexGlobal } from "../../../../src/shared/context-mentions"
99
import { formatLargeNumber } from "../../utils/format"
10+
import { normalizeApiConfiguration } from "../settings/ApiOptions"
1011

1112
interface TaskHeaderProps {
1213
task: ClineMessage
@@ -32,11 +33,14 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
3233
onClose,
3334
}) => {
3435
const { apiConfiguration } = useExtensionState()
36+
const { selectedModelInfo } = useMemo(() => normalizeApiConfiguration(apiConfiguration), [apiConfiguration])
3537
const [isTaskExpanded, setIsTaskExpanded] = useState(true)
3638
const [isTextExpanded, setIsTextExpanded] = useState(false)
3739
const [showSeeMore, setShowSeeMore] = useState(false)
3840
const textContainerRef = useRef<HTMLDivElement>(null)
3941
const textRef = useRef<HTMLDivElement>(null)
42+
const contextWindow = selectedModelInfo?.contextWindow || 1
43+
const contextPercentage = Math.round((contextTokens / contextWindow) * 100)
4044

4145
/*
4246
When dealing with event listeners in React components that depend on state variables, we face a challenge. We want our listener to always use the most up-to-date version of a callback function that relies on current state, but we don't want to constantly add and remove event listeners as that function updates. This scenario often arises with resize listeners or other window events. Simply adding the listener in a useEffect with an empty dependency array risks using stale state, while including the callback in the dependencies can lead to unnecessary re-registrations of the listener. There are react hook libraries that provide a elegant solution to this problem by utilizing the useRef hook to maintain a reference to the latest callback function without triggering re-renders or effect re-runs. This approach ensures that our event listener always has access to the most current state while minimizing performance overhead and potential memory leaks from multiple listener registrations.
@@ -277,7 +281,9 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
277281
<div style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" }}>
278282
<span style={{ fontWeight: "bold" }}>Context:</span>
279283
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
280-
{contextTokens ? formatLargeNumber(contextTokens) : '-'}
284+
{contextTokens
285+
? `${formatLargeNumber(contextTokens)} (${contextPercentage}%)`
286+
: "-"}
281287
</span>
282288
</div>
283289

0 commit comments

Comments
 (0)