Commit 4b622d9
Changed files (5)
lib
elelem
lib/elelem/mcp/oauth.rb
@@ -146,24 +146,29 @@ module Elelem
def wait_for_callback(expected_state)
code = nil
- server = WEBrick::HTTPServer.new(
+ @server = WEBrick::HTTPServer.new(
Port: CALLBACK_PORT,
Logger: WEBrick::Log.new(File::NULL),
AccessLog: []
)
- server.mount_proc("/callback") do |req, res|
+ at_exit { @server&.shutdown }
+
+ @server.mount_proc("/callback") do |req, res|
state = req.query["state"]
raise "State mismatch" unless state == expected_state
code = req.query["code"]
res.content_type = "text/html"
res.body = "<html><body><h1>Authorization complete</h1><p>You can close this window.</p></body></html>"
- server.shutdown
+ @server.shutdown
end
- server.start
+ Timeout.timeout(120) { @server.start }
code
+ rescue Timeout::Error
+ @server.shutdown
+ raise "OAuth callback timed out"
end
def exchange_code(metadata, client, code, verifier)
lib/elelem/plugins/zz_confirm.rb
@@ -3,9 +3,7 @@
Elelem::Plugins.register(:confirm) do |agent|
permissions = Elelem::Permissions.new
- agent.toolbox.tools.each_key do |tool_name|
- agent.toolbox.before(tool_name) do |args|
- permissions.check(tool_name, args, terminal: agent.terminal)
- end
+ agent.toolbox.before do |args, tool_name:|
+ permissions.check(tool_name, args, terminal: agent.terminal)
end
end
lib/elelem/conversation.rb
@@ -8,9 +8,9 @@ module Elelem
@messages = []
end
- def add(role:, content:)
+ def add(role:, content:, **extra)
raise ArgumentError, "invalid role: #{role}" unless ROLES.include?(role)
- @messages << { role: role, content: content }
+ @messages << { role: role, content: content, **extra }.compact
end
def last = @messages.last
lib/elelem/system_prompt.rb
@@ -100,12 +100,17 @@ module Elelem
end
def ctags_fallback(files)
- output = `ctags -x --languages=Ruby --kinds-Ruby=cfm -L - 2>/dev/null <<< "#{files.join("\n")}"`
- return [] unless $?.success?
+ return [] if files.empty?
+
+ output = IO.popen(["ctags", "-x", "--languages=Ruby", "--kinds-Ruby=cfm", "-L", "-"], "r+") do |io|
+ io.puts(files)
+ io.close_write
+ io.read
+ end
output.lines.map do |line|
parts = line.split(/\s+/, 4)
- { file: parts[3]&.split&.first, name: parts[0] }
+ { file: parts[2], name: parts[0] }
end
rescue Errno::ENOENT
[]
lib/elelem/toolbox.rb
@@ -16,11 +16,11 @@ module Elelem
tool.aliases.each { |a| @aliases[a] = name }
end
- def before(tool_name, &block)
+ def before(tool_name = :*, &block)
@hooks[:before][tool_name] << block
end
- def after(tool_name, &block)
+ def after(tool_name = :*, &block)
@hooks[:after][tool_name] << block
end
@@ -38,8 +38,10 @@ module Elelem
errors = tool.validate(args)
return failure(error: errors.join(", ")) if errors.any?
+ @hooks[:before][:*].each { |h| h.call(args, tool_name: tool.name) }
@hooks[:before][tool.name].each { |h| h.call(args) }
result = tool.call(args)
+ @hooks[:after][:*].each { |h| h.call(args, result, tool_name: tool.name) }
@hooks[:after][tool.name].each { |h| h.call(args, result) }
result[:error] ? failure(result) : success(result)
rescue => e