diff --git a/src/core/Cline.ts b/src/core/Cline.ts
index 34d20120567..9c2977a2669 100644
--- a/src/core/Cline.ts
+++ b/src/core/Cline.ts
@@ -3112,11 +3112,14 @@ export class Cline {
}
details += "\n\n# VSCode Open Tabs"
+ const { maxOpenTabsContext } = (await this.providerRef.deref()?.getState()) ?? {}
+ const maxTabs = maxOpenTabsContext ?? 20
const openTabs = vscode.window.tabGroups.all
.flatMap((group) => group.tabs)
.map((tab) => (tab.input as vscode.TabInputText)?.uri?.fsPath)
.filter(Boolean)
.map((absolutePath) => path.relative(cwd, absolutePath).toPosix())
+ .slice(0, maxTabs)
.join("\n")
if (openTabs) {
details += `\n${openTabs}`
diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts
index eeefc7578cc..0d59d78e716 100644
--- a/src/core/webview/ClineProvider.ts
+++ b/src/core/webview/ClineProvider.ts
@@ -127,6 +127,7 @@ type GlobalStateKey =
| "requestyModelInfo"
| "unboundModelInfo"
| "modelTemperature"
+ | "maxOpenTabsContext"
export const GlobalFileNames = {
apiConversationHistory: "api_conversation_history.json",
@@ -1207,6 +1208,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.updateGlobalState("screenshotQuality", message.value)
await this.postStateToWebview()
break
+ case "maxOpenTabsContext":
+ const tabCount = Math.min(Math.max(0, message.value ?? 20), 500)
+ await this.updateGlobalState("maxOpenTabsContext", tabCount)
+ await this.postStateToWebview()
+ break
case "enhancementApiConfigId":
await this.updateGlobalState("enhancementApiConfigId", message.text)
await this.postStateToWebview()
@@ -2378,6 +2384,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
enhancementApiConfigId,
autoApprovalEnabled,
experiments,
+ maxOpenTabsContext,
} = await this.getState()
const allowedCommands = vscode.workspace.getConfiguration("roo-cline").get("allowedCommands") || []
@@ -2427,6 +2434,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
customModes: await this.customModesManager.getCustomModes(),
experiments: experiments ?? experimentDefault,
mcpServers: this.mcpHub?.getAllServers() ?? [],
+ maxOpenTabsContext: maxOpenTabsContext ?? 20,
}
}
@@ -2562,6 +2570,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
requestyModelId,
requestyModelInfo,
modelTemperature,
+ maxOpenTabsContext,
] = await Promise.all([
this.getGlobalState("apiProvider") as Promise,
this.getGlobalState("apiModelId") as Promise,
@@ -2642,6 +2651,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("requestyModelId") as Promise,
this.getGlobalState("requestyModelInfo") as Promise,
this.getGlobalState("modelTemperature") as Promise,
+ this.getGlobalState("maxOpenTabsContext") as Promise,
])
let apiProvider: ApiProvider
@@ -2768,6 +2778,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
experiments: experiments ?? experimentDefault,
autoApprovalEnabled: autoApprovalEnabled ?? false,
customModes,
+ maxOpenTabsContext: maxOpenTabsContext ?? 20,
}
}
diff --git a/src/core/webview/__tests__/ClineProvider.test.ts b/src/core/webview/__tests__/ClineProvider.test.ts
index 25a4f0bd166..227c032a8fc 100644
--- a/src/core/webview/__tests__/ClineProvider.test.ts
+++ b/src/core/webview/__tests__/ClineProvider.test.ts
@@ -351,6 +351,7 @@ describe("ClineProvider", () => {
mode: defaultModeSlug,
customModes: [],
experiments: experimentDefault,
+ maxOpenTabsContext: 20,
}
const message: ExtensionMessage = {
diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts
index 76a029d487b..fe9fa394270 100644
--- a/src/shared/ExtensionMessage.ts
+++ b/src/shared/ExtensionMessage.ts
@@ -128,6 +128,7 @@ export interface ExtensionState {
autoApprovalEnabled?: boolean
customModes: ModeConfig[]
toolRequirements?: Record // Map of tool names to their requirements (e.g. {"apply_diff": true} if diffEnabled)
+ maxOpenTabsContext: number // Maximum number of VSCode open tabs to include in context (0-500)
}
export interface ClineMessage {
diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts
index 33da2a117f4..fd26f887c86 100644
--- a/src/shared/WebviewMessage.ts
+++ b/src/shared/WebviewMessage.ts
@@ -92,6 +92,7 @@ export interface WebviewMessage {
| "openCustomModesSettings"
| "checkpointDiff"
| "checkpointRestore"
+ | "maxOpenTabsContext"
text?: string
disabled?: boolean
askResponse?: ClineAskResponse
diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx
index 307ac250da6..b866561adff 100644
--- a/webview-ui/src/components/settings/SettingsView.tsx
+++ b/webview-ui/src/components/settings/SettingsView.tsx
@@ -63,6 +63,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
setExperimentEnabled,
alwaysAllowModeSwitch,
setAlwaysAllowModeSwitch,
+ maxOpenTabsContext,
+ setMaxOpenTabsContext,
} = useExtensionState()
const [apiErrorMessage, setApiErrorMessage] = useState(undefined)
const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined)
@@ -104,6 +106,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
vscode.postMessage({ type: "alwaysApproveResubmit", bool: alwaysApproveResubmit })
vscode.postMessage({ type: "requestDelaySeconds", value: requestDelaySeconds })
vscode.postMessage({ type: "rateLimitSeconds", value: rateLimitSeconds })
+ vscode.postMessage({ type: "maxOpenTabsContext", value: maxOpenTabsContext })
vscode.postMessage({ type: "currentApiConfigName", text: currentApiConfigName })
vscode.postMessage({
type: "upsertApiConfiguration",
@@ -626,6 +629,28 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
+
+
+
Open tabs context limit
+
+ setMaxOpenTabsContext(parseInt(e.target.value))}
+ style={{ ...sliderStyle }}
+ />
+ {maxOpenTabsContext ?? 20}
+
+
+
+ Maximum number of VSCode open tabs to include in context. Higher values provide more context
+ but increase token usage.
+
+
+
(event: any) => void
customModes: ModeConfig[]
setCustomModes: (value: ModeConfig[]) => void
+ setMaxOpenTabsContext: (value: number) => void
}
export const ExtensionStateContext = createContext(undefined)
@@ -117,6 +118,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
enhancementApiConfigId: "",
autoApprovalEnabled: false,
customModes: [],
+ maxOpenTabsContext: 20,
})
const [didHydrateState, setDidHydrateState] = useState(false)
@@ -350,6 +352,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setAutoApprovalEnabled: (value) => setState((prevState) => ({ ...prevState, autoApprovalEnabled: value })),
handleInputChange,
setCustomModes: (value) => setState((prevState) => ({ ...prevState, customModes: value })),
+ setMaxOpenTabsContext: (value) => setState((prevState) => ({ ...prevState, maxOpenTabsContext: value })),
}
return {children}