Skip to content

Commit e37f6e3

Browse files
authored
Context in context (RooCodeInc#2745)
* context in context * keeping comments * minimal context window line * nit
1 parent 4c72bd9 commit e37f6e3

File tree

4 files changed

+73
-20
lines changed

4 files changed

+73
-20
lines changed

.changeset/curvy-walls-cry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": minor
3+
---
4+
5+
Added context window usage to env variables context for messages

src/core/context-management/ContextManager.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Anthropic } from "@anthropic-ai/sdk"
22
import { ClineApiReqInfo, ClineMessage } from "../../shared/ExtensionMessage"
33
import { ApiHandler } from "../../api"
4-
import { OpenAiHandler } from "../../api/providers/openai"
4+
import { getContextWindowInfo } from "./context-window-utils"
55
import { formatResponse } from "../prompts/responses"
66
import { GlobalFileNames } from "../storage/disk"
77
import { fileExistsAtPath } from "../../utils/fs"
@@ -125,25 +125,7 @@ export class ContextManager {
125125
const timestamp = previousRequest.ts
126126
const { tokensIn, tokensOut, cacheWrites, cacheReads }: ClineApiReqInfo = JSON.parse(previousRequest.text)
127127
const totalTokens = (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0)
128-
let contextWindow = api.getModel().info.contextWindow || 128_000
129-
// FIXME: hack to get anyone using openai compatible with deepseek to have the proper context window instead of the default 128k. We need a way for the user to specify the context window for models they input through openai compatible
130-
if (api instanceof OpenAiHandler && api.getModel().id.toLowerCase().includes("deepseek")) {
131-
contextWindow = 64_000
132-
}
133-
let maxAllowedSize: number
134-
switch (contextWindow) {
135-
case 64_000: // deepseek models
136-
maxAllowedSize = contextWindow - 27_000
137-
break
138-
case 128_000: // most models
139-
maxAllowedSize = contextWindow - 30_000
140-
break
141-
case 200_000: // claude models
142-
maxAllowedSize = contextWindow - 40_000
143-
break
144-
default:
145-
maxAllowedSize = Math.max(contextWindow - 40_000, contextWindow * 0.8) // for deepseek, 80% of 64k meant only ~10k buffer which was too small and resulted in users getting context window errors.
146-
}
128+
const { maxAllowedSize } = getContextWindowInfo(api)
147129

148130
// This is the most reliable way to know when we're close to hitting the context window.
149131
if (totalTokens >= maxAllowedSize) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { ApiHandler } from "../../api"
2+
import { OpenAiHandler } from "../../api/providers/openai"
3+
4+
/**
5+
* Gets context window information for the given API handler
6+
*
7+
* @param api The API handler to get context window information for
8+
* @returns An object containing the raw context window size and the effective max allowed size
9+
*/
10+
export function getContextWindowInfo(api: ApiHandler) {
11+
let contextWindow = api.getModel().info.contextWindow || 128_000
12+
// FIXME: hack to get anyone using openai compatible with deepseek to have the proper context window instead of the default 128k. We need a way for the user to specify the context window for models they input through openai compatible
13+
14+
// Handle special cases like DeepSeek
15+
if (api instanceof OpenAiHandler && api.getModel().id.toLowerCase().includes("deepseek")) {
16+
contextWindow = 64_000
17+
}
18+
19+
let maxAllowedSize: number
20+
switch (contextWindow) {
21+
case 64_000: // deepseek models
22+
maxAllowedSize = contextWindow - 27_000
23+
break
24+
case 128_000: // most models
25+
maxAllowedSize = contextWindow - 30_000
26+
break
27+
case 200_000: // claude models
28+
maxAllowedSize = contextWindow - 40_000
29+
break
30+
default:
31+
maxAllowedSize = Math.max(contextWindow - 40_000, contextWindow * 0.8) // for deepseek, 80% of 64k meant only ~10k buffer which was too small and resulted in users getting context window errors.
32+
}
33+
34+
return { contextWindow, maxAllowedSize }
35+
}

src/core/task/index.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ApiHandler, buildApiHandler } from "../../api"
1313
import { AnthropicHandler } from "../../api/providers/anthropic"
1414
import { ClineHandler } from "../../api/providers/cline"
1515
import { OpenRouterHandler } from "../../api/providers/openrouter"
16+
import { getContextWindowInfo } from "../context-management/context-window-utils"
1617
import { ApiStream } from "../../api/transform/stream"
1718
import CheckpointTracker from "../../integrations/checkpoints/CheckpointTracker"
1819
import { DIFF_VIEW_URI_SCHEME, DiffViewProvider } from "../../integrations/editor/DiffViewProvider"
@@ -3682,6 +3683,36 @@ export class Task {
36823683
}
36833684
}
36843685

3686+
// Add context window usage information
3687+
const { contextWindow, maxAllowedSize } = getContextWindowInfo(this.api)
3688+
3689+
// Get the token count from the most recent API request to accurately reflect context management
3690+
const getTotalTokensFromApiReqMessage = (msg: ClineMessage) => {
3691+
if (!msg.text) {
3692+
return 0
3693+
}
3694+
try {
3695+
const { tokensIn, tokensOut, cacheWrites, cacheReads } = JSON.parse(msg.text)
3696+
return (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0)
3697+
} catch (e) {
3698+
return 0
3699+
}
3700+
}
3701+
3702+
const modifiedMessages = combineApiRequests(combineCommandSequences(this.clineMessages.slice(1)))
3703+
const lastApiReqMessage = findLast(modifiedMessages, (msg) => {
3704+
if (msg.say !== "api_req_started") {
3705+
return false
3706+
}
3707+
return getTotalTokensFromApiReqMessage(msg) > 0
3708+
})
3709+
3710+
const lastApiReqTotalTokens = lastApiReqMessage ? getTotalTokensFromApiReqMessage(lastApiReqMessage) : 0
3711+
const usagePercentage = Math.round((lastApiReqTotalTokens / contextWindow) * 100)
3712+
3713+
details += "\n# Context Window Usage"
3714+
details += `\n${lastApiReqTotalTokens.toLocaleString()} / ${(contextWindow / 1000).toLocaleString()}K tokens used (${usagePercentage}%)`
3715+
36853716
details += "\n\n# Current Mode"
36863717
if (this.chatSettings.mode === "plan") {
36873718
details += "\nPLAN MODE\n" + formatResponse.planModeInstructions()

0 commit comments

Comments
 (0)