Fix shell output display (#24490)

This commit is contained in:
Jacob Richman
2026-04-01 22:53:46 -07:00
committed by GitHub
parent 973092df50
commit 40b73c9447
10 changed files with 240 additions and 56 deletions

View File

@@ -19,6 +19,7 @@ export type ExecutionMethod =
export interface ExecutionResult {
rawOutput?: Buffer;
output: string;
ansiOutput?: AnsiOutput;
exitCode: number | null;
signal: number | null;
error: Error | null;
@@ -452,10 +453,13 @@ export class ExecutionLifecycleService {
} = options ?? {};
const output = execution.getBackgroundOutput?.() ?? execution.output;
const snapshot = execution.getSubscriptionSnapshot?.();
const ansiOutput = Array.isArray(snapshot) ? snapshot : undefined;
this.settleExecution(executionId, {
rawOutput: Buffer.from(output, 'utf8'),
output,
ansiOutput,
exitCode,
signal,
error,

View File

@@ -1123,9 +1123,21 @@ export class ShellExecutionService {
ShellExecutionService.activePtys.delete(ptyPid);
});
const endLine = headlessTerminal.buffer.active.length;
const startLine = Math.max(
0,
endLine - (shellExecutionConfig.maxSerializedLines ?? 2000),
);
const ansiOutputSnapshot = serializeTerminalToObject(
headlessTerminal,
startLine,
endLine,
);
ExecutionLifecycleService.completeWithResult(ptyPid, {
rawOutput: Buffer.from(''),
output: getFullBufferText(headlessTerminal),
ansiOutput: ansiOutputSnapshot,
exitCode,
signal: signal ?? null,
error,

View File

@@ -661,33 +661,34 @@ export class ShellToolInvocation extends BaseToolInvocation<
llmContent = llmContentParts.join('\n');
}
let returnDisplayMessage = '';
let returnDisplay: string | AnsiOutput = '';
if (this.context.config.getDebugMode()) {
returnDisplayMessage = llmContent;
returnDisplay = llmContent;
} else {
if (this.params.is_background || result.backgrounded) {
returnDisplayMessage = `Command moved to background (PID: ${result.pid}). Output hidden. Press Ctrl+B to view.`;
returnDisplay = `Command moved to background (PID: ${result.pid}). Output hidden. Press Ctrl+B to view.`;
} else if (result.aborted) {
const cancelMsg = timeoutMessage || 'Command cancelled by user.';
if (result.output.trim()) {
returnDisplayMessage = `${cancelMsg}\n\nOutput before cancellation:\n${result.output}`;
returnDisplay = `${cancelMsg}\n\nOutput before cancellation:\n${result.output}`;
} else {
returnDisplayMessage = cancelMsg;
returnDisplay = cancelMsg;
}
} else if (result.output.trim()) {
returnDisplayMessage = result.output;
} else if (result.output.trim() || result.ansiOutput) {
returnDisplay =
result.ansiOutput && result.ansiOutput.length > 0
? result.ansiOutput
: result.output;
} else {
if (result.signal) {
returnDisplayMessage = `Command terminated by signal: ${result.signal}`;
returnDisplay = `Command terminated by signal: ${result.signal}`;
} else if (result.error) {
returnDisplayMessage = `Command failed: ${getErrorMessage(
result.error,
)}`;
returnDisplay = `Command failed: ${getErrorMessage(result.error)}`;
} else if (result.exitCode !== null && result.exitCode !== 0) {
returnDisplayMessage = `Command exited with code: ${result.exitCode}`;
returnDisplay = `Command exited with code: ${result.exitCode}`;
}
// If output is empty and command succeeded (code 0, no error/signal/abort),
// returnDisplayMessage will remain empty, which is fine.
// returnDisplay will remain empty, which is fine.
}
}
@@ -824,7 +825,7 @@ export class ShellToolInvocation extends BaseToolInvocation<
return {
llmContent: 'Sandbox expansion required',
returnDisplay: returnDisplayMessage,
returnDisplay,
error: {
type: ToolErrorType.SANDBOX_EXPANSION_REQUIRED,
message: JSON.stringify(confirmationDetails),
@@ -856,14 +857,14 @@ export class ShellToolInvocation extends BaseToolInvocation<
);
return {
llmContent: summary,
returnDisplay: returnDisplayMessage,
returnDisplay,
...executionError,
};
}
return {
llmContent,
returnDisplay: returnDisplayMessage,
returnDisplay,
data,
...executionError,
};