Skip to Content
DocsModelsOverview

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

AdapterUse it whenInstall
AnthropicModelYou’re calling Claude (Opus / Sonnet / Haiku).pip install 'loomflow[anthropic]'
OpenAIModelYou’re calling OpenAI (GPT-4o, etc.) or any OpenAI-compatible server.pip install 'loomflow[openai]'
LiteLLMModelOne adapter, ~100 providers (Mistral, Cohere, Bedrock, Vertex, Ollama, Groq, …).pip install 'loomflow[litellm]'
EchoModelZero-key dev / smoke tests. Echoes the prompt back.bare install
ScriptedModelDeterministic 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

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