MingaAgent.Provider behaviour (Minga v0.1.0)

Copy Markdown View Source

Behaviour for AI agent provider backends.

A provider manages the connection to an AI agent (LLM API, subprocess, etc.) and translates between the provider's native protocol and Minga's internal Agent.Event structs. The provider process runs under the agent supervisor and is crash-isolated from the editor.

Implementing a provider

defmodule MyProvider do
  @behaviour MingaAgent.Provider

  use GenServer

  @impl MingaAgent.Provider
  def start_link(opts), do: GenServer.start_link(__MODULE__, opts)

  @impl MingaAgent.Provider
  def send_prompt(pid, text), do: GenServer.cast(pid, {:prompt, text})

  # ... other callbacks
end

Events are delivered to the subscriber (typically Agent.Session) as {:agent_provider_event, event} messages where event is an Agent.Event struct.

Summary

Types

Model information returned by the provider.

Provider configuration options.

Provider state reference (pid or name).

Session state returned by the provider.

Callbacks

Aborts the current agent operation.

Cycles to the next model in the configured model rotation.

Cycles to the next thinking level and returns the new level.

Returns available models from the provider.

Returns available commands (extensions, skills, prompts) from the provider.

Returns the current session state (model info, streaming status, etc.).

Starts a fresh agent session, clearing conversation history.

Seeds conversation history without sending a prompt.

Sends a user prompt to the agent. Returns immediately; responses arrive as events.

Sets the model without resetting conversation context.

Sets the thinking level (e.g. "low", "medium", "high").

Starts the provider process.

Types

model_info()

@type model_info() :: %{id: String.t(), name: String.t(), provider: String.t()}

Model information returned by the provider.

opts()

@type opts() :: keyword()

Provider configuration options.

provider()

@type provider() :: GenServer.server()

Provider state reference (pid or name).

session_state()

@type session_state() :: %{
  optional(:system_prompt) => String.t() | nil,
  optional(:thinking_level) => String.t() | nil,
  optional(:active_skill_names) => [String.t()],
  optional(:project_root) => String.t() | nil,
  optional(:mcp_status) => [map()],
  model: model_info() | String.t() | nil,
  is_streaming: boolean(),
  token_usage: MingaAgent.Event.token_usage() | nil
}

Session state returned by the provider.

Callbacks

abort(provider)

@callback abort(provider()) :: :ok

Aborts the current agent operation.

cycle_model(provider)

(optional)
@callback cycle_model(provider()) :: {:ok, map()} | {:error, term()}

Cycles to the next model in the configured model rotation.

cycle_thinking_level(provider)

(optional)
@callback cycle_thinking_level(provider()) :: {:ok, term()} | {:error, term()}

Cycles to the next thinking level and returns the new level.

get_available_models(provider)

(optional)
@callback get_available_models(provider()) :: {:ok, [map()]} | {:error, term()}

Returns available models from the provider.

get_commands(provider)

(optional)
@callback get_commands(provider()) :: {:ok, [map()]} | {:error, term()}

Returns available commands (extensions, skills, prompts) from the provider.

get_state(provider)

@callback get_state(provider()) :: {:ok, session_state()} | {:error, term()}

Returns the current session state (model info, streaming status, etc.).

new_session(provider)

@callback new_session(provider()) :: :ok | {:error, term()}

Starts a fresh agent session, clearing conversation history.

seed_messages(provider, list)

@callback seed_messages(provider(), [MingaAgent.Message.t()]) :: :ok | {:error, term()}

Seeds conversation history without sending a prompt.

send_prompt(provider, t)

@callback send_prompt(provider(), String.t()) :: :ok | {:error, term()}

Sends a user prompt to the agent. Returns immediately; responses arrive as events.

set_model(provider, t)

(optional)
@callback set_model(provider(), String.t()) :: :ok | {:error, term()}

Sets the model without resetting conversation context.

set_thinking_level(provider, t)

(optional)
@callback set_thinking_level(provider(), String.t()) :: :ok | {:error, term()}

Sets the thinking level (e.g. "low", "medium", "high").

start_link(opts)

@callback start_link(opts()) :: GenServer.on_start()

Starts the provider process.

Options must include :subscriber (the pid that receives events). Provider-specific options (model, binary path, etc.) are also passed here.