Packages
Provider-agnostic Elixir client for agent runtimes — one Session loop, any loop host: server-side (Anthropic Claude Managed Agents, AWS Bedrock AgentCore) or in-process (Local, over any OpenAI-compatible chat endpoint). Your tools run locally.
Current section
Files
Jump to
Current section
Files
lib/req_managed_agents/tools.ex
defmodule ReqManagedAgents.Tools do
@moduledoc false
# Shared local-tool execution for Session and run_to_completion. Always returns
# a `user.custom_tool_result` event; any failure becomes an `is_error` result so
# the session never hangs.
alias ReqManagedAgents.Event
@type handler_fun :: (String.t(), map(), term() -> {:ok, String.t()} | {:error, String.t()})
@spec run(module() | handler_fun(), String.t(), String.t(), map(), term(), map()) :: map()
def run(handler, id, name, input, context, meta \\ %{}) do
:telemetry.span([:req_managed_agents, :tool], Map.merge(meta, %{tool: name}), fn ->
event = do_run(handler, id, name, input, context)
{event, Map.merge(meta, %{tool: name, is_error: event["is_error"] == true})}
end)
end
defp do_run(handler, id, name, input, context) do
result =
cond do
is_function(handler, 3) -> handler.(name, input, context)
is_atom(handler) -> handler.handle_tool_call(name, input, context)
end
case result do
{:ok, text} -> Event.custom_tool_result(id, to_string(text))
{:error, text} -> Event.custom_tool_result(id, to_string(text), is_error: true)
end
catch
kind, reason ->
Event.custom_tool_result(id, "tool #{kind}: #{inspect(reason)}", is_error: true)
end
end