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

The Model protocol requires only stream(). complete() is optional — adapters may override it with a non-streaming call, and otherwise it falls back to consuming the stream internally.

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. Omitting the kwarg raises ConfigError with a list of valid values.

Last updated on