Model configuration management.
Handles loading and saving model configuration from TOML files, providing a structured way to define available models and providers.
Public docs page for configuring model providers.
Referenced by UnknownProviderError and the /auth manager so the same
URL is used everywhere a user is sent to read about provider setup.
Directory for user-level Deep Agents configuration (~/.deepagents).
Path to the user's model configuration file (~/.deepagents/config.toml).
Directory for app-managed internal state (~/.deepagents/.state).
Holds files the app writes for its own bookkeeping — OAuth tokens, the
sessions database, version-check caches, input history. Kept separate from
top-level user-facing config and agent directories so listing/iterating
~/.deepagents doesn't conflate state with agents.
Well-known providers mapped to the env var that holds their API key.
Used by has_provider_credentials to verify credentials before model
creation, so the UI can show a warning icon and a specific error message
(e.g., "ANTHROPIC_API_KEY not set") instead of letting the provider fail at call
time.
Providers not listed here fall through to the config-file check or the langchain registry fallback.
Providers that support ambient auth outside app env-var checks.
These providers can authenticate without the env var listed in
PROVIDER_API_KEY_ENV, so a missing env var should not be treated as a hard
credential failure. Used by create_model to skip the early credential check
and by get_provider_auth_status for user-facing auth labels.
Providers whose default local configuration does not require API keys.
Optional env vars that enable authenticated provider modes when present.
Provider-specific env vars that can point a local provider at a remote host.
Default endpoint assumed when no base_url or OLLAMA_HOST is configured.
Socket timeout for Ollama discovery probes.
Kept short so a dead daemon does not stall switcher loading. Discovery runs
off the UI loop in a worker thread and may call /api/tags and /api/show,
so this caps the worst-case wait visible to the user.
Default visibility for thread selector columns.
Return whichever env var name actually carries the resolved value.
Mirrors resolve_env_var's precedence: when the prefixed variant is
present in os.environ (even empty), it wins; otherwise the canonical
name is returned. Useful for UI labels that need to reflect what the
app is actually reading rather than the canonical name.
Look up an env var with DEEPAGENTS_CODE_ prefix override.
Checks DEEPAGENTS_CODE_{name} first, then falls back to {name}.
If the prefixed variable is present in the environment (even as an empty
string), the canonical variable is never consulted. This lets users
set DEEPAGENTS_CODE_X="" to shadow a canonically-set key -- the function
will return None (since empty strings are normalized to None),
effectively suppressing the canonical value.
If name already carries the prefix, the double-prefixed lookup is skipped
to avoid nonsensical DEEPAGENTS_CODE_DEEPAGENTS_CODE_* reads
(e.g., when the name comes from a user's config.toml).
Reset module-level caches so the next call recomputes from scratch.
Intended for tests and for the /reload command.
Get available models dynamically from installed LangChain provider packages.
Imports model profiles from each provider package and extracts model names.
Results are cached after the first call; use clear_caches() to reset.
Load upstream profiles merged with config.toml overrides.
Keyed by provider:model spec string. Each entry contains the
merged profile dict and the set of keys overridden by config.toml.
Unlike get_available_models(), this includes all models from upstream
profiles regardless of capability filters (tool calling, text I/O).
Results are cached; use clear_caches() to reset. When cli_override is
provided the result is stored in a single-slot cache keyed by
id(cli_override). This relies on the caller retaining the same dict
object for the session (the app stores it once on the app instance);
passing a different dict with the same contents will bypass the cache
and overwrite the previous entry.
Resolve the credential value for provider from any configured source.
Lookup order:
~/.deepagents/.state/auth.json (added via /auth).resolve_env_var() (which honors the
DEEPAGENTS_CODE_ prefix and dotenv files).A user who has both a stored key and an env var set gets the stored key — entering one in the TUI is the more deliberate, more recent action, so "I just typed this in" beats whatever the shell exported.
Return credential readiness details for a provider.
Combines config, well-known provider metadata, optional provider auth, and implicit-auth provider metadata before attempting model creation:
config.toml
[models.providers.<name>]):
api_key_env, that env var is checked
via resolve_env_var() (which honors DEEPAGENTS_CODE_ prefixes).class_path but no api_key_env, the provider is
assumed to manage its own auth (e.g., custom headers, JWT, mTLS).api_key_env nor class_path is set, falls through
to provider-specific defaults.PROVIDER_API_KEY_ENV): a module-level dict
mapping well-known provider names to their canonical env var
(e.g., "anthropic" → "ANTHROPIC_API_KEY"). The env var is checked
via resolve_env_var().OPTIONAL_AUTH_ENV): when present, mark
the provider as configured for hosted/cloud use.NO_AUTH_REQUIRED_PROVIDERS): default
local endpoints report NOT_REQUIRED; non-local endpoints fall back
to UNKNOWN so the SDK can decide.Use has_provider_credentials() when compatibility with the historic
True/False/None contract is required.
Check if credentials are available for a provider.
This compatibility wrapper preserves the historic tri-state contract while
get_provider_auth_status() carries the richer user-facing distinctions:
configured credentials, missing credentials, no-auth local providers,
implicit auth, custom provider-managed auth, and unknown providers.
Return the env var name that holds credentials for a provider.
Checks the config file first (user override), then falls back to the
hardcoded PROVIDER_API_KEY_ENV map.
Export this provider's stored API key into os.environ for SDK use.
LangChain's chat-model factories read credentials from process env vars, so a stored key only takes effect once it's copied onto the env var name registered for that provider. This is a no-op when the provider has no env-var mapping (custom auth) or no stored credential.
The env var is overwritten whether or not it was already set, matching
the precedence rule documented on resolve_provider_credential: a
credential the user typed in /auth is the most recent deliberate
action and should take effect.
Update the default model in config file.
Reads existing config (if any), updates [models].default, and writes
back using proper TOML serialization.
Remove the default model from the config file.
Deletes the [models].default key so that future launches fall back to
[models].recent or environment auto-detection.
Check if a warning key is suppressed in the config file.
Reads the [warnings].suppress list from config.toml and checks
whether key is present.
Add a warning key to the suppression list in the config file.
Reads existing config (if any), adds key to [warnings].suppress,
and writes back using atomic temp-file rename. Deduplicates entries.
Remove a warning key from the suppression list in the config file.
Reads existing config (if any), removes key from [warnings].suppress,
and writes back using atomic temp-file rename. No-op if the key is not
present or the file does not exist.
Load all thread-selector settings from one config file read.
Returns a cached result when reading the default config path. The
prewarm worker calls this at startup so subsequent opens of the
/threads modal avoid disk I/O entirely.
Clear the cached ThreadConfig so the next load re-reads disk.
Load thread column visibility from config file.
Save thread column visibility to config file.
Load the relative-time display preference for thread timestamps.
Save the relative-time display preference for thread timestamps.
Load the sort order preference for the thread selector.
Save the sort order preference for the thread selector.
Update the recently used model in config file.
Writes to [models].recent instead of [models].default, so that /model
switches do not overwrite the user's intentional default.
Update the recently used agent in config file.
Writes to [agents].recent so a later bare deepagents launch (no
-a) can bring the user back to their last agent instead of the
default.
Read [agents].recent from the config file.
Update the default agent in config file.
Writes to [agents].default. This is the user's intentional sticky
default — set via Ctrl+S in the /agents picker — and takes
precedence over [agents].recent on bare-launch resolution.
Remove the default agent from the config file.
Deletes the [agents].default key so that future launches fall back
to [agents].recent and then DEFAULT_AGENT_NAME.
Read [agents].default from the config file.
Raised when model configuration or creation fails.
Raised when no credentials are configured for any default-resolvable provider.
Distinct from MissingCredentialsError (which targets a specific provider
the user has selected): this fires from _get_default_model_spec() when
auto-detection finds no usable credentials at all. Callers (the deferred-
start path in the TUI and CLI) isinstance-check this type to recover by
launching the TUI with model creation deferred, rather than string-matching
the formatted message.
Raised when neither the app nor init_chat_model can infer a provider.
Carries the offending model spec as an attribute and exposes
PROVIDERS_DOCS_URL as a class-level constant so callers can render
a clickable link without string-scanning the formatted message. This
mirrors how MissingCredentialsError exposes provider / env_var
for targeted recovery hints.
Raised when a provider is selected but its API key env var is unset.
Subclasses ModelConfigError so existing except ModelConfigError blocks
keep working. Carries the provider name and the canonical env_var so
callers can render targeted recovery hints (e.g., "set OPENAI_API_KEY" or
"run /model <other_provider>:<model>") without string-matching on the
formatted exception message and without re-deriving the env-var name.
Credential readiness state for a model provider.
Origin of a CONFIGURED credential, used to discriminate display.
Credential readiness information for a provider.
A model specification in provider:model format.
Profile data for a model with override tracking.
Configuration for a model provider.
The optional class_path field allows bypassing init_chat_model entirely
and instantiating an arbitrary BaseChatModel subclass via importlib.
Setting class_path executes arbitrary Python code from the user's
config file. This has the same trust model as pyproject.toml build
scripts — the user controls their own machine.
Parsed model configuration from config.toml.
Instances are immutable once constructed. The providers mapping is
wrapped in MappingProxyType to prevent accidental mutation of the
globally cached singleton returned by load().
Coalesced thread-selector configuration read from a single TOML parse.
User-level credential storage for model providers.
Persists API keys (and, in the future, OAuth tokens) under
~/.deepagents/.state/auth.json (file mode 0600, parent 0700) so users can
enter credentials directly in the TUI rather than exporting environment
variables before launch.
Security notes:
ApiKeyCredential.key) must never be logged, formatted
via %r/!r, or interpolated into exception messages — every helper here
reports only structural facts ("set credential for provider X").O_EXCL | 0o600 to a temp path, then atomically
replaced. A second chmod 0600 runs on the final path so filesystems that
ignore the create-mode argument still end up with private perms. Permission
failures are reported back to the caller in WriteOutcome.warnings so the
UI can surface them to the user — logger.warning alone is invisible
inside a Textual TUI session.