Commit cafe700
Changed files (2)
lib
elelem
builtins
spec
elelem
builtins
lib/elelem/builtins/tools.rb
@@ -1,5 +1,26 @@
# frozen_string_literal: true
+module Elelem
+ module Builtins
+ module ToolMarkdown
+ def self.summary(tool)
+ "| #{tool.name} | #{tool.description.lines.first.chomp} |"
+ end
+
+ def self.to_markdown(tool)
+ lines = ["## #{tool.name}", "", tool.description, "", "### Parameters", ""]
+ tool.params.each do |param, spec|
+ req = tool.required.include?(param.to_s) ? ", required" : ""
+ desc = spec[:description] ? " - #{spec[:description]}" : ""
+ lines << "- `#{param}` (#{spec[:type]}#{req})#{desc}"
+ end
+ lines << "" << "*aliases: #{tool.aliases.join(", ")}*" if tool.aliases.any?
+ lines.join("\n")
+ end
+ end
+ end
+end
+
Elelem.configure do |config|
config.setup(:tools) do |agent|
completions = -> { agent.toolbox.tools.keys }
@@ -12,9 +33,9 @@ Elelem.configure do |config|
next
end
- agent.output.say tool.to_markdown, as: :markdown
+ agent.output.say Elelem::Builtins::ToolMarkdown.to_markdown(tool), as: :markdown
else
- rows = agent.toolbox.tools.each_value.map(&:summary)
+ rows = agent.toolbox.tools.each_value.map { |tool| Elelem::Builtins::ToolMarkdown.summary(tool) }
md = String.new("| Tool | Description |\n")
md << "|------|-------------|\n"
spec/elelem/builtins/tool_markdown_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+RSpec.describe Elelem::Builtins::ToolMarkdown do
+ subject(:tool) do
+ Elelem::Tool.new("greet",
+ description: "Greets someone.\nMore detail.",
+ params: { name: { type: "string", description: "who to greet" } },
+ required: ["name"],
+ aliases: ["hi"]
+ ) { |args| { greeting: "hi #{args["name"]}" } }
+ end
+
+ describe ".summary" do
+ it "renders a single table row with the first description line" do
+ expect(described_class.summary(tool)).to eq("| greet | Greets someone. |")
+ end
+ end
+
+ describe ".to_markdown" do
+ it "renders name, description, params, and aliases" do
+ markdown = described_class.to_markdown(tool)
+
+ expect(markdown).to include("## greet")
+ expect(markdown).to include("Greets someone.\nMore detail.")
+ expect(markdown).to include("- `name` (string, required) - who to greet")
+ expect(markdown).to include("*aliases: hi*")
+ end
+
+ it "omits the aliases line when there are none" do
+ plain_tool = Elelem::Tool.new("greet", description: "Greets someone.") { }
+
+ expect(described_class.to_markdown(plain_tool)).not_to include("aliases:")
+ end
+ end
+end