1#![cfg_attr(
2 not(test),
3 allow(
4 clippy::map_err_ignore,
5 clippy::cast_sign_loss,
6 clippy::collapsible_if,
7 clippy::large_futures,
8 )
9)]
10#![cfg_attr(test, allow(clippy::unreachable))]
12#![recursion_limit = "256"]
13pub mod a2a; pub mod acp;
139#[cfg(feature = "anthropic-api")]
140pub mod anthropic_api; pub mod audit;
142pub mod auth; pub mod cache; pub mod cli;
145pub mod code;
146pub mod command_safety; pub mod commands;
148pub mod compaction;
149pub mod components; pub mod config;
151pub mod constants;
152pub mod context; pub mod copilot;
154pub mod core;
155pub mod diagnostics;
156pub mod dotfile_protection; pub mod error; pub mod exec;
159pub mod exec_policy; pub use exec_policy::command_validation as execpolicy;
162pub mod gemini; pub mod git_info; pub mod hooks;
165pub mod http_client;
166pub mod ide_context;
167pub mod instructions;
168pub mod llm;
169pub mod marketplace;
170pub mod mcp;
171pub mod memory; pub mod metrics;
173pub mod models;
174pub mod models_manager; pub mod notifications;
176pub mod open_responses; pub mod orchestrator;
178pub mod permissions;
179pub mod persistent_memory;
180pub mod plugins;
181pub mod pods;
182pub mod primary_agent;
183pub mod project_doc;
184pub mod prompts;
185pub mod retry;
186mod retry_after;
187pub mod review;
188pub mod safety;
189pub mod sandboxing; pub mod scheduler;
191pub mod security;
192pub mod session;
193pub mod shutdown;
194pub mod skills;
195pub mod subagents;
196pub mod telemetry;
197pub mod terminal_setup;
198pub mod tool_policy;
199pub mod tools;
200pub mod trace; pub mod turn_metadata; pub mod types;
203pub mod ui;
204pub mod utils;
205mod zsh_exec_bridge;
206
207pub use vtcode_commons::errors::*;
209pub use vtcode_commons::{ctx_err, file_err};
210
211pub use cli::args::{Cli, Commands};
214pub use code::code_completion::{CompletionEngine, CompletionSuggestion};
215pub use commands::stats::handle_stats_command;
216pub use config::types::{
217 AnalysisDepth, CapabilityLevel, CommandResult, ContextConfig, LoggingConfig, OutputFormat,
218 PerformanceMetrics, ReasoningEffortLevel, SessionInfo, ToolConfig,
219};
220pub use config::{
221 AgentClientProtocolConfig, AgentClientProtocolTransport, AgentClientProtocolZedConfig,
222 AgentClientProtocolZedToolsConfig, AgentConfig, IdeContextConfig, IdeContextProviderConfig,
223 IdeContextProviderFamily, IdeContextProviderMode, IdeContextProvidersConfig,
224 PluginRuntimeConfig, PluginTrustLevel, VTCodeConfig, WorkspaceTrustLevel,
225};
226pub use core::agent::core::Agent;
227pub use core::agent::runner::AgentRunner;
228pub use core::agent::task::{
229 ContextItem as RunnerContextItem, Task as RunnerTask, TaskOutcome as RunnerTaskOutcome,
230 TaskResults as RunnerTaskResults,
231};
232pub use core::memory_pool::{MemoryPool, global_pool};
233pub use core::performance_profiler::{BenchmarkResults, BenchmarkUtils, PerformanceProfiler};
234pub use core::threads::{
235 SubmissionId, ThreadBootstrap, ThreadEventRecord, ThreadId, ThreadManager, ThreadRuntimeHandle,
236 ThreadSnapshot, build_thread_archive_metadata, loaded_skills_from_session_listing,
237 messages_from_session_listing,
238};
239pub use ide_context::{
240 EditorContextSnapshot, EditorFileContext, EditorLineRange, EditorSelectionContext,
241 EditorSelectionRange,
242};
243pub use primary_agent::{
244 ActivePrimaryAgent, ActivePrimaryAgentSpecIdentity, ActivePrimaryAgentState,
245 PrimaryAgentResolutionError, apply_primary_agent_tool_policy, clamp_primary_permission_mode,
246 resolve_discovered_primary_agent, resolve_primary_agent,
247};
248pub use subagents::{
249 SendInputRequest as SubagentSendInputRequest, SpawnAgentRequest as SubagentSpawnRequest,
250 SpawnBackgroundSubprocessRequest as SubagentSpawnBackgroundSubprocessRequest,
251 SubagentController, SubagentControllerConfig, SubagentInputItem, SubagentStatus,
252 SubagentStatusEntry,
253};
254pub use vtcode_bash_runner::BashRunner;
255
256pub use core::prompt_caching::{CacheStats, PromptCache, PromptCacheConfig, PromptOptimizer};
257pub use core::timeout_detector::TimeoutDetector;
258pub use diagnostics::{
259 DiagnosticReport, HealthSample, LabeledAction, PredictiveMonitor, RecoveryAction,
260 RecoveryPlaybook,
261};
262pub use dotfile_protection::{
263 AccessType as DotfileAccessType, AuditEntry as DotfileAuditEntry, AuditLog as DotfileAuditLog,
264 AuditOutcome as DotfileAuditOutcome, BackupManager as DotfileBackupManager, DotfileBackup,
265 DotfileGuardian, ProtectionDecision, ProtectionViolation, get_global_guardian,
266 init_global_guardian, is_protected_dotfile,
267};
268pub use error::{
269 ErrorCategory as VtCodeErrorCategory, ErrorCode as VtCodeErrorCode, Result as VtCodeResult,
270 VtCodeError,
271};
272pub use exec::events::{
273 AgentMessageItem, CommandExecutionItem, CommandExecutionStatus, EVENT_SCHEMA_VERSION,
274 ErrorItem, FileChangeItem, FileUpdateChange, ItemCompletedEvent, ItemStartedEvent,
275 ItemUpdatedEvent, McpToolCallItem, McpToolCallStatus, PatchApplyStatus, PatchChangeKind,
276 PlanDeltaEvent, PlanItem, ReasoningItem, ThreadEvent, ThreadItem, ThreadItemDetails,
277 ThreadStartedEvent, ToolCallStatus, ToolInvocationItem, ToolOutputItem, TurnCompletedEvent,
278 TurnFailedEvent, TurnStartedEvent, Usage, VersionedThreadEvent, WebSearchItem,
279};
280pub use exec::{CodeExecutor, ExecutionConfig, ExecutionResult, Language};
281pub use llm::providers::gemini::wire::{Content, FunctionDeclaration, Part};
282pub use llm::{AnyClient, make_client};
283pub use mcp::{
284 tool_discovery::{DetailLevel, ToolDiscovery, ToolDiscoveryResult},
285 validate_mcp_config,
286};
287pub use memory::{MemoryCheckpoint, MemoryMonitor, MemoryPressure, MemoryReport};
288pub use models_manager::{
289 ModelFamily, ModelPreset, ModelsCache, ModelsManager, builtin_model_presets,
290 model_family::find_family_for_model,
291};
292pub use notifications::{
293 NotificationConfig, NotificationEvent, NotificationManager, apply_global_notification_config,
294 apply_global_notification_config_from_vtcode, get_global_notification_manager,
295 init_global_notification_manager, init_global_notification_manager_with_config,
296 notify_command_failure, notify_error, notify_human_in_the_loop, notify_tool_failure,
297 notify_tool_success, send_global_notification,
298};
299pub use orchestrator::{
300 DistributedOrchestrator, ExecutionTarget, ExecutorRegistry, LocalExecutor, ScheduledWork,
301 WorkExecutor,
302};
303pub use pods::*;
304pub use prompts::{
305 generate_lightweight_instruction, generate_specialized_instruction, generate_system_instruction,
306};
307pub use retry::{RetryDecision, RetryPolicy};
308pub use security::{IntegrityTag, PayloadEnvelope, ZeroTrustContext};
309pub use telemetry::{TelemetryEvent, TelemetryPipeline};
310pub use zsh_exec_bridge::maybe_run_zsh_exec_wrapper_mode;
311
312pub use open_responses::{
314 ContentPart, CustomItem, DualEventEmitter, FunctionCallItem, FunctionCallOutputItem,
315 IncompleteDetails, IncompleteReason, InputTokensDetails, ItemStatus, MessageItem, MessageRole,
316 OpenResponseError, OpenResponseErrorCode, OpenResponseErrorType, OpenResponsesCallback,
317 OpenResponsesIntegration, OpenResponsesProvider, OpenUsage, OutputItem, OutputItemId,
318 OutputTokensDetails, ReasoningItem as OpenReasoningItem, Response as OpenResponse,
319 ResponseBuilder, ResponseId, ResponseStatus, ResponseStreamEvent, StreamEventEmitter,
320 ToOpenResponse, VecStreamEmitter, generate_item_id, generate_response_id,
321};
322
323pub use tool_policy::{ToolPolicy, ToolPolicyManager};
324
325pub use exec_policy::{
327 AskForApproval, Decision, ExecApprovalRequirement, ExecPolicyAmendment, ExecPolicyConfig,
328 ExecPolicyManager, Policy, PolicyEvaluation, PolicyParser, PrefixRule, RuleMatch,
329 SharedExecPolicyManager,
330};
331pub use sandboxing::{
332 CommandSpec as SandboxCommandSpec, ExecEnv as SandboxExecEnv, ExecExpiration,
333 SandboxManager as CodexSandboxManager, SandboxPermissions as CodexSandboxPermissions,
334 SandboxPolicy as CodexSandboxPolicy, SandboxType, WritableRoot,
335};
336
337pub use tools::OptimizedToolRegistry;
338pub use tools::grep_file::GrepSearchManager;
339pub use tools::{ToolRegistration, ToolRegistry};
340pub use ui::diff_renderer::DiffRenderer;
341pub use utils::dot_config::{
342 CacheConfig, DotConfig, DotManager, ProviderConfigs, UiConfig, UserPreferences,
343 WorkspaceTrustRecord, WorkspaceTrustStore, initialize_dot_folder, load_user_config,
344 load_workspace_trust_level, save_user_config, update_model_preference, update_theme_preference,
345 update_workspace_trust,
346};
347pub use utils::vtcodegitignore::initialize_vtcode_gitignore;
348pub use vtcode_indexer::SimpleIndexer;
349pub use vtcode_markdown_store::{
350 MarkdownStorage, ProjectData, ProjectStorage, SimpleCache, SimpleKVStorage,
351 SimpleProjectManager,
352};
353
354#[cfg(test)]
355mod memory_tests;
356
357#[cfg(test)]
358mod memory_integration_tests;
359
360#[cfg(test)]
361mod config_verification_tests;
362
363#[cfg(test)]
364mod tests {
365 use super::*;
366
367 use tempfile::TempDir;
368
369 struct CwdGuard {
370 previous: std::path::PathBuf,
371 }
372
373 impl CwdGuard {
374 fn new() -> Self {
375 let previous = std::env::current_dir().expect("current dir");
376 Self { previous }
377 }
378 }
379
380 impl Drop for CwdGuard {
381 fn drop(&mut self) {
382 let _ = std::env::set_current_dir(&self.previous);
383 }
384 }
385
386 #[tokio::test]
387 async fn test_library_exports() {
388 let _cache = PromptCache::new().await;
390 }
391
392 #[test]
393 fn test_module_structure() {
394 }
397
398 #[test]
399 fn test_version_consistency() {
400 }
403
404 #[tokio::test]
405 async fn test_tool_registry_integration() {
406 use crate::config::constants::tools;
407
408 let temp_dir = TempDir::new().expect("Failed to create temp dir");
409 let _cwd_guard = CwdGuard::new();
410 std::env::set_current_dir(&temp_dir).expect("Failed to change dir");
411
412 let registry = ToolRegistry::new(temp_dir.path().to_path_buf()).await;
413 registry
414 .initialize_async()
415 .await
416 .expect("Failed to init registry");
417
418 let list_args = serde_json::json!({
420 "action": "list",
421 "path": "."
422 });
423
424 let result = registry
425 .execute_tool(tools::UNIFIED_SEARCH, list_args)
426 .await;
427 assert!(result.is_ok());
428
429 let response: serde_json::Value = result.expect("Failed to execute unified_search:list");
430 assert!(response.is_object() || response.is_array());
431 }
432
433 #[tokio::test]
434 async fn test_pty_basic_command() {
435 let temp_dir = TempDir::new().expect("Failed to create temp dir");
436 let workspace = temp_dir.path().to_path_buf();
437 let registry = ToolRegistry::new(workspace.clone()).await;
438 registry
439 .initialize_async()
440 .await
441 .expect("Failed to init registry");
442
443 let args = serde_json::json!({
445 "command": "echo",
446 "args": ["Hello, PTY!"]
447 });
448
449 let result = registry.execute_tool("run_pty_cmd", args).await;
450 assert!(result.is_ok());
451 let response: serde_json::Value = result.expect("Failed to run PTY");
452 assert_eq!(response["is_exited"], true);
453 assert_eq!(response["exit_code"], 0);
454 assert!(response["output"].is_string());
455 }
456
457 #[tokio::test]
458 async fn test_pty_session_management() {
459 let temp_dir = TempDir::new().expect("Failed to create temp dir");
460 let workspace = temp_dir.path().to_path_buf();
461 let registry = ToolRegistry::new(workspace.clone()).await;
462 registry
463 .initialize_async()
464 .await
465 .expect("Failed to init registry");
466
467 let args = serde_json::json!({
469 "command": "cat",
470 "yield_time_ms": 10
471 });
472
473 let result = registry.execute_tool("create_pty_session", args).await;
474 assert!(result.is_ok());
475 let response: serde_json::Value = result.expect("Failed to create PTY session");
476 assert_eq!(response["success"], true);
477 assert_eq!(response["is_exited"], false);
478 let session_id = response["session_id"]
479 .as_str()
480 .expect("create_pty_session should return a session id")
481 .to_string();
482 assert!(!session_id.is_empty());
483
484 let args = serde_json::json!({});
486 let result = registry.execute_tool("list_pty_sessions", args).await;
487 assert!(result.is_ok());
488 let response: serde_json::Value = result.expect("Failed to list PTY sessions");
489 assert!(response.is_object() || response.is_array());
490
491 let args = serde_json::json!({
493 "session_id": session_id.clone()
494 });
495
496 let result = registry.execute_tool("close_pty_session", args).await;
497 assert!(result.is_ok());
498 let response: serde_json::Value = result.expect("Failed to close PTY session");
499 assert_eq!(response["success"], true);
500 assert_eq!(response["session_id"], session_id);
501 }
502}