From 0b4fa0b1d6cbc82da343bcdd8c04119b26e9ea02 Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Sun, 9 Mar 2025 19:23:58 -0700 Subject: [PATCH] feat: compress repeated terminal output lines Add Terminal.compressTerminalOutput static method to apply run-length encoding before truncating terminal output. This significantly reduces output size for repeated lines while maintaining readability. - Add compressTerminalOutput static method to Terminal class - Replace all truncateOutput calls with Terminal.compressTerminalOutput - Import required functions from extract-text Test program demonstrating compression: ```python def generate_repeats(): patterns = [ ("A\n", 10), # 10 lines ("AA\n", 100), # 100 lines ("AAA\n", 1000), # 1K lines ("AAAA\n", 10000), # 10K lines ("AAAAA\n", 100000), # 100K lines ("AAAAAA\n", 1000000) # 1M lines ] for text, count in patterns: print(text * count, end="") ``` Sample output showing compression: ``` A A A A A A A A A A AA AAA AAAA AAAAA AAAAAA ``` Signed-off-by: Eric Wheeler --- src/core/Cline.ts | 12 ++++++------ src/integrations/terminal/Terminal.ts | 10 ++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index d043e63412..4a93acec5c 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -25,9 +25,9 @@ import { addLineNumbers, stripLineNumbers, everyLineHasLineNumbers, - truncateOutput, } from "../integrations/misc/extract-text" import { ExitCodeDetails } from "../integrations/terminal/TerminalProcess" +import { Terminal } from "../integrations/terminal/Terminal" import { TerminalRegistry } from "../integrations/terminal/TerminalRegistry" import { UrlContentFetcher } from "../services/browser/UrlContentFetcher" import { listFiles } from "../services/glob/list-files" @@ -968,9 +968,9 @@ export class Cline { process.on("line", (line) => { if (!didContinue) { - sendCommandOutput(truncateOutput(line, terminalOutputLineLimit)) + sendCommandOutput(Terminal.compressTerminalOutput(line, terminalOutputLineLimit)) } else { - this.say("command_output", truncateOutput(line, terminalOutputLineLimit)) + this.say("command_output", Terminal.compressTerminalOutput(line, terminalOutputLineLimit)) } }) @@ -1000,7 +1000,7 @@ export class Cline { // grouping command_output messages despite any gaps anyways) await delay(50) - result = truncateOutput(result, terminalOutputLineLimit) + result = Terminal.compressTerminalOutput(result, terminalOutputLineLimit) if (userFeedback) { await this.say("user_feedback", userFeedback.text, userFeedback.images) @@ -3546,7 +3546,7 @@ export class Cline { terminalDetails += `\n## Original command: \`${busyTerminal.getLastCommand()}\`` let newOutput = TerminalRegistry.getUnretrievedOutput(busyTerminal.id) if (newOutput) { - newOutput = truncateOutput(newOutput, terminalOutputLineLimit) + newOutput = Terminal.compressTerminalOutput(newOutput, terminalOutputLineLimit) terminalDetails += `\n### New Output\n${newOutput}` } else { // details += `\n(Still running, no new output)` // don't want to show this right after running the command @@ -3573,7 +3573,7 @@ export class Cline { for (const process of completedProcesses) { let output = process.getUnretrievedOutput() if (output) { - output = truncateOutput(output, terminalOutputLineLimit) + output = Terminal.compressTerminalOutput(output, terminalOutputLineLimit) terminalOutputs.push(`Command: \`${process.command}\`\n${output}`) } } diff --git a/src/integrations/terminal/Terminal.ts b/src/integrations/terminal/Terminal.ts index 6416cee2bd..40e2f8cca5 100644 --- a/src/integrations/terminal/Terminal.ts +++ b/src/integrations/terminal/Terminal.ts @@ -1,6 +1,7 @@ import * as vscode from "vscode" import pWaitFor from "p-wait-for" import { ExitCodeDetails, mergePromise, TerminalProcess, TerminalProcessResultPromise } from "./TerminalProcess" +import { truncateOutput, applyRunLengthEncoding } from "../misc/extract-text" export class Terminal { public terminal: vscode.Terminal @@ -218,4 +219,13 @@ export class Terminal { throw error } } + + /** + * Compresses terminal output by applying run-length encoding and truncating to line limit + * @param input The terminal output to compress + * @returns The compressed terminal output + */ + public static compressTerminalOutput(input: string, lineLimit: number): string { + return truncateOutput(applyRunLengthEncoding(input), lineLimit) + } }