From 3eab3abedef29381612546f386397e14bde0d0f1 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:50:35 -0400 Subject: [PATCH] Wait for active terminals to cool down before sending api request --- src/ClaudeDev.ts | 7 +++++++ src/integrations/TerminalManager.ts | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/ClaudeDev.ts b/src/ClaudeDev.ts index d0acef7..0760bc9 100644 --- a/src/ClaudeDev.ts +++ b/src/ClaudeDev.ts @@ -1783,6 +1783,13 @@ ${ const busyTerminals = this.terminalManager.getTerminals(true) if (busyTerminals.length > 0) { + // wait for terminals to cool down + await delay(500) // delay after saving file + await pWaitFor(() => busyTerminals.every((t) => !this.terminalManager.isProcessHot(t.id)), { + interval: 100, + timeout: 7_000, + }).catch(() => {}) + // terminals are cool, let's retrieve their output details += "\n\n# Active Terminals" for (const busyTerminal of busyTerminals) { details += `\n## ${busyTerminal.lastCommand}` diff --git a/src/integrations/TerminalManager.ts b/src/integrations/TerminalManager.ts index a8e86f8..dec8851 100644 --- a/src/integrations/TerminalManager.ts +++ b/src/integrations/TerminalManager.ts @@ -221,6 +221,11 @@ export class TerminalManager { return process ? process.getUnretrievedOutput() : "" } + isProcessHot(terminalId: number): boolean { + const process = this.processes.get(terminalId) + return process ? process.isHot : false + } + disposeAll() { // for (const info of this.terminals) { // //info.terminal.dispose() // dont want to dispose terminals when task is aborted @@ -251,6 +256,8 @@ export class TerminalProcess extends EventEmitter { private buffer: string = "" private fullOutput: string = "" private lastRetrievedIndex: number = 0 + isHot: boolean = false + private hotTimer: NodeJS.Timeout | null = null // constructor() { // super() @@ -264,6 +271,14 @@ export class TerminalProcess extends EventEmitter { let didOutputNonCommand = false let didEmitEmptyLine = false for await (let data of stream) { + // Set to hot to stall API requests until terminal is cool again + this.isHot = true + if (this.hotTimer) { + clearTimeout(this.hotTimer) + } + this.hotTimer = setTimeout(() => { + this.isHot = false + }, 4_000) if (isFirstChunk) { /* The first chunk we get from this stream needs to be processed to be more human readable, ie remove vscode's custom escape sequences and identifiers, removing duplicate first char bug, etc. @@ -329,6 +344,12 @@ export class TerminalProcess extends EventEmitter { } this.emitRemainingBufferIfListening() + + if (this.hotTimer) { + clearTimeout(this.hotTimer) + } + this.isHot = false + this.emit("completed") this.emit("continue") } else {