LlmCore.LLM.Native (llm_core v0.8.1)

Copy Markdown View Source

In-process agentic provider — runs the agent loop inside the BEAM VM.

  1. Reads the agent .md system prompt
  2. Resolves an LLM API provider from configuration
  3. Calls LlmCore.Agent.Loop.run with LlmToolkit.CodeTools
  4. Returns a standard LlmCore.LLM.Response

Zero CLI cost. Uses whatever API provider your configuration makes available.

Provider Resolution

llm_core ships no provider order. Configure a [native] cascade (see LlmCore.LLM.Native.Config); providers are tried in that order, skipping any that are disabled, cannot run the native loop, or have no credential. With no cascade configured, the single provider named by [routing] default is used. If nothing is usable the call fails with a structured {:no_native_provider, details} error; if every candidate fails, the error lists every attempt.

Usage

This provider implements LlmCore.LLM.Provider and is selected by provider routing when provider: "native" is specified or when no CLI providers are available.

{:ok, response} = LlmCore.LLM.Native.send(task,
  system_prompt_file: "/path/to/agent.md",
  cwd: "/path/to/project",
  model: "my-model-id"
)

Summary

Functions

Walk a list of {module, model, opts} candidates and invoke run_fn on each until one succeeds.

Functions

try_cascade(candidates, run_fn)

@spec try_cascade([{module(), String.t(), keyword()}], (tuple() -> term())) ::
  {:ok, LlmCore.LLM.Response.t(), [map()]} | {:error, term()}

Walk a list of {module, model, opts} candidates and invoke run_fn on each until one succeeds.

  • {:ok, response, messages} from run_fn → returned immediately.
  • {:error, :max_iterations_reached} → returned immediately (reasoning failure, not a provider outage — retrying elsewhere won't help).
  • Any other {:error, reason} (including the typed {:empty_stop, _} — provider-specific degenerate output may not repeat on another backend) → logs and advances to the next candidate.
  • Every candidate failed: a single candidate surfaces its raw error; several return {:error, {:cascade_exhausted, %{last: reason, attempts: attempts}}} where attempts lists every candidate's %{provider: module, reason: term} in order, so the first failure is never masked by the last one.
  • Empty list → {:error, :no_provider_succeeded}.

Exposed for direct testing; production call sites go through send/2.