SideCar Architecture
SideCar Architecture
Overview
SideCar is an AI-powered coding assistant for VS Code that operates as an autonomous agent. It can interact with your codebase, execute commands, and perform various development tasks using a combination of local LLMs (via Ollama) and cloud APIs (Anthropic Claude).
Visual architecture
For contributors onboarding to the codebase, these four Mermaid diagrams cover the shape of the moving parts:
- Agent loop flow — iteration pseudocode, hook bus ordering, termination paths.
- Tool registry & dispatch — how built-ins, MCP tools, and specials compose; approval gates.
- Context selection pipeline — retriever fusion, PKI symbol-level vs. legacy file-level.
- MCP client lifecycle — connect, reconnect backoff, transport selection, invocation path.
The prose below fills in the pieces the diagrams don’t cover (component responsibilities, data flow, feature gates).
Core Components
1. Extension Entry Point
extension.ts- Main activation point that initializes all components- Sets up webview chat interface
- Registers commands and keyboard shortcuts
- Initializes workspace indexing
- Configures tooling and agent components
2. Webview Interface
ChatViewProvider- Manages the chat UI in VS Code- Handles user messages and displays responses
- Routes commands to appropriate handlers
- Manages chat state and history
3. Agent Loop System
runAgentLoop— orchestrator insrc/agent/loop.ts(~686 lines) that reads top-to-bottom as one iteration’s pseudo-codesrc/agent/loop/— 14 focused helpers, each taking a singleLoopStatecontainer:state.tsbundles all run state into one objectcompression.tshandles pre-turn + post-tool context compressionstreamTurn.tsowns the streamChat request loop with per-event timeoutcycleDetection.tsimplements the burst cap + cycle detectionmessageBuild.tspushes assistant + tool-result messages and accounts tokensexecuteToolUses.tsdispatches tool calls in parallel (spawn_agent, delegate_task, normal)autoFix.ts,isolateRewrite.ts,stubCheck.ts,criticHook.ts,actionReprompt.ts,gate.tsback the post-turn policies (the critic file also provides the analysis-critic)policyHook.ts—PolicyHookinterface +HookBusregistration class. Orchestrator callshookBus.runAfter()/hookBus.runEmptyResponse()instead of calling policies directly;AgentOptions.extraPolicyHookslets callers register additional hooksbuiltInHooks.ts—defaultPolicyHooks()wraps the seven built-in policies asPolicyHookadapters, registered in order: autoFix → isolateRewrite → stubCheck → critic → actionReprompt → completionGate → analysisCriticpostTurnPolicies.ts— the post-turn policy application pipeline (still active; the bus invokes it)notifications.tsemits iteration telemetry + checkpoint promptsfinalize.tsruns the post-loop teardown + next-step suggestionstextParsing.tsparses model text output for tool-call patterns and strips repeated content
4. Tool System
tools.ts- Registry of available tools for the agent- Built-in tools for file operations, code search, shell commands, Git operations
- Custom tools defined in settings (gated via
checkWorkspaceConfigTrust) - MCP (Model Control Protocol) integration for external tools
- Tool execution with approval modes and security checks
ToolExecutorContextcarries per-call data: streaming callback, abort signal,cwdoverride for Shadow Workspace routing, and the activeSideCarClientreference for model-attribution git trailers.fs.tstools resolve relative paths viaresolveRootUri(context)so ShadowWorkspace can pin writes into a shadow worktree transparently
5. Context Management
WorkspaceIndex- Indexes project files for context retrievalastContext.ts- AST-based context for code understanding- Context compression and summarization to manage token limits
- File pattern filtering for workspace inclusion
streamingFileReader.ts- Streaming reads with summary mode for large files (>50KB)documentationIndexer.ts- Doc Index: discovers and indexes documentation, provides keyword-based searchagentMemory.ts- Persistent learning: stores and retrieves patterns, decisions, and conventionssrc/agent/retrieval/- UnifiedRetrieverinterface + reciprocal-rank fusion across documentation index, agent memory, and workspace semantic search (SemanticRetrieverwrapsWorkspaceIndex.rankFiles). All three sources compete under a single shared budget insideinjectSystemContextviafuseRetrievers().ConversationSummarizerhas a per-turn cap (default 220 chars) that usually skips the LLM compression round-trip entirely
6. Communication Layer
SideCarClient- LLM API client routes to the right backend per providerollamaBackend.ts- Ollama native/api/chatprotocolanthropicBackend.ts- Anthropic Messages API with thinking + tool_use blocksopenaiBackend.ts- OpenAI-compatible/v1/chat/completions(OpenAI, LM Studio, vLLM, llama.cpp)kickstandBackend.ts- Kickstand self-hosted (OpenAI-compatible wrapper)openrouterBackend.ts- OpenRouter with referrer headers + catalog pricing (subclass of OpenAIBackend)groqBackend.ts- Groq LPU inference (empty-body subclass of OpenAIBackend — pure plumbing, no protocol quirks)fireworksBackend.ts- Fireworks open-weight model hosting (empty-body subclass of OpenAIBackend)openAiSseStream.ts- Shared OpenAI-compatible SSE parser (anticorruption layer). Every backend that speaks/v1/chat/completionsdelegates here for stream framing, tool_call reconstruction, think-tag parsing, text tool-call interception, usage events, and finish_reason mapping. Adding a new OpenAI-compatible provider becomes a ~10-line subclass (see Groq and Fireworks)mcpManager.ts- Manages MCP servers for external tool integrationcircuitBreaker.ts- Per-provider three-state circuit breaker (closed → open after 5 consecutive failures → half-open after 60s cooldown). Fast-fails when a provider is demonstrably down instead of hanging on a dead requeststreamTurn.ts- Captures partial assistant text when a stream dies mid-turn and firesonStreamFailureso/resumecan re-dispatch with a continuation hint
Data Flow
flowchart LR
User[User input] --> Webview[Chat webview]
Webview --> Handlers[chatHandlers.ts]
Handlers --> Inject[injectSystemContext<br/>retriever fusion]
Inject --> Loop[runAgentLoop]
Loop --> LLM[SideCarClient<br/>streamChat]
LLM --> Exec[executeToolUses]
Exec --> VS[VS Code API<br/>fs, terminal, git, diagnostics]
Exec --> MCP[MCP servers<br/>external tools]
VS --> Results[tool results]
MCP --> Results
Results --> Loop
Loop --> Hooks[HookBus<br/>auto-fix / stub / critic / gate]
Hooks --> LLM
Loop --> Webview
Per-diagram detail lives under the links at the top of this page. The short version: user input lands in the chat webview, flows through context assembly (where retrievers inject relevant files/docs/memory into the system prompt), into the agent loop, out to the LLM, back through tool execution + hooks, and the resulting text/tool-calls stream back to the webview for display.
Key Features
Autonomous Mode
- Agent runs without user intervention
- Automatically executes tools based on LLM decisions
- Can generate and execute plans before implementation
Plan Mode
- Generates a plan for approval before executing tools
- Allows user to review and modify the approach
Tool Permissions
- Configurable approval modes (ask, allow, deny)
- Custom tool permissions
- Security scanning for file operations
Context Management
- Workspace indexing with file pattern filtering
- Automatic context compression
- Conversation summarization to extend context window
- Large file handling: streaming reads with head+tail summary for files >50KB
- Monorepo support: lazy indexing, depth-limited traversal, multi-root workspace configuration
- RAG context injection: automatic documentation discovery and retrieval
- Agent memory injection: learned patterns and conventions injected alongside RAG results
Integration Points
- Git operations (status, diff, commit, push, pull, branch, stash, worktree add/remove/list)
- Testing framework integration
- Security scanning
- Custom shell commands
- Persistent learning: automatic recording of successful patterns during agent runs
- MCP (Model Control Protocol) for external tool integration
Shadow Workspaces (v0.59+)
An opt-in sandbox for agent tasks. When sidecar.shadowWorkspace.mode is always (or opt-in + explicit per-task opt-in), the agent loop runs inside an ephemeral git worktree at .sidecar/shadows/<task-id>/ off the current HEAD. The user’s main working tree stays pristine; at task end, a showQuickPick prompt lets the user accept (apply diff to main as staged changes) or reject (discard the shadow).
Key pieces in src/agent/shadow/:
shadowWorkspace.ts—ShadowWorkspaceclass wrapsGitCLI.worktreeAdd/Remove/getHeadSha/diffAgainstHead/applyPatch.git worktree add --detachshares the main repo’s object database, so only the tracked-source checkout costs disk (tens of MB typically, not a full repo clone)sandbox.ts—runAgentLoopInSandbox()drop-in replacement forrunAgentLoopthat plumbscwdOverride = shadow.paththrough every per-toolToolExecutorContext.cwd
v0.59 ships the MVP: per-hunk review UI, gate-command integration, shell-tool cwd pinning, symlinked build dirs, and rebase-on-moved-main conflict handling all land in v0.60+.
Agent Terminal Integration (v0.59+)
src/terminal/agentExecutor.ts routes agent run_command / run_tests dispatches through VS Code’s terminal.shellIntegration.executeCommand API in a reusable SideCar Agent terminal. The user sees the agent’s commands execute live instead of in a hidden child_process.spawn, and on SSH / Dev Containers / WSL / Codespaces the shell integration inherits VS Code’s remote shell session rather than escaping to the host. Listens to onDidEndTerminalShellExecution for exit codes. Falls back to ShellSession (the pre-v0.59 child_process-based path) when shell integration isn’t available (bare shells without VS Code’s init script, older VS Code, or user-disabled via sidecar.terminalExecution.enabled).