mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
CoderAgent: Render summary prompt conditionally (#1461)
* CoderAgent: Render repo summary conditionally * Add unittests --------- Co-authored-by: Robert Brennan <accounts@rbren.io>
This commit is contained in:
parent
c50319138e
commit
c7dd443fa2
14
agenthub/micro/README.md
Normal file
14
agenthub/micro/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
## Introduction
|
||||
|
||||
This package contains definitions of micro-agents. A micro-agent is defined
|
||||
in the following structure:
|
||||
|
||||
```
|
||||
[AgentName]
|
||||
├── agent.yaml
|
||||
└── prompt.md
|
||||
```
|
||||
|
||||
Note that `prompt.md` could use jinja2 template syntax. During runtime, `prompt.md`
|
||||
is loaded and rendered, and used together with `agent.yaml` to initialize a
|
||||
micro-agent.
|
||||
@ -4,9 +4,11 @@ need to modify to complete this task:
|
||||
|
||||
{{ state.plan.main_goal }}
|
||||
|
||||
{% if state.inputs.summary %}
|
||||
Here's a summary of the codebase, as it relates to this task:
|
||||
|
||||
{{ state.inputs.summary }}
|
||||
{% endif %}
|
||||
|
||||
## Available Actions
|
||||
{{ instructions.actions.run }}
|
||||
|
||||
74
tests/unit/test_micro_agents.py
Normal file
74
tests/unit/test_micro_agents.py
Normal file
@ -0,0 +1,74 @@
|
||||
import json
|
||||
import os
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import yaml
|
||||
|
||||
from agenthub.micro.registry import all_microagents
|
||||
from opendevin.agent import Agent
|
||||
from opendevin.plan import Plan
|
||||
from opendevin.state import State
|
||||
|
||||
|
||||
def test_all_agents_are_loaded():
|
||||
full_path = os.path.join('agenthub', 'micro')
|
||||
agent_names = set()
|
||||
for root, _, files in os.walk(full_path):
|
||||
for file in files:
|
||||
if file == 'agent.yaml':
|
||||
file_path = os.path.join(root, file)
|
||||
with open(file_path, 'r') as yaml_file:
|
||||
data = yaml.safe_load(yaml_file)
|
||||
agent_names.add(data['name'])
|
||||
assert agent_names == set(all_microagents.keys())
|
||||
|
||||
|
||||
def test_coder_agent_with_summary():
|
||||
"""
|
||||
Coder agent should render code summary as part of prompt
|
||||
"""
|
||||
mock_llm = MagicMock()
|
||||
content = json.dumps({'action': 'finish', 'args': {}})
|
||||
mock_llm.completion.return_value = {
|
||||
'choices': [{'message': {'content': content}}]
|
||||
}
|
||||
|
||||
coder_agent = Agent.get_cls('CoderAgent')(llm=mock_llm)
|
||||
assert coder_agent is not None
|
||||
task = 'This is a dummy task'
|
||||
plan = Plan(task)
|
||||
summary = 'This is a dummy summary about this repo'
|
||||
state = State(plan, inputs={'summary': summary})
|
||||
coder_agent.step(state)
|
||||
|
||||
mock_llm.completion.assert_called_once()
|
||||
_, kwargs = mock_llm.completion.call_args
|
||||
prompt = kwargs['messages'][0]['content']
|
||||
assert task in prompt
|
||||
assert "Here's a summary of the codebase, as it relates to this task" in prompt
|
||||
assert summary in prompt
|
||||
|
||||
|
||||
def test_coder_agent_without_summary():
|
||||
"""
|
||||
When there's no codebase_summary available, there shouldn't be any prompt
|
||||
about 'code summary'
|
||||
"""
|
||||
mock_llm = MagicMock()
|
||||
content = json.dumps({'action': 'finish', 'args': {}})
|
||||
mock_llm.completion.return_value = {
|
||||
'choices': [{'message': {'content': content}}]
|
||||
}
|
||||
|
||||
coder_agent = Agent.get_cls('CoderAgent')(llm=mock_llm)
|
||||
assert coder_agent is not None
|
||||
task = 'This is a dummy task'
|
||||
plan = Plan(task)
|
||||
state = State(plan)
|
||||
coder_agent.step(state)
|
||||
|
||||
mock_llm.completion.assert_called_once()
|
||||
_, kwargs = mock_llm.completion.call_args
|
||||
prompt = kwargs['messages'][0]['content']
|
||||
assert task in prompt
|
||||
assert "Here's a summary of the codebase, as it relates to this task" not in prompt
|
||||
Loading…
x
Reference in New Issue
Block a user