mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: add includeVSCodeFileContext setting to control VSCode file context in API calls
- Add new global setting includeVSCodeFileContext (defaults to true) - Update getEnvironmentDetails to conditionally include VSCode file context - Add setting to ExtensionState and webview message handler - Add comprehensive tests for the new functionality This fixes issue #6194 where excessive VSCode file context was causing connection errors with LLMs that have limited context windows.
This commit is contained in:
parent
2170c61e3c
commit
d68eeb35c7
8 changed files with 123 additions and 34 deletions
|
|
@ -101,6 +101,7 @@ export const globalSettingsSchema = z.object({
|
|||
maxWorkspaceFiles: z.number().optional(),
|
||||
showRooIgnoredFiles: z.boolean().optional(),
|
||||
maxReadFileLine: z.number().optional(),
|
||||
includeVSCodeFileContext: z.boolean().optional(),
|
||||
|
||||
terminalOutputLineLimit: z.number().optional(),
|
||||
terminalOutputCharacterLimit: z.number().optional(),
|
||||
|
|
@ -272,6 +273,7 @@ export const EVALS_SETTINGS: RooCodeSettings = {
|
|||
maxWorkspaceFiles: 200,
|
||||
showRooIgnoredFiles: true,
|
||||
maxReadFileLine: -1, // -1 to enable full file reading.
|
||||
includeVSCodeFileContext: true, // Include VSCode file context in all API calls by default
|
||||
|
||||
includeDiagnosticMessages: true,
|
||||
maxDiagnosticMessages: 50,
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ describe("getEnvironmentDetails", () => {
|
|||
terminalOutputLineLimit: 100,
|
||||
maxWorkspaceFiles: 50,
|
||||
maxOpenTabsContext: 10,
|
||||
includeVSCodeFileContext: true,
|
||||
mode: "code",
|
||||
customModes: [],
|
||||
experiments: {},
|
||||
|
|
@ -361,4 +362,54 @@ describe("getEnvironmentDetails", () => {
|
|||
|
||||
await expect(getEnvironmentDetails(mockCline as Task)).resolves.not.toThrow()
|
||||
})
|
||||
|
||||
describe("VSCode file context inclusion", () => {
|
||||
it("should include VSCode file context when includeVSCodeFileContext is true", async () => {
|
||||
mockProvider.getState.mockResolvedValue({
|
||||
...mockState,
|
||||
includeVSCodeFileContext: true,
|
||||
})
|
||||
|
||||
const result = await getEnvironmentDetails(mockCline as Task, false)
|
||||
|
||||
expect(result).toContain("# VSCode Visible Files")
|
||||
expect(result).toContain("# VSCode Open Tabs")
|
||||
})
|
||||
|
||||
it("should exclude VSCode file context when includeVSCodeFileContext is false and includeFileDetails is false", async () => {
|
||||
mockProvider.getState.mockResolvedValue({
|
||||
...mockState,
|
||||
includeVSCodeFileContext: false,
|
||||
})
|
||||
|
||||
const result = await getEnvironmentDetails(mockCline as Task, false)
|
||||
|
||||
expect(result).not.toContain("# VSCode Visible Files")
|
||||
expect(result).not.toContain("# VSCode Open Tabs")
|
||||
})
|
||||
|
||||
it("should always include VSCode file context when includeFileDetails is true regardless of includeVSCodeFileContext", async () => {
|
||||
mockProvider.getState.mockResolvedValue({
|
||||
...mockState,
|
||||
includeVSCodeFileContext: false,
|
||||
})
|
||||
|
||||
const result = await getEnvironmentDetails(mockCline as Task, true)
|
||||
|
||||
expect(result).toContain("# VSCode Visible Files")
|
||||
expect(result).toContain("# VSCode Open Tabs")
|
||||
})
|
||||
|
||||
it("should default to including VSCode file context when includeVSCodeFileContext is undefined", async () => {
|
||||
mockProvider.getState.mockResolvedValue({
|
||||
...mockState,
|
||||
includeVSCodeFileContext: undefined,
|
||||
})
|
||||
|
||||
const result = await getEnvironmentDetails(mockCline as Task, false)
|
||||
|
||||
expect(result).toContain("# VSCode Visible Files")
|
||||
expect(result).toContain("# VSCode Open Tabs")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -30,48 +30,54 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo
|
|||
terminalOutputLineLimit = 500,
|
||||
terminalOutputCharacterLimit = DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
|
||||
maxWorkspaceFiles = 200,
|
||||
includeVSCodeFileContext = true,
|
||||
} = state ?? {}
|
||||
|
||||
// It could be useful for cline to know if the user went from one or no
|
||||
// file to another between messages, so we always include this context.
|
||||
details += "\n\n# VSCode Visible Files"
|
||||
// Only include VSCode file context if enabled in settings or if this is the first request
|
||||
const shouldIncludeVSCodeContext = includeFileDetails || includeVSCodeFileContext
|
||||
|
||||
const visibleFilePaths = vscode.window.visibleTextEditors
|
||||
?.map((editor) => editor.document?.uri?.fsPath)
|
||||
.filter(Boolean)
|
||||
.map((absolutePath) => path.relative(cline.cwd, absolutePath))
|
||||
.slice(0, maxWorkspaceFiles)
|
||||
if (shouldIncludeVSCodeContext) {
|
||||
// It could be useful for cline to know if the user went from one or no
|
||||
// file to another between messages, so we always include this context.
|
||||
details += "\n\n# VSCode Visible Files"
|
||||
|
||||
// Filter paths through rooIgnoreController
|
||||
const allowedVisibleFiles = cline.rooIgnoreController
|
||||
? cline.rooIgnoreController.filterPaths(visibleFilePaths)
|
||||
: visibleFilePaths.map((p) => p.toPosix()).join("\n")
|
||||
const visibleFilePaths = vscode.window.visibleTextEditors
|
||||
?.map((editor) => editor.document?.uri?.fsPath)
|
||||
.filter(Boolean)
|
||||
.map((absolutePath) => path.relative(cline.cwd, absolutePath))
|
||||
.slice(0, maxWorkspaceFiles)
|
||||
|
||||
if (allowedVisibleFiles) {
|
||||
details += `\n${allowedVisibleFiles}`
|
||||
} else {
|
||||
details += "\n(No visible files)"
|
||||
}
|
||||
// Filter paths through rooIgnoreController
|
||||
const allowedVisibleFiles = cline.rooIgnoreController
|
||||
? cline.rooIgnoreController.filterPaths(visibleFilePaths)
|
||||
: visibleFilePaths.map((p) => p.toPosix()).join("\n")
|
||||
|
||||
details += "\n\n# VSCode Open Tabs"
|
||||
const { maxOpenTabsContext } = state ?? {}
|
||||
const maxTabs = maxOpenTabsContext ?? 20
|
||||
const openTabPaths = vscode.window.tabGroups.all
|
||||
.flatMap((group) => group.tabs)
|
||||
.map((tab) => (tab.input as vscode.TabInputText)?.uri?.fsPath)
|
||||
.filter(Boolean)
|
||||
.map((absolutePath) => path.relative(cline.cwd, absolutePath).toPosix())
|
||||
.slice(0, maxTabs)
|
||||
if (allowedVisibleFiles) {
|
||||
details += `\n${allowedVisibleFiles}`
|
||||
} else {
|
||||
details += "\n(No visible files)"
|
||||
}
|
||||
|
||||
// Filter paths through rooIgnoreController
|
||||
const allowedOpenTabs = cline.rooIgnoreController
|
||||
? cline.rooIgnoreController.filterPaths(openTabPaths)
|
||||
: openTabPaths.map((p) => p.toPosix()).join("\n")
|
||||
details += "\n\n# VSCode Open Tabs"
|
||||
const { maxOpenTabsContext } = state ?? {}
|
||||
const maxTabs = maxOpenTabsContext ?? 20
|
||||
const openTabPaths = vscode.window.tabGroups.all
|
||||
.flatMap((group) => group.tabs)
|
||||
.map((tab) => (tab.input as vscode.TabInputText)?.uri?.fsPath)
|
||||
.filter(Boolean)
|
||||
.map((absolutePath) => path.relative(cline.cwd, absolutePath).toPosix())
|
||||
.slice(0, maxTabs)
|
||||
|
||||
if (allowedOpenTabs) {
|
||||
details += `\n${allowedOpenTabs}`
|
||||
} else {
|
||||
details += "\n(No open tabs)"
|
||||
// Filter paths through rooIgnoreController
|
||||
const allowedOpenTabs = cline.rooIgnoreController
|
||||
? cline.rooIgnoreController.filterPaths(openTabPaths)
|
||||
: openTabPaths.map((p) => p.toPosix()).join("\n")
|
||||
|
||||
if (allowedOpenTabs) {
|
||||
details += `\n${allowedOpenTabs}`
|
||||
} else {
|
||||
details += "\n(No open tabs)"
|
||||
}
|
||||
}
|
||||
|
||||
// Get task-specific and background terminals.
|
||||
|
|
|
|||
|
|
@ -1420,6 +1420,7 @@ export class ClineProvider
|
|||
experiments,
|
||||
maxOpenTabsContext,
|
||||
maxWorkspaceFiles,
|
||||
includeVSCodeFileContext,
|
||||
browserToolEnabled,
|
||||
telemetrySetting,
|
||||
showRooIgnoredFiles,
|
||||
|
|
@ -1523,6 +1524,7 @@ export class ClineProvider
|
|||
mcpServers: this.mcpHub?.getAllServers() ?? [],
|
||||
maxOpenTabsContext: maxOpenTabsContext ?? 20,
|
||||
maxWorkspaceFiles: maxWorkspaceFiles ?? 200,
|
||||
includeVSCodeFileContext: includeVSCodeFileContext ?? true,
|
||||
cwd,
|
||||
browserToolEnabled: browserToolEnabled ?? true,
|
||||
telemetrySetting,
|
||||
|
|
@ -1697,6 +1699,7 @@ export class ClineProvider
|
|||
customModes,
|
||||
maxOpenTabsContext: stateValues.maxOpenTabsContext ?? 20,
|
||||
maxWorkspaceFiles: stateValues.maxWorkspaceFiles ?? 200,
|
||||
includeVSCodeFileContext: stateValues.includeVSCodeFileContext ?? true,
|
||||
openRouterUseMiddleOutTransform: stateValues.openRouterUseMiddleOutTransform ?? true,
|
||||
browserToolEnabled: stateValues.browserToolEnabled ?? true,
|
||||
telemetrySetting: stateValues.telemetrySetting || "unset",
|
||||
|
|
|
|||
|
|
@ -528,6 +528,7 @@ describe("ClineProvider", () => {
|
|||
experiments: experimentDefault,
|
||||
maxOpenTabsContext: 20,
|
||||
maxWorkspaceFiles: 200,
|
||||
includeVSCodeFileContext: true,
|
||||
browserToolEnabled: true,
|
||||
telemetrySetting: "unset",
|
||||
showRooIgnoredFiles: true,
|
||||
|
|
@ -1079,6 +1080,25 @@ describe("ClineProvider", () => {
|
|||
expect(mockPostMessage).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("handles includeVSCodeFileContext message", async () => {
|
||||
await provider.resolveWebviewView(mockWebviewView)
|
||||
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
|
||||
|
||||
// Test setting to false
|
||||
await messageHandler({ type: "includeVSCodeFileContext", bool: false })
|
||||
|
||||
expect(updateGlobalStateSpy).toHaveBeenCalledWith("includeVSCodeFileContext", false)
|
||||
expect(mockContext.globalState.update).toHaveBeenCalledWith("includeVSCodeFileContext", false)
|
||||
expect(mockPostMessage).toHaveBeenCalled()
|
||||
|
||||
// Test setting to true
|
||||
await messageHandler({ type: "includeVSCodeFileContext", bool: true })
|
||||
|
||||
expect(updateGlobalStateSpy).toHaveBeenCalledWith("includeVSCodeFileContext", true)
|
||||
expect(mockContext.globalState.update).toHaveBeenCalledWith("includeVSCodeFileContext", true)
|
||||
expect(mockPostMessage).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("handles mode-specific custom instructions updates", async () => {
|
||||
await provider.resolveWebviewView(mockWebviewView)
|
||||
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
|
||||
|
|
|
|||
|
|
@ -1236,6 +1236,10 @@ export const webviewMessageHandler = async (
|
|||
await updateGlobalState("maxWorkspaceFiles", fileCount)
|
||||
await provider.postStateToWebview()
|
||||
break
|
||||
case "includeVSCodeFileContext":
|
||||
await updateGlobalState("includeVSCodeFileContext", message.bool ?? true)
|
||||
await provider.postStateToWebview()
|
||||
break
|
||||
case "alwaysAllowFollowupQuestions":
|
||||
await updateGlobalState("alwaysAllowFollowupQuestions", message.bool ?? false)
|
||||
await provider.postStateToWebview()
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ export type ExtensionState = Pick<
|
|||
// | "maxOpenTabsContext" // Optional in GlobalSettings, required here.
|
||||
// | "maxWorkspaceFiles" // Optional in GlobalSettings, required here.
|
||||
// | "showRooIgnoredFiles" // Optional in GlobalSettings, required here.
|
||||
// | "includeVSCodeFileContext" // Optional in GlobalSettings, required here.
|
||||
// | "maxReadFileLine" // Optional in GlobalSettings, required here.
|
||||
| "maxConcurrentFileReads" // Optional in GlobalSettings, required here.
|
||||
| "terminalOutputLineLimit"
|
||||
|
|
@ -277,6 +278,7 @@ export type ExtensionState = Pick<
|
|||
maxOpenTabsContext: number // Maximum number of VSCode open tabs to include in context (0-500)
|
||||
maxWorkspaceFiles: number // Maximum number of files to include in current working directory details (0-500)
|
||||
showRooIgnoredFiles: boolean // Whether to show .rooignore'd files in listings
|
||||
includeVSCodeFileContext: boolean // Whether to include VSCode file context (visible files and open tabs) in API calls after the first one
|
||||
maxReadFileLine: number // Maximum number of lines to read from a file before truncating
|
||||
|
||||
experiments: Experiments // Map of experiment IDs to their enabled state
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ export interface WebviewMessage {
|
|||
| "deleteMcpServer"
|
||||
| "maxOpenTabsContext"
|
||||
| "maxWorkspaceFiles"
|
||||
| "includeVSCodeFileContext"
|
||||
| "humanRelayResponse"
|
||||
| "humanRelayCancel"
|
||||
| "browserToolEnabled"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue