include environment information in prompts
This commit is contained in:
parent
f1a33fc1c0
commit
c323098aec
|
|
@ -63,6 +63,8 @@ from ra_aid.database.repositories.config_repository import (
|
|||
ConfigRepositoryManager,
|
||||
get_config_repository
|
||||
)
|
||||
from ra_aid.env_inv import EnvDiscovery
|
||||
from ra_aid.env_inv_context import EnvInvManager, get_env_inv
|
||||
from ra_aid.model_formatters import format_key_facts_dict
|
||||
from ra_aid.model_formatters.key_snippets_formatter import format_key_snippets_dict
|
||||
from ra_aid.console.output import cpm
|
||||
|
|
@ -506,13 +508,19 @@ def main():
|
|||
config = {}
|
||||
|
||||
# Initialize repositories with database connection
|
||||
# Create environment inventory data
|
||||
env_discovery = EnvDiscovery()
|
||||
env_discovery.discover()
|
||||
env_data = env_discovery.format_markdown()
|
||||
|
||||
with KeyFactRepositoryManager(db) as key_fact_repo, \
|
||||
KeySnippetRepositoryManager(db) as key_snippet_repo, \
|
||||
HumanInputRepositoryManager(db) as human_input_repo, \
|
||||
ResearchNoteRepositoryManager(db) as research_note_repo, \
|
||||
RelatedFilesRepositoryManager() as related_files_repo, \
|
||||
WorkLogRepositoryManager() as work_log_repo, \
|
||||
ConfigRepositoryManager(config) as config_repo:
|
||||
ConfigRepositoryManager(config) as config_repo, \
|
||||
EnvInvManager(env_data) as env_inv:
|
||||
# This initializes all repositories and makes them available via their respective get methods
|
||||
logger.debug("Initialized KeyFactRepository")
|
||||
logger.debug("Initialized KeySnippetRepository")
|
||||
|
|
@ -521,6 +529,7 @@ def main():
|
|||
logger.debug("Initialized RelatedFilesRepository")
|
||||
logger.debug("Initialized WorkLogRepository")
|
||||
logger.debug("Initialized ConfigRepository")
|
||||
logger.debug("Initialized Environment Inventory")
|
||||
|
||||
# Check dependencies before proceeding
|
||||
check_dependencies()
|
||||
|
|
@ -671,6 +680,7 @@ def main():
|
|||
key_facts=format_key_facts_dict(get_key_fact_repository().get_facts_dict()),
|
||||
key_snippets=format_key_snippets_dict(get_key_snippet_repository().get_snippets_dict()),
|
||||
project_info=formatted_project_info,
|
||||
env_inv=get_env_inv(),
|
||||
),
|
||||
config,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ from ra_aid.tools.memory import (
|
|||
log_work_event,
|
||||
)
|
||||
from ra_aid.database.repositories.config_repository import get_config_repository
|
||||
from ra_aid.env_inv_context import get_env_inv
|
||||
|
||||
console = Console()
|
||||
|
||||
|
|
@ -422,6 +423,8 @@ def run_research_agent(
|
|||
logger.warning(f"Failed to get project info: {e}")
|
||||
formatted_project_info = ""
|
||||
|
||||
# Get environment inventory information
|
||||
|
||||
prompt = (RESEARCH_ONLY_PROMPT if research_only else RESEARCH_PROMPT).format(
|
||||
current_date=current_date,
|
||||
working_directory=working_directory,
|
||||
|
|
@ -440,6 +443,7 @@ def run_research_agent(
|
|||
related_files=related_files,
|
||||
project_info=formatted_project_info,
|
||||
new_project_hints=NEW_PROJECT_HINTS if project_info.is_new else "",
|
||||
env_inv=get_env_inv(),
|
||||
)
|
||||
|
||||
config = get_config_repository().get_all() if not config else config
|
||||
|
|
@ -562,6 +566,8 @@ def run_web_research_agent(
|
|||
current_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
working_directory = os.getcwd()
|
||||
|
||||
# Get environment inventory information
|
||||
|
||||
prompt = WEB_RESEARCH_PROMPT.format(
|
||||
current_date=current_date,
|
||||
working_directory=working_directory,
|
||||
|
|
@ -572,6 +578,7 @@ def run_web_research_agent(
|
|||
work_log=get_work_log_repository().format_work_log(),
|
||||
key_snippets=key_snippets,
|
||||
related_files=related_files,
|
||||
env_inv=get_env_inv(),
|
||||
)
|
||||
|
||||
config = get_config_repository().get_all() if not config else config
|
||||
|
|
@ -688,6 +695,8 @@ def run_planning_agent(
|
|||
logger.error(f"Failed to access research note repository: {str(e)}")
|
||||
formatted_research_notes = ""
|
||||
|
||||
# Get environment inventory information
|
||||
|
||||
planning_prompt = PLANNING_PROMPT.format(
|
||||
current_date=current_date,
|
||||
working_directory=working_directory,
|
||||
|
|
@ -706,6 +715,7 @@ def run_planning_agent(
|
|||
if config.get("research_only")
|
||||
else " Only request implementation if the user explicitly asked for changes to be made."
|
||||
),
|
||||
env_inv=get_env_inv(),
|
||||
)
|
||||
|
||||
config = get_config_repository().get_all() if not config else config
|
||||
|
|
@ -808,6 +818,8 @@ def run_task_implementation_agent(
|
|||
logger.error(f"Failed to access research note repository: {str(e)}")
|
||||
formatted_research_notes = ""
|
||||
|
||||
# Get environment inventory information
|
||||
|
||||
prompt = IMPLEMENTATION_PROMPT.format(
|
||||
current_date=current_date,
|
||||
working_directory=working_directory,
|
||||
|
|
@ -831,6 +843,7 @@ def run_task_implementation_agent(
|
|||
if config.get("web_research_enabled")
|
||||
else ""
|
||||
),
|
||||
env_inv=get_env_inv(),
|
||||
)
|
||||
|
||||
config = get_config_repository().get_all() if not config else config
|
||||
|
|
@ -991,78 +1004,6 @@ def _handle_fallback_response(
|
|||
msg_list.extend(msg_list_response)
|
||||
|
||||
|
||||
# def _run_agent_stream(agent: RAgents, msg_list: list[BaseMessage], config: dict):
|
||||
# for chunk in agent.stream({"messages": msg_list}, config):
|
||||
# logger.debug("Agent output: %s", chunk)
|
||||
# check_interrupt()
|
||||
# agent_type = get_agent_type(agent)
|
||||
# print_agent_output(chunk, agent_type)
|
||||
# if is_completed() or should_exit():
|
||||
# reset_completion_flags()
|
||||
# break
|
||||
# def _run_agent_stream(agent: RAgents, msg_list: list[BaseMessage], config: dict):
|
||||
# while True: ## WE NEED TO ONLY KEEP ITERATING IF IT IS AN INTERRUPT, NOT UNCONDITIONALLY
|
||||
# stream = agent.stream({"messages": msg_list}, config)
|
||||
# for chunk in stream:
|
||||
# logger.debug("Agent output: %s", chunk)
|
||||
# check_interrupt()
|
||||
# agent_type = get_agent_type(agent)
|
||||
# print_agent_output(chunk, agent_type)
|
||||
# if is_completed() or should_exit():
|
||||
# reset_completion_flags()
|
||||
# return True
|
||||
# print("HERE!")
|
||||
|
||||
# def _run_agent_stream(agent: RAgents, msg_list: list[BaseMessage], config: dict):
|
||||
# while True:
|
||||
# for chunk in agent.stream({"messages": msg_list}, config):
|
||||
# print("Chunk received:", chunk)
|
||||
# check_interrupt()
|
||||
# agent_type = get_agent_type(agent)
|
||||
# print_agent_output(chunk, agent_type)
|
||||
# if is_completed() or should_exit():
|
||||
# reset_completion_flags()
|
||||
# return True
|
||||
# print("HERE!")
|
||||
# print("Config passed to _run_agent_stream:", config)
|
||||
# print("Config keys:", list(config.keys()))
|
||||
|
||||
# # Ensure the configuration for state retrieval contains a 'configurable' key.
|
||||
# state_config = config.copy()
|
||||
# if "configurable" not in state_config:
|
||||
# print("Key 'configurable' not found in config. Adding it as an empty dict.")
|
||||
# state_config["configurable"] = {}
|
||||
# print("Using state_config for agent.get_state():", state_config)
|
||||
|
||||
# try:
|
||||
# state = agent.get_state(state_config)
|
||||
# print("Agent state retrieved:", state)
|
||||
# print("State type:", type(state))
|
||||
# print("State attributes:", dir(state))
|
||||
# except Exception as e:
|
||||
# print("Error retrieving agent state with state_config", state_config, ":", e)
|
||||
# raise
|
||||
|
||||
# # Since state.current is not available, we rely solely on state.next.
|
||||
# try:
|
||||
# next_node = state.next
|
||||
# print("State next value:", next_node)
|
||||
# except Exception as e:
|
||||
# print("Error accessing state.next:", e)
|
||||
# next_node = None
|
||||
|
||||
# # Resume execution if state.next is truthy (indicating further steps remain).
|
||||
# if next_node:
|
||||
# print("Resuming execution because state.next is nonempty:", next_node)
|
||||
# agent.invoke(None, config)
|
||||
# continue
|
||||
# else:
|
||||
# print("No further steps indicated; breaking out of loop.")
|
||||
# break
|
||||
|
||||
# return True
|
||||
|
||||
|
||||
def _run_agent_stream(agent: RAgents, msg_list: list[BaseMessage], config: dict):
|
||||
"""
|
||||
Streams agent output while handling completion and interruption.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
"""
|
||||
Context management for environment inventory.
|
||||
|
||||
This module provides thread-safe access to environment inventory information
|
||||
using context variables.
|
||||
"""
|
||||
|
||||
import contextvars
|
||||
from typing import Dict, Any, Optional, Type
|
||||
|
||||
# Create contextvar to hold the environment inventory
|
||||
env_inv_var = contextvars.ContextVar("env_inv", default=None)
|
||||
|
||||
|
||||
class EnvInvManager:
|
||||
"""
|
||||
Context manager for environment inventory.
|
||||
|
||||
This class provides a context manager interface for environment inventory,
|
||||
using the contextvars approach for thread safety.
|
||||
|
||||
Example:
|
||||
from ra_aid.env_inv import EnvDiscovery
|
||||
|
||||
# Get environment inventory
|
||||
env_discovery = EnvDiscovery()
|
||||
env_discovery.discover()
|
||||
env_data = env_discovery.format_markdown()
|
||||
|
||||
# Set as current environment inventory
|
||||
with EnvInvManager(env_data) as env_mgr:
|
||||
# Environment inventory is now available through get_env_inv()
|
||||
pass
|
||||
"""
|
||||
|
||||
def __init__(self, env_data: Dict[str, Any]):
|
||||
"""
|
||||
Initialize the EnvInvManager.
|
||||
|
||||
Args:
|
||||
env_data: Dictionary containing environment inventory data
|
||||
"""
|
||||
self.env_data = env_data
|
||||
|
||||
def __enter__(self) -> 'EnvInvManager':
|
||||
"""
|
||||
Set the environment inventory and return self.
|
||||
|
||||
Returns:
|
||||
EnvInvManager: The initialized manager
|
||||
"""
|
||||
env_inv_var.set(self.env_data)
|
||||
return self
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: Optional[Type[BaseException]],
|
||||
exc_val: Optional[BaseException],
|
||||
exc_tb: Optional[object],
|
||||
) -> None:
|
||||
"""
|
||||
Reset the environment inventory when exiting the context.
|
||||
|
||||
Args:
|
||||
exc_type: The exception type if an exception was raised
|
||||
exc_val: The exception value if an exception was raised
|
||||
exc_tb: The traceback if an exception was raised
|
||||
"""
|
||||
# Reset the contextvar to None
|
||||
env_inv_var.set(None)
|
||||
|
||||
# Don't suppress exceptions
|
||||
return False
|
||||
|
||||
|
||||
def get_env_inv() -> Dict[str, Any]:
|
||||
"""
|
||||
Get the current environment inventory.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: The current environment inventory
|
||||
|
||||
Raises:
|
||||
RuntimeError: If no environment inventory has been initialized with EnvInvManager
|
||||
"""
|
||||
env_data = env_inv_var.get()
|
||||
if env_data is None:
|
||||
raise RuntimeError(
|
||||
"No environment inventory available. "
|
||||
"Make sure to initialize one with EnvInvManager first."
|
||||
)
|
||||
return env_data
|
||||
|
|
@ -23,6 +23,9 @@ Current Date: {current_date}
|
|||
Project Info:
|
||||
{project_info}
|
||||
|
||||
Environment Info:
|
||||
{env_inv}
|
||||
|
||||
Agentic Chat Mode Instructions:
|
||||
|
||||
Overview:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,16 @@ Working Directory: {working_directory}
|
|||
{research_notes}
|
||||
</research notes>
|
||||
|
||||
<environment inventory>
|
||||
{env_inv}
|
||||
</environment inventory>
|
||||
|
||||
MAKE USE OF THE ENVIRONMENT INVENTRY TO GET YOUR WORK DONE AS EFFICIENTLY AND ACCURATELY AS POSSIBLE
|
||||
|
||||
E.G. IF WE ARE USING A LIBRARY AND IT IS FOUND IN ENV INVENTORY, ADD THE INCLUDE/LINKER FLAGS TO YOUR MAKEFILE/CMAKELISTS/COMPILATION COMMAND/ETC.
|
||||
|
||||
YOU MUST **EXPLICITLY** INCLUDE ANY PATHS FROM THE ABOVE INFO IF NEEDED. IT IS NOT AUTOMATIC.
|
||||
|
||||
Important Notes:
|
||||
- Focus solely on the given task and implement it as described.
|
||||
- Scale the complexity of your solution to the complexity of the request. For simple requests, keep it straightforward and minimal. For complex requests, maintain the previously planned depth.
|
||||
|
|
|
|||
|
|
@ -11,30 +11,37 @@ from ra_aid.prompts.web_research_prompts import WEB_RESEARCH_PROMPT_SECTION_PLAN
|
|||
PLANNING_PROMPT = """Current Date: {current_date}
|
||||
Working Directory: {working_directory}
|
||||
|
||||
<base task>
|
||||
{base_task}
|
||||
<base task>
|
||||
|
||||
KEEP IT SIMPLE
|
||||
|
||||
Project Info:
|
||||
<project info>
|
||||
{project_info}
|
||||
</project info>
|
||||
|
||||
Research Notes:
|
||||
<notes>
|
||||
<research notes>
|
||||
{research_notes}
|
||||
</notes>
|
||||
</research notes>
|
||||
|
||||
Relevant Files:
|
||||
{related_files}
|
||||
|
||||
Key Facts:
|
||||
<key facts>
|
||||
{key_facts}
|
||||
</key facts>
|
||||
|
||||
Key Snippets:
|
||||
<key snippets>
|
||||
{key_snippets}
|
||||
</key snippets>
|
||||
|
||||
<environment inventory>
|
||||
{env_inv}
|
||||
</environment inventory>
|
||||
|
||||
MAKE USE OF THE ENVIRONMENT INVENTRY TO GET YOUR WORK DONE AS EFFICIENTLY AND ACCURATELY AS POSSIBLE
|
||||
|
||||
E.G. IF WE ARE USING A LIBRARY AND IT IS FOUND IN ENV INVENTORY, ADD THE INCLUDE/LINKER FLAGS TO YOUR MAKEFILE/CMAKELISTS/COMPILATION COMMAND/
|
||||
ETC.
|
||||
|
||||
YOU MUST **EXPLICITLY** INCLUDE ANY PATHS FROM THE ABOVE INFO IF NEEDED. IT IS NOT AUTOMATIC.
|
||||
|
||||
Work done so far:
|
||||
|
||||
<work log>
|
||||
{work_log}
|
||||
</work log>
|
||||
|
|
@ -78,6 +85,12 @@ You have often been criticized for:
|
|||
- Asking the user if they want to implement the plan (you are an *autonomous* agent, with no user interaction unless you use the ask_human tool explicitly).
|
||||
- Not calling tools/functions properly, e.g. leaving off required arguments, calling a tool in a loop, calling tools inappropriately.
|
||||
|
||||
<base task>
|
||||
{base_task}
|
||||
<base task>
|
||||
|
||||
YOU MUST FOCUS ON THIS BASE TASK. IT TAKES PRECEDENT OVER EVERYTHING ELSE.
|
||||
|
||||
DO NOT WRITE ANY FILES YET. CODE WILL BE WRITTEN AS YOU CALL request_task_implementation.
|
||||
|
||||
DO NOT USE run_shell_command TO WRITE ANY FILE CONTENTS! USE request_task_implementation.
|
||||
|
|
|
|||
|
|
@ -36,10 +36,22 @@ Work already done:
|
|||
<project info>
|
||||
{project_info}
|
||||
</project info>
|
||||
|
||||
<caveat>You should make the most efficient use of this previous research possible, with the caveat that not all of it will be relevant to the current task you are assigned with. Use this previous research to save redudant research, and to inform what you are currently tasked with. Be as efficient as possible.</caveat>
|
||||
</previous research>
|
||||
|
||||
Role
|
||||
<environment inventory>
|
||||
{env_inv}
|
||||
</environment inventory>
|
||||
|
||||
MAKE USE OF THE ENVIRONMENT INVENTRY TO GET YOUR WORK DONE AS EFFICIENTLY AND ACCURATELY AS POSSIBLE
|
||||
|
||||
E.G. IF WE ARE USING A LIBRARY AND IT IS FOUND IN ENV INVENTORY, ADD THE INCLUDE/LINKER FLAGS TO YOUR MAKEFILE/CMAKELISTS/COMPILATION COMMAND/
|
||||
ETC.
|
||||
|
||||
YOU MUST **EXPLICITLY** INCLUDE ANY PATHS FROM THE ABOVE INFO IF NEEDED. IT IS NOT AUTOMATIC.
|
||||
|
||||
Role:
|
||||
|
||||
You are an autonomous research agent focused solely on enumerating and describing the current codebase and its related files. You are not a planner, not an implementer, and not a chatbot for general problem solving. You will not propose solutions, improvements, or modifications.
|
||||
|
||||
|
|
|
|||
|
|
@ -100,5 +100,9 @@ Present well-structured responses that:
|
|||
<related_files>
|
||||
{related_files}
|
||||
</related_files>
|
||||
|
||||
<environment inventory>
|
||||
{env_inv}
|
||||
</environment inventory>
|
||||
</context>
|
||||
"""
|
||||
Loading…
Reference in New Issue