feat: enhance documentation and CLI interface

- Add comprehensive usage documentation and examples to README
- Add warning about shell command execution risks
- Improve CLI with --message and --research-only flags
- Add environment validation for API keys
- Replace requirements.txt with pyproject.toml
This commit is contained in:
AI Christianson 2024-12-10 19:27:31 -05:00
parent b529456ca4
commit 5cebfed28e
3 changed files with 122 additions and 56 deletions

View File

@ -20,6 +20,22 @@
RA.Aid (ReAct Aid) is a powerful AI-driven command-line tool that integrates `aider` (https://aider.chat/) within a LangChain ReAct agent loop. This unique combination allows developers to leverage aider's code editing capabilities while benefiting from LangChain's agent-based task execution framework. The tool provides an intelligent assistant that can help with research, planning, and implementation of development tasks. RA.Aid (ReAct Aid) is a powerful AI-driven command-line tool that integrates `aider` (https://aider.chat/) within a LangChain ReAct agent loop. This unique combination allows developers to leverage aider's code editing capabilities while benefiting from LangChain's agent-based task execution framework. The tool provides an intelligent assistant that can help with research, planning, and implementation of development tasks.
⚠️ **IMPORTANT: USE AT YOUR OWN RISK** ⚠️
- This tool **can and will** automatically execute shell commands on your system
- No warranty is provided, either express or implied
- Always review the actions the agent proposes before allowing them to proceed
## Key Features
- **Multi-Step Task Planning**: The agent breaks down complex tasks into discrete, manageable steps and executes them sequentially. This systematic approach ensures thorough implementation and reduces errors.
- **Automated Command Execution**: The agent can run shell commands automatically to accomplish tasks. While this makes it powerful, it also means you should carefully review its actions.
- **Three-Stage Architecture**:
1. **Research**: Analyzes codebases and gathers context
2. **Planning**: Breaks down tasks into specific, actionable steps
3. **Implementation**: Executes each planned step sequentially
What sets RA.Aid apart is its ability to handle complex programming tasks that extend beyond single-shot code edits. By combining research, strategic planning, and implementation into a cohesive workflow, RA.Aid can: What sets RA.Aid apart is its ability to handle complex programming tasks that extend beyond single-shot code edits. By combining research, strategic planning, and implementation into a cohesive workflow, RA.Aid can:
- Break down and execute multi-step programming tasks - Break down and execute multi-step programming tasks
@ -62,70 +78,76 @@ What sets RA.Aid apart is its ability to handle complex programming tasks that e
## Installation ## Installation
### Prerequisites RA.Aid can be installed directly using pip:
- Python 3.8 or higher
- pip package manager
### Steps
1. Install from PyPI:
```bash ```bash
pip install ra-aid pip install ra-aid
``` ```
Or install from source: ### Prerequisites
Before using RA.Aid, you'll need to set up your API keys for the required AI services:
```bash ```bash
git clone https://github.com/ai-christianson/ra-aid.git # Required: Set up your Anthropic API key
cd ra-aid export ANTHROPIC_API_KEY=your_api_key_here
pip install .
# Optional: Set up OpenAI API key if using OpenAI features
export OPENAI_API_KEY=your_api_key_here
``` ```
2. Install additional dependencies: You can get your API keys from:
```bash - Anthropic API key: https://console.anthropic.com/
pip install -r requirements.txt - OpenAI API key: https://platform.openai.com/api-keys
```
3. (Optional) Install development dependencies:
```bash
pip install -r requirements-dev.txt
```
## Usage ## Usage
RA.Aid is used via the `ra-aid` command. The basic usage pattern is: RA.Aid is designed to be simple yet powerful. Here's how to use it:
```bash ```bash
ra-aid [task] # Basic usage
ra-aid -m "Your task or query here"
# Research-only mode (no implementation)
ra-aid -m "Explain the authentication flow" --research-only
``` ```
### Examples ### Command Line Options
Research a topic: - `-m, --message`: The task or query to be executed (required)
- `--research-only`: Only perform research without implementation
### Example Tasks
1. Code Implementation:
```bash ```bash
ra-aid "Research best practices for Python package structure" ra-aid -m "Add input validation to the user registration endpoint"
``` ```
Plan a development task: 2. Code Research:
```bash ```bash
ra-aid "Plan the implementation of a new REST API endpoint" ra-aid -m "Explain how the authentication middleware works" --research-only
``` ```
Generate code or documentation: 3. Refactoring:
```bash ```bash
ra-aid "Create a README.md template for my project" ra-aid -m "Refactor the database connection code to use connection pooling"
``` ```
### Interactive Mode ### Environment Variables
For an interactive session where you can enter multiple tasks: RA.Aid uses the following environment variables:
- `ANTHROPIC_API_KEY` (Required): Your Anthropic API key for accessing Claude
- `OPENAI_API_KEY` (Optional): Your OpenAI API key if using OpenAI features
You can set these permanently in your shell's configuration file (e.g., `~/.bashrc` or `~/.zshrc`):
```bash ```bash
ra-aid export ANTHROPIC_API_KEY=your_api_key_here
export OPENAI_API_KEY=your_api_key_here
``` ```
This will start an interactive prompt where you can input tasks sequentially.
## Architecture ## Architecture
RA.Aid implements a three-stage architecture for handling development and research tasks: RA.Aid implements a three-stage architecture for handling development and research tasks:

View File

@ -1,5 +1,8 @@
import sqlite3 import sqlite3
import argparse import argparse
import os
import sys
import shutil
from langchain_anthropic import ChatAnthropic from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage from langchain_core.messages import HumanMessage
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import MemorySaver
@ -24,13 +27,24 @@ from ra_aid.prompts import (
def parse_arguments(): def parse_arguments():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='AI Agent for executing programming and research tasks', description='RA.Aid - AI Agent for executing programming and research tasks',
formatter_class=argparse.RawDescriptionHelpFormatter formatter_class=argparse.RawDescriptionHelpFormatter,
epilog='''
Examples:
ra-aid -m "Add error handling to the database module"
ra-aid -m "Explain the authentication flow" --research-only
'''
) )
parser.add_argument( parser.add_argument(
'task', '-m', '--message',
type=str, type=str,
help='The task to be executed by the agent' required=True,
help='The task or query to be executed by the agent'
)
parser.add_argument(
'--research-only',
action='store_true',
help='Only perform research without implementation'
) )
return parser.parse_args() return parser.parse_args()
@ -59,7 +73,8 @@ def is_informational_query() -> bool:
Returns: Returns:
bool: True if query is informational (no implementation requested), False otherwise bool: True if query is informational (no implementation requested), False otherwise
""" """
return not is_stage_requested('implementation') # Check both the research_only flag and implementation_requested state
return _global_memory.get('config', {}).get('research_only', False) or not is_stage_requested('implementation')
def is_stage_requested(stage: str) -> bool: def is_stage_requested(stage: str) -> bool:
"""Check if a stage has been requested to proceed. """Check if a stage has been requested to proceed.
@ -195,17 +210,53 @@ def run_research_subtasks(base_task: str, config: dict):
print(f"Encountered Anthropic Internal Server Error: {e}. Retrying...") print(f"Encountered Anthropic Internal Server Error: {e}. Retrying...")
continue continue
def validate_environment():
"""Validate required environment variables and dependencies."""
missing = []
# Check API keys
if not os.environ.get('ANTHROPIC_API_KEY'):
missing.append('ANTHROPIC_API_KEY environment variable is not set')
if not os.environ.get('OPENAI_API_KEY'):
missing.append('OPENAI_API_KEY environment variable is not set')
# Check for aider binary
if not shutil.which('aider'):
missing.append('aider binary not found in PATH. Please install aider: pip install aider')
if missing:
print("Error: Missing required dependencies:", file=sys.stderr)
for error in missing:
print(f"- {error}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
validate_environment()
args = parse_arguments() args = parse_arguments()
base_task = args.task base_task = args.message
config = {"configurable": {"thread_id": "abc123"}, "recursion_limit": 100} config = {
"configurable": {
"thread_id": "abc123"
},
"recursion_limit": 100,
"research_only": args.research_only
}
# Store config in global memory for access by is_informational_query
_global_memory['config'] = config
# Run research stage # Run research stage
print_stage_header("RESEARCH STAGE") print_stage_header("RESEARCH STAGE")
research_prompt = f"""User query: {base_task}
{RESEARCH_PROMPT}
Be very thorough in your research and emit lots of snippets, key facts. If you take more than a few steps, be eager to emit research subtasks.{'' if args.research_only else ' Only request implementation if the user explicitly asked for changes to be made.'}"""
while True: while True:
try: try:
for chunk in research_agent.stream( for chunk in research_agent.stream(
{"messages": [HumanMessage(content=f"User query: {base_task}\n\n{RESEARCH_PROMPT}\n\nBe very thorough in your research and emit lots of snippets, key facts. If you take more than a few steps, be eager to emit research subtasks. Only request implementation if the user explicitly asked for changes to be made.")]}, {"messages": [HumanMessage(content=research_prompt)]},
config config
): ):
print_agent_output(chunk) print_agent_output(chunk)

View File

@ -1,7 +0,0 @@
langchain-anthropic
langgraph
rich>=13.0.0
GitPython==3.1.41
fuzzywuzzy==0.18.0
python-Levenshtein==0.23.0
pathspec>=0.11.0