mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
[Feat]: Trigger microagents on agent keywords (#7516)
This commit is contained in:
@@ -479,8 +479,18 @@ class AgentController:
|
||||
|
||||
if self.get_agent_state() != AgentState.RUNNING:
|
||||
await self.set_agent_state_to(AgentState.RUNNING)
|
||||
elif action.source == EventSource.AGENT and action.wait_for_response:
|
||||
await self.set_agent_state_to(AgentState.AWAITING_USER_INPUT)
|
||||
elif action.source == EventSource.AGENT:
|
||||
# Check if we need to trigger microagents based on agent message content
|
||||
recall_action = RecallAction(
|
||||
query=action.content, recall_type=RecallType.KNOWLEDGE
|
||||
)
|
||||
self._pending_action = recall_action
|
||||
# This is source=AGENT because the agent message is the trigger for the microagent retrieval
|
||||
self.event_stream.add_event(recall_action, EventSource.AGENT)
|
||||
|
||||
# If the agent is waiting for a response, set the appropriate state
|
||||
if action.wait_for_response:
|
||||
await self.set_agent_state_to(AgentState.AWAITING_USER_INPUT)
|
||||
|
||||
def _reset(self) -> None:
|
||||
"""Resets the agent controller."""
|
||||
|
||||
@@ -98,11 +98,14 @@ class Memory:
|
||||
return
|
||||
|
||||
# Handle knowledge recall (triggered microagents)
|
||||
# Allow triggering from both user and agent messages
|
||||
elif (
|
||||
event.source == EventSource.USER
|
||||
and event.recall_type == RecallType.KNOWLEDGE
|
||||
):
|
||||
logger.debug('Microagent knowledge recall')
|
||||
or event.source == EventSource.AGENT
|
||||
) and event.recall_type == RecallType.KNOWLEDGE:
|
||||
logger.debug(
|
||||
f'Microagent knowledge recall from {event.source} message'
|
||||
)
|
||||
microagent_obs: RecallObservation | NullObservation | None = None
|
||||
microagent_obs = self._on_microagent_recall(event)
|
||||
if microagent_obs is None:
|
||||
|
||||
@@ -261,3 +261,61 @@ REPOSITORY INSTRUCTIONS: This is a test repository.
|
||||
|
||||
# Clean up
|
||||
os.remove(os.path.join(prompt_dir, 'micro', f'{repo_microagent_name}.md'))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_memory_with_agent_microagents():
|
||||
"""
|
||||
Test that Memory processes microagent based on trigger words from agent messages.
|
||||
"""
|
||||
# Create a mock event stream
|
||||
event_stream = MagicMock(spec=EventStream)
|
||||
|
||||
# Initialize Memory to use the global microagents dir
|
||||
memory = Memory(
|
||||
event_stream=event_stream,
|
||||
sid='test-session',
|
||||
)
|
||||
|
||||
# Verify microagents were loaded - at least one microagent should be loaded
|
||||
# from the global directory that's in the repo
|
||||
assert len(memory.knowledge_microagents) > 0
|
||||
|
||||
# We know 'flarglebargle' exists in the global directory
|
||||
assert 'flarglebargle' in memory.knowledge_microagents
|
||||
|
||||
# Create a microagent action with the trigger word
|
||||
microagent_action = RecallAction(
|
||||
query='Hello, flarglebargle!', recall_type=RecallType.KNOWLEDGE
|
||||
)
|
||||
|
||||
# Set the source to AGENT
|
||||
microagent_action._source = EventSource.AGENT # type: ignore[attr-defined]
|
||||
|
||||
# Mock the event_stream.add_event method
|
||||
added_events = []
|
||||
|
||||
def original_add_event(event, source):
|
||||
added_events.append((event, source))
|
||||
|
||||
event_stream.add_event = original_add_event
|
||||
|
||||
# Add the microagent action to the event stream
|
||||
event_stream.add_event(microagent_action, EventSource.AGENT)
|
||||
|
||||
# Clear the events list to only capture new events
|
||||
added_events.clear()
|
||||
|
||||
# Process the microagent action
|
||||
await memory._on_event(microagent_action)
|
||||
|
||||
# Verify a RecallObservation was added to the event stream
|
||||
assert len(added_events) == 1
|
||||
observation, source = added_events[0]
|
||||
assert isinstance(observation, RecallObservation)
|
||||
assert source == EventSource.ENVIRONMENT
|
||||
assert observation.recall_type == RecallType.KNOWLEDGE
|
||||
assert len(observation.microagent_knowledge) == 1
|
||||
assert observation.microagent_knowledge[0].name == 'flarglebargle'
|
||||
assert observation.microagent_knowledge[0].trigger == 'flarglebargle'
|
||||
assert 'magic word' in observation.microagent_knowledge[0].content
|
||||
|
||||
Reference in New Issue
Block a user