Deep Agents Code - Interactive AI coding assistant.
Attach a file handler to target when DEEPAGENTS_CODE_DEBUG is set.
Intended to be called once on the deepagents_code package logger; child
module loggers reach the same file via propagation, so individual modules do
not configure logging themselves.
The log file defaults to DEFAULT_DEBUG_FILE but can be overridden with
DEEPAGENTS_CODE_DEBUG_FILE. The handler appends (mode='a') so logs
are preserved across separate process runs. Calling this again with the same
resolved path is a no-op: the existing tagged handler is reused rather than
stacking duplicates. If the resolved path changes, the stale handler is
closed and replaced.
Does nothing when DEEPAGENTS_CODE_DEBUG is not truthy (see is_env_truthy).
Best-effort writer for terminal escape/control sequences.
Centralizes the "fire and forget" pattern the app uses for cosmetic terminal
control (OSC 9;4 taskbar progress today; eventually OSC 52 clipboard and the
iTerm2 cursor guide). Writes prefer /dev/tty so output reaches the terminal
even when stdout/stderr are redirected, fall back to sys.__stderr__, and
never raise — cosmetic control output must not crash the app.
Set DEEPAGENTS_CODE_NO_TERMINAL_ESCAPE=1 to disable all output (useful for
unsupported terminals or noisy logs).
First-run onboarding state for the interactive TUI.
Subagent loader for app.
Loads custom subagent definitions from the filesystem. Subagents are defined as markdown files with YAML frontmatter in the agents/ directory.
External event ingress for the Textual app.
Exposes a small EventSource protocol plus a Unix-domain-socket implementation
that lets local processes push commands, prompts, and signals into a running
session over a newline-delimited JSON wire protocol.
The wire format and configuration env vars may change without semver guarantees while this surface stabilizes.
Middleware for injecting local context into system prompt.
Detects git state, project structure, package managers, runtimes, and directory layout by running a bash script via the backend. Because the script executes inside the backend (local shell or remote sandbox), the same detection logic works regardless of where the agent runs.
Utilities for project root detection and project-specific configuration.
Canonical manifest and resolver for every user-tunable scalar config option.
This module is the single source of truth for the configuration surface: the
set of options, their types, typed defaults, env-var names, and config.toml
locations. The typed defaults for config-file-only options (notably the
[interpreter] section) live here as module constants, and Settings derives
its dataclass defaults from them — so a default is defined in exactly one place.
resolve_scalar is the shared resolution engine used both by the runtime
(Settings.from_environment) and by the config CLI command, so introspection
can never drift from what the app actually reads. Resolution precedence mirrors
the loaders: a DEEPAGENTS_CODE_-prefixed env var beats the canonical name,
env beats config.toml, and the typed default is the final fallback. A
malformed numeric/list/PTC value, an unrecognized boolean token, or a
wrong-typed TOML value is logged and falls back to the next layer rather than
raising, so a bad config never blocks startup.
Structured, user-defined config is not a flat scalar option and is parsed by
dedicated typed loaders elsewhere. The manifest references [threads].columns
and [warnings].suppress as STRUCTURED options for discovery; other tables
such as [models.providers.*] and [themes.*] are handled entirely by their
own loaders and the manifest does not enumerate them at all.
Import discipline: the module top level stays stdlib + _env_vars only (both
light) so it is safe to import from config.py at class-definition time without
pulling the heavy model_config/agent runtime onto the startup fast path.
Anything needing model_config (provider credentials, the config path, env-var
prefix resolution) is imported lazily inside functions.
Remote agent client — thin wrapper around LangGraph's RemoteGraph.
Delegates streaming, state management, and SSE handling to
langgraph.pregel.remote.RemoteGraph. This wrapper converts streamed message
dicts into LangChain message objects for the app's Textual adapter, but leaves
state snapshots in the server's serialized form.
Custom tools for the agent.
UI-agnostic interaction interface for MCP OAuth login.
The OAuth login flow needs to ask the user a few things during the
handshake — open or display the authorize URL, accept a pasted callback
URL when the provider has no loopback redirect, show RFC 8628 device-code
instructions, and report success or failure. The CLI uses print and
input; a TUI surface needs in-app widgets instead. OAuthInteraction is
the small Protocol both implementations satisfy, and CliOAuthInteraction
is the existing CLI behavior preserved as one implementation of that
interface.
Important: implementations must never embed access or refresh tokens in user-facing messages. The interaction surface only ever sees authorize URLs, callback URLs, device codes, and short status strings, so leaks come from misuse, not from this interface's shape.
Agent management and creation.
Registry of pending actionable notifications.
Stores plain data for notices the user can act on from a dedicated modal screen. The registry is deliberately UI-agnostic: UI routing (toast click, keybinds) lives in the app layer.
Machine-readable JSON output helpers for CLI subcommands.
This module deliberately stays stdlib-only so it can be imported from CLI startup paths without pulling in unnecessary dependency trees.
Configuration, constants, and model creation.
Lightweight text-formatting helpers.
Keep this module free of heavy dependencies so it can be imported anywhere in the app without pulling in large frameworks.
Clipboard utilities.
One-time migration of legacy state files into ~/.deepagents/.state/.
Earlier versions wrote internal state directly under ~/.deepagents/,
mixing it with user-facing agent directories (so e.g. mcp-tokens/
showed up in deepagents agents list). State now lives in a dedicated
.state/ subdirectory; this module moves any legacy files into place
on startup.
The migration is best-effort and idempotent: it skips entries whose destination already exists, logs and continues on per-entry failures, and never blocks startup on I/O errors.
Server-side graph entry point for langgraph dev.
This module is referenced by the generated langgraph.json and exposes the
agent graph as a module-level variable that the LangGraph server can load
and serve.
The graph is created at module import time via make_graph(), which reads
configuration from ServerConfig.from_env() — the same dataclass the CLI uses
to write the configuration via ServerConfig.to_env(). This shared schema
ensures the two sides stay in sync.
Server lifecycle orchestration for the app.
Provides start_server_and_get_agent which handles the full flow of:
ServerConfig from application argumentsServerConfig.to_env()langgraph dev serverRemoteAgent clientAlso provides server_session, an async context manager that wraps
server startup and guaranteed cleanup so callers don't need to
duplicate try/finally teardown.
Trust store for project-level MCP server configurations.
Manages persistent approval of project-level MCP configs that contain stdio servers (which execute local commands). Trust is fingerprint-based: if the config content changes, the user must re-approve.
Trust entries are app-managed bookkeeping (a map of project root to config
fingerprint), not user-facing configuration, so they live alongside the
other state files under ~/.deepagents/.state/mcp_trust.json rather than in
the hand-editable config.toml.
Terminal capability detection.
Detect optional terminal features without reading from stdin.
The app only uses kitty-keyboard-protocol support to choose a user-facing newline shortcut label. To keep startup safe on remote or high-latency PTYs, detection is conservative and relies on side-effect-free terminal identity signals plus an explicit environment-variable override.
Inspect optional-dependency install status for the running distribution.
Reads Requires-Dist metadata to report which packages declared under
[project.optional-dependencies] are installed, and renders that status
in either plain text (for stdout) or markdown (for rich UI contexts).
UI-agnostic helpers for resolving an MCP login target.
The MCP login flow historically inlined config discovery, trust gating,
shape validation, and print()-based error reporting. The TUI cannot
consume those print statements, so this module extracts the same logic
into pure functions that return structured results (ConfigResolution,
ServerSelection) plus a typed ConfigResolutionError. Callers decide
how to render those results.
No print() calls live in this module. No imports happen at module
top level beyond dataclasses/typing/pathlib so the CLI fast path
stays cheap; the actual config loaders are imported inside the
functions that need them.
Unified slash-command registry.
Every slash command is declared once as a SlashCommand entry in COMMANDS.
Bypass-tier frozensets and autocomplete entries are derived automatically — no
other file should hard-code command metadata.
Formatting utilities for tool call display in the app.
This module handles rendering tool calls and tool messages for the TUI.
Imported at module level by textual_adapter (itself deferred from the startup
path). Heavy SDK dependencies (e.g., backends) are deferred to function bodies.
Helpers for tracking file operations and computing diffs for display.
Ask user middleware for interactive question-answering during agent execution.
Textual UI application.
Model configuration management.
Handles loading and saving model configuration from TOML files, providing a structured way to define available models and providers.
Normalize empty ls/glob tool output for the model.
This middleware exists only because the SDK's ls/glob tools currently
serialize a successful-but-empty result as the literal "[]". Upstream is
expected to start returning useful empty-result content directly, at which
point this middleware becomes redundant and should be removed. The canary
test test_sdk_still_returns_bracket_for_empty_listing in
tests/unit_tests/test_filesystem_empty_result.py fails loudly when that
upstream change lands, signalling that this module can be deleted.
Middleware that persists per-checkpoint state needed to resume a thread.
Registers two checkpointed, schema-private channels and writes them from
after_model:
_context_tokens — total context tokens from the latest
AIMessage.usage_metadata. Powers /tokens and the status bar._model_spec — the provider:model spec that was effectively in use for
the turn, read from runtime.context["effective_model"]. Lets dcode -r
restore the model the resumed thread was actually using instead of falling
back to the user's global default.Both are facts the CLI reads back from state_values on thread resume so it
can rehydrate the session without replaying or re-tokenizing history.
Persisting from inside the graph (rather than via a separate client-side
aupdate_state call) keeps the write on the same checkpoint as the model
response and avoids creating a standalone UpdateState run in LangSmith.
Because both values are versioned channel state, resuming a specific
checkpoint yields the values as of that checkpoint — not a thread-level
aggregate. It also works identically against local and remote (HTTP) graphs.
Unicode security helpers for deceptive text and URL checks.
This module is intentionally lightweight so it can be imported in display and approval paths without affecting startup performance.
iTerm2 cursor guide workaround for Textual alternate-screen rendering.
LangGraph server lifecycle management for the app.
Handles starting/stopping a langgraph dev server process and generating the
required langgraph.json configuration file.
Thread management using LangGraph's built-in checkpoint persistence.
Protect machine-managed memory blocks from agent edits.
The onboarding flow writes the user's preferred name into the user AGENTS.md
inside a marker-delimited block (see onboarding.ONBOARDING_NAME_MEMORY_START /
ONBOARDING_NAME_MEMORY_END). MemoryMiddleware strips HTML comments before
injecting memory, so the model never sees those markers and has no way to know
the region is off-limits. Since the same prompt tells the model to edit_file
that file to persist learnings, nothing stops it from rewriting the managed
block.
This middleware intercepts write_file/edit_file calls targeting the guarded
file(s). When a call would change or remove the managed block, the model's other
edits are kept (though surrounding whitespace may be normalized, and a fully
removed block is re-appended rather than restored in place) while the managed
block is restored, and an error is returned so the model learns the region is
machine-managed. When the block was altered but the restore could not be
completed, an error is still returned so the failure is never silent.
Middleware for runtime model selection via LangGraph runtime context.
Allows switching the model per invocation by passing a CLIContext via
context= on agent.astream() / agent.invoke() without recompiling
the graph.
Main entry point and loop.
LangChain brand colors and semantic constants for the app.
Single source of truth for color values used in Python code (Rich markup,
Content.styled, Content.from_markup). CSS-side styling should reference
Textual CSS variables: built-in variables
($primary, $background, $text-muted, $error-muted, etc.) are set via
register_theme() in DeepAgentsApp.__init__, while the few app-specific
variables ($mode-bash, $mode-command, $mode-incognito, $skill,
$skill-hover, $tool, $tool-hover) are backed by these constants via
App.get_theme_variable_defaults().
Code that needs custom CSS variable values should call
get_css_variable_defaults(dark=...). For the full semantic color palette, look
up the ThemeColors instance via get_registry().
Users can define custom themes in ~/.deepagents/config.toml under
[themes.<name>] sections. Each new theme section must include label (str);
dark (bool) defaults to False if omitted (set to True for dark themes).
Color fields are optional and fall back to the built-in dark/light palette based
on the dark flag. Sections whose name matches a built-in theme override its
colors without replacing it. See _load_user_themes() for details.
Utilities for handling image and video media from clipboard and files.
Input handling utilities including image/video tracking and file mention parsing.
Auto-install pinned upstream binaries for optional tools.
Today this only manages ripgrep. The SDK shells out to rg via PATH,
so installing into ~/.deepagents/bin/ and prepending that directory to
os.environ["PATH"] is sufficient — no SDK change required.
The pinned RIPGREP_VERSION and RIPGREP_ASSETS table is the single
source of truth for what gets downloaded and verified. When bumping the
version, refresh both the version and the SHA-256 entries together.
MCP (Model Context Protocol) tools loader.
This module provides async functions to load and manage MCP servers using
langchain-mcp-adapters, supporting Claude Desktop style JSON configs.
It also supports automatic discovery of .mcp.json files from user-level
and project-level locations.
Persistent store of MCP server names the user has disabled.
Disabled servers are skipped at config merge time so their tools never
reach the agent and no connection is attempted. State lives under
[mcp_disabled] in ~/.deepagents/config.toml, alongside the user's
other configuration sections.
The store keys on server name alone. Two configs that both declare a
github server will both be disabled by a single entry — intentional,
since the agent cannot distinguish overlapping names at runtime anyway
(later configs in the merge order win).
Textual UI adapter for agent execution.
Shared provider auth status formatting.
OAuth login flow and token storage for MCP servers.
Note: mcp.shared.auth.OAuthToken is a pydantic model whose default
repr includes the access and refresh token strings verbatim. Never
log one via %r, str(), f-string interpolation, or
logger.exception/exc_info on an exception that wraps one — the
tokens will land in stdout, log files, and error-reporting
pipelines. Pass only structural facts ("refreshed token for
server X") rather than the token itself.
External editor support for composing prompts.
Update lifecycle for deepagents-code.
Handles version checking against PyPI (with caching), install-method detection, auto-upgrade execution, config-driven opt-in/out, notification throttling, and "what's new" tracking.
Most public entry points absorb errors and return sentinel values.
set_auto_update raises on write failures so callers can surface
actionable feedback.
Non-interactive execution mode.
Provides run_non_interactive which runs a single user task against the
agent graph, streams results to stdout, and exits with an appropriate code.
The agent runs inside a langgraph dev server subprocess, connected via
the RemoteAgent client (see server_manager.server_session).
Shell commands are gated by an optional allow-list (--shell-allow-list):
recommended or explicit list → shell enabled, commands validated
against the list; non-shell tools approved unconditionally.all → shell enabled, any command allowed, all tools auto-approved.An optional quiet mode (--quiet / -q) redirects all console output to
stderr, leaving stdout exclusively for the agent's response text.
CLI commands of the MCP module.
CLI commands for the config group: inspect the configuration surface.
config list prints the static manifest (every tunable option, its type,
default, and where it can be set). config show resolves each option against
the live environment and config.toml, reporting the effective value and which
source provided it. config get <key> does the same for a single option.
config path prints the on-disk config locations.
Secret-flagged options (API keys and other credentials) are never printed by
value — config show/config get report only whether they are set and from
which source, so the output is safe to paste into a bug report.
Help rendering for a bare config invocation is served by ui.show_config_help,
which does not import this module. The heavy manifest/runtime imports here are
function-local to the subcommands, so a bare config/config -h invocation
never pulls them onto the startup path (parse_args does import this module to
register the subparsers, but only its light top-level imports run then).
Help screens and argparse utilities for the app.
This module is imported at app startup to wire -h actions into the
argparse tree. It must stay lightweight — no SDK or langchain imports.
Business logic for the /offload command.
Extracts the core offload workflow from the UI layer so it can be tested independently of the Textual app.
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.Integrations for external systems used by the Deep Agents Code.
Provider-specific MCP OAuth dispatch.
resolve_provider(url) returns the registered policy whose matches
predicate fires for url, with GenericProvider as the fallback.
Skills module for Deep Agents Code.
Public API:
All other components are internal implementation details.
Built-in skills that ship with the Deep Agents Code.
These skills are always available at the lowest precedence level. User and project skills with the same name will override them.
Lightweight hook dispatch for external tool integration.
Loads hook configuration from ~/.deepagents/hooks.json and fires matching
commands with JSON payloads on stdin. Subprocess work is offloaded to a
background thread so the caller's event loop is never stalled. Failures are
logged but never bubble up to the caller.
Config format (~/.deepagents/hooks.json):
{"hooks": [{"command": ["bash", "adapter.sh"], "events": ["session.start"]}]}
If events is omitted or empty the hook receives all events.
Onboarding emits user.name.set with {"name": "...", "assistant_id": "..."}
after the user submits a non-empty preferred name.
Textual widgets for deepagents-code.
Import directly from submodules, e.g.:
from deepagents_code.widgets.chat_input import ChatInput
from deepagents_code.widgets.messages import AssistantMessage