Architecture
CodeBuddy is a deepagentsjs agent extended with an IDE-native tool set, custom middleware, and a routed backend. This page maps every piece and how they connect.
The Developer Agent
Section titled “The Developer Agent”DeveloperAgent.create() returns a standard LangGraph runnable produced by createDeepAgent(). What it plugs in:
| Slot | Wired to |
|---|---|
model | buildChatModel() — resolves the active provider (9 supported) from user settings |
systemPrompt | base prompt + ProjectRulesService + MemoryTool.getFormattedMemories() + SkillManager.getSkillsPrompt() |
tools | ToolProvider.getToolsAsync() — 27+ core tools + dynamically loaded MCP tools |
subagents | 8 specialists via createDeveloperSubagents(); deepagents adds a 9th general-purpose |
backend | CompositeBackend — routes /workspace/ → real FS, /docs/ → Store, / → State |
middleware | Built-in todoList + filesystem + subAgent + custom Memory + Skills |
interruptOn | delete_file requires modal approval; configurable per-tool |
store | InMemoryStore — persists /docs/ across conversations |
checkpointer | SqlJsCheckpointSaver (SQLite WASM), falls back to MemorySaver |
The graph LangGraph returns supports streaming, HITL, memory, and LangSmith Studio out of the box. Nothing custom.
Request flow
Section titled “Request flow”Middleware stack
Section titled “Middleware stack”Order matters — each layer wraps the next.
| Layer | Source | Provides |
|---|---|---|
todoList | deepagents | write_todos — task planning + progress tracking |
filesystem | deepagents | ls, read_file, write_file, edit_file, glob, grep |
subAgent | deepagents | task tool — spawns a specialist with context isolation |
memory | CodeBuddy | Reads AGENTS.md / project rules, injects into the system prompt |
skills | CodeBuddy | Loads .codebuddy/skills/, adds prompts + tools |
A failing custom middleware logs a warning; the agent still starts. Built-in middleware failures are fatal (deepagents contract).
Subagents
Section titled “Subagents”createDeveloperSubagents() returns 8 role-filtered specialists. The 9th (general-purpose) is added by deepagents itself and inherits the full parent tool set.
| Subagent | Focus |
|---|---|
code-analyzer | Review, bug detection, architecture analysis |
doc-writer | Technical docs, API references, ADRs |
debugger | Root-cause via Debug Adapter Protocol |
file-organizer | Directory restructuring, moves, import updates |
architect | System design, pattern selection |
reviewer | Code quality + security review |
tester | Test creation, execution, failure analysis |
architecture-expert | Repo-structure Q&A over static analysis |
general-purpose | Auto-included; inherits all parent tools + skills |
When the main agent calls task({subagent_type, description}), deepagents constructs a new ReactAgent with the subagent config, runs it to completion, returns the result as a ToolMessage, and destroys the instance. Subagents run in parallel when tasks are independent.
Deep dive: Subagents.
Backend routing
Section titled “Backend routing”CompositeBackend routes file operations to different storage layers based on path prefix.
| Route | Backend | Persistence | Used for |
|---|---|---|---|
/workspace/ | VscodeFsBackend | Real filesystem | Actual project files (via ripgrep + VS Code FS API) |
/docs/ | StoreBackend | LangGraph Store | Long-lived docs, ADRs, refs — survives sessions |
/ (default) | StateBackend | LangGraph State | Ephemeral scratch — conversation-scoped |
VscodeFsBackend adds ripgrep for fast search, SimpleMutex for atomic writes, TOCTOU-resistant validatePathWithinWorkspace() on every path, and diff-review integration on writes.
ToolProvider builds the tool list at agent construction. Broadly:
| Category | Examples |
|---|---|
| File ops | read_file, write_file, edit_file, ast_edit, list_files, compose_files, find_files |
| Search | ripgrep_search, search_symbols, search_vector_db, web_search |
| Editor / LSP | get_active_editor, lsp_query, get_diagnostics, query_graph |
| Execution | manage_terminal, run_terminal_command, run_tests, run_skill_script |
| Debugging | debug_get_state, debug_get_stack_trace, debug_get_variables, debug_evaluate, debug_control (5) |
| Browser | browser — Playwright automation |
| Knowledge | manage_core_memory, manage_tasks, think, get_architecture_knowledge |
| Integrations | git_ops, git_read, open_web_preview, standup_intelligence, team_graph |
Every tool passes through ToolProvider.applyPermissionFilter → filter by security profile → wrap with ToolRateLimiter (600/min global, 200/min per-tool).
MCP tools load lazily (5-min cache, per-server circuit breaker). See MCP.
Safety
Section titled “Safety”The AgentSafetyGuard caps every task:
- 15000 stream events
- 2000 tool calls
- 60-minute wall clock
- Consecutive-failure circuit breaker
- Context-window compaction when message history exceeds threshold
Hitting any limit ends the stream cleanly with a diagnostic message; the diff view stays empty.
When a provider fails, ProviderFailoverService classifies the reason (auth / rate_limit / billing / timeout / overloaded) and can switch to an alternate. Transient network errors get 2 auto-retries with exponential backoff. Catastrophic shell patterns (rm -rf /, mkfs, fork bombs) deny in all permission profiles.
Deep dive: Self-healing.
Provider abstraction
Section titled “Provider abstraction”9 providers behind one ChatModel type — Anthropic, OpenAI, Google Gemini, Groq, DeepSeek, xAI Grok, Qwen, GLM, plus a Local slot covering Ollama, LM Studio, Docker, and any OpenAI-API-compatible endpoint. Switching providers is one setting change; the graph is provider-agnostic.
Cost tracked per-token per-model via CostTrackingService; see Cost tracking.
Related
Section titled “Related”- deepagentsjs — the foundation
- Subagents — delegation + role-scoped tools
- Memory — how the agent remembers
- MCP — external tool servers
- Self-healing — retries, failover, safety guard