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:
- Calls
ReqLLM.stream_text/3with the conversation history and tools - Uses
StreamResponse.process_stream/2with callbacks to emit events in real time as chunks arrive - If the response contains tool calls, executes each tool, appends results to the conversation context, and loops back to step 1
- 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.
Summary
Types
Function that executes a matching hook.
Function that performs the LLM streaming call.
Captures the immutable parameters for one agent turn loop invocation.
Internal state for the native provider.
Functions
Returns the agent hooks from the provider's config.
Returns the changeset PID, or nil.
Returns a specification to start this module under a supervisor.
Manually triggers context compaction.
Continues from an interrupted stream, asking the model to pick up where it left off.
Returns the PID of the fork store, or nil if not active.
Returns the project view associated with this provider, or nil.
Refreshes the project view and rebuilds file tools around the new overlay.
Returns the current tool list registered with this provider.
Types
@type hook_runner() :: (MingaAgent.Hooks.Hook.t(), MingaAgent.Hooks.PreToolUsePayload.t() -> MingaAgent.Hooks.Result.t())
Function that executes a matching hook.
@type llm_client() :: (String.t(), [ReqLLM.Message.t()], keyword() -> {:ok, ReqLLM.StreamResponse.t()} | {:error, term()})
Function that performs the LLM streaming call.
@type loop_ctx() :: MingaAgent.Providers.Native.LoopCtx.t()
Captures the immutable parameters for one agent turn loop invocation.
@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()) => String.t()}, mcp_registry: MingaAgent.MCP.Registry.t() | nil, read_only?: boolean(), tool_allowlist: :all | [String.t()], tool_workers: %{required(reference()) => pid()} }
Internal state for the native provider.
Functions
@spec agent_hooks(GenServer.server()) :: [MingaAgent.Hooks.Hook.t()]
Returns the agent hooks from the provider's config.
@spec changeset(GenServer.server()) :: pid() | nil
Returns the changeset PID, or nil.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec compact(GenServer.server()) :: {:ok, String.t()} | {:error, String.t()}
Manually triggers context compaction.
@spec continue(GenServer.server()) :: :ok | {:error, term()}
Continues from an interrupted stream, asking the model to pick up where it left off.
@spec detect_project_root() :: String.t()
@spec fork_store(GenServer.server()) :: pid() | nil
Returns the PID of the fork store, or nil if not active.
@spec project_view(GenServer.server()) :: MingaAgent.ProjectView.t() | nil
Returns the project view associated with this provider, or nil.
@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.
@spec tools(GenServer.server()) :: [ReqLLM.Tool.t()]
Returns the current tool list registered with this provider.