more improvements on tool calling

This commit is contained in:
2026-03-06 09:08:16 -07:00
parent b89d4e5a28
commit 7c7e763809
7 changed files with 275 additions and 142 deletions

View File

@@ -19,6 +19,7 @@ defmodule ElixirAi.ChatUtils do
headers = [{"authorization", "Bearer #{api_key}"}]
Logger.info("sending AI request with body: #{inspect(body)}")
case Req.post(api_url,
json: body,
headers: headers,
@@ -39,6 +40,28 @@ defmodule ElixirAi.ChatUtils do
end)
end
def api_message(%{role: :assistant, tool_calls: [_ | _] = tool_calls} = msg) do
%{
role: "assistant",
content: Map.get(msg, :content, ""),
tool_calls:
Enum.map(tool_calls, fn call ->
%{
id: call.id,
type: "function",
function: %{
name: call.name,
arguments: call.arguments
}
}
end)
}
end
def api_message(%{role: :tool, tool_call_id: tool_call_id, content: content}) do
%{role: "tool", tool_call_id: tool_call_id, content: content}
end
def api_message(%{role: role, content: content}) do
%{role: Atom.to_string(role), content: content}
end

View File

@@ -76,72 +76,49 @@ defmodule ElixirAi.AiUtils.StreamLineUtils do
)
end
# start tool call
# start and middle tool call
def handle_stream_line(server, %{
"choices" => [
%{
"delta" => %{
"tool_calls" => [
%{
"function" => %{
"name" => tool_name,
"arguments" => tool_args_start
}
}
]
"tool_calls" => tool_calls
},
"finish_reason" => nil,
"index" => tool_index
"finish_reason" => nil
}
],
"id" => id
}) do
send(
server,
{:ai_tool_call_start, id, {tool_name, tool_args_start, tool_index}}
)
end
})
when is_list(tool_calls) do
Enum.each(tool_calls, fn
%{
"id" => tool_call_id,
"index" => tool_index,
"type" => "function",
"function" => %{"name" => tool_name, "arguments" => tool_args_start}
} ->
Logger.info("Received tool call start for tool #{tool_name}")
# middle tool call
def handle_stream_line(server, %{
"choices" => [
%{
"delta" => %{
"tool_calls" => [
%{
"function" => %{
"arguments" => tool_args_diff
}
}
]
},
"finish_reason" => nil,
"index" => tool_index
}
],
"id" => id
}) do
send(
server,
{:ai_tool_call_middle, id, {tool_args_diff, tool_index}}
)
send(
server,
{:ai_tool_call_start, id, {tool_name, tool_args_start, tool_index, tool_call_id}}
)
%{"index" => tool_index, "function" => %{"arguments" => tool_args_diff}} ->
Logger.info("Received tool call middle for index #{tool_index}")
send(server, {:ai_tool_call_middle, id, {tool_args_diff, tool_index}})
other ->
Logger.warning("Unmatched tool call item: #{inspect(other)}")
end)
end
# end tool call
def handle_stream_line(server, %{
"choices" => [
%{
"delta" => %{},
"finish_reason" => "tool_calls",
"index" => tool_index
}
],
"choices" => [%{"finish_reason" => "tool_calls"}],
"id" => id
}) do
send(
server,
{:ai_tool_call_end, id, tool_index}
)
Logger.info("Received tool call end")
send(server, {:ai_tool_call_end, id})
end
def handle_stream_line(_server, %{"error" => error_info}) do