# `MingaAgent.Providers.Native`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_agent/providers/native.ex#L3)

Native Elixir agent provider backed by ReqLLM.

Runs entirely inside the BEAM with no external dependencies. Supports any
provider that ReqLLM supports (Anthropic, OpenAI, Ollama, Groq, Bedrock,
etc.) by accepting a model string like `"anthropic:claude-sonnet-4-20250514"`.

The provider manages conversation history via `ReqLLM.Context`, executes
tools locally, and emits `Agent.Event` structs to its subscriber (the
`Agent.Session`) for rendering in the chat panel.

## Architecture

When `send_prompt/2` is called, the provider spawns a linked `Task` to run
the agent turn loop. The loop:

1. Calls `ReqLLM.stream_text/3` with the conversation history and tools
2. Uses `StreamResponse.process_stream/2` with callbacks to emit events
   in real time as chunks arrive
3. If the response contains tool calls, executes each tool, appends results
   to the conversation context, and loops back to step 1
4. If no tool calls, the turn is complete

The task sends events to the GenServer via `send/2`, and the GenServer
forwards them to the subscriber. This keeps the GenServer responsive for
abort and state queries while streaming is in progress.

# `hook_runner`

```elixir
@type hook_runner() :: (MingaAgent.Hooks.Hook.t(),
                  MingaAgent.Hooks.PreToolUsePayload.t() -&gt;
                    MingaAgent.Hooks.Result.t())
```

Function that executes a matching hook.

# `llm_client`

```elixir
@type llm_client() :: (String.t(), [ReqLLM.Message.t()], keyword() -&gt;
                   {:ok, ReqLLM.StreamResponse.t()} | {:error, term()})
```

Function that performs the LLM streaming call.

# `loop_ctx`

```elixir
@type loop_ctx() :: MingaAgent.Providers.Native.LoopCtx.t()
```

Captures the immutable parameters for one agent turn loop invocation.

# `state`

```elixir
@type state() :: %{
  subscriber: pid(),
  model: String.t(),
  config: MingaAgent.Config.t(),
  context: ReqLLM.Context.t(),
  tools: [term()],
  project_root: String.t(),
  project_view: MingaAgent.ProjectView.t() | nil,
  thinking_level: String.t(),
  max_tokens: pos_integer(),
  max_retries: non_neg_integer(),
  llm_client: llm_client(),
  hook_runner: hook_runner(),
  task: Task.t() | nil,
  streaming: boolean(),
  interrupted: boolean(),
  last_user_prompt: String.t() | nil,
  active_skills: [MingaAgent.Skills.skill()],
  internal_state: MingaAgent.InternalState.t(),
  max_turns: pos_integer(),
  max_cost: float() | nil,
  session_cost: float(),
  fork_store: pid() | nil,
  changeset: pid() | nil,
  base_tools: [term()],
  mcp_tools: [term()],
  internal_tools: [term()],
  custom_tools?: boolean(),
  configured_mcp_configs: [MingaAgent.MCP.ServerConfig.t()],
  mcp_configs: [MingaAgent.MCP.ServerConfig.t()],
  mcp_client_opts: keyword(),
  mcp_enabled_override: boolean() | nil,
  mcp_errors: %{required(String.t()) =&gt; String.t()},
  mcp_registry: MingaAgent.MCP.Registry.t() | nil,
  read_only?: boolean(),
  tool_allowlist: :all | [String.t()],
  tool_workers: %{required(reference()) =&gt; pid()}
}
```

Internal state for the native provider.

# `agent_hooks`

```elixir
@spec agent_hooks(GenServer.server()) :: [MingaAgent.Hooks.Hook.t()]
```

Returns the agent hooks from the provider's config.

# `changeset`

```elixir
@spec changeset(GenServer.server()) :: pid() | nil
```

Returns the changeset PID, or nil.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `compact`

```elixir
@spec compact(GenServer.server()) :: {:ok, String.t()} | {:error, String.t()}
```

Manually triggers context compaction.

# `continue`

```elixir
@spec continue(GenServer.server()) :: :ok | {:error, term()}
```

Continues from an interrupted stream, asking the model to pick up where it left off.

# `detect_project_root`

```elixir
@spec detect_project_root() :: String.t()
```

# `fork_store`

```elixir
@spec fork_store(GenServer.server()) :: pid() | nil
```

Returns the PID of the fork store, or nil if not active.

# `project_view`

```elixir
@spec project_view(GenServer.server()) :: MingaAgent.ProjectView.t() | nil
```

Returns the project view associated with this provider, or nil.

# `refresh_project_view`

```elixir
@spec refresh_project_view(GenServer.server(), MingaAgent.ProjectView.t() | nil) ::
  :ok | {:error, term()}
```

Refreshes the project view and rebuilds file tools around the new overlay.

# `strip_provider_prefix`

# `tools`

```elixir
@spec tools(GenServer.server()) :: [ReqLLM.Tool.t()]
```

Returns the current tool list registered with this provider.

---

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