diff --git a/web/src/components/ToolCard/knownTools.tsx b/web/src/components/ToolCard/knownTools.tsx index ac92e7b2..253b9bd8 100644 --- a/web/src/components/ToolCard/knownTools.tsx +++ b/web/src/components/ToolCard/knownTools.tsx @@ -285,6 +285,18 @@ export const knownTools: Record , + title: (opts) => { + const description = getInputStringAny(opts.input, ['description']) + return description ?? 'Agent' + }, + subtitle: (opts) => { + const model = getInputStringAny(opts.input, ['subagent_type']) + return model ?? null + }, + minimal: true + }, CodexReasoning: { icon: () => , title: (opts) => getInputStringAny(opts.input, ['title']) ?? 'Reasoning', diff --git a/web/src/components/ToolCard/views/_all.tsx b/web/src/components/ToolCard/views/_all.tsx index fdca717d..784649ed 100644 --- a/web/src/components/ToolCard/views/_all.tsx +++ b/web/src/components/ToolCard/views/_all.tsx @@ -11,6 +11,7 @@ import { MultiEditFullView, MultiEditView } from '@/components/ToolCard/views/Mu import { TodoWriteView } from '@/components/ToolCard/views/TodoWriteView' import { UpdatePlanView } from '@/components/ToolCard/views/UpdatePlanView' import { WriteView } from '@/components/ToolCard/views/WriteView' +import { isObject } from '@hapi/protocol' import { getInputStringAny } from '@/lib/toolInputUtils' export type ToolViewProps = { @@ -29,6 +30,25 @@ const SkillFullView: ToolViewComponent = ({ block }: ToolViewProps) => { ) } +const AgentFullView: ToolViewComponent = ({ block }: ToolViewProps) => { + const input = block.tool.input + const description = getInputStringAny(input, ['description']) + const subagentType = getInputStringAny(input, ['subagent_type']) + const runInBackground = isObject(input) && input.run_in_background === true + + return ( +
+ {description && ( +
{description}
+ )} +
+ {subagentType && Type: {subagentType}} + {runInBackground && Background} +
+
+ ) +} + export const toolViewRegistry: Record = { Edit: EditView, MultiEdit: MultiEditView, @@ -50,6 +70,7 @@ export const toolFullViewRegistry: Record = { CodexDiff: CodexDiffFullView, CodexPatch: CodexPatchView, Skill: SkillFullView, + Agent: AgentFullView, AskUserQuestion: AskUserQuestionView, ExitPlanMode: ExitPlanModeView, ask_user_question: AskUserQuestionView, diff --git a/web/src/components/ToolCard/views/_results.tsx b/web/src/components/ToolCard/views/_results.tsx index effaf660..0f4630c4 100644 --- a/web/src/components/ToolCard/views/_results.tsx +++ b/web/src/components/ToolCard/views/_results.tsx @@ -507,6 +507,47 @@ const TodoWriteResultView: ToolViewComponent = (props: ToolViewProps) => { return } +const AgentResultView: ToolViewComponent = (props: ToolViewProps) => { + const { state, result } = props.block.tool + + if (result === undefined || result === null) { + return
{placeholderForState(state)}
+ } + + // For errors, show the error text + if (state === 'error') { + const text = extractTextFromResult(result) + return ( +
+ {text?.trim() ? text : 'Agent failed'} +
+ ) + } + + const text = extractTextFromResult(result) + if (!text) { + return
{state === 'completed' ? 'Done' : placeholderForState(state)}
+ } + + // Detect internal launch metadata. Check structurally first (result object + // may carry agentId/output_file keys), then fall back to a strict text + // pattern that is unlikely to appear in normal agent prose. + const isInternalMeta = isObject(result) && ('agentId' in result || 'output_file' in result) + || (text.startsWith('Async agent launched successfully.') && text.includes('agentId:')) + + if (isInternalMeta) { + const label = state === 'completed' ? 'Done' : 'Agent launched' + return
{label}
+ } + + return ( + <> + + + + ) +} + const SkillResultView: ToolViewComponent = (props: ToolViewProps) => { const { state, result, input } = props.block.tool @@ -597,6 +638,7 @@ export const toolResultViewRegistry: Record = { CodexPatch: CodexPatchResultView, CodexDiff: CodexDiffResultView, Skill: SkillResultView, + Agent: AgentResultView, AskUserQuestion: AskUserQuestionResultView, ExitPlanMode: MarkdownResultView, ask_user_question: AskUserQuestionResultView,