# VT Code Architecture Guide

## Overview

VT Code follows a modular architecture designed for maintainability,
extensibility, and performance. Internally, VT Code uses Rust traits for
runtime composition. Externally, VT Code prefers protocol- and manifest-driven
extension seams such as MCP, skills, plugin manifests, and
`[[custom_providers]]` so third-party integrations do not need to land new Rust
impls in the core workspace. This is deliberate: Rust coherence and orphan-rule
constraints make public trait APIs a poor default extension boundary for an
ecosystem-style project.

For internal composition, prefer explicit provider selection over "clever"
trait resolution when a boundary starts depending on many overlapping impls,
associated types, or context-specific behavior. In practice, VT Code treats
`HasComponent<Name>::Provider` as an elaborated dictionary: the context chooses
the provider once, and blanket consumer traits delegate through that explicit
selection. See `vtcode-core/src/components.rs` and `vtcode-core/src/llm/cgp.rs`.

## Model + Harness

VT Code treats the model as the reasoning engine and the harness as the runtime that makes that reasoning useful. Phase 1 of the
exec/full-auto runtime is built around that split rather than around a separate agent subsystem.

Harness primitives in VT Code map to the runtime like this:

- **Instruction memory**: AGENTS.md loading, project docs, prompt assembly, onboarding guidance, and session bootstrap live in `vtcode-core/src/prompts/`, `vtcode-core/src/core/agent/`, and the workspace instruction loaders.
- **Tools**: `vtcode-tools/`, `vtcode-core/src/tools/`, MCP integration, slash commands, and the tool registry expose filesystem, search, edit, exec, and protocol-backed capabilities to the model.
- **Sandbox / execution environment**: `vtcode-bash-runner/`, unified exec, workspace trust, command policies, and tool allow-lists define where generated code runs and what it can touch.
- **Dynamic context**: context assembly, instruction merging, task tracker state, history, plan sidecars, and spooled tool outputs let VT Code rehydrate long-running work without keeping every token in the live window. The persisted `SessionMemoryEnvelope` is the harness working-memory artifact: it summarizes objective, constraints, touched files, grounded facts, verification status, verification TODOs, and delegated findings for resume and summarized-fork handoff.
- **Compaction / offloading**: split tool results, spool files, archive transcripts, and provider-aware auto-compaction reduce context rot while preserving recoverable state on disk. On VT Code's local compaction path, older repeated single-file reads are deduplicated before summarization so the summary prompt keeps the newest copy and avoids re-injecting stale file payloads.
- **Hooks / middleware**: lifecycle hooks, tool middleware, guard rails, duplicate-call protection, and plan-mode enforcement add deterministic control around the model loop.
- **Continuation**: exec/full-auto now uses a harness-managed continuation controller that accepts completion only when tracker state is complete and verification commands pass.
- **Scheduling**: session-scoped `/loop` tasks live on the interactive runtime, while durable `vtcode schedule` jobs persist definitions under the VT Code config/data directories and launch fresh `vtcode exec` runs through a local daemon.
- **Traces / archives**: thread events, session archives, checkpoints, Open Responses emission, ATIF trajectory export, and optional harness event logs capture what happened for resume, audit, and downstream tooling. The [ATIF](https://www.harborframework.com/docs/agents/trajectory-format) exporter (`vtcode-exec-events::atif`) converts live `ThreadEvent` streams into the standardized Agent Trajectory Interchange Format for SFT/RL pipelines, debugging, and visualization.

`vtcode-exec-events::ThreadEvent` is the authoritative runtime event contract across exec mode, harness logs, and interactive lifecycle emission. Item lifecycle events come from the shared runtime/event builders, while outer `TurnStarted` / `TurnCompleted` / `TurnFailed` events remain wrapper-owned submission boundaries. Follow-up inputs are queued in the runtime and injected one-at-a-time only after a turn reaches an idle boundary.

For the public loop semantics and the Agent SDK concept mapping, see [Agent Loop Contract](./guides/agent-loop-contract.md).

The harness configuration is intentionally split across three existing surfaces instead of a new top-level subsystem:

- `agent.harness` controls continuation, event logging, and per-turn safety limits.
- `automation.full_auto` controls autonomous execution and turn limits.
- `context.dynamic` controls how much state and history are reintroduced on each turn.

That split keeps VT Code aligned with the current runtime while making the harness explicit enough to evolve.

When `agent.harness.orchestration_mode = "plan_build_evaluate"` is enabled for `exec/full-auto`, VT Code adds a lightweight
planner/evaluator loop on top of the single-agent runtime instead of introducing a separate always-on agent subsystem:

- The planner writes `.vtcode/tasks/current_spec.md` and `.vtcode/tasks/current_contract.md`, then seeds `current_task.md`.
- The generator still runs on the main session, but it is constrained by those artifacts plus tracker completion and verification.
- The evaluator performs a skeptical post-build pass over the spec, contract, tracker, verification results, warnings, and changed files, then writes `.vtcode/tasks/current_evaluation.md`.
- Failed evaluation triggers bounded revision rounds rather than silent acceptance, and the artifacts survive blocked handoff, resume, and local compaction.

Broader multi-agent orchestration, dynamic tool assembly, and harness self-analysis remain follow-on work after this single-threaded
plan/build/evaluate path is stable.

### Explicit Delegation Model

VT Code treats delegation like explicit thread spawning rather than ambient background concurrency.

- The main session stays responsible for the current control flow, user-visible plan, and final integration.
- Child agents are for bounded sidecar work: focused exploration, isolated verification, or disjoint implementation slices.
- If the next local action depends on a result, the main session should usually do that work itself instead of delegating and waiting.
- Child output is advisory until the parent thread reads it, validates it, and folds it back into the main task state.
- Completed child results are merged back into the parent `SessionMemoryEnvelope` at turn boundaries, so delegated facts, touched files, open questions, and verification follow-ups survive resume and summarized forks.

### Rig Alignment Boundary

VT Code borrows selected request-shaping patterns from the Rig ecosystem without delegating runtime control to `rig-core` agents.

- Rig-backed usage in VT Code is limited to provider/model validation and provider-specific reasoning payload shaping.
- The VT Code harness remains the execution engine for turns, tool routing, continuation, compaction, and resume flows.
- Session continuity stays on VT Code primitives: `.vtcode/history/` artifacts, local/server compaction, and prompt-side memory injection.
- This keeps VT Code’s existing tool registry, sandboxing, and resume semantics intact while still adopting Rig’s provider-facing patterns where they reduce duplication.

### CLI Architecture

The command-line interface is built on specific principles for robustness and interoperability:

1.  **Strict Output Separation**: Data goes to `stdout`, diagnostics/logs go to `stderr`. This enables clean piping of machine-readable output.
2.  **Standard Argument Parsing**: Uses `clap` for POSIX/GNU compliance, supporting standard flags and behavior.
3.  **Command Isolation**: Each sub-command (`ask`, `exec`, `chat`) is handled by a dedicated module in `src/cli/`, sharing core logic via `vtcode-core`.
4.  **Signal Handling**: Graceful handling of `SIGINT`/`SIGTERM` to ensure resource cleanup (e.g., restoring terminal state).

## Core Architecture

### TUI Architecture

The terminal UI now has a dedicated crate boundary:

- `vtcode-tui`: public TUI-facing API surface for downstream consumers
- `vtcode-core::ui::tui`: canonical runtime type surface for VT Code internals

This separation allows external code to import TUI types and session APIs from
`vtcode-tui` while keeping host-specific integrations inside `vtcode-core`.

`vtcode-tui` now exposes standalone launch primitives (`SessionOptions`,
`SessionSurface`, `KeyboardProtocolSettings`) plus host adapters
(`host::HostAdapter`) so downstream projects can start sessions without
importing `vtcode_core::config` types directly.

The full TUI source tree is now located in:

- `vtcode-tui/src/core_tui/`

`vtcode-core/src/ui/tui.rs` is a compatibility shim that compiles this migrated
source tree to preserve existing `vtcode_core::ui::tui` paths.

The TUI runner is organized into focused modules:

```
vtcode-tui/src/core_tui/runner/
 mod.rs           # Orchestration entrypoint (`run_tui`)
 drive.rs         # Main terminal/event loop drive logic
 events.rs        # Async event stream + tick scheduling
 signal.rs        # SIGINT/SIGTERM cleanup guard
 surface.rs       # Inline vs alternate screen detection
 terminal_io.rs   # Cursor/screen prep + drain helpers
 terminal_modes.rs# Raw/mouse/focus/keyboard mode management
```

### Modular Tools System

```
tools/
 mod.rs           # Module coordination & exports
 traits.rs        # Core composability traits
 types.rs         # Common types & structures
 cache.rs         # Enhanced caching system
 grep_file.rs     # Ripgrep-backed search manager
 file_ops.rs      # File operations tool (async + cached)
 command.rs       # Command execution tool (3 modes)
 registry.rs      # Tool coordination & function declarations
```

### Core Traits

```rust
// Base tool interface
pub trait Tool: Send + Sync {
    async fn execute(&self, args: Value) -> Result<Value>;
    fn name(&self) -> &'static str;
    fn description(&self) -> &'static str;
}

// Multi-mode execution
pub trait ModeTool: Tool {
    fn supported_modes(&self) -> Vec<&'static str>;
    async fn execute_mode(&self, mode: &str, args: Value) -> Result<Value>;
}

// Intelligent caching
pub trait CacheableTool: Tool {
    fn cache_key(&self, args: &Value) -> String;
    fn should_cache(&self, args: &Value) -> bool;
}
```

## Tool Implementations

### GrepSearchManager (`tools::grep_file`)

- Debounce and cancellation pipeline for responsive searches
- Ripgrep primary backend with perg fallback when unavailable
- Supports glob filters, hidden file handling, and context lines
- Enforces workspace boundaries with robust path validation

### Search Stack Consolidation

- `grep_file.rs` is the single source of truth for content search
- Higher-level helpers were removed; use `ToolRegistry::grep_file_executor`
- `list_files` remains a discovery/metadata tool; defer all content scanning to `grep_file`

### FileOpsTool

- Workspace-scoped file listing, metadata inspection, and traversal
- Async directory walking with cache integration for large trees
- Path policy enforcement shared with the command subsystem

### CommandTool

- Standard command execution with exit-code and output capture
- PTY session management for interactive commands
- Streaming support for long-lived shell tasks with cancellation

## Design Principles

1. **Internal Traits, External Protocols** - Keep Rust traits as internal composition seams; prefer config, manifests, and protocols for third-party extension points so external integrations do not depend on compile-time impl slots in VT Code
2. **Prefer Explicit Provider Dictionaries** - When internal Rust abstractions become coherence-sensitive, move behavior behind context-selected providers instead of adding more blanket impl magic
3. **Mode-based Execution** - Single tools support multiple execution modes
4. **Simplicity First** - Prefer simple algorithms and control flow until real workload data justifies more complexity
5. **Data-Oriented Design** - Choose data structures and boundaries so the right algorithm is obvious
6. **Backward Compatibility** - All existing APIs remain functional
7. **Measured Optimization** - Profile and benchmark before keeping performance-motivated complexity
8. **Clear Separation** - Each module has single responsibility
9. **Handle/Context Before Clever Ownership** - When modeling complex Rust state, start with explicit handles/IDs and an owning context. Reach for self-referential layouts, raw pointers, lifetime-branding tricks, or custom `Send`/`Sync` only when a simpler handle-based design is demonstrably insufficient, and document the invariant at the boundary

## Adding New Tools

```rust
use super::traits::{Tool, ModeTool};
use async_trait::async_trait;

pub struct MyTool;

#[async_trait]
impl Tool for MyTool {
    async fn execute(&self, args: Value) -> Result<Value> {
        // Implementation
    }

    fn name(&self) -> &'static str { "my_tool" }
    fn description(&self) -> &'static str { "My custom tool" }
}

#[async_trait]
impl ModeTool for MyTool {
    fn supported_modes(&self) -> Vec<&'static str> {
        vec!["mode1", "mode2"]
    }

    async fn execute_mode(&self, mode: &str, args: Value) -> Result<Value> {
        match mode {
            "mode1" => self.execute_mode1(args).await,
            "mode2" => self.execute_mode2(args).await,
            _ => Err(anyhow::anyhow!("Unsupported mode: {}", mode))
        }
    }
}
```

## Benefits

- **77% complexity reduction** from monolithic structure
- **Enhanced functionality** through mode-based execution
- **100% backward compatibility** maintained
- **Protocol-friendly extension model** for external development
- **Performance optimized** with intelligent caching

## RL Optimization Loop (Adaptive Action Selection)

- **Module:** `vtcode-core/src/llm/rl` (bandit and actor-critic implementations)
- **Config:** `[optimization]` with `strategy = "bandit" | "actor_critic"` plus reward shaping knobs
- **Signals:** Success/timeout + latency feed `RewardSignal`, stored in a rolling `RewardLedger`
- **Usage:** Construct `RlEngine::from_config(&VTCodeConfig::optimization)` and call `select(actions, PolicyContext)`; on completion emit `apply_reward`
- **Goal:** Prefer low-latency, high-success actions (e.g., choose edge vs cloud executors) while remaining pluggable for future policies

## Training & Evaluation Alignment

To operationalize the staged training paradigm introduced in `docs/research/kimi_dev_agentless_training.md`, VT Code couples its
modular runtime with a data and evaluation strategy designed for agentless skill priors:

- **Dual Roles** – Prompt templates for `BugFixer` and `TestWriter` share the same tool registry, enabling deterministic skill
  acquisition before agentic orchestration.
- **Execution Telemetry** – Command and sandbox outputs are captured through the existing `bash_runner` and PTY subsystems,
  allowing outcome-based rewards for RL without extra instrumentation. The ATIF trajectory exporter provides standardized
  per-step metrics (token usage, costs, logprobs) directly consumable by SFT and RL training pipelines.
- **Self-Play Hooks** – The tool layer exposes high-signal search, diff, and patching capabilities that feed directly into the
  multi-rollout evaluation loop defined in the training roadmap.
- **Context Capacity** – Long-context support in the LLM provider abstraction ensures that multi-turn reasoning traces and
  aggregated rollouts remain accessible during both SFT and inference.

See the research note for the full pipeline (mid-training data curation, SFT cold start, RL curriculum, and test-time self-play).
