Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions lib/roast/cogs/agent/providers/pi/messages/tool_call_message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,32 @@ def format_grep
details.any? ? "#{base} (#{details.join(", ")})" : base
end

# Formats a find tool call.
#
# Input fields:
# :pattern (String) – filename glob to match [required]
# :path (String) – directory to search in [optional]
# :limit (Integer) – max number of results [optional]
#
# Output: "FIND <pattern> (path: <path>, limit: <limit>)" – the "path:"
# and "limit:" details are each included only when present and joined
# with ", " inside a single trailing "(...)".
#
# Examples:
# FIND *.rb (path: lib, limit: 50)
# FIND *.rb (limit: 50)
# FIND *.rb
#
#: () -> String
def format_find
pattern, path, limit = arguments.values_at(:pattern, :path, :limit)
details = [
("path: #{path}" if path.present?),
("limit: #{limit}" if limit.present?),
].compact
details.any? ? "FIND #{pattern} (#{details.join(", ")})" : "FIND #{pattern}"
end

# Formats a tool call for which Roast has no dedicated formatter.
#
# Output: "<NAME> <key>: <value>, ..." – the upcased tool name, then each
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,24 @@ def format_grep
ok_line("#{count} #{"match".pluralize(count)}", note)
end

# Formats a find tool result.
#
# Content: matching paths, one per line.
#
# Output: "FIND OK <n> <path|paths>" – <n> is the number of non-blank
# lines (pluralized).
#
# Examples:
# FIND OK 12 paths
# FIND OK 1 path
# FIND OK 0 paths
#
#: () -> String
def format_find

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency note (also raised on #1017): this drops blank lines via .map(&:strip).reject(&:empty?), whereas format_read counts raw .lines.length. Fine if intentional (paths vs. file lines), but the two counting rules across sibling formatters should be a conscious, ideally documented, choice.

count = content.to_s.lines.map(&:strip).reject(&:empty?).length
ok_line("#{count} #{"path".pluralize(count)}")
end

# Formats a result for which Roast has no dedicated formatter.
#
# Content: the tool's output text.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,30 @@ class ToolCallMessageTest < ActiveSupport::TestCase
assert_equal "GREP \"#{"x" * (ToolCallMessage::TRUNCATE_LIMIT - 3)}...\" #{long}", msg.format
end

test "format renders FIND with the search path but no limit" do
msg = ToolCallMessage.new(
id: "1",
name: "find",
arguments: { pattern: "*.rb", path: "lib" },
)
assert_equal "FIND *.rb (path: lib)", msg.format
end

test "format renders FIND with the path and limit joined in one parenthetical" do
msg = ToolCallMessage.new(id: "1", name: "find", arguments: { pattern: "*.rb", path: "lib", limit: 50 })
assert_equal "FIND *.rb (path: lib, limit: 50)", msg.format
end

test "format renders FIND with the limit but no path" do
msg = ToolCallMessage.new(id: "1", name: "find", arguments: { pattern: "*.rb", limit: 50 })
assert_equal "FIND *.rb (limit: 50)", msg.format
end

test "format renders FIND with only the pattern" do
msg = ToolCallMessage.new(id: "1", name: "find", arguments: { pattern: "*.rb" })
assert_equal "FIND *.rb", msg.format
end

test "format renders an unhandled tool as NAME key: value, ..." do
msg = ToolCallMessage.new(
id: "1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,39 @@ def setup
assert_equal "GREP OK 1 match · NOTE results truncated", msg.format(@context)
end

test "format summarizes find output with a path count" do
msg = ToolResultMessage.new(
tool_call_id: "1",
tool_name: "find",
content: "lib/roast.rb\nlib/roast/version.rb\nlib/roast/cog.rb",
is_error: false,
)

assert_equal "FIND OK 3 paths", msg.format(@context)
end

test "format pluralizes a single find path" do
msg = ToolResultMessage.new(
tool_call_id: "1",
tool_name: "find",
content: "lib/roast.rb",
is_error: false,
)

assert_equal "FIND OK 1 path", msg.format(@context)
end

test "format reports zero find paths when there is no output" do
msg = ToolResultMessage.new(
tool_call_id: "1",
tool_name: "find",
content: nil,
is_error: false,
)

assert_equal "FIND OK 0 paths", msg.format(@context)
end

test "format renders NAME ERROR with the message for an error result" do
msg = ToolResultMessage.new(
tool_call_id: "1",
Expand Down
Loading