AgentLoom docs Providers

Providers

AgentLoom calls OpenAI, Anthropic, Google and Ollama over their HTTP APIs, any OpenAI-compatible server through generic_openai, and a mock provider for offline runs. This page covers which provider answers a step, how to set each one up, and what each supports.

Which provider answers

Without a config file, agentloom run sets up a provider for each key it finds in the environment:

ProviderSet up whenKeyEndpoint
openaiOPENAI_API_KEY is setOPENAI_API_KEYOPENAI_BASE_URL
anthropicANTHROPIC_API_KEY is setANTHROPIC_API_KEYANTHROPIC_BASE_URL
googleGOOGLE_API_KEY is setGOOGLE_API_KEYGOOGLE_BASE_URL
ollamaThe workflow says provider: ollama, or AGENTLOOM_OLLAMA_FALLBACK is onnoneOLLAMA_BASE_URL, else http://localhost:11434
generic_openaiThe workflow says provider: generic_openaiThe variable api_key_env namesbase_url
mockThe workflow says provider: mock, or the run passes --mock-responsesnonenone

config.provider, or --provider, goes first for any model it can serve. The other providers that serve the model’s name follow it, as fallbacks:

ProviderServes
OpenAINames that start with gpt-, o1, o3, o4, text-embedding-3- or text-embedding-ada-.
AnthropicNames that contain claude.
GoogleNames that contain gemini, and names that start with embedding-.
Ollama, generic_openai, mockAny name.

A provider that can’t serve the name is left out, even when provider names it: under provider: anthropic, a step on gpt-4o goes to OpenAI. An unknown provider name is accepted without an error, and changes nothing.

Each step runs config.model unless it names its own model. --model changes config.model, so a step’s own model wins over it. Without a model, config.model is the provider’s default, and --provider brings its own:

providerDefault model
openai, or nonegpt-4o-mini
anthropicclaude-haiku-4-5-20251001
googlegemini-2.5-flash
ollama, generic_openaiNone: the workflow must set model, or name one on every step that calls a model. Otherwise it fails at load.

A model that no provider serves fails with No provider registered for model 'llama3.2', without a retry.

Pin dated model IDs rather than aliases: a dated ID behaves as it did when you tested it, while an alias such as -latest can change or stop answering without notice.

ProviderRecommended IDNotes
Anthropicclaude-haiku-4-5-20251001Not claude-3-5-haiku-latest: current keys get a 404 for it.
Googlegemini-2.5-flashNot gemini-2.0-flash, which returns a 404 for new users.
OpenAIgpt-4o-mini, gpt-4o

Six names belong to their provider: gpt-4o-mini, gpt-4o, gpt-4.1, o4-mini, claude-haiku-4-5-20251001 and gemini-2.5-flash go to it, to config.provider if that can serve them, and to the fallback providers.

Fallback

When a provider fails, the attempt moves on to the next one that can serve the model: config.provider first, then the providers that serve its name, by priority, then Ollama when it is a fallback. A few limits:

  • Every provider receives the model name as requested, unless its model_aliases translates it. Without an alias, Anthropic can’t answer for gpt-4o, so a fallback is useful only towards a provider that takes any name, and only if it serves a model of that exact name.
  • A streamed call falls back only before its first chunk. After that, a provider error fails the attempt.

When every provider fails, the error starts with All providers failed for model. Reliability covers how fallback, circuit breakers and rate limits combine with retries.

Using Ollama

  • provider: ollama sets up Ollama and tries it first for every model: with an OpenAI key set, o3 or gpt-4o-mini go to Ollama before OpenAI. It has no default model, so the workflow must set model, or name one on every step that calls a model.
  • AGENTLOOM_OLLAMA_FALLBACK=1, or true, yes or on, sets up Ollama as a fallback, tried after the others. Any other value leaves it off, without a warning.
  • AgentLoom doesn’t look for a running Ollama: without one of the two, it isn’t used.
  • Ollama costs 0, and its requests time out after 120 seconds.

Config file

A providers: block in a config file replaces the discovery above: the CLI sets up the providers it lists, and only those.

