1#![doc = r#"
2# VTCode Core - Research-Preview Rust Coding Agent Library
3
4A sophisticated terminal-based coding agent library that implements state-of-the-art agent
5architecture patterns, inspired by Anthropic's SWE-bench breakthroughs.
6
7## Features
8
9### Core Capabilities
10
11- **Single-Agent Reliability**: Streamlined, linear agent with robust context engineering
12- **Decision Ledger**: Structured record of key decisions injected each turn for consistency
13- **Multi-Provider LLM Support**: Gemini, OpenAI, Anthropic, DeepSeek integration
14- **Advanced Code Analysis**: Tree-sitter parsers for Rust, Python, JavaScript, TypeScript, Go, Java
15- **Intelligent Tool Suite**: File operations, search, terminal commands, and PTY integration
16- **Configuration Management**: TOML-based configuration with comprehensive policies
17- **Safety & Security**: Path validation, command policies, and human-in-the-loop controls
18- **Workspace-First Automation**: Reads, writes, indexing, and shell execution anchored to `WORKSPACE_DIR`
19
20### Advanced Features
21
22- **Context Engineering**: Full conversation history with intelligent management
23- **Performance Monitoring**: Real-time metrics and benchmarking capabilities
24- **Prompt Caching**: Strategic caching for improved response times
25- **Conversation Summarization**: Automatic compression for long sessions
26- **Tool Policy Management**: Configurable tool execution policies
27- **PTY Integration**: Full terminal emulation for interactive commands
28- **Project Indexing**: Intelligent workspace analysis and file discovery
29
30## Quick Start
31
32```rust,no_run
33use vtcode_core::{Agent, VTCodeConfig};
34
35#[tokio::main]
36async fn main() -> Result<(), Box<dyn std::error::Error>> {
37 // Load configuration
38 let config = VTCodeConfig::load()?;
39
40 // Create agent
41 let agent = Agent::new(config).await?;
42
43 // Start interactive session
44 agent.run().await?;
45
46 Ok(())
47}
48```
49
50## Architecture
51
52The agent follows proven patterns for reliable, long-running coding assistance:
53
54- **Model-Driven Control**: Maximum autonomy given to language models
55- **Decision Transparency**: Complete audit trail of all agent actions
56- **Error Recovery**: Intelligent error handling with context preservation
57- **Conversation Summarization**: Automatic compression for long sessions
58- **Tool Integration**: Modular tool system with policy-based execution
59
60## Core Components
61
62### Agent System
63- [`Agent`] - Main agent implementation with conversation management
64- [`ConversationSummarizer`] - Automatic conversation compression
65- [`ContextCompressor`] - Intelligent context management
66
67### Tool System
68- [`ToolRegistry`] - Central tool registration and execution
69- [`ToolPolicy`] - Configurable tool execution policies
70- [`ToolPolicyManager`] - Policy enforcement and validation
71
72### LLM Integration
73- [`AnyClient`] - Unified interface for multiple LLM providers
74- [`make_client`] - Factory function for creating LLM clients
75- Gemini, OpenAI, Anthropic, DeepSeek provider implementations
76
77### Configuration
78- [`VTCodeConfig`] - Main configuration structure
79- [`AgentConfig`] - Agent-specific configuration
80- TOML-based configuration with comprehensive policies
81
82## Examples
83
84### Basic Agent Usage
85
86```rust,no_run
87use vtcode_core::{Agent, VTCodeConfig};
88use std::path::PathBuf;
89
90#[tokio::main]
91async fn main() -> Result<(), Box<dyn std::error::Error>> {
92 // Load configuration
93 let config = VTCodeConfig::load()?;
94
95 // Create agent with custom workspace
96 let workspace = PathBuf::from("/path/to/project");
97 let agent = Agent::new_with_workspace(config, workspace).await?;
98
99 // Process a coding task
100 let task = "Add error handling to the user authentication function";
101 let result = agent.process_task(task).await?;
102
103 println!("Task completed: {}", result);
104
105 Ok(())
106}
107```
108
109### Tool Registry Usage
110
111```rust,no_run
112use vtcode_core::tools::{ToolRegistry, ToolRegistration};
113use serde_json::Value;
114
115#[tokio::main]
116async fn main() -> Result<(), Box<dyn std::error::Error>> {
117 let workspace = std::env::current_dir()?;
118 let mut registry = ToolRegistry::new(workspace);
119
120 // Register a custom tool
121 let custom_tool = ToolRegistration {
122 name: "analyze_code".to_string(),
123 description: "Analyze code for potential issues".to_string(),
124 parameters: serde_json::json!({
125 "type": "object",
126 "properties": {
127 "file_path": {"type": "string", "description": "Path to file to analyze"},
128 "analysis_type": {"type": "string", "enum": ["security", "performance", "style"]}
129 },
130 "required": ["file_path"]
131 }),
132 handler: |args: Value| async move {
133 let file_path = args["file_path"].as_str().unwrap_or("");
134 let analysis_type = args["analysis_type"].as_str().unwrap_or("general");
135
136 // Perform analysis
137 let result = format!("Analysis of {} for {} completed", file_path, analysis_type);
138
139 Ok(serde_json::json!({
140 "success": true,
141 "analysis": result,
142 "issues_found": 0
143 }))
144 },
145 };
146
147 registry.register_tool(custom_tool).await?;
148
149 // Execute the tool
150 let args = serde_json::json!({
151 "file_path": "src/main.rs",
152 "analysis_type": "security"
153 });
154
155 let result = registry.execute_tool("analyze_code", args).await?;
156 println!("Tool result: {}", result);
157
158 Ok(())
159}
160```
161
162### Configuration Management
163
164```rust,no_run
165use vtcode_core::{VTCodeConfig, AgentConfig};
166use vtcode_core::config::types::{ToolConfig, LoggingConfig};
167
168#[tokio::main]
169async fn main() -> Result<(), Box<dyn std::error::Error>> {
170 // Create custom configuration
171 let config = VTCodeConfig {
172 agent: AgentConfig {
173 max_iterations: 50,
174 timeout_seconds: 300,
175 ..Default::default()
176 },
177 tools: ToolConfig {
178 max_tool_loops: 25,
179 default_policy: "prompt".to_string(),
180 ..Default::default()
181 },
182 logging: LoggingConfig {
183 level: "info".to_string(),
184 file_path: Some("vtcode.log".to_string()),
185 ..Default::default()
186 },
187 ..Default::default()
188 };
189
190 // Save configuration
191 config.save()?;
192
193 // Load and verify
194 let loaded = VTCodeConfig::load()?;
195 assert_eq!(loaded.agent.max_iterations, 50);
196
197 Ok(())
198}
199```
200
201### LLM Provider Integration
202
203```rust,no_run
204use vtcode_core::llm::{AnyClient, make_client};
205use vtcode_core::config::types::ProviderConfigs;
206
207#[tokio::main]
208async fn main() -> Result<(), Box<dyn std::error::Error>> {
209 // Configure providers
210 let providers = ProviderConfigs {
211 gemini: Some(vtcode_core::utils::dot_config::ProviderConfig {
212 api_key: std::env::var("GEMINI_API_KEY")?,
213 model: "gemini-2.5-flash-exp".to_string(),
214 ..Default::default()
215 }),
216 ..Default::default()
217 };
218
219 // Create LLM client
220 let client = make_client(&providers, "gemini")?;
221
222 // Make a request
223 let messages = vec![
224 vtcode_core::llm::types::Message {
225 role: "user".to_string(),
226 content: "Hello, can you help me with Rust code?".to_string(),
227 }
228 ];
229
230 let response = client.chat(&messages, None).await?;
231 println!("LLM Response: {}", response.content);
232
233 Ok(())
234}
235```
236
237## Safety & Security
238
239VTCode implements multiple layers of security:
240
241- **Path Validation**: All file operations check workspace boundaries
242- **Command Policies**: Configurable allow/deny lists for terminal commands
243- **Tool Policies**: Granular control over tool execution
244- **Human-in-the-Loop**: Optional approval for sensitive operations
245- **Audit Logging**: Complete trail of all agent actions
246
247## Performance
248
249- **Prompt Caching**: Reduces API calls for repeated prompts
250- **Context Compression**: Efficient memory usage for long conversations
251- **Parallel Processing**: Concurrent tool execution where appropriate
252- **Resource Limits**: Configurable timeouts and size limits
253
254## Distribution
255
256- **Cargo**: `cargo install vtcode-core`
257- **GitHub**: Source code and releases
258- **Documentation**: Available on [docs.rs](https://docs.rs/vtcode-core)
259
260## Contributing
261
262Contributions are welcome! Please see the main VTCode repository for contribution guidelines.
263
264## License
265
266Licensed under the MIT License.
267"#]
268
269pub mod bash_runner;
288pub mod cli;
289pub mod code;
290pub mod commands;
291pub mod config;
292pub mod constants;
293pub mod core;
294pub mod gemini;
295pub mod llm;
296pub mod markdown_storage;
297pub mod models;
298pub mod project;
299pub mod project_doc;
300pub mod prompts;
301pub mod safety;
302pub mod simple_indexer;
303pub mod tool_policy;
304pub mod tools;
305pub mod types;
306pub mod ui;
307pub mod utils;
308
309pub use bash_runner::BashRunner;
311pub use cli::args::{Cli, Commands};
312pub use code::code_completion::{CompletionEngine, CompletionSuggestion};
313pub use commands::stats::handle_stats_command;
314pub use config::types::{
315 AnalysisDepth, CapabilityLevel, CommandResult, CompressionLevel, ContextConfig, LoggingConfig,
316 OutputFormat, PerformanceMetrics, ReasoningEffortLevel, SessionInfo, ToolConfig,
317};
318pub use config::{AgentConfig, VTCodeConfig};
319pub use core::agent::core::Agent;
320pub use core::context_compression::{
321 CompressedContext, ContextCompressionConfig, ContextCompressor,
322};
323pub use core::conversation_summarizer::ConversationSummarizer;
324pub use core::performance_profiler::PerformanceProfiler;
325pub use core::prompt_caching::{CacheStats, PromptCache, PromptCacheConfig, PromptOptimizer};
326pub use core::timeout_detector::TimeoutDetector;
327pub use gemini::{Content, FunctionDeclaration, Part};
328pub use llm::{AnyClient, make_client};
329pub use markdown_storage::{MarkdownStorage, ProjectData, ProjectStorage, SimpleKVStorage};
330pub use project::{SimpleCache, SimpleProjectManager};
331pub use prompts::{
332 generate_lightweight_instruction, generate_specialized_instruction, generate_system_instruction,
333};
334pub use simple_indexer::SimpleIndexer;
335pub use tool_policy::{ToolPolicy, ToolPolicyManager};
336pub use tools::advanced_search::{AdvancedSearchTool, SearchOptions};
337pub use tools::grep_search::GrepSearchManager;
338pub use tools::tree_sitter::TreeSitterAnalyzer;
339pub use tools::{
340 ToolRegistration, ToolRegistry, build_function_declarations,
341 build_function_declarations_for_level,
342};
343pub use ui::diff_renderer::DiffRenderer;
344pub use utils::dot_config::{
345 CacheConfig, DotConfig, DotManager, ProviderConfigs, UiConfig, UserPreferences,
346 WorkspaceTrustLevel, WorkspaceTrustRecord, WorkspaceTrustStore, initialize_dot_folder,
347 load_user_config, save_user_config, update_theme_preference,
348};
349pub use utils::vtcodegitignore::initialize_vtcode_gitignore;
350
351#[cfg(test)]
352mod tests {
353 use super::*;
354
355 use tempfile::TempDir;
356
357 #[test]
358 fn test_library_exports() {
359 let _cache = PromptCache::new();
361 }
362
363 #[test]
364 fn test_module_structure() {
365 }
368
369 #[test]
370 fn test_version_consistency() {
371 }
374
375 #[tokio::test]
376 async fn test_tool_registry_integration() {
377 use crate::config::constants::tools;
378
379 let temp_dir = TempDir::new().unwrap();
380 std::env::set_current_dir(&temp_dir).unwrap();
381
382 let mut registry = ToolRegistry::new(temp_dir.path().to_path_buf());
383
384 let list_args = serde_json::json!({
386 "path": "."
387 });
388
389 let result = registry.execute_tool(tools::LIST_FILES, list_args).await;
390 assert!(result.is_ok());
391
392 let response: serde_json::Value = result.unwrap();
393 assert!(response["files"].is_array());
394 }
395
396 #[tokio::test]
397 async fn test_pty_basic_command() {
398 let temp_dir = TempDir::new().unwrap();
399 let workspace = temp_dir.path().to_path_buf();
400 let mut registry = ToolRegistry::new(workspace.clone());
401
402 let args = serde_json::json!({
404 "command": "echo",
405 "args": ["Hello, PTY!"]
406 });
407
408 let result = registry.execute_tool("run_pty_cmd", args).await;
409 assert!(result.is_ok());
410 let response: serde_json::Value = result.unwrap();
411 assert_eq!(response["success"], true);
412 assert_eq!(response["code"], 0);
413 assert!(response["output"].as_str().unwrap().contains("Hello, PTY!"));
414 }
415
416 #[tokio::test]
417 async fn test_pty_session_management() {
418 let temp_dir = TempDir::new().unwrap();
419 let workspace = temp_dir.path().to_path_buf();
420 let mut registry = ToolRegistry::new(workspace.clone());
421
422 let args = serde_json::json!({
424 "session_id": "test_session",
425 "command": "bash"
426 });
427
428 let result = registry.execute_tool("create_pty_session", args).await;
429 assert!(result.is_ok());
430 let response: serde_json::Value = result.unwrap();
431 assert_eq!(response["success"], true);
432 assert_eq!(response["session_id"], "test_session");
433
434 let args = serde_json::json!({});
436 let result = registry.execute_tool("list_pty_sessions", args).await;
437 assert!(result.is_ok());
438 let response: serde_json::Value = result.unwrap();
439 assert!(
440 response["sessions"]
441 .as_array()
442 .unwrap()
443 .contains(&"test_session".into())
444 );
445
446 let args = serde_json::json!({
448 "session_id": "test_session"
449 });
450
451 let result = registry.execute_tool("close_pty_session", args).await;
452 assert!(result.is_ok());
453 let response: serde_json::Value = result.unwrap();
454 assert_eq!(response["success"], true);
455 assert_eq!(response["session_id"], "test_session");
456 }
457}