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
9 changes: 9 additions & 0 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ import { languagesSchema } from "./vscode.js"
*/
export const DEFAULT_WRITE_DELAY_MS = 1000

/**
* Default terminal output character limit constant.
* This provides a reasonable default that aligns with typical terminal usage
* while preventing context window explosions from extremely long lines.
*/
export const DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT = 50_000

/**
* GlobalSettings
*/
Expand Down Expand Up @@ -85,6 +92,7 @@ export const globalSettingsSchema = z.object({
maxReadFileLine: z.number().optional(),

terminalOutputLineLimit: z.number().optional(),
terminalOutputCharacterLimit: z.number().optional(),
terminalShellIntegrationTimeout: z.number().optional(),
terminalShellIntegrationDisabled: z.boolean().optional(),
terminalCommandDelay: z.number().optional(),
Expand Down Expand Up @@ -227,6 +235,7 @@ export const EVALS_SETTINGS: RooCodeSettings = {
soundVolume: 0.5,

terminalOutputLineLimit: 500,
terminalOutputCharacterLimit: DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
terminalShellIntegrationTimeout: 30000,
terminalCommandDelay: 0,
terminalPowershellCounter: false,
Expand Down
19 changes: 16 additions & 3 deletions src/core/environment/getEnvironmentDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import pWaitFor from "p-wait-for"
import delay from "delay"

import type { ExperimentId } from "@roo-code/types"
import { DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT } from "@roo-code/types"

import { EXPERIMENT_IDS, experiments as Experiments } from "../../shared/experiments"
import { formatLanguage } from "../../shared/language"
Expand All @@ -25,7 +26,11 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo

const clineProvider = cline.providerRef.deref()
const state = await clineProvider?.getState()
const { terminalOutputLineLimit = 500, maxWorkspaceFiles = 200 } = state ?? {}
const {
terminalOutputLineLimit = 500,
terminalOutputCharacterLimit = DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
maxWorkspaceFiles = 200,
} = 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.
Expand Down Expand Up @@ -111,7 +116,11 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo
let newOutput = TerminalRegistry.getUnretrievedOutput(busyTerminal.id)

if (newOutput) {
newOutput = Terminal.compressTerminalOutput(newOutput, terminalOutputLineLimit)
newOutput = Terminal.compressTerminalOutput(
newOutput,
terminalOutputLineLimit,
terminalOutputCharacterLimit,
)
terminalDetails += `\n### New Output\n${newOutput}`
}
}
Expand Down Expand Up @@ -139,7 +148,11 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo
let output = process.getUnretrievedOutput()

if (output) {
output = Terminal.compressTerminalOutput(output, terminalOutputLineLimit)
output = Terminal.compressTerminalOutput(
output,
terminalOutputLineLimit,
terminalOutputCharacterLimit,
)
terminalOutputs.push(`Command: \`${process.command}\`\n${output}`)
}
}
Expand Down
23 changes: 19 additions & 4 deletions src/core/tools/executeCommandTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as vscode from "vscode"

import delay from "delay"

import { CommandExecutionStatus } from "@roo-code/types"
import { CommandExecutionStatus, DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT } from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"

import { Task } from "../task/Task"
Expand Down Expand Up @@ -63,7 +63,11 @@ export async function executeCommandTool(
const executionId = cline.lastMessageTs?.toString() ?? Date.now().toString()
const clineProvider = await cline.providerRef.deref()
const clineProviderState = await clineProvider?.getState()
const { terminalOutputLineLimit = 500, terminalShellIntegrationDisabled = false } = clineProviderState ?? {}
const {
terminalOutputLineLimit = 500,
terminalOutputCharacterLimit = DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
terminalShellIntegrationDisabled = false,
} = clineProviderState ?? {}

// Get command execution timeout from VSCode configuration (in seconds)
const commandExecutionTimeoutSeconds = vscode.workspace
Expand All @@ -87,6 +91,7 @@ export async function executeCommandTool(
customCwd,
terminalShellIntegrationDisabled,
terminalOutputLineLimit,
terminalOutputCharacterLimit,
commandExecutionTimeout,
}

Expand Down Expand Up @@ -133,6 +138,7 @@ export type ExecuteCommandOptions = {
customCwd?: string
terminalShellIntegrationDisabled?: boolean
terminalOutputLineLimit?: number
terminalOutputCharacterLimit?: number
commandExecutionTimeout?: number
}

Expand All @@ -144,6 +150,7 @@ export async function executeCommand(
customCwd,
terminalShellIntegrationDisabled = false,
terminalOutputLineLimit = 500,
terminalOutputCharacterLimit = DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
commandExecutionTimeout = 0,
}: ExecuteCommandOptions,
): Promise<[boolean, ToolResponse]> {
Expand Down Expand Up @@ -179,7 +186,11 @@ export async function executeCommand(
const callbacks: RooTerminalCallbacks = {
onLine: async (lines: string, process: RooTerminalProcess) => {
accumulatedOutput += lines
const compressedOutput = Terminal.compressTerminalOutput(accumulatedOutput, terminalOutputLineLimit)
const compressedOutput = Terminal.compressTerminalOutput(
accumulatedOutput,
terminalOutputLineLimit,
terminalOutputCharacterLimit,
)
const status: CommandExecutionStatus = { executionId, status: "output", output: compressedOutput }
clineProvider?.postMessageToWebview({ type: "commandExecutionStatus", text: JSON.stringify(status) })

Expand All @@ -198,7 +209,11 @@ export async function executeCommand(
} catch (_error) {}
},
onCompleted: (output: string | undefined) => {
result = Terminal.compressTerminalOutput(output ?? "", terminalOutputLineLimit)
result = Terminal.compressTerminalOutput(
output ?? "",
terminalOutputLineLimit,
terminalOutputCharacterLimit,
)
cline.say("command_output", result)
completed = true
},
Expand Down
5 changes: 5 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
openRouterDefaultModelId,
glamaDefaultModelId,
ORGANIZATION_ALLOW_ALL,
DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
} from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
import { CloudService, getRooCodeApiUrl } from "@roo-code/cloud"
Expand Down Expand Up @@ -1393,6 +1394,7 @@ export class ClineProvider
cachedChromeHostUrl,
writeDelayMs,
terminalOutputLineLimit,
terminalOutputCharacterLimit,
terminalShellIntegrationTimeout,
terminalShellIntegrationDisabled,
terminalCommandDelay,
Expand Down Expand Up @@ -1493,6 +1495,7 @@ export class ClineProvider
cachedChromeHostUrl: cachedChromeHostUrl,
writeDelayMs: writeDelayMs ?? DEFAULT_WRITE_DELAY_MS,
terminalOutputLineLimit: terminalOutputLineLimit ?? 500,
terminalOutputCharacterLimit: terminalOutputCharacterLimit ?? DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
terminalShellIntegrationTimeout: terminalShellIntegrationTimeout ?? Terminal.defaultShellIntegrationTimeout,
terminalShellIntegrationDisabled: terminalShellIntegrationDisabled ?? false,
terminalCommandDelay: terminalCommandDelay ?? 0,
Expand Down Expand Up @@ -1662,6 +1665,8 @@ export class ClineProvider
fuzzyMatchThreshold: stateValues.fuzzyMatchThreshold ?? 1.0,
writeDelayMs: stateValues.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS,
terminalOutputLineLimit: stateValues.terminalOutputLineLimit ?? 500,
terminalOutputCharacterLimit:
stateValues.terminalOutputCharacterLimit ?? DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
terminalShellIntegrationTimeout:
stateValues.terminalShellIntegrationTimeout ?? Terminal.defaultShellIntegrationTimeout,
terminalShellIntegrationDisabled: stateValues.terminalShellIntegrationDisabled ?? false,
Expand Down
25 changes: 23 additions & 2 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1049,8 +1049,29 @@ export const webviewMessageHandler = async (
await provider.postStateToWebview()
break
case "terminalOutputLineLimit":
await updateGlobalState("terminalOutputLineLimit", message.value)
await provider.postStateToWebview()
// Validate that the line limit is a positive number
const lineLimit = message.value
if (typeof lineLimit === "number" && lineLimit > 0) {
await updateGlobalState("terminalOutputLineLimit", lineLimit)
await provider.postStateToWebview()
} else {
vscode.window.showErrorMessage(
t("common:errors.invalid_line_limit") || "Terminal output line limit must be a positive number",
)
}
break
case "terminalOutputCharacterLimit":
// Validate that the character limit is a positive number
const charLimit = message.value
if (typeof charLimit === "number" && charLimit > 0) {
await updateGlobalState("terminalOutputCharacterLimit", charLimit)
await provider.postStateToWebview()
} else {
vscode.window.showErrorMessage(
t("common:errors.invalid_character_limit") ||
"Terminal output character limit must be a positive number",
)
}
break
case "terminalShellIntegrationTimeout":
await updateGlobalState("terminalShellIntegrationTimeout", message.value)
Expand Down
Loading