Skip to content

Commit 323bbb2

Browse files
committed
feat: Update default agent configuration to HuggingFace and refine tool schemas and prompt generation logic.
1 parent d961886 commit 323bbb2

File tree

12 files changed

+86
-62
lines changed

12 files changed

+86
-62
lines changed

.vtcode/tool-policy.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@
5454
"skill": "prompt",
5555
"code_intelligence": "prompt",
5656
"agent_info": "prompt",
57-
"mcp_get_current_time": "prompt",
58-
"mcp_time_get_current_time": "prompt",
57+
"mcp_fetch": "prompt",
58+
"mcp_fetch_fetch": "prompt",
5959
"mcp_convert_time": "prompt",
6060
"mcp_time_convert_time": "prompt",
61-
"mcp_fetch": "prompt",
62-
"mcp_fetch_fetch": "prompt"
61+
"mcp_get_current_time": "prompt",
62+
"mcp_time_get_current_time": "prompt"
6363
},
6464
"constraints": {},
6565
"mcp": {

docs/project/TODO.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,18 @@ Add LSP (Language Server Protocol) tool for code intelligence features like go-t
1616
--
1717

1818
revivew prompt caching strategy for better performance and lower latency
19+
20+
--
21+
22+
remove this for simplicity
23+
24+
Adaptive context trimming near budget thresholds
25+
• Semantic compression and pruning
26+
• Token budget enforcement
27+
28+
--
29+
30+
31+
analyze and improve
32+
33+
Now let me summarize the core agent loop analysis:\n\n## Core Agent Loop Analysis\n\nBased on my analysis of the VT Code codebase, here's a comprehensive overview of the core agent loop architecture:\n\n### Entry Points\n\n**Primary Entry**: `src/agent/agents.rs::run_single_agent_loop()`\n- Loads configuration from workspace\n- Creates provider client and tool registry\n- Initializes session components\n- Delegates to unified turn loop\n\n**Main Loop**: `src/agent/runloop/unified/turn/run_loop.rs`\n- ~3,218 lines implementing the core agent loop\n- Located in `run_single_agent_loop_unified()` function\n\n### Loop Structure\n\nThe agent loop is a nested structure:\n\n```\nsession_loop (outer)\n └─ turn_loop (middle)\n └─ tool_execution_loop (inner)\n```\n\n**Session Loop** (`session_loop.rs`):\n- Handles session lifecycle\n- Manages TUI initialization and cleanup\n- Supports session resumption and forking\n- Handles slash commands\n- Manages terminal state restoration\n\n**Turn Loop** (`run_loop.rs:1974`):\n- Main processing loop labeled `'outer`\n- Executes individual conversation turns\n- Manages context trimming and budget enforcement\n- Handles tool calls and responses\n- Implements self-review mechanism\n\n**Tool Execution Loop** (within turn processing):\n- Processes multiple tool calls per turn\n- Supports parallel tool execution\n- Implements tool caching\n- Handles tool permissions and approvals\n\n### Key Components\n\n**Context Management** (`context_manager.rs`):\n- Adaptive context trimming near budget thresholds\n- Semantic compression and pruning\n- Token budget enforcement\n- System prompt building with incremental updates\n\n**Tool Pipeline** (`tool_pipeline.rs`):\n- Permission checking and HITL (Human-in-the-Loop) approval\n- Tool result caching for read-only tools\n- Timeout handling with cancellation\n- Modified files tracking\n\n**Loop Detection** (`loop_detection.rs`):\n- Tracks repeated tool call signatures\n- Configurable threshold for loop detection\n- Selective signature reset capability\n- Turn balancer to prevent low-signal churn\n\n**Decision Tracking** (`decision_tracker.rs`):\n- Records all agent decisions\n- Tracks outcomes (success/failure)\n- Generates transparency reports\n- Confidence scoring\n\n**State Management** (`state.rs`):\n- `CtrlCState`: Handles cancellation and exit signals\n- `SessionStats`: Tracks tool usage across session\n\n### Core Flow\n\n1. **Session Setup** (`session_setup.rs`):\n - Load configuration and initialize provider\n - Build tool definitions with mode-based declarations\n - Create context manager with trim configuration\n - Initialize MCP (Model Context Protocol) support\n\n2. **Turn Processing**:\n - Build system prompt with incremental updates\n - Execute LLM request with streaming\n - Parse response for tool calls and final text\n - Handle tool calls through permission pipeline\n - Cache tool results for read-only operations\n - Update decision ledger\n\n3. **Context Management**:\n - Adaptive trimming at budget thresholds\n - Turn balancer triggers compaction on repeated calls\n - Semantic pruning based on message importance\n - Token budget enforcement\n\n4. **Error Handling**:\n - Tool failure handling with enhanced error messages\n - Timeout detection and cancellation\n - Loop detection and prevention\n - Error recovery strategies\n\n### Safety Mechanisms\n\n1. **Loop Prevention**:\n - Repeated tool call tracking\n - Turn balancer limits low-signal churn\n - Configurable repeat thresholds\n\n2. **Human-in-the-Loop**:\n - Tool permission checks\n - Destructive operation confirmation\n - Git diff integration for change review\n\n3. **Resource Management**:\n - Token budget enforcement\n - Context window limits\n - Tool execution timeouts\n - Ctrl+C signal handling\n\n4. **Recovery**:\n - Error recovery manager with strategies\n - Snapshot/checkpoint support\n - Session resumption capability\n\n### Key Patterns\n\n**Mode-Based Execution**: 77% complexity reduction through mode-based tool selection and execution\n\n**Trait-Based Tools**: Single source of truth for content search and file operations\n\n**Incremental System Prompt**: Dynamic prompt building based on conversation state\n\n**Decision Ledger**: Comprehensive tracking of all agent actions and outcomes\n\n**Semantic Pruning**: Context compression based on message importance and age\n\nThe loop is designed to be robust, safe, and efficient while maintaining transparency through comprehensive decision tracking and reportingq

src/agent/runloop/text_tools.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -708,25 +708,23 @@ fn parse_tagged_tool_call(text: &str) -> Option<(String, Value)> {
708708
_ => {}
709709
}
710710
}
711-
if let Some(end) = json_end {
712-
if let Ok(parsed) = serde_json::from_str::<Value>(&json_content[..end]) {
713-
if let Some(obj) = parsed.as_object() {
714-
for (k, v) in obj {
715-
object.insert(k.clone(), v.clone());
716-
}
717-
}
711+
if let Some(end) = json_end
712+
&& let Ok(parsed) = serde_json::from_str::<Value>(&json_content[..end])
713+
&& let Some(obj) = parsed.as_object()
714+
{
715+
for (k, v) in obj {
716+
object.insert(k.clone(), v.clone());
718717
}
719718
}
720719
}
721720

722721
// If JSON parsing didn't work, try key=value or key:value pairs
723-
if object.is_empty() {
724-
if let Some(parsed) = parse_key_value_arguments(content) {
725-
if let Some(obj) = parsed.as_object() {
726-
for (k, v) in obj {
727-
object.insert(k.clone(), v.clone());
728-
}
729-
}
722+
if object.is_empty()
723+
&& let Some(parsed) = parse_key_value_arguments(content)
724+
&& let Some(obj) = parsed.as_object()
725+
{
726+
for (k, v) in obj {
727+
object.insert(k.clone(), v.clone());
730728
}
731729
}
732730
}

src/agent/runloop/unified/prompts.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use vtcode_core::prompts::system::compose_system_instruction_text;
66
pub(crate) async fn read_system_prompt(workspace: &Path, session_addendum: Option<&str>) -> String {
77
// Build PromptContext with available information (workspace and current directory)
88
// Tool information will be added when tools are initialized
9-
let mut prompt_context = PromptContext::default();
10-
prompt_context.workspace = Some(workspace.to_path_buf());
9+
let mut prompt_context = PromptContext {
10+
workspace: Some(workspace.to_path_buf()),
11+
..Default::default()
12+
};
1113

1214
// Set current working directory
1315
if let Ok(cwd) = std::env::current_dir() {

src/startup/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,7 @@ impl StartupContext {
158158
} else if let Some(value) = args.resume_session.as_ref() {
159159
if value == "__interactive__" {
160160
// --resume with interactive mode
161-
if custom_session_id.is_some() {
162-
Some(SessionResumeMode::Interactive) // Will fork after selection
163-
} else {
164-
Some(SessionResumeMode::Interactive)
165-
}
161+
Some(SessionResumeMode::Interactive)
166162
} else {
167163
// --resume with specific ID
168164
if custom_session_id.is_some() {

vtcode-core/src/prompts/system.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -329,26 +329,24 @@ pub async fn compose_system_instruction_text(
329329
}
330330

331331
// ENHANCEMENT 2: Temporal context (metadata - goes at end)
332-
if let Some(cfg) = vtcode_config {
333-
if cfg.agent.include_temporal_context {
334-
let temporal = generate_temporal_context(cfg.agent.temporal_context_use_utc);
335-
instruction.push_str(&temporal);
336-
}
332+
if let Some(cfg) = vtcode_config
333+
&& cfg.agent.include_temporal_context
334+
{
335+
let temporal = generate_temporal_context(cfg.agent.temporal_context_use_utc);
336+
instruction.push_str(&temporal);
337337
}
338338

339339
// ENHANCEMENT 3: Working directory context (metadata - goes at end)
340-
if let Some(cfg) = vtcode_config {
341-
if cfg.agent.include_working_directory {
342-
if let Some(ctx) = prompt_context {
343-
if let Some(cwd) = &ctx.current_directory {
344-
let _ = write!(
345-
instruction,
346-
"\n\nCurrent working directory: {}",
347-
cwd.display()
348-
);
349-
}
350-
}
351-
}
340+
if let Some(cfg) = vtcode_config
341+
&& cfg.agent.include_working_directory
342+
&& let Some(ctx) = prompt_context
343+
&& let Some(cwd) = &ctx.current_directory
344+
{
345+
let _ = write!(
346+
instruction,
347+
"\n\nCurrent working directory: {}",
348+
cwd.display()
349+
);
352350
}
353351

354352
instruction

vtcode-core/src/tools/file_ops.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ impl FileOpsTool {
8383

8484
// Try to get result from cache first for directories
8585
let cache_key = format!("dir_list:{}:hidden={}", input.path, input.include_hidden);
86-
if base.is_dir() {
87-
if let Some(cached_result) = FILE_CACHE.get_directory(&cache_key).await {
88-
return Ok(cached_result);
89-
}
86+
if base.is_dir()
87+
&& let Some(cached_result) = FILE_CACHE.get_directory(&cache_key).await
88+
{
89+
return Ok(cached_result);
9090
}
9191

9292
// Pre-allocate with reasonable estimate for directory entries

vtcode-core/src/tools/registry/declarations.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -570,17 +570,25 @@ fn base_function_declarations() -> Vec<FunctionDeclaration> {
570570
"type": "array",
571571
"description": "Plan steps with status. Required: 3-7 steps for quality. Include specific file paths with line numbers (e.g., 'Update validate_plan in plan.rs:395-417'). Order by dependencies. One in_progress at a time.",
572572
"items": {
573-
"type": "object",
574-
"properties": {
575-
"step": {"type": "string", "description": "Step description with file path and line numbers"},
576-
"status": {
573+
"anyOf": [
574+
{
577575
"type": "string",
578-
"enum": ["pending", "in_progress", "completed"],
579-
"description": "Step status"
576+
"description": "Simple step description"
577+
},
578+
{
579+
"type": "object",
580+
"properties": {
581+
"step": {"type": "string", "description": "Step description with file path and line numbers"},
582+
"status": {
583+
"type": "string",
584+
"enum": ["pending", "in_progress", "completed"],
585+
"description": "Step status (defaults to 'pending' if not specified)"
586+
}
587+
},
588+
"required": ["step"],
589+
"additionalProperties": false
580590
}
581-
},
582-
"required": ["step", "status"],
583-
"additionalProperties": false
591+
]
584592
}
585593
}
586594
},

vtcode-core/src/tools/registry/executors.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,12 @@ impl ToolRegistry {
566566
"available_tools_count": available_tools.len(),
567567
"available_tools": available_tools,
568568
})),
569-
"full" | _ => Ok(json!({
569+
"full" => Ok(json!({
570+
"tools_registered": available_tools.clone(),
571+
"workspace_root": workspace_root,
572+
"available_tools_count": available_tools.len(),
573+
})),
574+
_ => Ok(json!({
570575
"tools_registered": available_tools.clone(),
571576
"workspace_root": workspace_root,
572577
"available_tools_count": available_tools.len(),

vtcode-core/src/ui/diff_renderer.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ pub struct DiffRenderer {
220220
show_line_numbers: bool,
221221
context_lines: usize,
222222
use_colors: bool,
223+
#[allow(dead_code)]
223224
pub(crate) palette: GitDiffPalette,
224225
// Pre-rendered ANSI codes for performance (cached)
225226
cached_styles: CachedStyles,
@@ -338,7 +339,7 @@ impl DiffRenderer {
338339

339340
// Bullet: "▸" (3 bytes UTF-8)
340341
output.push_str(&self.cached_styles.bullet);
341-
output.push_str("▸");
342+
output.push('▸');
342343
output.push_str(&self.cached_styles.reset);
343344
output.push(' ');
344345

@@ -422,6 +423,7 @@ impl DiffRenderer {
422423
}
423424
}
424425

426+
#[allow(dead_code)]
425427
pub(crate) fn paint(&self, style: &Style, text: &str) -> String {
426428
if self.use_colors {
427429
// CRITICAL: Apply style and reset without including newlines in the styled block

0 commit comments

Comments
 (0)