mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
feat(core): refactor shell execution to use node-pty (#6491)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
@@ -96,6 +96,8 @@ class ShellToolInvocation extends BaseToolInvocation<
|
||||
async execute(
|
||||
signal: AbortSignal,
|
||||
updateOutput?: (output: string) => void,
|
||||
terminalColumns?: number,
|
||||
terminalRows?: number,
|
||||
): Promise<ToolResult> {
|
||||
const strippedCommand = stripShellWrapper(this.params.command);
|
||||
|
||||
@@ -128,13 +130,11 @@ class ShellToolInvocation extends BaseToolInvocation<
|
||||
this.params.directory || '',
|
||||
);
|
||||
|
||||
let cumulativeStdout = '';
|
||||
let cumulativeStderr = '';
|
||||
|
||||
let cumulativeOutput = '';
|
||||
let lastUpdateTime = Date.now();
|
||||
let isBinaryStream = false;
|
||||
|
||||
const { result: resultPromise } = ShellExecutionService.execute(
|
||||
const { result: resultPromise } = await ShellExecutionService.execute(
|
||||
commandToExecute,
|
||||
cwd,
|
||||
(event: ShellOutputEvent) => {
|
||||
@@ -147,15 +147,9 @@ class ShellToolInvocation extends BaseToolInvocation<
|
||||
|
||||
switch (event.type) {
|
||||
case 'data':
|
||||
if (isBinaryStream) break; // Don't process text if we are in binary mode
|
||||
if (event.stream === 'stdout') {
|
||||
cumulativeStdout += event.chunk;
|
||||
} else {
|
||||
cumulativeStderr += event.chunk;
|
||||
}
|
||||
currentDisplayOutput =
|
||||
cumulativeStdout +
|
||||
(cumulativeStderr ? `\n${cumulativeStderr}` : '');
|
||||
if (isBinaryStream) break;
|
||||
cumulativeOutput = event.chunk;
|
||||
currentDisplayOutput = cumulativeOutput;
|
||||
if (Date.now() - lastUpdateTime > OUTPUT_UPDATE_INTERVAL_MS) {
|
||||
shouldUpdate = true;
|
||||
}
|
||||
@@ -186,6 +180,9 @@ class ShellToolInvocation extends BaseToolInvocation<
|
||||
}
|
||||
},
|
||||
signal,
|
||||
this.config.getShouldUseNodePtyShell(),
|
||||
terminalColumns,
|
||||
terminalRows,
|
||||
);
|
||||
|
||||
const result = await resultPromise;
|
||||
@@ -217,7 +214,7 @@ class ShellToolInvocation extends BaseToolInvocation<
|
||||
if (result.aborted) {
|
||||
llmContent = 'Command was cancelled by user before it could complete.';
|
||||
if (result.output.trim()) {
|
||||
llmContent += ` Below is the output (on stdout and stderr) before it was cancelled:\n${result.output}`;
|
||||
llmContent += ` Below is the output before it was cancelled:\n${result.output}`;
|
||||
} else {
|
||||
llmContent += ' There was no output before it was cancelled.';
|
||||
}
|
||||
@@ -231,8 +228,7 @@ class ShellToolInvocation extends BaseToolInvocation<
|
||||
llmContent = [
|
||||
`Command: ${this.params.command}`,
|
||||
`Directory: ${this.params.directory || '(root)'}`,
|
||||
`Stdout: ${result.stdout || '(empty)'}`,
|
||||
`Stderr: ${result.stderr || '(empty)'}`,
|
||||
`Output: ${result.output || '(empty)'}`,
|
||||
`Error: ${finalError}`, // Use the cleaned error string.
|
||||
`Exit Code: ${result.exitCode ?? '(none)'}`,
|
||||
`Signal: ${result.signal ?? '(none)'}`,
|
||||
|
||||
Reference in New Issue
Block a user