From 599425cc63c514bcfee2432f9469f4b28a26c23b Mon Sep 17 00:00:00 2001 From: Aaron Weisberg Date: Sun, 11 Jan 2026 11:32:06 -0800 Subject: [PATCH] fix(ui): improve task tool output formatting - Display agent type in task description (e.g., @explore) - Show task summary items with status icons (completed/running/pending/error) - Strip task_metadata tags from output for cleaner display - Fix metadata.summary structure handling (items have {id, tool, state} not full parts) - Add TaskToolSummaryItem type definition --- lua/opencode/types.lua | 9 ++++++- lua/opencode/ui/formatter.lua | 46 +++++++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lua/opencode/types.lua b/lua/opencode/types.lua index 310770dd..f9b7fc95 100644 --- a/lua/opencode/types.lua +++ b/lua/opencode/types.lua @@ -219,7 +219,8 @@ ---@field message string|nil Optional status or error message ---@class TaskToolMetadata: ToolMetadataBase ----@field summary OpencodeMessagePart[] +---@field summary TaskToolSummaryItem[] +---@field sessionId string|nil Child session ID ---@class WebFetchToolMetadata: ToolMetadataBase ---@field http_status number|nil HTTP response status code @@ -279,6 +280,12 @@ ---@class TaskToolInput ---@field prompt string The subtask prompt ---@field description string Description of the subtask +---@field subagent_type string The type of specialized agent to use + +---@class TaskToolSummaryItem +---@field id string Tool call ID +---@field tool string Tool name +---@field state { status: string, title?: string } ---@class MessageTokenCount ---@field reasoning number diff --git a/lua/opencode/ui/formatter.lua b/lua/opencode/ui/formatter.lua index f1804631..be5f3da8 100644 --- a/lua/opencode/ui/formatter.lua +++ b/lua/opencode/ui/formatter.lua @@ -712,20 +712,50 @@ end ---@param tool_output string function M._format_task_tool(output, input, metadata, tool_output) local start_line = output:get_line_count() + 1 - M._format_action(output, icons.get('task') .. ' task', input and input.description) + + -- Show agent type if available + local description = input and input.description or '' + local agent_type = input and input.subagent_type + if agent_type then + description = string.format('%s (@%s)', description, agent_type) + end + + M._format_action(output, icons.get('task') .. ' task', description) if config.ui.output.tools.show_output then - if tool_output and tool_output ~= '' then + -- Show task summary from metadata + -- The summary contains items with structure: {id, tool, state: {status, title}} + if metadata and metadata.summary and type(metadata.summary) == 'table' and #metadata.summary > 0 then output:add_empty_line() - output:add_lines(vim.split(tool_output, '\n')) + + local status_icons = { + completed = icons.get('status_on') or '+', + running = icons.get('run') or '>', + pending = icons.get('status_off') or '-', + error = icons.get('error') or 'x', + } + + for _, item in ipairs(metadata.summary) do + if item.tool then + local status = item.state and item.state.status or 'pending' + local title = item.state and item.state.title or item.tool + local icon = status_icons[status] or status_icons.pending + + output:add_line(string.format(' %s %s', icon, title)) + end + end + output:add_empty_line() end - if metadata.summary and type(metadata.summary) == 'table' then - for _, sub_part in ipairs(metadata.summary) do - if sub_part.type == 'tool' and sub_part.tool then - M._format_tool(output, sub_part) - end + -- Show tool output text (usually the final summary from the subagent) + if tool_output and tool_output ~= '' then + -- Strip task_metadata tags from output for cleaner display + local clean_output = tool_output:gsub('.-', ''):gsub('%s+$', '') + if clean_output ~= '' then + output:add_empty_line() + output:add_lines(vim.split(clean_output, '\n')) + output:add_empty_line() end end end