1#![cfg_attr(
2 not(test),
3 allow(
4 clippy::large_futures,
5 reason = "Core async orchestration intentionally keeps some large stateful futures together."
6 )
7)]
8#![allow(
10 clippy::expect_used,
11 clippy::panic,
12 clippy::unnecessary_safety_comment,
13 clippy::unreachable,
14 clippy::unwrap_used,
15 missing_docs,
16 reason = "Core exposes compatibility and feature-gated surfaces whose documentation is maintained in project guides."
17)]
18#![expect(
19 unused_results,
20 clippy::let_underscore_must_use,
21 clippy::indexing_slicing,
22 clippy::string_slice,
23 clippy::cast_possible_truncation,
24 clippy::cast_possible_wrap,
25 reason = "Core runtime code intentionally maintains side-effect-only caches, validated text offsets, and protocol-sized counters across feature-gated paths."
26)]
27#![recursion_limit = "256"]
28pub mod a2a; pub mod acp;
154#[cfg(feature = "anthropic-api")]
155pub mod anthropic_api; pub mod audit;
157pub mod auth; pub mod cache; pub mod cli;
160pub mod code;
161pub mod command_safety; pub mod commands;
163pub mod compaction;
164pub mod components; pub mod config;
166pub mod constants;
167pub mod context; pub mod copilot {
170 pub use vtcode_llm::copilot::*;
171}
172pub mod core;
173pub mod diagnostics;
174pub mod dotfile_protection; pub mod error; pub mod exec;
177pub mod exec_policy; pub use components::delegate_components;
180pub use exec_policy::command_validation as execpolicy;
181pub mod gemini; pub mod git; pub mod git_info; pub mod hooks;
185pub mod http_client;
186mod id_newtype;
187pub mod instructions;
188pub mod llm;
189pub mod loop_memory; pub mod loop_state; pub mod marketplace;
192pub mod mcp;
193pub mod memory; pub mod metrics;
195pub mod models;
196pub mod models_manager; pub mod notifications;
198pub mod open_responses {
200 pub use vtcode_llm::open_responses::*;
201}
202pub mod permissions;
203pub mod persistent_memory;
204pub mod planning; pub mod plugins;
206pub mod pods;
207pub mod primary_agent;
208pub mod project_doc;
209pub mod prompts;
210pub mod retry;
211mod retry_after;
212pub mod review;
213pub mod safety;
214pub mod sandboxing; pub mod scheduler;
216pub mod security;
217pub mod session;
218pub mod shutdown;
219pub mod skills;
220pub mod subagents;
221pub mod telemetry;
222pub mod terminal_setup;
223pub mod tool_policy;
224pub mod tools;
225pub mod trace; pub mod turn_metadata; pub mod types;
228pub mod ui;
229pub mod utils;
230mod zsh_exec_bridge;
231
232pub use vtcode_commons::errors::*;
234pub use vtcode_commons::{ctx_err, file_err};
235
236pub use cli::args::{Cli, Commands};
239pub use code::code_completion::{CompletionEngine, CompletionSuggestion};
240pub use commands::stats::handle_stats_command;
241pub use config::types::{
242 AnalysisDepth, CapabilityLevel, OutputFormat, PerformanceMetrics, ReasoningEffortLevel, SessionInfo,
243};
244pub use config::{
245 AgentClientProtocolConfig, AgentClientProtocolTransport, AgentClientProtocolZedConfig,
246 AgentClientProtocolZedToolsConfig, AgentConfig, PluginRuntimeConfig, PluginTrustLevel, ToolProfile, VTCodeConfig,
247 WorkspaceTrustLevel,
248};
249pub use core::agent::core::Agent;
250pub use core::agent::runner::AgentRunner;
251pub use core::agent::task::{
252 ContextItem as RunnerContextItem, Task as RunnerTask, TaskOutcome as RunnerTaskOutcome,
253 TaskResults as RunnerTaskResults,
254};
255pub use core::memory_pool::{MemoryPool, global_pool};
256pub use core::performance_profiler::{BenchmarkResults, BenchmarkUtils, PerformanceProfiler};
257pub use core::threads::{
258 SubmissionId, ThreadBootstrap, ThreadEventRecord, ThreadId, ThreadManager, ThreadRuntimeHandle, ThreadSnapshot,
259 build_thread_archive_metadata, loaded_skills_from_session_listing, messages_from_session_listing,
260};
261pub use primary_agent::{
262 ActivePrimaryAgent, ActivePrimaryAgentSpecIdentity, ActivePrimaryAgentState, PrimaryAgentResolutionError,
263 active_primary_agent_permissions, apply_primary_agent_prompt_context, apply_primary_agent_tool_policy,
264 build_primary_agent_hook_config, build_primary_agent_runtime_config, evaluate_active_primary_agent_permissions,
265 resolve_discovered_primary_agent, resolve_primary_agent,
266};
267pub use subagents::{
268 SendInputRequest as SubagentSendInputRequest, SpawnAgentRequest as SubagentSpawnRequest,
269 SpawnBackgroundSubprocessRequest as SubagentSpawnBackgroundSubprocessRequest, SubagentController,
270 SubagentControllerConfig, SubagentInputItem, SubagentStatus, SubagentStatusEntry, VerificationResult,
271};
272pub use vtcode_bash_runner::BashRunner;
273
274pub use core::prompt_caching::{CacheStats, PromptCache, PromptCacheConfig, PromptOptimizer};
275pub use core::timeout_detector::TimeoutDetector;
276pub use diagnostics::{
277 DiagnosticReport, HealthSample, LabeledAction, PredictiveMonitor, RecoveryAction, RecoveryPlaybook,
278};
279pub use dotfile_protection::{
280 AccessType as DotfileAccessType, AuditEntry as DotfileAuditEntry, AuditLog as DotfileAuditLog,
281 AuditOutcome as DotfileAuditOutcome, BackupManager as DotfileBackupManager, DotfileBackup, DotfileGuardian,
282 ProtectionDecision, ProtectionViolation, get_global_guardian, init_global_guardian, is_protected_dotfile,
283};
284pub use error::{
285 ConfigGuidance, ErrorCategory as VtCodeErrorCategory, ErrorCode as VtCodeErrorCode, MisconfigurationKind,
286 Result as VtCodeResult, VtCodeError,
287};
288pub use exec::events::{
289 AgentMessageItem, CommandExecutionItem, CommandExecutionStatus, ContextResetEvent, ContextResetTrigger,
290 EVENT_SCHEMA_VERSION, ErrorItem, FileChangeItem, FileUpdateChange, ItemCompletedEvent, ItemStartedEvent,
291 ItemUpdatedEvent, McpToolCallItem, McpToolCallStatus, PatchApplyStatus, PatchChangeKind, PlanApprovalDecision,
292 PlanApprovalRequestedEvent, PlanApprovalResolvedEvent, PlanDeltaEvent, PlanItem, ReasoningItem, ThreadEvent,
293 ThreadItem, ThreadItemDetails, ThreadStartedEvent, ToolCallStatus, ToolInvocationItem, ToolOutputItem,
294 TurnCompletedEvent, TurnFailedEvent, TurnStartedEvent, Usage, VersionedThreadEvent, WebSearchItem,
295};
296pub use exec::{CodeExecutor, ExecutionConfig, ExecutionResult, Language};
297pub use llm::providers::gemini::wire::{Content, FunctionDeclaration, Part};
298pub use llm::{AnyClient, make_client};
299pub use mcp::{
300 tool_discovery::{DetailLevel, ToolDiscovery, ToolDiscoveryResult},
301 validate_mcp_config,
302};
303pub use memory::{MemoryMonitor, MemoryPressure, MemoryReport, RssCheckpoint};
304pub use models_manager::{
305 ModelFamily, ModelPreset, ModelsCache, ModelsManager, builtin_model_presets, model_family::find_family_for_model,
306};
307pub use notifications::{
308 NotificationConfig, NotificationEvent, NotificationManager, apply_global_notification_config,
309 apply_global_notification_config_from_vtcode, get_global_notification_manager, init_global_notification_manager,
310 init_global_notification_manager_with_config, notify_command_failure, notify_error, notify_human_in_the_loop,
311 notify_tool_failure, notify_tool_success, send_global_notification,
312};
313pub use pods::*;
314pub use prompts::SystemPromptReport;
315pub use prompts::{generate_lightweight_instruction, generate_specialized_instruction, measure_system_prompt_size};
316pub use retry::{RetryDecision, RetryPolicy, RetryPolicyCoreExt};
317pub use security::{IntegrityTag, PayloadEnvelope, ZeroTrustContext};
318pub use telemetry::{TelemetryEvent, TelemetryPipeline};
319pub use zsh_exec_bridge::maybe_run_zsh_exec_wrapper_mode;
320
321pub use open_responses::{
323 ContentPart, CustomItem, DualEventEmitter, FunctionCallItem, FunctionCallOutputItem, IncompleteDetails,
324 IncompleteReason, InputTokensDetails, ItemStatus, MessageItem, MessageRole, OpenResponseError,
325 OpenResponseErrorCode, OpenResponseErrorType, OpenResponsesCallback, OpenResponsesIntegration,
326 OpenResponsesProvider, OpenUsage, OutputItem, OutputItemId, OutputTokensDetails,
327 ReasoningItem as OpenReasoningItem, Response as OpenResponse, ResponseBuilder, ResponseId, ResponseStatus,
328 ResponseStreamEvent, StreamEventEmitter, ToOpenResponse, VecStreamEmitter, generate_item_id, generate_response_id,
329};
330
331pub use tool_policy::{ToolPolicy, ToolPolicyManager};
332
333pub use exec_policy::{
335 AskForApproval, Decision, ExecApprovalRequirement, ExecPolicyAmendment, ExecPolicyConfig, ExecPolicyManager,
336 Policy, PolicyEvaluation, PolicyParser, PrefixRule, RuleMatch, SharedExecPolicyManager,
337};
338pub use sandboxing::{
339 CommandSpec as SandboxCommandSpec, ExecEnv as SandboxExecEnv, ExecExpiration,
340 SandboxManager as CodexSandboxManager, SandboxPermissions as CodexSandboxPermissions,
341 SandboxPolicy as CodexSandboxPolicy, SandboxType, WritableRoot,
342};
343
344pub use tools::OptimizedToolRegistry;
345pub use tools::grep_file::GrepSearchManager;
346pub use tools::registry::{
347 McpBridge, PtySessionControl, SharedRegistry, ToolCatalog, ToolGroup, ToolMetrics, ToolRegistryApi, ToolResilience,
348 ToolSecurity, tool_groups,
349};
350pub use tools::{ToolRegistration, ToolRegistry};
351pub use ui::diff_renderer::{DiffRenderer, DiffRendererOptions};
352pub use utils::dot_config::{
353 CacheConfig, DotConfig, DotManager, LifecycleHookApprovalRecord, ProviderConfigs, UiConfig, UserPreferences,
354 WorkspaceTrustRecord, WorkspaceTrustStore, initialize_dot_folder, load_lifecycle_hook_approval, load_user_config,
355 load_workspace_trust_level, save_user_config, update_lifecycle_hook_approval, update_model_preference,
356 update_theme_preference, update_workspace_trust,
357};
358pub use utils::vtcodegitignore::initialize_vtcode_gitignore;
359pub use vtcode_indexer::SimpleIndexer;
360pub use vtcode_indexer::markdown_store::{
361 MarkdownStorage, ProjectData, ProjectStorage, SimpleCache, SimpleKVStorage, SimpleProjectManager,
362};
363
364#[cfg(test)]
365mod memory_tests;
366
367#[cfg(test)]
368mod memory_integration_tests;
369
370#[cfg(test)]
371mod config_verification_tests;
372
373#[cfg(test)]
374mod tests {
375 use super::*;
376
377 use tempfile::TempDir;
378
379 struct CwdGuard {
380 previous: std::path::PathBuf,
381 }
382
383 impl CwdGuard {
384 fn new() -> Self {
385 let previous = std::env::current_dir().expect("current dir");
386 Self { previous }
387 }
388 }
389
390 impl Drop for CwdGuard {
391 fn drop(&mut self) {
392 let _ = std::env::set_current_dir(&self.previous);
393 }
394 }
395
396 #[tokio::test]
397 async fn test_library_exports() {
398 let _cache = PromptCache::new().await;
400 }
401
402 #[test]
403 fn test_module_structure() {
404 }
407
408 #[test]
409 fn test_version_consistency() {
410 }
413
414 #[tokio::test]
415 async fn test_tool_registry_integration() {
416 let temp_dir = TempDir::new().expect("Failed to create temp dir");
417 let _cwd_guard = CwdGuard::new();
418 std::env::set_current_dir(&temp_dir).expect("Failed to change dir");
419
420 let registry = ToolRegistry::new(temp_dir.path().to_path_buf()).await;
421 registry.initialize_async().await.expect("Failed to init registry");
422
423 let list_args = serde_json::json!({
425 "path": "."
426 });
427
428 let result = registry.list_files(list_args).await;
429 assert!(result.is_ok());
430
431 let response: serde_json::Value = result.expect("Failed to execute list_files");
432 assert!(response.is_object() || response.is_array());
433 }
434
435 #[tokio::test]
436 async fn test_pty_basic_command() {
437 let temp_dir = TempDir::new().expect("Failed to create temp dir");
438 let workspace = temp_dir.path().to_path_buf();
439 let registry = ToolRegistry::new(workspace.clone()).await;
440 registry.initialize_async().await.expect("Failed to init registry");
441
442 let args = serde_json::json!({
444 "command": "echo",
445 "args": ["Hello, PTY!"]
446 });
447
448 let result = registry.execute_tool("run_pty_cmd", args).await;
449 assert!(result.is_ok());
450 let response: serde_json::Value = result.expect("Failed to run PTY");
451 assert_eq!(response["is_exited"], true);
452 assert_eq!(response["exit_code"], 0);
453 assert!(response["output"].is_string());
454 }
455
456 #[tokio::test]
457 async fn test_pty_session_management() {
458 let temp_dir = TempDir::new().expect("Failed to create temp dir");
459 let workspace = temp_dir.path().to_path_buf();
460 std::fs::write(workspace.join("vtcode.toml"), "[workspace]\nuse_root_config = true\n")
461 .expect("write isolated workspace config");
462 let registry = ToolRegistry::new(workspace.clone()).await;
463 registry.initialize_async().await.expect("Failed to init registry");
464
465 let args = serde_json::json!({
467 "command": "cat",
468 "yield_time_ms": 10
469 });
470
471 let result = registry.execute_tool("create_pty_session", args).await;
472 assert!(result.is_ok());
473 let response: serde_json::Value = result.expect("Failed to create PTY session");
474 assert_eq!(response["success"], true);
475 assert_eq!(response["is_exited"], false);
476 let session_id = response["session_id"]
477 .as_str()
478 .expect("create_pty_session should return a session id")
479 .to_string();
480 assert!(!session_id.is_empty());
481
482 let args = serde_json::json!({});
484 let result = registry.execute_tool("list_pty_sessions", args).await;
485 assert!(result.is_ok());
486 let response: serde_json::Value = result.expect("Failed to list PTY sessions");
487 assert!(response.is_object() || response.is_array());
488
489 let args = serde_json::json!({
491 "session_id": session_id.clone()
492 });
493
494 let result = registry.execute_tool("close_pty_session", args).await;
495 assert!(result.is_ok());
496 let response: serde_json::Value = result.expect("Failed to close PTY session");
497 assert_eq!(response["success"], true);
498 assert_eq!(response["session_id"], session_id);
499 }
500}