fix(tui): clarify inline subagent rows (#30051)

This commit is contained in:
Kit Langton
2026-06-01 15:44:11 -04:00
committed by GitHub
parent 32d5058f8c
commit 5f2b4eab28
3 changed files with 105 additions and 16 deletions

View File

@@ -1789,6 +1789,7 @@ function InlineTool(props: {
complete: any
pending: string
spinner?: boolean
subagent?: boolean
children: JSX.Element
part: ToolPart
onClick?: () => void
@@ -1829,6 +1830,7 @@ function InlineTool(props: {
return (
<InlineToolRow
id={`tool-inline-${props.subagent ? "subagent-" : ""}${props.part.id}`}
icon={props.icon}
iconColor={props.iconColor}
color={fg()}
@@ -1840,6 +1842,7 @@ function InlineTool(props: {
complete={props.complete}
pending={props.pending}
spinner={props.spinner}
subagent={props.subagent}
separateAfter={(id) =>
sync.data.message[ctx.sessionID]?.some((message) => message.role === "user" && message.id === id) ?? false
}
@@ -1860,6 +1863,7 @@ function InlineTool(props: {
}
export function InlineToolRow(props: {
id?: string
icon: string
iconColor?: RGBA
color?: RGBA
@@ -1871,6 +1875,7 @@ export function InlineToolRow(props: {
complete: any
pending: string
spinner?: boolean
subagent?: boolean
children: JSX.Element
separateAfter?: (id: string | undefined) => boolean
onMouseOver?: () => void
@@ -1881,6 +1886,7 @@ export function InlineToolRow(props: {
return (
<box
id={props.id}
marginTop={margin()}
paddingLeft={3}
onMouseOver={props.onMouseOver}
@@ -1895,9 +1901,12 @@ export function InlineToolRow(props: {
const children = parent.getChildren()
const index = children.indexOf(el)
const previous = children[index - 1]
const previousInline = previous?.id.startsWith("tool-inline-") ?? false
const previousSubagent = previous?.id.startsWith("tool-inline-subagent-") ?? false
setMargin(
previous?.id.startsWith("text-") ||
previous?.id.startsWith("tool-block-") ||
(previousInline && previousSubagent !== Boolean(props.subagent)) ||
props.separateAfter?.(previous?.id)
? 1
: 0,
@@ -2123,8 +2132,8 @@ function Read(props: ToolProps<typeof ReadTool>) {
Read {pathFormatter.format(props.input.filePath)} {input(props.input, ["filePath"])}
</InlineTool>
<For each={loaded()}>
{(filepath) => (
<box paddingLeft={3}>
{(filepath, index) => (
<box id={`tool-inline-loaded-${props.part.id}-${index()}`} paddingLeft={3}>
<text paddingLeft={3} fg={theme.textMuted}>
Loaded {pathFormatter.format(filepath)}
</text>
@@ -2190,11 +2199,14 @@ function Task(props: ToolProps<typeof TaskTool>) {
tools().findLast((x) => (x.state.status === "running" || x.state.status === "completed") && x.state.title),
)
const isRunning = createMemo(() => props.part.state.status === "running")
const status = createMemo(() => sync.data.session_status[props.metadata.sessionId ?? ""])
const isRunning = createMemo(
() => props.part.state.status === "running" || (props.metadata.background === true && status() !== undefined),
)
const retry = createMemo(() => {
const status = sync.data.session_status[props.metadata.sessionId ?? ""]
if (status?.type !== "retry") return
return status
const value = status()
if (value?.type !== "retry") return
return value
})
const duration = createMemo(() => {
@@ -2214,20 +2226,15 @@ function Task(props: ToolProps<typeof TaskTool>) {
if (isRunning() && retrying) {
content.push(`${Locale.truncate(retrying.message, 80)} [retrying attempt #${retrying.attempt}]`)
} else if (isRunning() && tools().length > 0) {
// content[0] += ` · ${tools().length} toolcalls`
if (current()) {
const state = current()!.state
const title = state.status === "running" || state.status === "completed" ? state.title : undefined
content.push(`${Locale.titlecase(current()!.tool)} ${title}`)
} else content.push(`${tools().length} toolcalls`)
} else content.push(`${formatSubagentToolcalls(tools().length)}`)
}
if (props.part.state.status === "completed") {
content.push(
props.metadata.background === true
? `${tools().length} toolcalls`
: `${tools().length} toolcalls · ${Locale.duration(duration())}`,
)
if (!isRunning() && props.part.state.status === "completed") {
content.push(`${formatCompletedSubagentDetail(tools().length, Locale.duration(duration()))}`)
}
return content.join("\n")
@@ -2235,7 +2242,8 @@ function Task(props: ToolProps<typeof TaskTool>) {
return (
<InlineTool
icon="│"
icon={props.part.state.status === "completed" ? "✓" : "│"}
subagent={true}
color={retry() ? theme.error : undefined}
spinner={isRunning()}
complete={props.input.description}
@@ -2254,6 +2262,15 @@ function Task(props: ToolProps<typeof TaskTool>) {
)
}
export function formatSubagentToolcalls(count: number) {
return `${count} toolcall${count === 1 ? "" : "s"}`
}
export function formatCompletedSubagentDetail(toolcalls: number, duration: string) {
if (toolcalls === 0) return duration
return `${formatSubagentToolcalls(toolcalls)} · ${duration}`
}
function Edit(props: ToolProps<typeof EditTool>) {
const ctx = use()
const { theme, syntax } = useTheme()