feat: align TaskOutput UX with Bash output (#1029)
This commit is contained in:
@@ -21,7 +21,7 @@ import {
|
||||
isPatchTool,
|
||||
isPlanTool,
|
||||
isSearchTool,
|
||||
isShellTool,
|
||||
isShellOutputTool,
|
||||
isTaskTool,
|
||||
isTodoTool,
|
||||
} from "../helpers/toolNameMapping.js";
|
||||
@@ -192,7 +192,12 @@ export const ToolCallMessage = memo(
|
||||
const truncatedDisplay = needsTruncation
|
||||
? `${normalizedDisplay.slice(0, maxArgsChars - 1)}…`
|
||||
: normalizedDisplay;
|
||||
args = `(${truncatedDisplay})`;
|
||||
if (rawName.toLowerCase() === "taskoutput") {
|
||||
const separator = truncatedDisplay.startsWith("(") ? "" : " ";
|
||||
args = separator + truncatedDisplay;
|
||||
} else {
|
||||
args = `(${truncatedDisplay})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -850,16 +855,21 @@ export const ToolCallMessage = memo(
|
||||
</Box>
|
||||
|
||||
{/* Streaming output for shell tools during execution */}
|
||||
{isShellTool(rawName) && line.phase === "running" && line.streaming && (
|
||||
<StreamingOutputDisplay streaming={line.streaming} />
|
||||
)}
|
||||
{isShellOutputTool(rawName) &&
|
||||
line.phase === "running" &&
|
||||
line.streaming && (
|
||||
<StreamingOutputDisplay streaming={line.streaming} />
|
||||
)}
|
||||
|
||||
{/* Collapsed output for shell tools after completion */}
|
||||
{isShellTool(rawName) &&
|
||||
{isShellOutputTool(rawName) &&
|
||||
line.phase === "finished" &&
|
||||
line.resultText &&
|
||||
line.resultOk !== false && (
|
||||
<CollapsedOutputDisplay output={line.resultText} maxChars={300} />
|
||||
<CollapsedOutputDisplay
|
||||
output={extractMessageFromResult(line.resultText)}
|
||||
maxChars={300}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Tool result for non-shell tools or shell tool errors */}
|
||||
@@ -869,7 +879,7 @@ export const ToolCallMessage = memo(
|
||||
// - Shell tool with error (show error message)
|
||||
// - Shell tool in streaming/ready phase (show default "Running..." etc)
|
||||
const showDefaultResult =
|
||||
!isShellTool(rawName) ||
|
||||
!isShellOutputTool(rawName) ||
|
||||
(line.phase === "finished" && line.resultOk === false) ||
|
||||
(line.phase !== "running" && line.phase !== "finished");
|
||||
return showDefaultResult ? getResultElement() : null;
|
||||
|
||||
@@ -16,7 +16,7 @@ import { extractCompactionSummary } from "./backfill";
|
||||
import type { ContextTracker } from "./contextTracker";
|
||||
import { MAX_CONTEXT_HISTORY } from "./contextTracker";
|
||||
import { findLastSafeSplitPoint } from "./markdownSplit";
|
||||
import { isShellTool } from "./toolNameMapping";
|
||||
import { isShellOutputTool } from "./toolNameMapping";
|
||||
|
||||
type CompactionSummaryMessageChunk = {
|
||||
message_type: "summary_message";
|
||||
@@ -1207,7 +1207,7 @@ export function setToolCallsRunning(b: Buffers, toolCallIds: string[]): void {
|
||||
const line = b.byId.get(lineId);
|
||||
if (line && line.kind === "tool_call") {
|
||||
const shouldSeedStreaming =
|
||||
line.name && isShellTool(line.name) && !line.streaming;
|
||||
line.name && isShellOutputTool(line.name) && !line.streaming;
|
||||
b.byId.set(lineId, {
|
||||
...line,
|
||||
phase: "running",
|
||||
|
||||
@@ -272,6 +272,14 @@ export function formatArgsDisplay(
|
||||
return { display, parsed };
|
||||
}
|
||||
|
||||
// TaskOutput: show task id with optional non-blocking marker
|
||||
if (toolName.toLowerCase() === "taskoutput" && parsed.task_id) {
|
||||
const taskId = String(parsed.task_id);
|
||||
const isNonBlocking = parsed.block === false;
|
||||
display = isNonBlocking ? `(non-blocking) ${taskId}` : taskId;
|
||||
return { display, parsed };
|
||||
}
|
||||
|
||||
// Shell/Bash tools: show just the command
|
||||
if (isShellTool(toolName) && parsed.command) {
|
||||
// Handle both string and array command formats
|
||||
|
||||
@@ -68,9 +68,8 @@ export function getDisplayToolName(rawName: string): string {
|
||||
if (rawName === "Replace" || rawName === "replace") return "Update";
|
||||
if (rawName === "WriteFile" || rawName === "write_file") return "Write";
|
||||
if (rawName === "KillBash") return "Kill Bash";
|
||||
if (rawName === "BashOutput" || rawName === "TaskOutput") {
|
||||
return "Shell Output";
|
||||
}
|
||||
if (rawName === "BashOutput") return "Shell Output";
|
||||
if (rawName === "TaskOutput") return "Task Output";
|
||||
if (rawName === "MultiEdit") return "Update";
|
||||
|
||||
// No mapping found, return as-is
|
||||
@@ -215,6 +214,15 @@ export function isShellTool(name: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a tool should use shell-style streaming output rendering.
|
||||
* Includes shell command tools plus TaskOutput/BashOutput pollers.
|
||||
*/
|
||||
export function isShellOutputTool(name: string): boolean {
|
||||
const n = name.toLowerCase();
|
||||
return isShellTool(name) || n === "taskoutput" || n === "bashoutput";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a tool is a search/grep tool
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user