From 007a63852934e4c1bd89938ca9ced08b9743e931 Mon Sep 17 00:00:00 2001 From: Amolith Date: Sat, 3 Jan 2026 19:26:12 -0700 Subject: [PATCH] feat(acp): use description as tool call title Tool calls now display their description (e.g., "Echo a greeting") instead of the tool name ("bash"). The title is updated when the tool finishes streaming and input becomes available. Assisted-by: Claude Sonnet 4 via Crush --- internal/acp/sink.go | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/internal/acp/sink.go b/internal/acp/sink.go index 89134c3814e38cd84a873d2b18c00b54b1d38632..c3cc3c185059830098ecce4b46819294597c469b 100644 --- a/internal/acp/sink.go +++ b/internal/acp/sink.go @@ -260,29 +260,45 @@ func (s *Sink) translateToolCall(tc message.ToolCall) *acp.SessionUpdate { acp.WithStartKind(toolKind(tc.Name)), } - // Parse input to extract path and raw input. + // Parse input to extract path, title, and raw input. + title := tc.Name if input := parseToolInput(tc.Input); input != nil { if input.Path != "" { opts = append(opts, acp.WithStartLocations([]acp.ToolCallLocation{{Path: input.Path}})) } + if input.Title != "" { + title = input.Title + } opts = append(opts, acp.WithStartRawInput(input.Raw)) } - update := acp.StartToolCall(acp.ToolCallId(tc.ID), tc.Name, opts...) + update := acp.StartToolCall(acp.ToolCallId(tc.ID), title, opts...) return &update } - update := acp.UpdateToolCall( - acp.ToolCallId(tc.ID), + // Tool finished streaming - update with title and input now available. + opts := []acp.ToolCallUpdateOpt{ acp.WithUpdateStatus(acp.ToolCallStatusInProgress), - ) + } + if input := parseToolInput(tc.Input); input != nil { + if input.Title != "" { + opts = append(opts, acp.WithUpdateTitle(input.Title)) + } + if input.Path != "" { + opts = append(opts, acp.WithUpdateLocations([]acp.ToolCallLocation{{Path: input.Path}})) + } + opts = append(opts, acp.WithUpdateRawInput(input.Raw)) + } + + update := acp.UpdateToolCall(acp.ToolCallId(tc.ID), opts...) return &update } // toolInput holds parsed tool call input. type toolInput struct { - Path string - Raw map[string]any + Path string + Title string + Raw map[string]any } // parseToolInput extracts path and raw input from JSON tool input. @@ -305,6 +321,11 @@ func parseToolInput(input string) *toolInput { ti.Path = path } + // Extract title/description for display. + if desc, ok := raw["description"].(string); ok { + ti.Title = desc + } + return ti }