Daita agents / guide
LLM Providers
Use API-backed, local, custom, and supported subscription model routes through one normalized provider boundary.
#Supported Adapters
| Provider identity | Authentication 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.
#Recommended Setup
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 loginfirst. - Grok Build uses the installed client's saved login. Run
grok loginfirst.
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:
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:
provider = create_llm_provider("ollama:qwen3")A custom identity requires a base URL:
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:
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.