agentloom.yaml
providers:
- name: openai
models: [gpt-4o, gpt-4o-mini]
- name: anthropic
priority: 10
model_aliases:
gpt-4o: claude-haiku-4-5-20251001
- name: ollama
base_url: http://gpu-box:11434
priority: 100
KeyWhat it does
nameopenai, anthropic, google or ollama. Any other name, mock and generic_openai included, stops the command.
modelsNames that go to the providers that list them, by priority, besides config.provider and the fallback providers.
model_aliasesA requested model name and this provider’s name for it. The provider receives its own name, and is tried for the requested one even if it wouldn’t serve it.
priorityThe order among the providers that serve a model, lowest first. 0 by default; a tie keeps the file’s order.
base_urlThe endpoint. Without it, the provider’s *_BASE_URL variable, then its default. See Endpoints.
is_fallbackAlso tries the provider for names it doesn’t serve, after the others.
  • Keys stay in the environment. Each provider reads its usual variable, and an api_key in the file stops the command, so the file can be committed. A provider listed without its key is set up all the same, and its calls fail with the provider’s 401.
  • Ollama serves any name, so it is a candidate for every model that models doesn’t pin: give it a higher priority than the others, or it is tried first. It needs no AGENTLOOM_OLLAMA_FALLBACK, and the file must list it, even for a workflow that says provider: ollama.
  • Only models pins a name: with a file, the six names above are names like any other.
  • config.provider and --provider go first, when they can serve the model, whatever their priority; priority orders the rest.
  • A fallback gets the name as requested, unless model_aliases translates it.
  • providers is the only key. Any other, or a file that doesn’t parse, stops the command with a one-line error and exit 1.

run, resume, replay (for the steps a cut runs live) and callback-server read the file that --config names, else the one AGENTLOOM_CONFIG names, else agentloom.yaml in the current directory, when there is one. A --config or AGENTLOOM_CONFIG that names a missing file stops the command. callback-server reads the file when it starts, and stops if it doesn’t load. A workflow with provider: mock or provider: generic_openai doesn’t use it.

Endpoints

OPENAI_BASE_URL, ANTHROPIC_BASE_URL, GOOGLE_BASE_URL and OLLAMA_BASE_URL point a provider at a proxy or a self-hosted gateway. Each provider treats the URL its own way:

ProviderThe URLExample
OpenAI, generic_openaiA bare host gets /v1; any other path is kept as it is. A trailing / is dropped.http://vllm:8000 becomes http://vllm:8000/v1; https://gw.example.com/openai stays.
AnthropicGets /v1, unless it already ends in /v1.https://gw.example.com/anthropic becomes …/anthropic/v1; …/v2 becomes …/v2/v1.
GoogleUsed as it is: include /v1beta.https://generativelanguage.googleapis.com/v1beta
OllamaUsed as it is.http://gpu-box:11434

The *_BASE_URL variables apply to the CLI. From Python, pass base_url to the provider, except for Ollama, which reads OLLAMA_BASE_URL itself.

Requests honour HTTPS_PROXY, HTTP_PROXY, NO_PROXY and SSL_CERT_FILE. Keys go in the provider’s usual header, Authorization: Bearer, x-api-key or x-goog-api-key; custom headers can’t be added.

OpenAI-compatible servers

generic_openai reaches any server with an OpenAI-style API, such as vLLM, LM Studio or a hosted gateway:

config:
provider: generic_openai
base_url: http://localhost:8000
api_key_env: VLLM_API_KEY # optional
model: meta-llama/Llama-3.1-8B-Instruct
  • base_url is required with generic_openai, and refused with any other provider.
  • api_key_env names the environment variable that holds the key. If that variable isn’t set, the run stops before it starts. Without api_key_env, requests carry no key; OPENAI_API_KEY is never sent.
  • It is the only provider of the run: every model goes to it, and other keys and AGENTLOOM_OLLAMA_FALLBACK are ignored.
  • It supports what OpenAI does: streaming, tools, structured output, attachments in OpenAI’s format and embeddings, as far as the server does. Streaming sends stream_options, which some servers refuse.
  • Its cost comes from the price table, by model name: a model named like a cloud model is priced like it, and other names cost 0.
  • --provider generic_openai works only on a file that sets generic_openai already, and --provider with any other provider drops the file’s base_url, with a warning.

Capabilities

OpenAI, generic_openaiAnthropicGoogleOllama
StreamingYesYesYesYes
Tool callingYesYesYesYes, without tool_choice
Structured outputNativeThrough the promptNativeNative, as the model allows
ImagesYes, by URL tooYes, by URL tooYesYes
PDFNoYesYesNo
AudioWAV and MP3NoYesNo
ReasoningBuilt into the model, level onlyYesYesYes
Reasoning tokens reportedYesIn the reply’s tokensYesIn the reply’s tokens
EmbeddingsYesNoYesYes
CostPrice tablePrice tablePrice table0

