Docs

Daita agents / guide

LLM Providers

Use API-backed, local, custom, and supported subscription model routes through one normalized provider boundary.

#Supported Adapters

Provider identityAuthentication and transport
openai:<model>OpenAI API key
anthropic:<model>Anthropic API key
gemini:<model>Google Gemini API key
grok:<model>xAI API key
ollama:<model>Local or remote Ollama OpenAI-compatible endpoint
codex:<model>ChatGPT/Codex subscription authenticated inside Daita
claude-code:<model>Installed, signed-in Claude Code client
grok-build:<model>Installed, signed-in Grok Build client
<custom>:<model>Custom OpenAI-compatible endpoint with base_url

Provider SDKs are production dependencies but remain lazily imported at the boundary that first needs them.

Run daita and choose a route from the model onboarding flow. Daita shows exact reviewed models when it knows the hard context, output, and tool-support limits. An unreviewed or custom identity requires explicit context_window_tokens and max_output_tokens before it can be persisted.

Subscription routes are distinct from API routes:

  • Codex uses a ChatGPT device-code sign-in performed inside Daita; the Codex CLI is not required.
  • Claude Code uses the installed client's saved login. Run claude auth login first.
  • Grok Build uses the installed client's saved login. Run grok login first.

Daita never silently replaces a subscription with an API key, another provider, or a custom endpoint. Subscription requests use the connected account's allowance and model availability. They still receive the same bounded Daita request and can propose only Daita-validated tool calls.

#Provider Factory

Advanced callers can construct a runtime-only provider:

python
from daita import create_llm_provider
 
provider = create_llm_provider(
    "openai:gpt-5.6-terra",
    api_key=api_key,
    max_output_tokens=8_192,
)

Ollama defaults to http://127.0.0.1:11434/v1:

python
provider = create_llm_provider("ollama:qwen3")

A custom identity requires a base URL:

python
provider = create_llm_provider(
    "acme:internal-chat",
    base_url="https://models.example.com/v1",
    api_key=api_key,
    max_output_tokens=4_096,
)

#Injected Providers

Applications can inject a provider and exact profile for one open:

python
from pathlib import Path
 
from daita import Agent, LocalWorkspace
from daita.llm import ModelProfile
 
profile = ModelProfile(
    id="acme:internal-chat",
    context_window_tokens=128_000,
    max_output_tokens=4_096,
    supports_tools=True,
)
 
agent = await Agent.open(
    "atlas",
    workspace=LocalWorkspace(Path("/absolute/path/project")),
    model=provider,
    model_profile=profile,
)

The provider and profile IDs must match. Injection is runtime-only and does not rewrite the persisted route.

#Routes, Retry, and Cost

ModelRoute contains ordered ModelRouteCandidate records and a RetryPolicy. Routing retries only normalized transient provider failures and can move to an explicitly configured candidate. Authentication, configuration, invalid-request, and other permanent failures do not retry.

AgentLoop does not inspect provider-native errors or retry an entire run. Normalized provider translation and route selection stay inside the LLM layer.

Subscription usage is not treated as zero-cost API usage. Daita records tokens when available but marks dollar estimates incomplete. A run or routine requiring a complete dollar ceiling can fail closed rather than assume the request is free.

#Streaming Boundary

Provider adapters expose normalized streaming contracts for provider-level use, but Agent.run() returns a terminal LoopExit. Use an Agent observer for bounded lifecycle events; it does not emit answer-text deltas.