tech debt tool

This commit is contained in:
AI Christianson 2024-12-11 17:07:14 -05:00
parent f5d50ca349
commit de816867ee
4 changed files with 147 additions and 6 deletions

View File

@ -1,5 +1,6 @@
import sqlite3
import argparse
import glob
import os
import sys
import shutil
@ -11,7 +12,7 @@ from ra_aid.tools import (
ask_expert, run_shell_command, run_programming_task,
emit_research_notes, emit_plan, emit_related_files, emit_task,
emit_expert_context, get_memory_value, emit_key_facts, delete_key_facts,
emit_key_snippets, delete_key_snippets,
emit_key_snippets, delete_key_snippets, note_tech_debt,
request_implementation, read_file_tool, emit_research_subtask,
fuzzy_find_project_files, ripgrep_search, list_directory_tree
)
@ -63,9 +64,9 @@ planning_memory = MemorySaver()
implementation_memory = MemorySaver()
# Define tool sets for each stage
research_tools = [list_directory_tree, emit_research_subtask, run_shell_command, emit_expert_context, ask_expert, emit_research_notes, emit_related_files, emit_key_facts, delete_key_facts, emit_key_snippets, delete_key_snippets, request_implementation, read_file_tool, fuzzy_find_project_files, ripgrep_search]
planning_tools = [list_directory_tree, emit_expert_context, ask_expert, emit_plan, emit_task, emit_related_files, emit_key_facts, delete_key_facts, emit_key_snippets, delete_key_snippets, read_file_tool, fuzzy_find_project_files, ripgrep_search]
implementation_tools = [list_directory_tree, run_shell_command, emit_expert_context, ask_expert, run_programming_task, emit_related_files, emit_key_facts, delete_key_facts, emit_key_snippets, delete_key_snippets, read_file_tool, fuzzy_find_project_files, ripgrep_search]
research_tools = [list_directory_tree, emit_research_subtask, run_shell_command, emit_expert_context, ask_expert, emit_research_notes, emit_related_files, emit_key_facts, delete_key_facts, emit_key_snippets, delete_key_snippets, note_tech_debt, request_implementation, read_file_tool, fuzzy_find_project_files, ripgrep_search]
planning_tools = [list_directory_tree, emit_expert_context, ask_expert, emit_plan, emit_task, emit_related_files, emit_key_facts, delete_key_facts, emit_key_snippets, delete_key_snippets, note_tech_debt, read_file_tool, fuzzy_find_project_files, ripgrep_search]
implementation_tools = [list_directory_tree, run_shell_command, emit_expert_context, ask_expert, run_programming_task, emit_related_files, emit_key_facts, delete_key_facts, emit_key_snippets, delete_key_snippets, note_tech_debt, read_file_tool, fuzzy_find_project_files, ripgrep_search]
# Create stage-specific agents with individual memory objects
research_agent = create_react_agent(model, research_tools, checkpointer=research_memory)
@ -236,6 +237,47 @@ def validate_environment():
print(f"- {error}", file=sys.stderr)
sys.exit(1)
def review_tech_debt(model) -> None:
"""Review any technical debt notes collected during execution."""
tech_debt_dir = '.ra-aid/tech-debt'
tech_debt_files = glob.glob(os.path.join(tech_debt_dir, '*.md'))
if not tech_debt_files:
return
print_stage_header("Technical Debt Review")
# Read the contents of all tech debt notes
tech_debt_contents = []
for file_path in tech_debt_files:
with open(file_path, 'r') as file:
content = file.read()
tech_debt_contents.append(content)
# Analyze the tech debt notes
prompt = f"""Review the following technical debt notes collected during program execution:
{chr(10).join(tech_debt_contents)}
Please provide a brief, focused analysis:
1. Group similar issues if any
2. Highlight high-impact items
3. Suggest a rough priority order
Keep the response concise and actionable.
"""
# Stream the analysis
while True:
try:
for chunk in model.stream(
{"messages": [HumanMessage(content=prompt)]},
{"configurable": {"thread_id": "tech-debt"}, "recursion_limit": 100}
):
print_agent_output(chunk)
break
except ChatAnthropic.InternalServerError as e:
print(f"Encountered Anthropic Internal Server Error: {e}. Retrying...")
continue
def main():
"""Main entry point for the ra-aid command line tool."""
try:
@ -316,6 +358,7 @@ Be very thorough in your research and emit lots of snippets, key facts. If you t
related_files
)
except TaskCompletedException:
review_tech_debt(model)
sys.exit(0)
if __name__ == "__main__":

