Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/core/Cline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
Expand Down
11 changes: 11 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ type GlobalStateKey =
| "requestyModelInfo"
| "unboundModelInfo"
| "modelTemperature"
| "maxOpenTabsContext"

export const GlobalFileNames = {
apiConversationHistory: "api_conversation_history.json",
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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<string[]>("allowedCommands") || []
Expand Down Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -2562,6 +2570,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
requestyModelId,
requestyModelInfo,
modelTemperature,
maxOpenTabsContext,
] = await Promise.all([
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
this.getGlobalState("apiModelId") as Promise<string | undefined>,
Expand Down Expand Up @@ -2642,6 +2651,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("requestyModelId") as Promise<string | undefined>,
this.getGlobalState("requestyModelInfo") as Promise<ModelInfo | undefined>,
this.getGlobalState("modelTemperature") as Promise<number | undefined>,
this.getGlobalState("maxOpenTabsContext") as Promise<number | undefined>,
])

let apiProvider: ApiProvider
Expand Down Expand Up @@ -2768,6 +2778,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
experiments: experiments ?? experimentDefault,
autoApprovalEnabled: autoApprovalEnabled ?? false,
customModes,
maxOpenTabsContext: maxOpenTabsContext ?? 20,
}
}

Expand Down
1 change: 1 addition & 0 deletions src/core/webview/__tests__/ClineProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ describe("ClineProvider", () => {
mode: defaultModeSlug,
customModes: [],
experiments: experimentDefault,
maxOpenTabsContext: 20,
}

const message: ExtensionMessage = {
Expand Down
1 change: 1 addition & 0 deletions src/shared/ExtensionMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export interface ExtensionState {
autoApprovalEnabled?: boolean
customModes: ModeConfig[]
toolRequirements?: Record<string, boolean> // 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 {
Expand Down
1 change: 1 addition & 0 deletions src/shared/WebviewMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export interface WebviewMessage {
| "openCustomModesSettings"
| "checkpointDiff"
| "checkpointRestore"
| "maxOpenTabsContext"
text?: string
disabled?: boolean
askResponse?: ClineAskResponse
Expand Down
25 changes: 25 additions & 0 deletions webview-ui/src/components/settings/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
setExperimentEnabled,
alwaysAllowModeSwitch,
setAlwaysAllowModeSwitch,
maxOpenTabsContext,
setMaxOpenTabsContext,
} = useExtensionState()
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
const [modelIdErrorMessage, setModelIdErrorMessage] = useState<string | undefined>(undefined)
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -626,6 +629,28 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
</p>
</div>

<div style={{ marginBottom: 15 }}>
<div style={{ display: "flex", flexDirection: "column", gap: "5px" }}>
<span style={{ fontWeight: "500" }}>Open tabs context limit</span>
<div style={{ display: "flex", alignItems: "center", gap: "5px" }}>
<input
type="range"
min="0"
max="500"
step="1"
value={maxOpenTabsContext ?? 20}
onChange={(e) => setMaxOpenTabsContext(parseInt(e.target.value))}
style={{ ...sliderStyle }}
/>
<span style={{ ...sliderLabelStyle }}>{maxOpenTabsContext ?? 20}</span>
</div>
</div>
<p style={{ fontSize: "12px", marginTop: "5px", color: "var(--vscode-descriptionForeground)" }}>
Maximum number of VSCode open tabs to include in context. Higher values provide more context
but increase token usage.
</p>
</div>

<div style={{ marginBottom: 15 }}>
<VSCodeCheckbox
checked={diffEnabled}
Expand Down
3 changes: 3 additions & 0 deletions webview-ui/src/context/ExtensionStateContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface ExtensionStateContextType extends ExtensionState {
handleInputChange: (field: keyof ApiConfiguration, softUpdate?: boolean) => (event: any) => void
customModes: ModeConfig[]
setCustomModes: (value: ModeConfig[]) => void
setMaxOpenTabsContext: (value: number) => void
}

export const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
Expand Down Expand Up @@ -117,6 +118,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
enhancementApiConfigId: "",
autoApprovalEnabled: false,
customModes: [],
maxOpenTabsContext: 20,
})

const [didHydrateState, setDidHydrateState] = useState(false)
Expand Down Expand Up @@ -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 <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>
Expand Down
Loading