49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/legion/llm/patches/ruby_llm_parallel_tools.rb', line 49
def handle_tool_calls(response, &)
tool_calls = response.tool_calls.values
threads = tool_calls.map do |tool_call|
Thread.new do
@on[:new_message]&.call
@on[:tool_call]&.call(tool_call)
raw = execute_tool(tool_call)
wrapper = ToolResultWrapper.new(
raw, raw, tool_call.id, tool_call.id, tool_call.name )
@on[:tool_result]&.call(wrapper)
{ tool_call: tool_call, raw: raw }
end
end
begin
results = threads.map(&:value)
halt_result = nil
results.each do |entry|
tool_call = entry[:tool_call]
raw = entry[:raw]
tool_payload = raw.is_a?(RubyLLM::Tool::Halt) ? raw.content : raw
content = content_like?(tool_payload) ? tool_payload : tool_payload.to_s
message = add_message(role: :tool, content: content, tool_call_id: tool_call.id)
@on[:end_message]&.call(message)
halt_result = raw if raw.is_a?(RubyLLM::Tool::Halt)
end
reset_tool_choice if forced_tool_choice?
halt_result || complete(&)
ensure
threads.each do |thread|
thread.kill if thread.alive?
thread.join
end
end
end
|