Prices covers the price table and how to add models to it.

OpenAI

  • Chat Completions, at {base_url}/chat/completions. Requests time out after 60 seconds.
  • Reasoning models, the names that start with o1, o3, o4 or gpt-5 except gpt-5-chat, get max_tokens as max_completion_tokens, no temperature, and thinking.level as reasoning_effort, which o1-mini doesn’t take. Other models get temperature and max_tokens as given.
  • Reasoning tokens are reported apart from the reply’s.
  • Embeddings go in batches of 100, with dimensions.

Anthropic

  • The Messages API, at {base_url}/messages, with anthropic-version: 2023-06-01. Requests time out after 60 seconds.
  • max_tokens is required by the API: AgentLoom sends 4096 when it is unset, plus the reasoning budget if there is one. A step on a Claude model with thinking and no budget_tokens, or whose max_tokens isn’t above its budget, fails at load.
  • All system messages are joined into one.
  • No embeddings: an embed step skips Anthropic and goes to the next provider.

Google

  • The Gemini API, at {base_url}/models/{model}:generateContent. Requests time out after 60 seconds.
  • Reasoning tokens are reported whenever Gemini returns them.
  • Embeddings go in one batch, with dimensions. Gemini returns no token count for them: AgentLoom estimates about 1.3 tokens a word, and prices that.

Ollama

  • {base_url}/api/chat. Requests time out after 120 seconds.
  • <think> blocks are removed from replies.
  • Embeddings send dimensions, as far as the server takes it.

Errors

The provider returnsWhat AgentLoom raisesRetried
429RateLimitError, with the statusYes. The step waits at least what Retry-After asks, up to backoff_max. See Retries.
Any other error statusProviderError, with the status and the provider’s messageWhen the status is in retryable_status_codes.
No answer: a refused connection, a timeout, on a stream tooProviderError, without a statusYes.
A 200 whose body isn’t JSONProviderError, without a statusYes.
An attachment it can’t takeUnsupportedRequestError, before any requestNo, once no provider can take it. See Attachments.

When every provider fails, the gateway’s error keeps a status only if they all returned the same one. What is retried covers the rest.

Response metadata

Each step’s result records what answered:

  • model, as the provider reports it: OpenAI’s dated name, such as gpt-4o-2024-08-06, Ollama’s tag, such as llama3.2:latest, and Google’s requested name;
  • provider, the one that answered, which shows a fallback;
  • token_usage, with reasoning_tokens, and cost_usd;
  • prompt_metadata.finish_reason, as the provider wrote it: stop, end_turn, STOP.

agentloom run --json prints them. A failed step has no model or provider.

From Python, a provider’s ProviderResponse.meta adds what the call sent and got back besides the answer: the temperature, top_p and seed sent, the provider’s identifiers, its rate-limit headers and received_at. It reaches recordings too, but not results or --json.

Providersystem_fingerprintmodel_versionrequest_id
OpenAI, generic_openaiFrom the bodyThe x-request-id header
AnthropicThe request-id header
GooglemodelVersionresponseId
Ollama

Environment variables

VariableWhat it does
OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEYSet up the provider, with that key. AgentLoom reads no .env file.
OPENAI_BASE_URL, ANTHROPIC_BASE_URL, GOOGLE_BASE_URL, OLLAMA_BASE_URLThe provider’s endpoint. See Endpoints.
AGENTLOOM_OLLAMA_FALLBACK1, true, yes or on sets up Ollama as a fallback.
AGENTLOOM_CONFIGThe config file, when the command has no --config.
The variable api_key_env namesThe key of a generic_openai server.
AGENTLOOM_PRICING_FILEA price table that replaces the bundled one. See Prices.
AGENTLOOM_CANDIDATE_CACHE_MAXHow many model names the gateway remembers the providers of. 1024 by default.
AGENTLOOM_LOG_LEVEL, AGENTLOOM_LOG_FORMATThe level and format of the CLI’s logs. See Logs.

From Python

The CLI’s setup doesn’t apply to a Python program, which registers its providers on a ProviderGateway itself, with their priorities, fallbacks, rate limits and circuit breakers. See The provider gateway.

What’s next

Docs of agentloom 0.5.0. View the source of this page Report an issue