diff --git a/lib/roast/cogs/agent/providers/pi/messages/tool_call_message.rb b/lib/roast/cogs/agent/providers/pi/messages/tool_call_message.rb index 3f3561ea..96098fd0 100644 --- a/lib/roast/cogs/agent/providers/pi/messages/tool_call_message.rb +++ b/lib/roast/cogs/agent/providers/pi/messages/tool_call_message.rb @@ -118,6 +118,27 @@ def format_write "WRITE #{path} \"#{preview}\" (+#{count} #{"line".pluralize(count)})" end + # Formats an edit tool call. + # + # Input fields: + # :path (String) – file to edit [required] + # :edits (Array) – edit blocks, each {oldText, newText} [required] + # + # Output: "EDIT ( )" – is the number of edit + # blocks applied in the call. The count is always shown. + # + # Examples: + # EDIT lib/roast.rb (1 edit) + # EDIT config/app.yml (3 edits) + # + #: () -> String + def format_edit + path = arguments[:path] + edits = arguments[:edits] || [] + count = edits.length + "EDIT #{path} (#{count} #{"edit".pluralize(count)})" + end + # Formats a tool call for which Roast has no dedicated formatter. # # Output: " : , ..." – the upcased tool name, then each diff --git a/lib/roast/cogs/agent/providers/pi/messages/tool_result_message.rb b/lib/roast/cogs/agent/providers/pi/messages/tool_result_message.rb index ee62324d..3ffe6c85 100644 --- a/lib/roast/cogs/agent/providers/pi/messages/tool_result_message.rb +++ b/lib/roast/cogs/agent/providers/pi/messages/tool_result_message.rb @@ -107,6 +107,22 @@ def format_write ok_line(@input[:path]) end + # Formats an edit tool result. + # + # Input: :path – the path that was edited, from the originating call. + # + # Output: "EDIT OK " – the file path, omitted when the call + # had none. + # + # Examples: + # EDIT OK lib/roast/version.rb + # EDIT OK + # + #: () -> String + def format_edit + ok_line(@input[:path]) + end + # Formats a result for which Roast has no dedicated formatter. # # Content: the tool's output text. diff --git a/test/roast/cogs/agent/providers/pi/messages/tool_call_message_test.rb b/test/roast/cogs/agent/providers/pi/messages/tool_call_message_test.rb index ac6b1f15..fc57e80a 100644 --- a/test/roast/cogs/agent/providers/pi/messages/tool_call_message_test.rb +++ b/test/roast/cogs/agent/providers/pi/messages/tool_call_message_test.rb @@ -83,6 +83,32 @@ class ToolCallMessageTest < ActiveSupport::TestCase assert_equal "WRITE lib/roast.rb \"#{"x" * (ToolCallMessage::TRUNCATE_LIMIT - 3)}...\" (+1 line)", msg.format end + test "format renders EDIT with the path and edit count" do + msg = ToolCallMessage.new( + id: "1", + name: "edit", + arguments: { + path: "lib/roast.rb", + edits: [{ oldText: "a", newText: "b" }, { oldText: "c", newText: "d" }], + }, + ) + assert_equal "EDIT lib/roast.rb (2 edits)", msg.format + end + + test "format renders a singular edit count for a single edit" do + msg = ToolCallMessage.new( + id: "1", + name: "edit", + arguments: { path: "config/app.yml", edits: [{ oldText: "a", newText: "b" }] }, + ) + assert_equal "EDIT config/app.yml (1 edit)", msg.format + end + + test "format renders zero edits when the edits array is missing" do + msg = ToolCallMessage.new(id: "1", name: "edit", arguments: { path: "lib/roast.rb" }) + assert_equal "EDIT lib/roast.rb (0 edits)", msg.format + end + test "format renders an unhandled tool as NAME key: value, ..." do msg = ToolCallMessage.new( id: "1", diff --git a/test/roast/cogs/agent/providers/pi/messages/tool_result_message_test.rb b/test/roast/cogs/agent/providers/pi/messages/tool_result_message_test.rb index df84bf42..e6c3aef7 100644 --- a/test/roast/cogs/agent/providers/pi/messages/tool_result_message_test.rb +++ b/test/roast/cogs/agent/providers/pi/messages/tool_result_message_test.rb @@ -101,6 +101,31 @@ def setup assert_equal "WRITE OK", msg.format(@context) end + test "format renders EDIT OK with the path from the originating call" do + @context.add_tool_call( + ToolCallMessage.new(id: "1", name: "edit", arguments: { path: "lib/roast/version.rb" }), + ) + msg = ToolResultMessage.new( + tool_call_id: "1", + tool_name: "edit", + content: "The file has been updated successfully", + is_error: false, + ) + + assert_equal "EDIT OK lib/roast/version.rb", msg.format(@context) + end + + test "format renders a bare EDIT OK when the path is unavailable" do + msg = ToolResultMessage.new( + tool_call_id: "1", + tool_name: "edit", + content: "The file has been updated successfully", + is_error: false, + ) + + assert_equal "EDIT OK", msg.format(@context) + end + test "format renders NAME ERROR with the message for an error result" do msg = ToolResultMessage.new( tool_call_id: "1",