View File

@ -92,6 +92,18 @@ Thoroughness and Completeness
Carefully report what you found, including all directories and files.
Do not move on until you are certain you have a complete picture of the codebase structure.
Technical Debt Detection:
While exploring the codebase, use note_tech_debt to record any technical issues you discover, such as:
- Inconsistencies in code organization or naming
- Apparent dead or duplicated code
- Out-of-date dependencies or documentation
- Anti-patterns or code smells
- Confusing or poorly documented sections
When calling note_tech_debt, include:
- Clear description of the issue
- Specific file location where the issue was found
Focus on observation only - do not suggest fixes
Decision on Implementation
After completing your factual enumeration and description, decide:
@ -143,6 +155,15 @@ Guidelines:
Therefore, use as few tasks as needed, but no fewer.
Keep tasks organized as semantic divisions of the overall work, rather than a series of steps.
Technical Debt Management:
While analyzing implementation approaches, use note_tech_debt to record discovered issues:
- Architectural inconsistencies that need future attention
- Technical limitations that may need addressing
- Dependencies that could cause future problems
- Potential scalability or maintenance concerns
- API design issues or inconsistencies
This helps maintain a record of technical concerns while staying focused on the current task.
When planning the implementation:
Break the overall work into sub-tasks that are as detailed as necessary, but no more.
Each sub-task should be clear and unambiguous, and should fully describe what needs to be done, including:
@ -221,6 +242,13 @@ Important Notes:
- Use delete_key_facts to remove facts that become outdated, irrelevant, or duplicated.
- Use emit_key_snippets to manage code sections before and after modifications in batches.
- Regularly remove outdated snippets with delete_key_snippets.
- While implementing, use note_tech_debt to record technical issues you encounter:
* Code organization problems requiring refactoring
* Areas needing better error handling or validation
* Performance concerns that should be addressed
* Security considerations for future hardening
* Testing gaps or coverage issues
Record these observations without deviating from your current task.
Instructions:
1. Review the provided base task, plan, and key facts.

View File

@ -5,6 +5,7 @@ from .read_file import read_file_tool
from .fuzzy_find import fuzzy_find_project_files
from .list_directory import list_directory_tree
from .ripgrep import ripgrep_search
from .note_tech_debt import note_tech_debt
from .memory import (
emit_research_notes, emit_plan, emit_task, get_memory_value, emit_key_facts,
request_implementation, skip_implementation, delete_key_facts, emit_research_subtask,
@ -32,5 +33,6 @@ __all__ = [
'skip_implementation',
'emit_research_subtask',
'fuzzy_find_project_files',
'ripgrep_search'
'ripgrep_search',
'note_tech_debt'
]

View File

@ -0,0 +1,68 @@
from pathlib import Path
from typing import Dict, Optional
import os
import glob
from langchain_core.tools import tool
from rich.console import Console
from rich.panel import Panel
console = Console()
@tool
def note_tech_debt(
description: str,
location: Optional[str] = None
) -> Dict[str, any]:
"""Record a technical debt note for later review.
Creates a markdown file in .ra-aid/tech-debt/ containing the technical debt note.
Args:
description: Description of the technical debt issue
location: Optional file/location reference where the tech debt was found
Returns:
Dict containing:
- success: Boolean indicating if note was saved
- note_path: Path to the created note file
- note_number: Sequential number of the note
"""
# Ensure base directory exists
base_dir = Path('.ra-aid/tech-debt')
base_dir.mkdir(parents=True, exist_ok=True)
# Find next note number
existing_notes = glob.glob(str(base_dir / '*.md'))
next_num = 1
if existing_notes:
numbers = [int(Path(note).stem) for note in existing_notes]
next_num = max(numbers) + 1
# Create note path
note_path = base_dir / f'{next_num}.md'
# Format note content
content = [f'# Technical Debt Note {next_num}\n']
content.append('## Description\n')
content.append(f'{description}\n')
if location:
content.append('\n## Location\n')
content.append(f'{location}\n')
# Write note file
note_path.write_text(''.join(content))
# Display status panel
console.print(
Panel(
f"Created Tech Debt Note #{next_num} at {note_path}",
title="📝 Tech Debt Note",
border_style="bright_blue"
)
)
return {
'success': True,
'note_path': str(note_path),
'note_number': next_num
}