From cc63bf0bae18a00555de0e1de1c8a0db0586d65d Mon Sep 17 00:00:00 2001 From: AI Christianson Date: Wed, 18 Dec 2024 16:51:04 -0500 Subject: [PATCH] emit research subtask -> request research subtask --- ra_aid/__main__.py | 11 +++++------ ra_aid/prompts.py | 16 ++++++++++++---- ra_aid/tools/__init__.py | 4 ++-- ra_aid/tools/memory.py | 16 ++++++++++------ ra_aid/tools/research.py | 4 ++-- tests/ra_aid/tools/test_memory.py | 8 ++++---- 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/ra_aid/__main__.py b/ra_aid/__main__.py index 078870c..f18d8e9 100644 --- a/ra_aid/__main__.py +++ b/ra_aid/__main__.py @@ -11,7 +11,7 @@ from ra_aid.tools import ( 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_research_subtask, request_implementation, read_file_tool, fuzzy_find_project_files, ripgrep_search, list_directory_tree, + request_research_subtask, request_implementation, read_file_tool, fuzzy_find_project_files, ripgrep_search, list_directory_tree, swap_task_order, monorepo_detected, existing_project_detected, ui_detected ) from ra_aid.env import validate_environment @@ -33,6 +33,7 @@ READ_ONLY_TOOLS = [ delete_key_facts, emit_key_snippets, delete_key_snippets, + list_directory_tree, read_file_tool, fuzzy_find_project_files, ripgrep_search, @@ -55,9 +56,7 @@ EXPERT_TOOLS = [ # Research-specific tools RESEARCH_TOOLS = [ - list_directory_tree, - emit_research_subtask, - run_shell_command, + request_research_subtask, emit_research_notes, one_shot_completed, monorepo_detected, @@ -290,11 +289,11 @@ def run_research_subtasks(base_task: str, config: dict, model, expert_enabled: b print_stage_header("Research Subtasks") - # Get tools for subtask agents (excluding emit_research_subtask and implementation) + # Get tools for subtask agents (excluding request_research_subtask and implementation) research_only = _global_memory.get('config', {}).get('research_only', False) subtask_tools = [ t for t in get_research_tools(research_only=research_only, expert_enabled=expert_enabled) - if t.name not in ['emit_research_subtask'] + if t.name not in ['request_research_subtask'] ] for i, subtask in enumerate(subtasks, 1): diff --git a/ra_aid/prompts.py b/ra_aid/prompts.py index 34b3ec3..8459ee5 100644 --- a/ra_aid/prompts.py +++ b/ra_aid/prompts.py @@ -44,7 +44,7 @@ Tools and Methodology Be meticulous: If you find a directory, explore it thoroughly. If you find files of potential relevance, record them. Make sure you do not skip any directories you discover. Prefer to use list_directory_tree and other tools over shell commands. Do not produce huge outputs from your commands. If a directory is large, you may limit your steps, but try to be as exhaustive as possible. Incrementally gather details as needed. - Spawn subtasks for topics that require deeper investigation. + Request subtasks for topics that require deeper investigation. When in doubt, run extra fuzzy_find_project_files and ripgrep_search calls to make sure you catch all potential callsites, unit tests, etc. that could be relevant to the base task. You don't want to miss anything. Take your time and research thoroughly. @@ -91,10 +91,10 @@ Thoroughness and Completeness If you detect a UI, call ui_detected. You have often been criticized for: - - Missing 2nd- or 3rd-level related files. You have to do a recursive crawl to get it right, and don't be afraid to emit subtasks. + - Missing 2nd- or 3rd-level related files. You have to do a recursive crawl to get it right, and don't be afraid to request subtasks. - Missing related files spanning modules or parts of the monorepo. - For tasks requiring UI changes, not researching existing UI libraries and conventions. - - Not emitting enough research subtasks on changes on large projects, e.g. to discover testing or UI conventions, etc. + - Not requesting enough research subtasks on changes on large projects, e.g. to discover testing or UI conventions, etc. - Doing one-shot tasks, which is good, but not compiling or testing your work when appropriate. - Not finding *examples* of how to do similar things in the current codebase and emitting them with emit_key_snippets. - Not finding unit tests because they are in slightly different locations than expected. @@ -165,6 +165,11 @@ Guidelines: Testing strategies appropriate to the complexity of that sub-task You may include pseudocode, but not full code. + + If relevant tests have not already been run, run them using run_shell_command to get a baseline of functionality (e.g. were any tests failing before we started working? Do they all pass?) + Only test UI components if there is already a UI testing system in place. + Only test things that can be tested by an automated process. + After finalizing the overall approach: Use emit_plan to store the high-level implementation plan. For each sub-task, use emit_task to store a step-by-step description. @@ -207,14 +212,17 @@ Instructions: 5. Do not add features not explicitly required. 6. Only create or modify files directly related to this task. 7. Use file_str_replace and write_file_tool for simple file modifications. -8. Delegate to run_programming_task for more complex programming tasks. +8. Delegate to run_programming_task for more complex programming tasks. This is a capable human programmer that can work on multiple files at once. Testing: - If your task involves writing unit tests, first inspect existing test suites and analyze at least one existing test to learn about testing organization and conventions. + - If the tests have not already been run, run them using run_shell_command to get a baseline of functionality (e.g. were any tests failing before we started working? Do they all pass?) - If you add or change any unit tests, run them using run_shell_command and ensure they pass (check docs or analyze directory structure/test files to infer how to run them.) - Start with running very specific tests, then move to more general/complete test suites. - If you have any doubts about logic or debugging (or how to best test something), ask the expert to perform deep analysis. +- Only test UI components if there is already a UI testing system in place. +- Only test things that can be tested by an automated process. Once the task is complete, ensure all updated files are emitted. """ diff --git a/ra_aid/tools/__init__.py b/ra_aid/tools/__init__.py index 2cdbfe5..f979cf4 100644 --- a/ra_aid/tools/__init__.py +++ b/ra_aid/tools/__init__.py @@ -10,7 +10,7 @@ from .list_directory import list_directory_tree from .ripgrep import ripgrep_search 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, + request_implementation, skip_implementation, delete_key_facts, request_research_subtask, emit_key_snippets, delete_key_snippets, emit_related_files, swap_task_order ) @@ -34,7 +34,7 @@ __all__ = [ 'run_shell_command', 'skip_implementation', 'write_file_tool', - 'emit_research_subtask', + 'request_research_subtask', 'ripgrep_search', 'file_str_replace', 'swap_task_order', diff --git a/ra_aid/tools/memory.py b/ra_aid/tools/memory.py index 80f402a..9c3e596 100644 --- a/ra_aid/tools/memory.py +++ b/ra_aid/tools/memory.py @@ -79,12 +79,11 @@ def emit_task(task: str) -> str: console.print(Panel(Markdown(task), title=f"✅ Task #{task_id}")) return f"Task #{task_id} stored." -@tool("emit_research_subtask") -def emit_research_subtask(subtask: str) -> str: - """Spawn a research subtask for deeper investigation of a specific topic. - - Only use this when a topic requires dedicated focused research beyond the main task. - This should be used sparingly for truly complex research needs. +@tool("request_research_subtask") +def request_research_subtask(subtask: str) -> str: + """Spawn a research subtask for investigation of a specific topic. + + Use this anytime you can to offload your work to specific things that need to be looked into. Args: subtask: Detailed description of the research subtask @@ -175,6 +174,11 @@ def delete_tasks(task_ids: List[int]) -> str: def request_implementation(reason: str) -> str: """Request that implementation proceed after research/planning. Used to indicate the agent should move to implementation stage. + + Think carefully before requesting implementation. + Do you need to request research subtasks first? + Have you run relevant unit tests, if they exist, to get a baseline (this can be a subtask)? + Do you need to crawl deeper to find all related files and symbols? Args: reason: Why implementation should proceed diff --git a/ra_aid/tools/research.py b/ra_aid/tools/research.py index b21e10e..23cc827 100644 --- a/ra_aid/tools/research.py +++ b/ra_aid/tools/research.py @@ -40,7 +40,7 @@ def monorepo_detected() -> dict: "- Find and note existing versioning and release management practices already in place.\n\n" "- Pay extra attention to integration nuances such as authentication, authorization, examples of how APIs are called, etc.\n\n" "- Find and note specific examples of all of the above.\n\n" - "- Because you are in a monorepo, you will likely need to call emit_research_subtask multiple times.\n\n" + "- Because you are in a monorepo, you will likely need to call request_research_subtask multiple times.\n\n" "Your goal is to enhance the entire codebase without disrupting its well-established, unified structure." ) } @@ -61,4 +61,4 @@ def ui_detected() -> dict: "- Find and note established workflows for building, bundling, and deploying the UI layer, ensuring that any new changes do not conflict with the existing pipeline.\n\n" "Your goal is to enhance the user interface without disrupting the cohesive look, feel, and functionality already established." ) - } \ No newline at end of file + } diff --git a/tests/ra_aid/tools/test_memory.py b/tests/ra_aid/tools/test_memory.py index 3b79194..7311964 100644 --- a/tests/ra_aid/tools/test_memory.py +++ b/tests/ra_aid/tools/test_memory.py @@ -2,7 +2,7 @@ import pytest from ra_aid.tools.memory import ( _global_memory, get_memory_value, - emit_research_subtask, + request_research_subtask, emit_key_facts, delete_key_facts, emit_key_snippets, @@ -431,11 +431,11 @@ def test_swap_task_order_after_delete(reset_memory): assert _global_memory['tasks'][0] == "Task 3" assert _global_memory['tasks'][2] == "Task 1" -def test_emit_research_subtask(reset_memory): - """Test emitting research subtasks""" +def test_request_research_subtask(reset_memory): + """Test requesting research subtasks""" # Test adding a research subtask subtask = "Research Python async patterns" - result = emit_research_subtask(subtask) + result = request_research_subtask(subtask) # Verify return message assert result == "Subtask added."