diff options
| -rw-r--r-- | packages/cli/src/ui/components/messages/ToolMessage.tsx | 20 | ||||
| -rw-r--r-- | packages/server/src/tools/shell.ts | 27 |
2 files changed, 28 insertions, 19 deletions
diff --git a/packages/cli/src/ui/components/messages/ToolMessage.tsx b/packages/cli/src/ui/components/messages/ToolMessage.tsx index 922f59d0..51d3dffb 100644 --- a/packages/cli/src/ui/components/messages/ToolMessage.tsx +++ b/packages/cli/src/ui/components/messages/ToolMessage.tsx @@ -47,7 +47,7 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({ const displayableResult = React.useMemo( () => resultIsString - ? lines.slice(0, contentHeightEstimate).join('\n') + ? lines.slice(-contentHeightEstimate).join('\n') : resultDisplay, [lines, resultIsString, contentHeightEstimate, resultDisplay], ); @@ -66,8 +66,16 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({ {emphasis === 'high' && <TrailingIndicator />} </Box> {displayableResult && ( - <Box paddingLeft={STATUS_INDICATOR_WIDTH} width="100%"> + <Box paddingLeft={STATUS_INDICATOR_WIDTH} width="100%" marginTop={1}> <Box flexDirection="column"> + {hiddenLines > 0 && ( + <Box> + <Text color={Colors.SubtleComment}> + ... first {hiddenLines} line{hiddenLines === 1 ? '' : 's'}{' '} + hidden ... + </Text> + </Box> + )} {typeof displayableResult === 'string' && ( <Box flexDirection="column"> <MarkdownDisplay @@ -83,14 +91,6 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({ filename={displayableResult.fileName} /> )} - {hiddenLines > 0 && ( - <Box> - <Text color={Colors.SubtleComment}> - ... {hiddenLines} more line{hiddenLines === 1 ? '' : 's'}{' '} - hidden ... - </Text> - </Box> - )} </Box> </Box> )} diff --git a/packages/server/src/tools/shell.ts b/packages/server/src/tools/shell.ts index b43b2d0a..388c1543 100644 --- a/packages/server/src/tools/shell.ts +++ b/packages/server/src/tools/shell.ts @@ -25,6 +25,8 @@ export interface ShellToolParams { } import { spawn } from 'child_process'; +const OUTPUT_UPDATE_INTERVAL_MS = 1000; + export class ShellTool extends BaseTool<ShellToolParams, ToolResult> { static Name: string = 'execute_bash_command'; private whitelist: Set<string> = new Set(); @@ -124,7 +126,7 @@ export class ShellTool extends BaseTool<ShellToolParams, ToolResult> { async execute( params: ShellToolParams, abortSignal: AbortSignal, - onOutputChunk?: (chunk: string) => void, + updateOutput?: (chunk: string) => void, ): Promise<ToolResult> { const validationError = this.validateToolParams(params); if (validationError) { @@ -155,6 +157,19 @@ export class ShellTool extends BaseTool<ShellToolParams, ToolResult> { let exited = false; let stdout = ''; let output = ''; + let lastUpdateTime = Date.now(); + + const appendOutput = (str: string) => { + output += str; + if ( + updateOutput && + Date.now() - lastUpdateTime > OUTPUT_UPDATE_INTERVAL_MS + ) { + updateOutput(output); + lastUpdateTime = Date.now(); + } + }; + shell.stdout.on('data', (data: Buffer) => { // continue to consume post-exit for background processes // removing listeners can overflow OS buffer and block subprocesses @@ -162,10 +177,7 @@ export class ShellTool extends BaseTool<ShellToolParams, ToolResult> { if (!exited) { const str = data.toString(); stdout += str; - output += str; - if (onOutputChunk) { - onOutputChunk(str); - } + appendOutput(str); } }); @@ -174,10 +186,7 @@ export class ShellTool extends BaseTool<ShellToolParams, ToolResult> { if (!exited) { const str = data.toString(); stderr += str; - output += str; - if (onOutputChunk) { - onOutputChunk(str); - } + appendOutput(str); } }); |
