Models
The framework ships five model adapters and accepts any class that
satisfies the Model protocol. String resolution by prefix means most
users never construct an adapter directly.
from loomflow import Agent
agent = Agent("...", model="claude-opus-4-7") # → AnthropicModel
agent = Agent("...", model="gpt-4o") # → OpenAIModel
agent = Agent("...", model="mistral-large") # → LiteLLMModel
agent = Agent("...", model="bedrock/claude-3...") # → LiteLLMModel
agent = Agent("...", model="ollama/llama3") # → LiteLLMModel (local)
agent = Agent("...", model="echo") # → EchoModel (zero-key)Five shipped adapters
| Adapter | Use it when | Install |
|---|---|---|
AnthropicModel | You’re calling Claude (Opus / Sonnet / Haiku). | pip install 'loomflow[anthropic]' |
OpenAIModel | You’re calling OpenAI (GPT-4o, etc.) or any OpenAI-compatible server. | pip install 'loomflow[openai]' |
LiteLLMModel | One adapter, ~100 providers (Mistral, Cohere, Bedrock, Vertex, Ollama, Groq, …). | pip install 'loomflow[litellm]' |
EchoModel | Zero-key dev / smoke tests. Echoes the prompt back. | bare install |
ScriptedModel | Deterministic multi-turn scenarios for tests. | bare install |
When to construct an instance directly
-
Custom client config. Pass your own
AsyncOpenAI/AsyncAnthropic:from openai import AsyncOpenAI from loomflow import Agent from loomflow.model.openai import OpenAIModel client = AsyncOpenAI(timeout=30.0, max_retries=0) agent = Agent("...", model=OpenAIModel("gpt-4o", client=client)) -
Tuning provider-specific knobs (max_tokens, temperature defaults, metadata):
from loomflow.model.anthropic import AnthropicModel agent = Agent("...", model=AnthropicModel( "claude-opus-4-7", api_key="...", max_tokens=8192, temperature=0.2, ))
Read more
The full string-to-adapter dispatch table. Per-provider config notes for Anthropic / OpenAI / LiteLLM.ProvidersHow the framework classifies model errors and which ones it retries.RetryPolicy + error taxonomy
Custom Model adapter
Implement two methods:
from collections.abc import AsyncIterator
from typing import Protocol, runtime_checkable
from loomflow.core.types import Message, ModelChunk, ToolDef
@runtime_checkable
class Model(Protocol):
@property
def name(self) -> str: ...
async def stream(
self,
messages: list[Message],
*,
tools: list[ToolDef] | None = None,
output_schema: type | None = None,
) -> AsyncIterator[ModelChunk]:
...stream() is an async generator yielding ModelChunks. Every adapter
yields:
ModelChunk(kind="text", text="...")for streaming tokens.ModelChunk(kind="tool_call", tool_call=...)for assistant tool calls.ModelChunk(kind="usage", usage=...)for input/output token counts.
The agent loop aggregates chunks; it doesn’t care about chunk boundaries.
model= is required. A previous version of the framework
silently defaulted to EchoModel, which produced confusing behaviour.
v0.2 raises ConfigError if you forget the kwarg, with a list of
valid values. See Migrating from 0.1 → 0.2.
Last updated on