Textual UI application.
Default agent / assistant identifier when no -a flag is given.
URL for the full changelog.
URL for deepagents-code documentation.
Valid DeferredAction.kind values for type-checked deduplication.
Read the current git branch from repository metadata.
Fall back to git rev-parse for unusual repository layouts.
Format a token count into a human-readable short string.
Check whether the terminal is in ASCII charset mode.
Convenience wrapper so widgets can branch on charset without importing
both _detect_charset_mode and CharsetMode.
Format a message timestamp for display.
Shows only the time of day for messages from the current local date and
prefixes the date otherwise. The 12- versus 24-hour clock follows the
system configuration (see uses_24_hour_clock).
Restore iTerm2 cursor guide when launch-time profile state required it.
Open url in a browser and toast on failure.
Runs webbrowser.open in a thread, catches the platform errors
that can arise when no browser backend is available, and posts a
warning toast containing the URL so the user can copy it manually
instead of the failure vanishing into a background worker log.
Persist theme preference to ~/.deepagents/config.toml.
Persist a [ui.terminal_themes][term_program] = name entry.
The write is atomic (temp file + Path.replace) to avoid corrupting
config.toml on crash or SIGINT. Mirrors save_theme_preference.
Run the Textual application.
When server_kwargs is provided (and agent is None), the app starts
immediately with a status-bar connection state and launches the server in
the background. Server cleanup is handled automatically after the app exits.
Runtime context passed via context= to the LangGraph graph.
Carries per-invocation overrides that ConfigurableModelMiddleware
reads from request.runtime.context.
Stats accumulated over a single agent turn (or full session).
Stable identifiers for notification actions dispatched by the app.
Typed payload for a missing-dependency notification.
One button/action row in the notification modal.
In-memory store of pending notifications.
Instance-scoped (one per app) so test apps don't pollute each other. Owns the bidirectional key-to-toast-identity binding so callers cannot accidentally desynchronize the click-routing indices.
A single notice waiting for user action.
Immutable value object: the registry owns the
key-to-toast-identity binding (see NotificationRegistry) so
external callers cannot corrupt click-routing indices by mutating
notifications after construction.
Typed payload for an update-available notification.
Chat input widget with prompt, multi-line text, autocomplete, and history.
Features:
config.newline_shortcut)Animated loading indicator with status text and elapsed time.
Displays:
In-memory message data for virtualization.
This dataclass holds all information needed to recreate a message widget. It is designed to be lightweight so that thousands of messages can be stored without meaningful memory overhead.
Manages message data and widget window for virtualization.
This class stores all messages as data and manages a sliding window of widgets that are actually mounted in the DOM.
Types of messages in the chat.
Status of a tool call.
Widget displaying an app message.
Widget displaying an assistant message with markdown support.
Uses MarkdownStream for smoother streaming instead of re-rendering
the full content on each update. Once a stream finishes, the message
is re-rendered from the complete source via Markdown.update() to
work around Textualize/textual#6518: MarkdownFence._update_from_block
refreshes the visible Label but leaves _highlighted_code pinned to
the first chunk, so any later recompose (click, focus change, theme
update) re-yields the stale value and wrapped fenced-code bodies vanish.
A full re-parse rebuilds every fence with correct internal state.
Streamed tokens are coalesced in _pending_append and flushed to the
MarkdownStream on a throttled timer (_STREAM_FLUSH_INTERVAL). Writing
every token immediately forced a markdown re-parse per chunk on the UI
event loop, which starved keyboard input while the model streamed.
Batching the writes keeps the event loop free so typing stays responsive.
Widget displaying an error message.
Widget displaying a queued (pending) user message in grey.
This is an ephemeral widget that gets removed when the message is dequeued.
Widget displaying a skill invocation with collapsible body.
Shows skill name, source badge, description, and user args as a compact
header. The full SKILL.md body (frontmatter stripped) is hidden behind a
preview/expand toggle (click or Ctrl+O). The expanded view renders
markdown via Rich's Markdown inside a single Static widget.
Visibility is driven by a CSS class (-expanded) toggled via a Textual
reactive var. Click handlers are scoped to the header and hint widgets
(_SkillToggle) so clicks on the rendered markdown body do not trigger
expansion toggles (preserving text selection, for instance).
Widget displaying a tool call with collapsible output.
Tool outputs are shown as a 3-line preview by default. Press Ctrl+O to expand/collapse the full output. Shows an animated "Running..." indicator while the tool is executing.
Widget displaying a user message.
Status bar showing mode, auto-approve, cwd, git branch, tokens, and model.
Welcome banner displayed at startup.
A question to ask the user.
Result of creating a chat model, bundling the model with its metadata.
This separates model creation from settings mutation so callers can decide when to commit the metadata to global settings.
Source of external events for the Textual app.
Implementations must be safe to stop() even when start() failed
partway through; the app always invokes stop() from a finally block.
A transport-independent event delivered from outside the TUI.
Metadata for a configured MCP server and its tools.
Raised when a provider is selected but its LangChain package is not installed.
Subclasses ModelConfigError so existing except ModelConfigError blocks
keep working. Carries the provider name and the package to install so
callers can render targeted recovery hints (e.g., suggest /install fireworks
or the /model slash command) without string-matching on the formatted
exception message.
Client that talks to a LangGraph server over HTTP+SSE.
Wraps langgraph.pregel.remote.RemoteGraph which handles SSE parsing,
stream-mode negotiation (messages-tuple), namespace extraction, and
interrupt detection. This class adds streamed message-object conversion for
the Textual adapter and thread-ID normalization. State snapshots are
returned as provided by the server.
Manages a langgraph dev server subprocess.
Focuses on subprocess lifecycle (start, stop, restart) and health checking.
Env-var management for restarts (e.g. configuration changes requiring a full
restart) is handled by _scoped_env_overrides, keeping this class focused
on process management.
Extended skill metadata for CLI display, adds source tracking.
Adapter for rendering agent output to Textual widgets.
This adapter provides an abstraction layer between the agent execution and the Textual UI, allowing streaming output to be rendered as widgets.
Approval menu using standard Textual patterns.
Key design decisions (following mistral-vibe reference):
Interactive widget for asking the user questions.
Supports text input and multiple choice questions. Multiple choice questions always include an "Other" option for free-form input.
Posted when the user picks SUPPRESS from a notification's detail modal.
The center does not dismiss on SUPPRESS because the remaining
notifications should still be reachable in place. The app handles
this message by running the suppress dispatch and calling
NotificationCenterScreen.reload with the refreshed registry
snapshot.
Modal that shows self-update progress and a bounded log tail.
Represents a queued user message awaiting processing.
Textual message carrying an external prompt or command.
An action deferred until the current busy state resolves.
Session state for the Textual app.
Main Textual application for deepagents-code.
Result from running the Textual application.