Comparing changes
v0.7.0
→
v0.8.0
3 commits
7 files changed
Commits
Changed files (7)
lib
elelem
spec
elelem
lib/elelem/toolbox.rb
@@ -2,7 +2,6 @@
module Elelem
class Toolbox
-
READ_TOOL = Tool.build("read", "Read complete contents of a file. Requires exact file path.", { path: { type: "string" } }, ["path"]) do |args|
path = args["path"]
full_path = Pathname.new(path).expand_path
@@ -37,12 +36,30 @@ module Elelem
{ bytes_written: full_path.write(args["content"]) }
end
+ FETCH_TOOL = Tool.build("fetch", "Fetch content from a URL. Returns status, headers, and body.", { url: { type: "string", description: "The URL to fetch" } }, ["url"]) do |args|
+ client = Net::Hippie::Client.new
+ response = client.get(args["url"])
+ { status: response.code.to_i, body: response.body }
+ end
+
+ WEB_SEARCH_TOOL = Tool.build("search_engine", "Search the web using DuckDuckGo. Returns raw API response.", { query: { type: "string", description: "The search query" } }, ["query"]) do |args|
+ query = CGI.escape(args["query"])
+ url = "https://api.duckduckgo.com/?q=#{query}&format=json&no_html=1"
+ client = Net::Hippie::Client.new
+ response = client.get(url)
+ JSON.parse(response.body)
+ end
+
TOOL_ALIASES = {
"bash" => "exec",
+ "duckduckgo" => "search_engine",
+ "ddg" => "search_engine",
"execute" => "exec",
+ "get" => "fetch",
"open" => "read",
"search" => "grep",
"sh" => "exec",
+ "web" => "fetch",
}
attr_reader :tools
@@ -52,7 +69,9 @@ module Elelem
@tool_permissions = {}
@tools = { read: [], write: [], execute: [] }
add_tool(eval_tool(binding), :execute)
+ add_tool(WEB_SEARCH_TOOL, :read)
add_tool(EXEC_TOOL, :execute)
+ add_tool(FETCH_TOOL, :read)
add_tool(GREP_TOOL, :read)
add_tool(LIST_TOOL, :read)
add_tool(PATCH_TOOL, :write)
lib/elelem/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Elelem
- VERSION = "0.7.0"
+ VERSION = "0.8.0"
end
\ No newline at end of file
lib/elelem.rb
@@ -1,11 +1,13 @@
# frozen_string_literal: true
+require "cgi"
require "cli/ui"
require "erb"
require "fileutils"
require "json"
require "json-schema"
require "logger"
+require "net/hippie"
require "net/llm"
require "open3"
require "pathname"
spec/elelem/toolbox_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Elelem::Toolbox do
tools = subject.tools_for(mode)
tool_names = tools.map { |t| t.dig(:function, :name) }
- expect(tool_names).to include("grep", "list", "read")
+ expect(tool_names).to include("grep", "list", "read", "fetch", "search_engine")
expect(tool_names).not_to include("write", "patch", "exec")
end
@@ -36,7 +36,7 @@ RSpec.describe Elelem::Toolbox do
tools = subject.tools_for(mode)
tool_names = tools.map { |t| t.dig(:function, :name) }
- expect(tool_names).to include("grep", "list", "read", "patch", "write", "exec")
+ expect(tool_names).to include("grep", "list", "read", "patch", "write", "exec", "fetch", "search_engine")
end
it "returns combined tools for build mode" do
@@ -44,11 +44,28 @@ RSpec.describe Elelem::Toolbox do
tools = subject.tools_for(mode)
tool_names = tools.map { |t| t.dig(:function, :name) }
- expect(tool_names).to include("grep", "read", "write", "patch")
+ expect(tool_names).to include("grep", "read", "write", "patch", "fetch", "search_engine")
expect(tool_names).not_to include("exec")
end
end
+ describe "web tools" do
+ it "includes fetch and search_engine in read permissions" do
+ tools = subject.tools_for([:read])
+ names = tools.map { |t| t.dig(:function, :name) }
+ expect(names).to include("fetch", "search_engine")
+ end
+
+ it "resolves web and get aliases to fetch" do
+ expect(Elelem::Toolbox::TOOL_ALIASES["web"]).to eq("fetch")
+ expect(Elelem::Toolbox::TOOL_ALIASES["get"]).to eq("fetch")
+ end
+
+ it "resolves duckduckgo alias to search_engine" do
+ expect(Elelem::Toolbox::TOOL_ALIASES["duckduckgo"]).to eq("search_engine")
+ end
+ end
+
describe "#run_tool mode enforcement" do
it "allows tool execution when mode matches" do
result = subject.run_tool("read", { "path" => __FILE__ }, permissions: [:read])
CHANGELOG.md
@@ -1,5 +1,13 @@
## [Unreleased]
+## [0.8.0] - 2026-01-14
+
+### Added
+- `fetch` tool for HTTP GET requests (returns status and body)
+- `search_engine` tool for DuckDuckGo Instant Answer API searches
+- Tool aliases: `get`/`web` → `fetch`, `ddg`/`duckduckgo` → `search_engine`
+- `net-hippie` and `cgi` dependencies for HTTP requests
+
## [0.7.0] - 2026-01-14
### Added
elelem.gemspec
@@ -40,12 +40,14 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
+ spec.add_dependency "cgi", "~> 0.1"
spec.add_dependency "cli-ui", "~> 2.0"
spec.add_dependency "erb", "~> 6.0"
spec.add_dependency "fileutils", "~> 1.0"
spec.add_dependency "json", "~> 2.0"
spec.add_dependency "json-schema", "~> 6.0"
spec.add_dependency "logger", "~> 1.0"
+ spec.add_dependency "net-hippie", "~> 1.0"
spec.add_dependency "net-llm", "~> 0.5", ">= 0.5.0"
spec.add_dependency "open3", "~> 0.1"
spec.add_dependency "pathname", "~> 0.1"
Gemfile.lock
@@ -1,13 +1,15 @@
PATH
remote: .
specs:
- elelem (0.7.0)
+ elelem (0.8.0)
+ cgi (~> 0.1)
cli-ui (~> 2.0)
erb (~> 6.0)
fileutils (~> 1.0)
json (~> 2.0)
json-schema (~> 6.0)
logger (~> 1.0)
+ net-hippie (~> 1.0)
net-llm (~> 0.5, >= 0.5.0)
open3 (~> 0.1)
pathname (~> 0.1)
@@ -23,6 +25,7 @@ GEM
public_suffix (>= 2.0.2, < 8.0)
base64 (0.3.0)
bigdecimal (4.0.1)
+ cgi (0.4.2)
cli-ui (2.7.0)
date (3.5.1)
diff-lcs (1.6.2)