Deep Agents Code - Interactive AI coding assistant.
Configure runtime logging and register target for per-thread files.
Attach the in-memory buffer handler to target (idempotent).
Lowers target's level to at most INFO so the console shows a useful tail
even when DEEPAGENTS_CODE_DEBUG is off; never raises the level. In
__init__.py this runs before configure_debug_logging, which then sets
the final level (honoring DEEPAGENTS_CODE_DEBUG and
DEEPAGENTS_CODE_LOG_LEVEL) over this INFO floor — so any startup warnings
configure_debug_logging emits are captured by the already-installed buffer.
On a fresh NOTSET logger the NOTSET branch forces INFO without
consulting DEEPAGENTS_CODE_LOG_LEVEL; the > INFO and no env branch only
matters on reconfiguration (e.g. an importlib.reload), where it preserves
an explicit DEEPAGENTS_CODE_LOG_LEVEL rather than clobbering it with INFO.
Lowering the level does not spill log output onto the terminal: because this
handler is present in the propagation chain, Logger.callHandlers finds a
handler (found > 0) and Python's lastResort stderr handler is never
consulted. The exception is an embedding process that attaches its own
INFO-or-lower handler to the root logger, which would then see the
propagated records.
Note: this runs as an import-time side effect (see __init__.py), so every
import deepagents_code attaches the handler and may lower the package
logger's level to INFO for the lifetime of the process.
Custom tools for the agent.
Shared size limits and status vocabulary for model-visible goal state.
Thread-resume policy shared by the TUI and non-interactive mode.
Kept free of Textual imports so the headless path can enforce the same
resume-age cutoff and working-directory comparison without loading app.py.
CLI-specific rubric middleware customizations.
Persist side-question and naming spend outside the graph's checkpoints.
The sessions database owns this subtotal. Readers add it to the graph's total; it is never fed back into the graph's cost recorder or checkpoint channels. Failed charges retain only usage and pricing metadata, never the conversation. Once priced, a charge is retried without recalculating its price. Only successfully persisted charges survive a server restart.
Large paste collapsing for the chat input.
When the user pastes text exceeding a size or line threshold, the full text
is stored off-screen and a compact [Pasted text #N +M lines] placeholder
is inserted into the input box instead. At submission time the placeholder
is expanded back to the original content so the agent receives the full text.
This mirrors the behavior of Claude Code's paste-collapsing system.
Server-side graph entry point for langgraph dev.
This module is referenced by the generated langgraph.json and exposes a graph
factory that the LangGraph server can load and serve.
The graph is created by 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.
Provider-native discovery for MCP tools on supported models.
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.
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.
Bounded, read-only Git evidence collected in the tool execution environment.
Estimated context audit for the /context-doctor command.
Durable, server-authoritative thread workspace bindings.
Reasoning effort support for /effort.
Supported levels and defaults come from LangChain model profiles. Provider
integrations translate the standard reasoning_effort constructor parameter
into their native request shapes.
Schema and middleware for per-checkpoint state restored when resuming.
ResumeState declares several checkpointed, schema-private channels. They fall
into two groups with different write paths:
Written from inside the graph on successful model turns:
_context_tokens — total context tokens from the latest
AIMessage.usage_metadata, written by ResumeStateMiddleware.after_model.
Powers /tokens and the status bar._model_spec / _model_params — the model and invocation params effectively
in use for the turn, written by ConfigurableModelMiddleware after a
successful model call. Lets dcode -r restore the model the resumed thread
was actually using instead of falling back to the user's global default._last_model_request_at / _last_cache_model_spec — UTC request-start time
and requested model identity captured by ConfigurableModelMiddleware and
committed only after that call succeeds. Lets the TUI detect when the
provider's reusable prompt prefix may be cold.Written through the main graph or by the TUI client via aupdate_state (see
DeepAgentsApp._persist_goal_rubric_state) — these are user/agent-owned. Their
write sites are called out below:
_goal_objective / _goal_status / _goal_rubric / _goal_status_note —
the accepted goal and its lifecycle status. _goal_objective/_goal_rubric
are client-only, but _goal_status/_goal_status_note are also written
from inside the graph by the agent's update_goal tool._pending_goal_completion_note — optional agent-provided completion evidence
awaiting the post-turn rubric result._sticky_rubric — the TUI-owned persistent rubric. This is separate from
the public rubric graph input so one-shot rubric turns can be checkpointed
without being restored as sticky state._rubric_model_spec — the thread-scoped rubric-grader model selection,
written by the TUI client. It is a tri-state: absent means the thread has
recorded no selection, so the grader keeps its construction-time default;
INHERIT_RUBRIC_MODEL means the grader follows the active main model; any
other value is a dedicated model spec._pending_goal_objective / _pending_goal_rubric / _pending_goal_kind /
_pending_goal_request_id — a proposed goal or amendment and its originating
request, written by GoalCriteriaMiddleware inside the main graph, then
cleared by the TUI when the user accepts or rejects it.All of these are facts the CLI reads back from state_values on thread resume
so it can rehydrate the session without replaying or re-tokenizing history.
The model-turn channels are persisted from inside the graph (rather than via a
separate client-side aupdate_state call) so the write rides the same checkpoint
as the model response and avoids creating a standalone UpdateState run in
LangSmith. Because they are versioned channel state, resuming a specific
checkpoint yields the values as of that checkpoint — not a thread-level
aggregate. Accepted goal/rubric state is client-written because the user sets it
outside any model turn; pending criteria proposals and agent-driven status
updates are graph-written. Both paths work identically against local and remote
(HTTP) graphs.
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.Clipboard utilities.
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.
Utilities for handling image and video media from clipboard and files.
Detect model replies that a provider cut off before they were complete.
LangChain has no normalized stop reason, so each provider's raw metadata is
read here. output_truncation classifies one message. EmptyTruncatedReplyMiddleware
turns an empty, truncated reply into a typed error, so the run fails visibly
instead of ending as a silent success with nothing to show. Subagent failures
become task-tool errors, while partial answers carry a warning to the parent.
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_servers in ~/.deepagents/config.toml, alongside the
user's other MCP configuration.
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).
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.
Dcode-specific ACP approval-mode adapter.
Validation and environment-variable expansion for MCP server config.
Resolves ${VAR} and ${VAR:-default} references in the supported
configuration fields (command, url, args, env, headers, oauth) and
validates their types. A ${VAR:-default} reference falls back to
default when VAR is unset or empty (POSIX :- semantics).
Bounded, isolated conversation title generation.
External editor support for composing prompts.
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.
Agent management and creation.
Canonical internal model-context messages for goal state and continuation.
Goal context is represented as a HumanMessage so it participates in the
provider's normal turn ordering. Its lc_source marks it as framework-owned
model context rather than conversational user input; transcript, title, and
derived-conversation projections must therefore hide it.
Shared unified-diff helpers.
Every diff passing through this module is "\n"-joined from lines that came
from splitlines() or split("\n"), so no element can contain a line boundary.
That is what makes split_diff_lines the exact inverse and splitlines() wrong
here — see its docstring for what breaks. Check any helper added to this module,
and any new producer of a diff it reads, against that invariant.
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.
Subagent loader for app.
Loads custom subagent definitions from the filesystem. Subagents are defined as markdown files with YAML frontmatter in the agents/ directory.
Tool-free side answers from a snapshot of the main conversation.
Retrospective metadata updates for the current turn's traced runs.
Safe, structured diagnostics for workspace binding and runtime rejections.
When the server refuses to bind or run a thread's workspace, the user sees
only a one-line refusal. This module defines the small, explicitly allowlisted
comparison snapshot persisted beside each durable binding (so a later refusal
can name what changed) and the structured diagnostics carried by
WorkspaceConflictError, the workspace HTTP route, and the TUI.
The snapshot allowlist is the security boundary: only policy fields whose values are booleans, integers, tool-name/command allowlists, or short enum-like identifiers may be recorded and reported. Model parameters, model specs, profile overrides, system prompts, environment values, credentials, and paths (which can embed user names or project structure) are never persisted or logged — and never hashed as a reporting workaround.
Provider policy and pricing helpers for cold prompt-cache warnings.
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.
Reconcile observed checkout work onto the current turn's traces.
Ask user middleware for interactive question-answering during agent execution.
Agent middleware covering what MCP tools need around every call.
The tools themselves come out of langchain.mcp unmodified. Everything this
app wants on top — an argument quirk, and translating a dead-token failure into
something a model and a user can act on — sits here instead, so the adapter
stays the plain conversion it is and this behavior applies to any MCP tool the
agent is given.
Shared provider auth status formatting.
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.
Provider-independent model metadata exchanged with the server.
First-run onboarding state for the interactive TUI.
Backend recovery at the proxy boundary, before errors reach the wire.
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.
Model discovery data shared by the inference host and model pickers.
Integrations for external systems used by the Deep Agents Code.
Hook contracts and compatibility dispatch.
This package contains two hook systems: Hooks v2 (current) and legacy hooks (deprecated, removal September 1, 2026).
To write a new hook integration, use the v2 config format — see
deepagents_code.hooks.loading for file locations and precedence, and
deepagents_code.hooks.models.config + deepagents_code.hooks.models.wire
for the schema and stdin payload shapes.
deepagents_code.hooks.legacy exists only for backward compatibility; new
integrations should not target it.
Provider-specific MCP OAuth dispatch.
resolve_provider(url) returns the registered policy whose matches
predicate fires for url, with GenericProvider as the fallback.
Plugin support for dcode.
Public contract for dcode Python extensions.
Textual user interface package for deepagents-code.
Client-side transport and headless execution for Deep Agents Code.
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.
Managed and user configuration: paths, providers, and merge.
Writes live in deepagents_code.configuration.writer and are imported from
there directly, so no writer symbol is re-exported here.