Fix issue #4931: Make use of microagents configurable in codeact_agent (#4932)

Co-authored-by: Graham Neubig <neubig@gmail.com>
This commit is contained in:
OpenHands 2024-11-12 10:42:13 -05:00 committed by GitHub
parent 0633a99298
commit b54724ac3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 79 additions and 4 deletions

View File

@ -103,15 +103,17 @@ class CodeActAgent(Agent):
f'TOOLS loaded for CodeActAgent: {json.dumps(self.tools, indent=2)}'
)
self.prompt_manager = PromptManager(
microagent_dir=os.path.join(os.path.dirname(__file__), 'micro'),
microagent_dir=os.path.join(os.path.dirname(__file__), 'micro') if self.config.use_microagents else None,
prompt_dir=os.path.join(os.path.dirname(__file__), 'prompts', 'tools'),
disabled_microagents=self.config.disabled_microagents,
)
else:
self.action_parser = CodeActResponseParser()
self.prompt_manager = PromptManager(
microagent_dir=os.path.join(os.path.dirname(__file__), 'micro'),
microagent_dir=os.path.join(os.path.dirname(__file__), 'micro') if self.config.use_microagents else None,
prompt_dir=os.path.join(os.path.dirname(__file__), 'prompts', 'default'),
agent_skills_docs=AgentSkillsRequirement.documentation,
disabled_microagents=self.config.disabled_microagents,
)
self.pending_actions: deque[Action] = deque()

View File

@ -16,6 +16,8 @@ class AgentConfig:
memory_enabled: Whether long-term memory (embeddings) is enabled.
memory_max_threads: The maximum number of threads indexing at the same time for embeddings.
llm_config: The name of the llm config to use. If specified, this will override global llm config.
use_microagents: Whether to use microagents at all. Default is True.
disabled_microagents: A list of microagents to disable. Default is None.
"""
function_calling: bool = True
@ -26,6 +28,8 @@ class AgentConfig:
memory_enabled: bool = False
memory_max_threads: int = 3
llm_config: str | None = None
use_microagents: bool = True
disabled_microagents: list[str] | None = None
def defaults_to_dict(self) -> dict:
"""Serialize fields to a dict for the frontend, including type hints, defaults, and whether it's optional."""

View File

@ -19,13 +19,16 @@ class PromptManager:
Attributes:
prompt_dir (str): Directory containing prompt templates.
agent_skills_docs (str): Documentation of agent skills.
microagent_dir (str): Directory containing microagent specifications.
disabled_microagents (list[str] | None): List of microagents to disable. If None, all microagents are enabled.
"""
def __init__(
self,
prompt_dir: str,
microagent_dir: str = '',
microagent_dir: str | None = None,
agent_skills_docs: str = '',
disabled_microagents: list[str] | None = None,
):
self.prompt_dir: str = prompt_dir
self.agent_skills_docs: str = agent_skills_docs
@ -43,9 +46,15 @@ class PromptManager:
]
for microagent_file in microagent_files:
microagent = MicroAgent(microagent_file)
self.microagents[microagent.name] = microagent
if (
disabled_microagents is None
or microagent.name not in disabled_microagents
):
self.microagents[microagent.name] = microagent
def _load_template(self, template_name: str) -> Template:
if self.prompt_dir is None:
raise ValueError('Prompt directory is not set')
template_path = os.path.join(self.prompt_dir, f'{template_name}.j2')
if not os.path.exists(template_path):
raise FileNotFoundError(f'Prompt file {template_path} not found')

View File

@ -119,3 +119,63 @@ def test_prompt_manager_template_rendering(prompt_dir, agent_skills_docs):
# Clean up temporary files
os.remove(os.path.join(prompt_dir, 'system_prompt.j2'))
os.remove(os.path.join(prompt_dir, 'user_prompt.j2'))
def test_prompt_manager_disabled_microagents(prompt_dir, agent_skills_docs):
# Create test microagent files
microagent1_name = 'test_microagent1'
microagent2_name = 'test_microagent2'
microagent1_content = """
---
name: Test Microagent 1
agent: CodeActAgent
triggers:
- test1
---
Test microagent 1 content
"""
microagent2_content = """
---
name: Test Microagent 2
agent: CodeActAgent
triggers:
- test2
---
Test microagent 2 content
"""
# Create temporary micro agent files
os.makedirs(os.path.join(prompt_dir, 'micro'), exist_ok=True)
with open(os.path.join(prompt_dir, 'micro', f'{microagent1_name}.md'), 'w') as f:
f.write(microagent1_content)
with open(os.path.join(prompt_dir, 'micro', f'{microagent2_name}.md'), 'w') as f:
f.write(microagent2_content)
# Test that specific microagents can be disabled
manager = PromptManager(
prompt_dir=prompt_dir,
microagent_dir=os.path.join(prompt_dir, 'micro'),
agent_skills_docs=agent_skills_docs,
disabled_microagents=['Test Microagent 1'],
)
assert len(manager.microagents) == 1
assert 'Test Microagent 2' in manager.microagents
assert 'Test Microagent 1' not in manager.microagents
# Test that all microagents are enabled by default
manager = PromptManager(
prompt_dir=prompt_dir,
microagent_dir=os.path.join(prompt_dir, 'micro'),
agent_skills_docs=agent_skills_docs,
)
assert len(manager.microagents) == 2
assert 'Test Microagent 1' in manager.microagents
assert 'Test Microagent 2' in manager.microagents
# Clean up temporary files
os.remove(os.path.join(prompt_dir, 'micro', f'{microagent1_name}.md'))
os.remove(os.path.join(prompt_dir, 'micro', f'{microagent2_name}.md'))