gleamunison/llm

LLM ability host surface (gap analysis concept A).

The LLM call is an effect; providers, retries, fallbacks, and mocks are composable handlers over the effects.run stack — no client registry, no codegen. Op contract at the handler boundary: args[0] = messages JSON BitArray ([{“role”:“user”,“content”:“…”}]) result passed to continuation = {ok, CompletionJsonBin} | {error, ReasonBin}

The provider wire codec (request building, response parsing, house completion shape) lives in gleamunison/llm_wire; this module owns the ability host surface.

Values

pub fn complete_env(prompt: String) -> Result(String, String)

One-shot completion from environment config: the default live handler body. Reads OPENAI_API_KEY/OPENAI_BASE_URL/OPENAI_MODEL (or ANTHROPIC_* when its key is set). Kept dependency-free so the Erlang runtime can call it directly as the ambient handler.

pub fn error_string(e: llm_types.LlmError) -> String
pub fn frame(
  handler: fn(
    List(dynamic.Dynamic),
    fn(dynamic.Dynamic) -> dynamic.Dynamic,
  ) -> dynamic.Dynamic,
) -> effects.HandlerFrame

Wrap any LLM OpHandler as a HandlerFrame for effects.run.

pub fn mock_handler(
  response: llm_types.Completion,
) -> fn(
  List(dynamic.Dynamic),
  fn(dynamic.Dynamic) -> dynamic.Dynamic,
) -> dynamic.Dynamic

Deterministic mock: always answers the same completion. The live call and the test double are the same handler swap — that is the whole point.

pub fn provider_handler(
  cfg: llm_types.ProviderConfig,
) -> fn(
  List(dynamic.Dynamic),
  fn(dynamic.Dynamic) -> dynamic.Dynamic,
) -> dynamic.Dynamic

Live provider handler: performs the HTTP call via http_client.

pub fn provider_handler_with_cancellation(
  cfg: llm_types.ProviderConfig,
  cancellation: option.Option(cancellation.Token),
) -> fn(
  List(dynamic.Dynamic),
  fn(dynamic.Dynamic) -> dynamic.Dynamic,
) -> dynamic.Dynamic

Build a live handler with an optional caller-owned cancellation token.

pub fn provider_name(provider: llm_types.Provider) -> String
pub fn resolve_config(
  provider: llm_types.Provider,
  env: fn(String) -> Result(String, Nil),
) -> Result(llm_types.ProviderConfig, String)

Resolve both CLI and ambient settings without silently accepting bad values.

pub fn validate_config(
  cfg: llm_types.ProviderConfig,
) -> Result(Nil, String)
✨ Search Document