Based Mdels

Agent Loop docs

agentloop.provider

Provider-independent request and response types. The loop sends a ModelRequest to an LLMClient and receives a ModelResponse; provider adapters translate between these types and each provider's API. The Pydantic models on this page are frozen.

StopReason

A StrEnum with members END_TURN, TOOL_USE, MAX_TOKENS, STOP_SEQUENCE, REFUSAL, ERROR, PAUSED, and UNKNOWN. Provider integrations preserve unfamiliar values as UNKNOWN; a local tool call forces TOOL_USE unless the response was truncated at MAX_TOKENS. PAUSED means a provider-hosted tool stopped partway through a turn and needs the loop to continue it.

Type aliases

  • ToolChoice: "auto" | "none" | "required".

ToolSchema

FieldTypeDefault
namenon-empty strrequired
descriptionstrrequired
parametersdict[str, Any]required
strictboolTrue

parameters is the bare JSON Schema, without a vendor-specific function envelope. strict=True asks supporting providers to constrain tool-call arguments to that schema; adapters omit or disable the setting when the selected API does not support it.

ModelRequest

FieldTypeDefault
messagestuple[Message, ...]required
system`strNone`
toolstuple[ToolSchema, ...]()
max_tokenspositive int16_000
temperature`float 0..2None`
stop_sequencestuple[str, ...]()
tool_choiceToolChoice"auto"
parallel_tool_callsboolTrue
hosted_toolstuple[HostedTool, ...]()

temperature=None means the parameter should be omitted.

Usage

FieldTypeDefault
input_tokens, output_tokensnon-negative int0
cache_read_tokens, cache_write_tokens, reasoning_tokensnon-negative `intNone`
cost_usdnon-negative `floatNone`
input_includes_cachedboolTrue

input_includes_cached reports whether input_tokens already includes cache reads. A None optional field means the provider did not report it; this differs from zero.

ModelResponse

FieldTypeDefault
contenttuple[ContentPart, ...]required
stop_reasonStopReasonrequired
usageUsagerequired
modelstrrequired
providerstrrequired
raw_stop_reason`strNone`
request_id`strNone`
attemptspositive int1
retry_wait_secondsnon-negative float0.0
attempt_logtuple[AttemptRecord, ...]()
origin`OriginNone`

content may be empty only when stop_reason=MAX_TOKENS and the provider stopped before producing usable content. attempts, retry_wait_seconds, and attempt_log describe retries; the log is empty when the first attempt succeeded. origin holds the adapter's wire representation for replay when available.

agentloop supports Anthropic, OpenAI, OpenRouter, and Modal/vLLM. This example calls OpenAI directly. Install its support and set the provider credentials:

python -m pip install 'based-models-agentloop[openai-compat]'
export LLM_PROVIDER=openai
export OPENAI_API_KEY='your-key'

Build a request, send it through the configured client, and read the normalized response:

import os

from agentloop import Settings, Transcript, build_client
from agentloop.provider import ModelRequest
from agentloop.transcript import TextPart

transcript = Transcript()
transcript.add_user_message("How many days are in a week? Reply with one digit.")
request = ModelRequest(messages=tuple(transcript.messages))

client = build_client(Settings.from_env(os.environ))
try:
    response = client.complete(request)
    print("".join(part.text for part in response.content if isinstance(part, TextPart)))
    print(response.stop_reason.value)
finally:
    client.close()

Output:

7
end_turn

build_client() supplies a retrying LLMClient. This direct call makes one model request; the higher-level Agent also handles tool calls and transcript updates.

AttemptRecord

One provider attempt in attempt_log. Its fields are attempt (one-based number), ok, error_type, status_code, phase, request_sent, request_id, and wait_seconds. Optional error fields are None when unknown. wait_seconds is the delay after this attempt and is zero for the last attempt.

LLMClient

Protocol with read-only name: str and model: str properties and:

complete(request: ModelRequest) -> ModelResponse

See custom providers for an implementation.

supported_hosted_tools

supported_hosted_tools(client) -> frozenset[str]

The hosted tool kinds a client can run: its optional hosted_tools attribute, or an empty set when it has none. A client that says nothing supports nothing, so a custom provider needs no new attribute to stay an LLMClient.

HostedTool

A provider-run capability declared on each request. kind names the capability, such as "web_search", and options contains settings for the adapter to translate. kind must be a non-empty string and options defaults to an empty dictionary. The provider client must advertise support for the kind; unsupported hosted tools are rejected when the agent is created. The separate agentloop-tools package offers validated helpers that create these HostedTool objects. See Hosted tools and web search.