Commit 18a4ef1
lib/elelem/net/claude.rb
@@ -38,7 +38,7 @@ module Elelem
handle_event(event, tool_calls, &block)
end
- finalize_tool_calls(tool_calls)
+ finalize_tool_calls(tool_calls, &block)
end
private
@@ -72,19 +72,21 @@ module Elelem
case delta["type"]
when "text_delta"
- block.call(content: delta["text"], thinking: nil)
+ block.call(type: "saying", text: delta["text"])
when "thinking_delta"
- block.call(content: nil, thinking: delta["thinking"])
+ block.call(type: "thinking", text: delta["thinking"])
when "input_json_delta"
tool_calls.last[:args] << delta["partial_json"].to_s if tool_calls.any?
end
end
- def finalize_tool_calls(tool_calls)
+ def finalize_tool_calls(tool_calls, &block)
tool_calls.each do |tool_call|
args = tool_call.delete(:args)
tool_call[:arguments] = args.empty? ? {} : JSON.parse(args)
+ block.call(type: "tool_call", id: tool_call[:id], name: tool_call[:name], arguments: tool_call[:arguments])
end
+ tool_calls
end
def stream(messages, system_prompt, tools)
lib/elelem/net/ollama.rb
@@ -35,11 +35,14 @@ module Elelem
message = event["message"] || {}
unless event["done"]
- block.call(content: message["content"], thinking: message["thinking"])
+ block.call(type: "saying", text: message["content"]) if message["content"]
+ block.call(type: "thinking", text: message["thinking"]) if message["thinking"]
end
if message["tool_calls"]
- tool_calls.concat(parse_tool_calls(message["tool_calls"]))
+ parsed = parse_tool_calls(message["tool_calls"])
+ parsed.each { |tc| block.call(type: "tool_call", **tc) }
+ tool_calls.concat(parsed)
end
end
lib/elelem/net/openai.rb
@@ -18,7 +18,7 @@ module Elelem
handle_event(event, tool_calls, &block)
end
- finalize_tool_calls(tool_calls)
+ finalize_tool_calls(tool_calls, &block)
end
private
@@ -30,7 +30,7 @@ module Elelem
def handle_event(event, tool_calls, &block)
delta = event.dig("choices", 0, "delta") || {}
- block.call(content: delta["content"], thinking: nil) if delta["content"]
+ block.call(type: "saying", text: delta["content"]) if delta["content"]
accumulate_tool_calls(delta["tool_calls"], tool_calls) if delta["tool_calls"]
end
@@ -72,13 +72,15 @@ module Elelem
end
end
- def finalize_tool_calls(tool_calls)
+ def finalize_tool_calls(tool_calls, &block)
tool_calls.values.map do |tool_call|
- {
+ result = {
id: tool_call[:id],
name: tool_call[:name],
arguments: JSON.parse(tool_call[:args])
}
+ block.call(type: "tool_call", **result)
+ result
end
end
end
lib/elelem/agent.rb
@@ -142,11 +142,20 @@ module Elelem
end
def fetch_response(ctx)
- content = ""
- tool_calls = client.fetch(combined_history + ctx, toolbox.to_a) do |delta|
- content += delta[:content].to_s
- terminal.print(terminal.think(delta[:thinking])) if delta[:thinking]
+ content = String.new
+ tool_calls = []
+
+ client.fetch(combined_history + ctx, toolbox.to_a) do |event|
+ case event[:type]
+ when "saying"
+ content << event[:text].to_s
+ when "thinking"
+ terminal.print(terminal.think(event[:text]))
+ when "tool_call"
+ tool_calls << { id: event[:id], name: event[:name], arguments: event[:arguments] }
+ end
end
+
[content, tool_calls]
rescue => e
terminal.say "\n ✗ #{e.message}"
@@ -177,8 +186,8 @@ module Elelem
text = messages.map { |message| { role: message[:role], content: message[:content] } }.to_json
String.new.tap do |buffer|
- client.fetch([{ role: "user", content: "Summarize key facts:\n#{text}" }], []) do |d|
- buffer << d[:content].to_s
+ client.fetch([{ role: "user", content: "Summarize key facts:\n#{text}" }], []) do |event|
+ buffer << event[:text].to_s if event[:type] == "saying"
end
end
end