Skip to Content
ModelsProviders

Providers

Pass a model name as a string and loomflow picks the adapter from the name’s prefix. This page lists every prefix it recognises, the environment variable each provider needs, and how to configure each adapter when the defaults aren’t enough.

String dispatch by prefix

String prefixResolves toRequired env var
claude-* (incl. claude-opus-*, claude-sonnet-*, claude-haiku-*)AnthropicModelANTHROPIC_API_KEY
gpt-*, o1, o3, o1-*, o3-*, o4-*OpenAIModelOPENAI_API_KEY
deepseek-*OpenAIModel at https://api.deepseek.comDEEPSEEK_API_KEY
mistral-*LiteLLMModelprovider-specific
command-* (Cohere)LiteLLMModelCOHERE_API_KEY
bedrock/*LiteLLMModelAWS creds
vertex_ai/*LiteLLMModelGCP creds
gemini/*LiteLLMModelGEMINI_API_KEY
together_ai/*LiteLLMModelTOGETHER_API_KEY
replicate/*LiteLLMModelREPLICATE_API_KEY
azure/*LiteLLMModelAzure creds
ollama/*LiteLLMModellocal Ollama running
groq/*LiteLLMModelGROQ_API_KEY
litellm/*LiteLLMModel (explicit opt-in; strips the prefix)provider-specific
echoEchoModelnone

Anything that doesn’t match one of these prefixes raises ConfigError rather than guessing, so mixtral-* or a bare provider name won’t resolve. For those, prefix with litellm/ (e.g. litellm/mistral/mixtral-8x7b) to route explicitly through LiteLLM.

from loomflow import Agent Agent("...", model="claude-opus-4-7") Agent("...", model="claude-haiku-4-5") Agent("...", model="gpt-4o") Agent("...", model="o3-mini") Agent("...", model="deepseek-chat") Agent("...", model="mistral-large") Agent("...", model="command-r-plus") Agent("...", model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0") Agent("...", model="vertex_ai/gemini-pro") Agent("...", model="ollama/llama3") Agent("...", model="groq/llama-3.1-70b") Agent("...", model="litellm/claude-3-haiku") # explicit opt-in

Anthropic

from loomflow import Agent agent = Agent("...", model="claude-opus-4-7") # ANTHROPIC_API_KEY must be set.

Install: pip install 'loomflow[anthropic]'.

The adapter wraps the official anthropic SDK’s AsyncAnthropic client: messages.create(...) for agent.run() and messages.stream(...) for agent.stream(). Tool calls serialize to Anthropic’s content-block format under the hood.

Structured output. With output_schema=, Claude 4.5 and later models get the schema as native JSON outputs (output_config.format), so the run’s tools stay callable. Older models (Opus 4 / 4.1, Sonnet 4, Sonnet 3.7, Claude 3.x), and schemas JSON outputs can’t express (recursive models, free-form dict fields), get a synthetic __output__ tool instead: forced when it’s the only tool, required among the tools when there are others, and left to the model when thinking is on, since a forced tool choice can’t be combined with thinking. Either way the agent loop validates the reply against the schema.

Neither adapter takes a temperature= option. Temperature is a per-call argument of the adapter’s complete() and stream() methods; the agent loop doesn’t set it, so agents use the provider default. The Anthropic adapter sends temperature only when you set one other than 1.0, so it works on anthropic SDK 1.x, whose messages.create no longer takes the argument (loomflow passes it in the request body there).

OpenAI

from loomflow import Agent agent = Agent("...", model="gpt-4o") # OPENAI_API_KEY must be set.

Install: pip install 'loomflow[openai]'.

OpenAI-compatible endpoints (Together, Fireworks, Anyscale, vLLM) work via base_url=, either on OpenAIModel itself or on the client you pass in.

GPT-6 and tools. The adapter calls Chat Completions, where some GPT-6 models restrict tool calling. GPT-6 Astra and GPT-6.1 Sol can’t call tools there at all: a request that offers tools raises PermanentModelError (use them without tools). GPT-6 Sol and GPT-6 Luna take tools only with reasoning_effort="none", which the adapter sends on those requests in place of your effort, warning once if you set one.

Gateways (OpenRouter)

Gateways that name models vendor/model work with both adapters. loomflow reads the vendor’s model out of the id (anthropic/claude-haiku-5.5 is Claude Haiku 5.5, openai/gpt-5-mini is GPT-5 mini), so native structured output, effort, the right output token parameter, tokenizer, context window and price all match the vendor’s model; the id is sent to the gateway unchanged. A :free variant costs nothing. Effort needs the adapter that speaks the vendor’s format: a Claude id on OpenAIModel drops it with a warning, so use AnthropicModel (below) for Claude thinking. (Before 0.17.1, gateway ids were priced at $0, so max_cost_usd budgets never tripped; before 0.17.2 they also lost the vendor model’s capabilities.)

Through OpenRouter’s OpenAI-compatible API, with OpenAIModel:

from loomflow import Agent from loomflow.model.openai import OpenAIModel model = OpenAIModel( "anthropic/claude-haiku-5.5", # or "openai/gpt-5-mini", ... api_key=OPENROUTER_API_KEY, base_url="https://openrouter.ai/api/v1", ) agent = Agent("...", model=model)

Through OpenRouter’s Anthropic-compatible Messages API, with the native AnthropicModel (Claude’s own request format: content blocks, output_config, thinking):

import anthropic from loomflow import Agent from loomflow.model.anthropic import AnthropicModel client = anthropic.AsyncAnthropic( base_url="https://openrouter.ai/api", auth_token=OPENROUTER_API_KEY, # sent as a Bearer token api_key=None, max_retries=0, # loomflow's RetryPolicy retries ) agent = Agent("...", model=AnthropicModel("anthropic/claude-haiku-5.5", client=client))

Both setups were checked against the live API for loomflow 0.17.2: plain runs, tool calls, structured output, streaming and effort.

DeepSeek

DeepSeek speaks the OpenAI wire format, so deepseek-* specs resolve to OpenAIModel pointed at https://api.deepseek.com, keyed by DEEPSEEK_API_KEY (Secrets backend or env var). A missing key raises ConfigError loudly rather than falling back to OPENAI_API_KEY.

Agent("...", model="deepseek-chat") # DEEPSEEK_API_KEY must be set

The V4 models (deepseek-v4-pro, deepseek-flash) are priced at DeepSeek’s peak-hour rate, an upper bound: off-peak is half, so cost_usd can overstate an off-peak bill but budget caps never under-count.

Using DeepSeek through a reseller / gateway? Construct the adapter directly with the gateway’s endpoint, and pass its actual rates so cost_usd and budget caps stay honest. The third element is the cached-input rate:

from loomflow.model.openai import OpenAIModel model = OpenAIModel( "deepseek-v4-flash", api_key=GATEWAY_KEY, base_url="https://gateway.example.com/v1", cost_per_mtoken=(0.75, 3.00, 0.008), # (input, output, cached input) USD/MTok )

On failover gateways, also set prompt_caching={"enabled": True, "cache_key": ...}. See Prompt caching for why the key is load-bearing there.

LiteLLM (~100 providers behind one adapter)

from loomflow import Agent agent = Agent("...", model="mistral-large") agent = Agent("...", model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0") agent = Agent("...", model="ollama/llama3")

Install: pip install 'loomflow[litellm]'.

Provider auth is whatever litellm expects. Typically env vars matching the provider’s official client (AWS_PROFILE, GOOGLE_APPLICATION_CREDENTIALS, MISTRAL_API_KEY, COHERE_API_KEY, etc.). See LiteLLM’s docs for the full matrix.

Echo

agent = Agent("...", model="echo") result = await agent.run("hi") print(result.output) # "Echo: hi"

EchoModel echoes the prompt as the assistant’s reply. No tool calls, no streaming meaningful tokens. For smoke-testing the agent loop without burning real tokens.

Scripted

from loomflow import Agent, ScriptedModel, ScriptedTurn model = ScriptedModel(turns=[ ScriptedTurn(text="The answer is 42."), ScriptedTurn(tool_calls=[...]), ScriptedTurn(text="Done."), ]) agent = Agent("...", model=model)

For tests with deterministic multi-turn scenarios. Each ScriptedTurn becomes one model response; the framework consumes them in order.

Secrets handling

API keys resolve in this order inside every adapter:

  1. Explicit api_key= argument on the adapter.
  2. secrets.lookup_sync(<ENV_VAR_NAME>) if a Secrets backend is wired on Agent(tuning=Tuning(secrets=...)).
  3. os.environ[<ENV_VAR_NAME>] as the bare fallback.

For Vault / AWS Secrets Manager / 1Password, write a custom Secrets adapter. See Secrets resolution.

Per-tenant model selection. Different tenants can use different models. Pass an instance per call by constructing a different Agent per tenant, or set up a router architecture where the classifier picks a specialist with the right model.

Last updated on