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 sqlite3
import argparse import argparse
import glob
import os import os
import sys import sys
import shutil import shutil
@ -11,7 +12,7 @@ from ra_aid.tools import (
ask_expert, run_shell_command, run_programming_task, ask_expert, run_shell_command, run_programming_task,
emit_research_notes, emit_plan, emit_related_files, emit_task, emit_research_notes, emit_plan, emit_related_files, emit_task,
emit_expert_context, get_memory_value, emit_key_facts, delete_key_facts, 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, request_implementation, read_file_tool, emit_research_subtask,
fuzzy_find_project_files, ripgrep_search, list_directory_tree fuzzy_find_project_files, ripgrep_search, list_directory_tree
) )
@ -63,9 +64,9 @@ planning_memory = MemorySaver()
implementation_memory = MemorySaver() implementation_memory = MemorySaver()
# Define tool sets for each stage # 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] 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, 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, 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 # Create stage-specific agents with individual memory objects
research_agent = create_react_agent(model, research_tools, checkpointer=research_memory) research_agent = create_react_agent(model, research_tools, checkpointer=research_memory)
@ -236,6 +237,47 @@ def validate_environment():
print(f"- {error}", file=sys.stderr) print(f"- {error}", file=sys.stderr)
sys.exit(1) 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(): def main():
"""Main entry point for the ra-aid command line tool.""" """Main entry point for the ra-aid command line tool."""
try: try:
@ -316,6 +358,7 @@ Be very thorough in your research and emit lots of snippets, key facts. If you t
related_files related_files
) )
except TaskCompletedException: except TaskCompletedException:
review_tech_debt(model)
sys.exit(0) sys.exit(0)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -92,6 +92,18 @@ Thoroughness and Completeness
Carefully report what you found, including all directories and files. 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. 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 Decision on Implementation
After completing your factual enumeration and description, decide: After completing your factual enumeration and description, decide:
@ -143,6 +155,15 @@ Guidelines:
Therefore, use as few tasks as needed, but no fewer. 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. 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: When planning the implementation:
Break the overall work into sub-tasks that are as detailed as necessary, but no more. 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: Each sub-task should be clear and unambiguous, and should fully describe what needs to be done, including:
@ -158,7 +179,7 @@ Guidelines:
Use emit_plan to store the high-level implementation plan. Use emit_plan to store the high-level implementation plan.
For each sub-task, use emit_task to store a step-by-step description. For each sub-task, use emit_task to store a step-by-step description.
The description should be only as detailed as warranted by the complexity of the request. The description should be only as detailed as warranted by the complexity of the request.
Do not implement anything yet. Do not implement anything yet.
""" """
@ -221,6 +242,13 @@ Important Notes:
- Use delete_key_facts to remove facts that become outdated, irrelevant, or duplicated. - 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. - Use emit_key_snippets to manage code sections before and after modifications in batches.
- Regularly remove outdated snippets with delete_key_snippets. - 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: Instructions:
1. Review the provided base task, plan, and key facts. 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 .fuzzy_find import fuzzy_find_project_files
from .list_directory import list_directory_tree from .list_directory import list_directory_tree
from .ripgrep import ripgrep_search from .ripgrep import ripgrep_search
from .note_tech_debt import note_tech_debt
from .memory import ( from .memory import (
emit_research_notes, emit_plan, emit_task, get_memory_value, emit_key_facts, emit_research_notes, emit_plan, emit_task, get_memory_value, emit_key_facts,
request_implementation, skip_implementation, delete_key_facts, emit_research_subtask, request_implementation, skip_implementation, delete_key_facts, emit_research_subtask,
@ -32,5 +33,6 @@ __all__ = [
'skip_implementation', 'skip_implementation',
'emit_research_subtask', 'emit_research_subtask',
'fuzzy_find_project_files', '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
}