Packages

Minimal Elixir AI SDK scaffolding for streaming text with tool calls.

Current section

Files

Jump to
ai_sdk_ex lib ai tool_executor.ex
Raw

lib/ai/tool_executor.ex

defmodule AI.ToolExecutor do
@moduledoc """
Executes tool calls concurrently.
"""
@doc """
Executes tool calls in parallel and returns their results in order.
"""
def execute_parallel(tool_calls, tools, context) do
tool_calls
|> Task.async_stream(
fn tool_call -> execute_one(tool_call, tools, context) end,
ordered: true,
timeout: :infinity
)
|> Enum.map(fn
{:ok, result} -> result
{:exit, reason} -> raise reason
end)
end
defp execute_one(%{name: name, input: input, id: id}, tools, context) do
tool = Map.get(tools, name)
if is_nil(tool) do
raise AI.Errors.NoSuchToolError, message: "no such tool", tool_name: name
end
validated = AI.Schema.validate!(tool.input_schema, input, name)
if is_nil(tool.execute) do
raise AI.Errors.ProviderError,
message: "tool has no execute function",
provider: :tool,
details: %{tool: name}
end
output =
case tool.execute do
fun when is_function(fun, 2) ->
fun.(validated, %{tool_call_id: id, messages: context[:messages]})
fun when is_function(fun, 1) ->
fun.(validated)
_ ->
raise AI.Errors.ProviderError,
message: "tool execute must be a function",
provider: :tool,
details: %{tool: name}
end
%{id: id, name: name, output: output, is_error?: false}
end
end