Commit 074912e
Changed files (2)
lib
elelem
lib/elelem/tool.rb
@@ -8,11 +8,37 @@ module Elelem
end
def call(args)
+ return ArgumentError.new(args) unless valid?(args)
+
@block.call(args)
end
+ def valid?(args)
+ # TODO:: Use JSON Schema Validator
+ true
+ end
+
def to_h
- @schema
+ @schema&.to_h
+ end
+
+ class << self
+ def build(name, description, properties, required = [])
+ new({
+ type: "function",
+ function: {
+ name: name,
+ description: description,
+ parameters: {
+ type: "object",
+ properties: properties,
+ required: required
+ }
+ }
+ }) do |args|
+ yield args
+ end
+ end
end
end
end
lib/elelem/toolbox.rb
@@ -33,12 +33,19 @@ module Elelem
private
- def expand_path(path)
- Pathname.new(path).expand_path
+ def run_exec(command, args: [], env: {}, cwd: Dir.pwd, stdin: nil)
+ cmd = command.is_a?(Array) ? command.first : command
+ cmd_args = command.is_a?(Array) ? command[1..] + args : args
+ stdout, stderr, status = Open3.capture3(env, cmd, *cmd_args, chdir: cwd, stdin_data: stdin)
+ {
+ "exit_status" => status.exitstatus,
+ "stdout" => stdout.to_s,
+ "stderr" => stderr.to_s
+ }
end
def exec_tool
- @exec_tools ||= Tool.new(build_tool(
+ @exec_tools ||= Tool.build(
"execute",
"Execute shell commands directly. Commands run in a shell context. Examples: 'date', 'git status'.",
{
@@ -49,7 +56,7 @@ module Elelem
stdin: { type: "string" }
},
["cmd"]
- )) do |args|
+ ) do |args|
run_exec(
args["cmd"],
args: args["args"] || [],
@@ -60,95 +67,61 @@ module Elelem
end
end
- def run_exec(command, args: [], env: {}, cwd: Dir.pwd, stdin: nil)
- cmd = command.is_a?(Array) ? command.first : command
- cmd_args = command.is_a?(Array) ? command[1..] + args : args
- stdout, stderr, status = Open3.capture3(env, cmd, *cmd_args, chdir: cwd, stdin_data: stdin)
- {
- "exit_status" => status.exitstatus,
- "stdout" => stdout.to_s,
- "stderr" => stderr.to_s
- }
- end
-
def grep_tool
- @grep_tool ||= Tool.new(build_tool(
+ @grep_tool ||= Tool.build(
"grep",
"Search all git-tracked files using git grep. Returns file paths with matching line numbers.",
{ query: { type: "string" } },
["query"]
- )) do |args|
+ ) do |args|
run_exec("git", args: ["grep", "-nI", args["query"]])
end
end
def list_tool
- @list_tool ||= Tool.new(build_tool(
+ @list_tool ||= Tool.build(
"list",
"List all git-tracked files in the repository, optionally filtered by path.",
{ path: { type: "string" } }
- )) do |args|
+ ) do |args|
run_exec("git", args: args["path"] ? ["ls-files", "--", args["path"]] : ["ls-files"])
end
end
def patch_tool
- @patch_tool ||= Tool.new(build_tool(
+ @patch_tool ||= Tool.build(
"patch",
"Apply a unified diff patch via 'git apply'. Use for surgical edits to existing files.",
{ diff: { type: "string" } },
["diff"]
- )) do |args|
+ ) do |args|
run_exec("git", args: ["apply", "--index", "--whitespace=nowarn", "-p1"], stdin: args["diff"])
end
end
def read_tool
- @read_tool ||= Tool.new(build_tool(
+ @read_tool ||= Tool.build(
"read",
"Read complete contents of a file. Requires exact file path.",
{ path: { type: "string" } },
["path"]
- )) do |args|
- read_file(args["path"])
+ ) do |args|
+ full_path = Pathname.new(args["path"]).expand_path
+ full_path.exist? ? { content: full_path.read } : { error: "File not found: #{path}" }
end
end
- def read_file(path)
- full_path = expand_path(path)
- full_path.exist? ? { content: full_path.read } : { error: "File not found: #{path}" }
- end
-
def write_tool
- @write_tool ||= Tool.new(build_tool(
+ @write_tool ||= Tool.build(
"write",
"Write complete file contents (overwrites existing files). Creates parent directories automatically.",
{ path: { type: "string" }, content: { type: "string" } },
["path", "content"]
- )) do |args|
- write_file(args["path"], args["content"])
+ ) do |args|
+ full_path = Pathname.new(args["path"]).expand_path
+ FileUtils.mkdir_p(full_path.dirname)
+ { bytes_written: full_path.write(args["content"]) }
end
end
-
- def write_file(path, content)
- full_path = expand_path(path)
- FileUtils.mkdir_p(full_path.dirname)
- { bytes_written: full_path.write(content) }
- end
-
- def build_tool(name, description, properties, required = [])
- {
- type: "function",
- function: {
- name: name,
- description: description,
- parameters: {
- type: "object",
- properties: properties,
- required: required
- }
- }
- }
- end
end
end