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 prompts;
300pub mod safety;
301pub mod simple_indexer;
302pub mod tool_policy;
303pub mod tools;
304pub mod types;
305pub mod ui;
306pub mod utils;
307
308pub use bash_runner::BashRunner;
310pub use cli::args::{Cli, Commands};
311pub use code::code_completion::{CompletionEngine, CompletionSuggestion};
312pub use commands::stats::handle_stats_command;
313pub use config::types::{
314 AnalysisDepth, CapabilityLevel, CommandResult, CompressionLevel, ContextConfig, LoggingConfig,
315 OutputFormat, PerformanceMetrics, SessionInfo, ToolConfig,
316};
317pub use config::{AgentConfig, VTCodeConfig};
318pub use core::agent::core::Agent;
319pub use core::context_compression::{
320 CompressedContext, ContextCompressionConfig, ContextCompressor,
321};
322pub use core::conversation_summarizer::ConversationSummarizer;
323pub use core::performance_profiler::PerformanceProfiler;
324pub use core::prompt_caching::{CacheStats, PromptCache, PromptCacheConfig, PromptOptimizer};
325pub use core::timeout_detector::TimeoutDetector;
326pub use gemini::{Content, FunctionDeclaration, Part};
327pub use llm::{AnyClient, make_client};
328pub use markdown_storage::{MarkdownStorage, ProjectData, ProjectStorage, SimpleKVStorage};
329pub use project::{SimpleCache, SimpleProjectManager};
330pub use prompts::{
331 generate_lightweight_instruction, generate_specialized_instruction, generate_system_instruction,
332};
333pub use simple_indexer::SimpleIndexer;
334pub use tool_policy::{ToolPolicy, ToolPolicyManager};
335pub use tools::advanced_search::{AdvancedSearchTool, SearchOptions};
336pub use tools::grep_search::GrepSearchManager;
337pub use tools::tree_sitter::TreeSitterAnalyzer;
338pub use tools::{
339 ToolRegistration, ToolRegistry, build_function_declarations,
340 build_function_declarations_for_level,
341};
342pub use ui::diff_renderer::DiffRenderer;
343pub use utils::dot_config::{
344 CacheConfig, DotConfig, DotManager, ProviderConfigs, UiConfig, UserPreferences,
345 initialize_dot_folder, load_user_config, save_user_config, update_theme_preference,
346};
347pub use utils::vtcodegitignore::initialize_vtcode_gitignore;
348
349#[cfg(test)]
350mod tests {
351 use super::*;
352
353 use tempfile::TempDir;
354
355 #[test]
356 fn test_library_exports() {
357 let _cache = PromptCache::new();
359 }
360
361 #[test]
362 fn test_module_structure() {
363 }
366
367 #[test]
368 fn test_version_consistency() {
369 }
372
373 #[tokio::test]
374 async fn test_tool_registry_integration() {
375 use crate::config::constants::tools;
376
377 let temp_dir = TempDir::new().unwrap();
378 std::env::set_current_dir(&temp_dir).unwrap();
379
380 let mut registry = ToolRegistry::new(temp_dir.path().to_path_buf());
381
382 let list_args = serde_json::json!({
384 "path": "."
385 });
386
387 let result = registry.execute_tool(tools::LIST_FILES, list_args).await;
388 assert!(result.is_ok());
389
390 let response: serde_json::Value = result.unwrap();
391 assert!(response["files"].is_array());
392 }
393
394 #[tokio::test]
395 async fn test_pty_basic_command() {
396 let temp_dir = TempDir::new().unwrap();
397 let workspace = temp_dir.path().to_path_buf();
398 let mut registry = ToolRegistry::new(workspace.clone());
399
400 let args = serde_json::json!({
402 "command": "echo",
403 "args": ["Hello, PTY!"]
404 });
405
406 let result = registry.execute_tool("run_pty_cmd", args).await;
407 assert!(result.is_ok());
408 let response: serde_json::Value = result.unwrap();
409 assert_eq!(response["success"], true);
410 assert_eq!(response["code"], 0);
411 assert!(response["output"].as_str().unwrap().contains("Hello, PTY!"));
412 }
413
414 #[tokio::test]
415 async fn test_pty_session_management() {
416 let temp_dir = TempDir::new().unwrap();
417 let workspace = temp_dir.path().to_path_buf();
418 let mut registry = ToolRegistry::new(workspace.clone());
419
420 let args = serde_json::json!({
422 "session_id": "test_session",
423 "command": "bash"
424 });
425
426 let result = registry.execute_tool("create_pty_session", args).await;
427 assert!(result.is_ok());
428 let response: serde_json::Value = result.unwrap();
429 assert_eq!(response["success"], true);
430 assert_eq!(response["session_id"], "test_session");
431
432 let args = serde_json::json!({});
434 let result = registry.execute_tool("list_pty_sessions", args).await;
435 assert!(result.is_ok());
436 let response: serde_json::Value = result.unwrap();
437 assert!(
438 response["sessions"]
439 .as_array()
440 .unwrap()
441 .contains(&"test_session".into())
442 );
443
444 let args = serde_json::json!({
446 "session_id": "test_session"
447 });
448
449 let result = registry.execute_tool("close_pty_session", args).await;
450 assert!(result.is_ok());
451 let response: serde_json::Value = result.unwrap();
452 assert_eq!(response["success"], true);
453 assert_eq!(response["session_id"], "test_session");
454 }
455}