# `Gemini.Tools.Executor`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L1)

Executes function calls from Gemini API responses against a registry of implementations.

This module provides the core function execution infrastructure for tool calling.
It handles:

- Executing single function calls against a function registry
- Batch execution of multiple calls (sequential or parallel)
- Building function responses for multi-turn conversations
- Error handling and recovery

## Function Registry

A function registry is a map from function names to implementations:

    registry = %{
      "get_weather" => fn args -> WeatherService.get(args["location"]) end,
      "search_database" => fn args -> Database.search(args["query"]) end
    }

You can also use `create_registry/1` for convenience:

    registry = Executor.create_registry(
      get_weather: &WeatherService.get(&1["location"]),
      search_database: &Database.search(&1["query"])
    )

## Examples

    # Single execution
    {:ok, call} = FunctionCall.new(call_id: "1", name: "add", args: %{"a" => 1, "b" => 2})
    registry = %{"add" => fn args -> args["a"] + args["b"] end}

    {:ok, result} = Executor.execute(call, registry)
    #=> {:ok, 3}

    # Batch execution
    calls = [call1, call2, call3]
    results = Executor.execute_all(calls, registry)

    # Parallel execution for I/O-bound functions
    results = Executor.execute_all_parallel(calls, registry)

    # Build responses for Gemini API
    responses = Executor.build_responses(calls, results)

# `execution_result`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L54)

```elixir
@type execution_result() :: {:ok, term()} | {:error, term()}
```

# `function_impl`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L52)

```elixir
@type function_impl() :: (map() -&gt; term()) | {module(), atom(), list()}
```

# `function_registry`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L53)

```elixir
@type function_registry() :: %{required(String.t()) =&gt; function_impl()}
```

# `build_responses`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L181)

```elixir
@spec build_responses([Altar.ADM.FunctionCall.t()], [execution_result()]) :: [
  Gemini.Types.FunctionResponse.t()
]
```

Build FunctionResponse structs from execution results.

Creates responses suitable for sending back to the Gemini API
in multi-turn function calling conversations.

## Parameters

- `calls`: Original function calls
- `results`: Execution results from `execute_all/2` or `execute_all_parallel/3`

## Returns

List of `FunctionResponse` structs.

## Examples

    calls = [call1, call2]
    results = Executor.execute_all(calls, registry)
    responses = Executor.build_responses(calls, results)

    # Use responses in next Gemini API call
    contents = [previous_response, %{role: "function", parts: responses}]

# `create_registry`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L231)

```elixir
@spec create_registry(keyword() | map()) :: function_registry()
```

Create a function registry from a keyword list or map.

Converts atom keys to strings for consistent lookup.

## Examples

    # From keyword list
    registry = Executor.create_registry(
      add: fn args -> args["a"] + args["b"] end,
      multiply: fn args -> args["a"] * args["b"] end
    )

    # From map with string keys
    registry = Executor.create_registry(%{
      "add" => fn args -> args["a"] + args["b"] end
    })

# `execute`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L78)

```elixir
@spec execute(Altar.ADM.FunctionCall.t(), function_registry()) :: execution_result()
```

Execute a single function call against the registry.

## Parameters

- `call`: A `FunctionCall` struct with name and args
- `registry`: Map from function names to implementations

## Returns

- `{:ok, result}` - Function executed successfully
- `{:error, {:unknown_function, name}}` - Function not found in registry
- `{:error, {:execution_error, exception}}` - Function raised an exception

## Examples

    {:ok, call} = FunctionCall.new(call_id: "1", name: "double", args: %{"n" => 5})
    registry = %{"double" => fn args -> args["n"] * 2 end}

    {:ok, 10} = Executor.execute(call, registry)

# `execute_all`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L117)

```elixir
@spec execute_all([Altar.ADM.FunctionCall.t()], function_registry()) :: [
  execution_result()
]
```

Execute multiple function calls sequentially.

Returns results in the same order as the input calls.

## Parameters

- `calls`: List of `FunctionCall` structs
- `registry`: Function registry

## Returns

List of execution results, one for each call.

## Examples

    results = Executor.execute_all([call1, call2], registry)
    [{:ok, result1}, {:ok, result2}] = results

# `execute_all_parallel`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/tools/executor.ex#L145)

```elixir
@spec execute_all_parallel(
  [Altar.ADM.FunctionCall.t()],
  function_registry(),
  keyword()
) :: [
  execution_result()
]
```

Execute multiple function calls in parallel.

Uses `Task.async_stream` for concurrent execution. Best for I/O-bound
functions like HTTP requests or database queries.

## Parameters

- `calls`: List of `FunctionCall` structs
- `registry`: Function registry
- `opts`: Options passed to `Task.async_stream` (default: `max_concurrency: 10`)

## Returns

List of execution results, in the same order as input calls.

## Examples

    # Execute 3 slow operations in parallel
    results = Executor.execute_all_parallel([call1, call2, call3], registry)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
