mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
fix occurrences of MicroAgent to the standard "Microagent" (#7791)
This commit is contained in:
parent
7910a90522
commit
d924e7cea5
@ -21,8 +21,8 @@ OpenHandsがリポジトリで動作する際:
|
||||
```
|
||||
---
|
||||
name: <Microagentの名前>
|
||||
type: <MicroAgentのタイプ>
|
||||
version: <MicroAgentのバージョン>
|
||||
type: <Microagentのタイプ>
|
||||
version: <Microagentのバージョン>
|
||||
agent: <エージェントのタイプ (通常はCodeActAgent)>
|
||||
triggers:
|
||||
- <オプション: microagentをトリガーするキーワード。トリガーを削除すると、常に含まれるようになります>
|
||||
|
||||
@ -21,8 +21,8 @@ Todos os microagentes usam arquivos markdown com frontmatter YAML que possuem in
|
||||
```
|
||||
---
|
||||
name: <Nome do microagente>
|
||||
type: <Tipo do MicroAgent>
|
||||
version: <Versão do MicroAgent>
|
||||
type: <Tipo do Microagent>
|
||||
version: <Versão do Microagent>
|
||||
agent: <O tipo de agente (normalmente CodeActAgent)>
|
||||
triggers:
|
||||
- <Palavras-chave opcionais que acionam o microagente. Se os gatilhos forem removidos, ele sempre será incluído>
|
||||
|
||||
@ -4961,19 +4961,19 @@
|
||||
"tr": "Gezinme tamamlandı"
|
||||
},
|
||||
"OBSERVATION_MESSAGE$RECALL": {
|
||||
"en": "MicroAgent Activated",
|
||||
"en": "Microagent Activated",
|
||||
"ja": "マイクロエージェントが有効化されました",
|
||||
"zh-CN": "微代理已激活",
|
||||
"zh-TW": "微代理已啟動",
|
||||
"ko-KR": "마이크로에이전트 활성화됨",
|
||||
"no": "MikroAgent aktivert",
|
||||
"it": "MicroAgent attivato",
|
||||
"pt": "MicroAgent ativado",
|
||||
"es": "MicroAgent activado",
|
||||
"it": "Microagent attivato",
|
||||
"pt": "Microagent ativado",
|
||||
"es": "Microagent activado",
|
||||
"ar": "تم تنشيط الوكيل المصغر",
|
||||
"fr": "MicroAgent activé",
|
||||
"fr": "Microagent activé",
|
||||
"tr": "MikroAjan Etkinleştirildi",
|
||||
"de": "MicroAgent aktiviert"
|
||||
"de": "Microagent aktiviert"
|
||||
},
|
||||
"EXPANDABLE_MESSAGE$SHOW_DETAILS": {
|
||||
"en": "Show details",
|
||||
@ -6089,4 +6089,4 @@
|
||||
"tr": "belgelendirme",
|
||||
"de": "Dokumentation"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# OpenHands MicroAgents
|
||||
# OpenHands Microagents
|
||||
|
||||
MicroAgents are specialized prompts that enhance OpenHands with domain-specific knowledge and task-specific workflows. They help developers by providing expert guidance, automating common tasks, and ensuring consistent practices across projects. Each microagent is designed to excel in a specific area, from Git operations to code review processes.
|
||||
Microagents are specialized prompts that enhance OpenHands with domain-specific knowledge and task-specific workflows. They help developers by providing expert guidance, automating common tasks, and ensuring consistent practices across projects. Each microagent is designed to excel in a specific area, from Git operations to code review processes.
|
||||
|
||||
## Sources of Microagents
|
||||
|
||||
@ -49,7 +49,7 @@ When OpenHands works with a repository, it:
|
||||
2. Loads relevant knowledge agents based on keywords in conversations
|
||||
3. Enable task agent if user select one of them
|
||||
|
||||
## Types of MicroAgents
|
||||
## Types of Microagents
|
||||
|
||||
Most microagents use markdown files with YAML frontmatter. For repository agents (repo.md), the frontmatter is optional - if not provided, the file will be loaded with default settings as a repository agent.
|
||||
|
||||
|
||||
@ -222,14 +222,14 @@ class BrowserUnavailableException(Exception):
|
||||
# ============================================
|
||||
|
||||
|
||||
class MicroAgentError(Exception):
|
||||
class MicroagentError(Exception):
|
||||
"""Base exception for all microagent errors."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class MicroAgentValidationError(MicroAgentError):
|
||||
class MicroagentValidationError(MicroagentError):
|
||||
"""Raised when there's a validation error in microagent metadata."""
|
||||
|
||||
def __init__(self, message: str = 'Micro agent validation failed') -> None:
|
||||
def __init__(self, message: str = 'Microagent validation failed') -> None:
|
||||
super().__init__(message)
|
||||
|
||||
@ -18,7 +18,7 @@ from openhands.events.event import Event
|
||||
from openhands.integrations.provider import ProviderToken, ProviderType, SecretStore
|
||||
from openhands.llm.llm import LLM
|
||||
from openhands.memory.memory import Memory
|
||||
from openhands.microagent.microagent import BaseMicroAgent
|
||||
from openhands.microagent.microagent import BaseMicroagent
|
||||
from openhands.runtime import get_runtime_cls
|
||||
from openhands.runtime.base import Runtime
|
||||
from openhands.security import SecurityAnalyzer, options
|
||||
@ -160,7 +160,7 @@ def create_memory(
|
||||
memory.set_runtime_info(runtime)
|
||||
|
||||
# loads microagents from repo/.openhands/microagents
|
||||
microagents: list[BaseMicroAgent] = runtime.get_microagents_from_selected_repo(
|
||||
microagents: list[BaseMicroagent] = runtime.get_microagents_from_selected_repo(
|
||||
selected_repository
|
||||
)
|
||||
memory.load_user_workspace_microagents(microagents)
|
||||
|
||||
@ -15,9 +15,9 @@ from openhands.events.observation.agent import (
|
||||
from openhands.events.observation.empty import NullObservation
|
||||
from openhands.events.stream import EventStream, EventStreamSubscriber
|
||||
from openhands.microagent import (
|
||||
BaseMicroAgent,
|
||||
KnowledgeMicroAgent,
|
||||
RepoMicroAgent,
|
||||
BaseMicroagent,
|
||||
KnowledgeMicroagent,
|
||||
RepoMicroagent,
|
||||
load_microagents_from_dir,
|
||||
)
|
||||
from openhands.runtime.base import Runtime
|
||||
@ -58,8 +58,8 @@ class Memory:
|
||||
)
|
||||
|
||||
# Additional placeholders to store user workspace microagents
|
||||
self.repo_microagents: dict[str, RepoMicroAgent] = {}
|
||||
self.knowledge_microagents: dict[str, KnowledgeMicroAgent] = {}
|
||||
self.repo_microagents: dict[str, RepoMicroagent] = {}
|
||||
self.knowledge_microagents: dict[str, KnowledgeMicroagent] = {}
|
||||
|
||||
# Store repository / runtime info to send them to the templating later
|
||||
self.repository_info: RepositoryInfo | None = None
|
||||
@ -229,7 +229,7 @@ class Memory:
|
||||
return recalled_content
|
||||
|
||||
def load_user_workspace_microagents(
|
||||
self, user_microagents: list[BaseMicroAgent]
|
||||
self, user_microagents: list[BaseMicroagent]
|
||||
) -> None:
|
||||
"""
|
||||
This method loads microagents from a user's cloned repo or workspace directory.
|
||||
@ -240,9 +240,9 @@ class Memory:
|
||||
'Loading user workspace microagents: %s', [m.name for m in user_microagents]
|
||||
)
|
||||
for user_microagent in user_microagents:
|
||||
if isinstance(user_microagent, KnowledgeMicroAgent):
|
||||
if isinstance(user_microagent, KnowledgeMicroagent):
|
||||
self.knowledge_microagents[user_microagent.name] = user_microagent
|
||||
elif isinstance(user_microagent, RepoMicroAgent):
|
||||
elif isinstance(user_microagent, RepoMicroagent):
|
||||
self.repo_microagents[user_microagent.name] = user_microagent
|
||||
|
||||
def _load_global_microagents(self) -> None:
|
||||
@ -253,10 +253,10 @@ class Memory:
|
||||
GLOBAL_MICROAGENTS_DIR
|
||||
)
|
||||
for name, agent in knowledge_agents.items():
|
||||
if isinstance(agent, KnowledgeMicroAgent):
|
||||
if isinstance(agent, KnowledgeMicroagent):
|
||||
self.knowledge_microagents[name] = agent
|
||||
for name, agent in repo_agents.items():
|
||||
if isinstance(agent, RepoMicroAgent):
|
||||
if isinstance(agent, RepoMicroagent):
|
||||
self.repo_microagents[name] = agent
|
||||
|
||||
def set_repository_info(self, repo_name: str, repo_directory: str) -> None:
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
from .microagent import (
|
||||
BaseMicroAgent,
|
||||
KnowledgeMicroAgent,
|
||||
RepoMicroAgent,
|
||||
TaskMicroAgent,
|
||||
BaseMicroagent,
|
||||
KnowledgeMicroagent,
|
||||
RepoMicroagent,
|
||||
TaskMicroagent,
|
||||
load_microagents_from_dir,
|
||||
)
|
||||
from .types import MicroAgentMetadata, MicroAgentType, TaskInput
|
||||
from .types import MicroagentMetadata, MicroagentType, TaskInput
|
||||
|
||||
__all__ = [
|
||||
'BaseMicroAgent',
|
||||
'KnowledgeMicroAgent',
|
||||
'RepoMicroAgent',
|
||||
'TaskMicroAgent',
|
||||
'MicroAgentMetadata',
|
||||
'MicroAgentType',
|
||||
'BaseMicroagent',
|
||||
'KnowledgeMicroagent',
|
||||
'RepoMicroagent',
|
||||
'TaskMicroagent',
|
||||
'MicroagentMetadata',
|
||||
'MicroagentType',
|
||||
'TaskInput',
|
||||
'load_microagents_from_dir',
|
||||
]
|
||||
|
||||
@ -6,25 +6,25 @@ import frontmatter
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openhands.core.exceptions import (
|
||||
MicroAgentValidationError,
|
||||
MicroagentValidationError,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.microagent.types import MicroAgentMetadata, MicroAgentType
|
||||
from openhands.microagent.types import MicroagentMetadata, MicroagentType
|
||||
|
||||
|
||||
class BaseMicroAgent(BaseModel):
|
||||
class BaseMicroagent(BaseModel):
|
||||
"""Base class for all microagents."""
|
||||
|
||||
name: str
|
||||
content: str
|
||||
metadata: MicroAgentMetadata
|
||||
metadata: MicroagentMetadata
|
||||
source: str # path to the file
|
||||
type: MicroAgentType
|
||||
type: MicroagentType
|
||||
|
||||
@classmethod
|
||||
def load(
|
||||
cls, path: Union[str, Path], file_content: str | None = None
|
||||
) -> 'BaseMicroAgent':
|
||||
) -> 'BaseMicroagent':
|
||||
"""Load a microagent from a markdown file with frontmatter."""
|
||||
path = Path(path) if isinstance(path, str) else path
|
||||
|
||||
@ -35,12 +35,12 @@ class BaseMicroAgent(BaseModel):
|
||||
|
||||
# Legacy repo instructions are stored in .openhands_instructions
|
||||
if path.name == '.openhands_instructions':
|
||||
return RepoMicroAgent(
|
||||
return RepoMicroagent(
|
||||
name='repo_legacy',
|
||||
content=file_content,
|
||||
metadata=MicroAgentMetadata(name='repo_legacy'),
|
||||
metadata=MicroagentMetadata(name='repo_legacy'),
|
||||
source=str(path),
|
||||
type=MicroAgentType.REPO_KNOWLEDGE,
|
||||
type=MicroagentType.REPO_KNOWLEDGE,
|
||||
)
|
||||
|
||||
file_io = io.StringIO(file_content)
|
||||
@ -51,15 +51,15 @@ class BaseMicroAgent(BaseModel):
|
||||
metadata_dict = loaded.metadata or {}
|
||||
|
||||
try:
|
||||
metadata = MicroAgentMetadata(**metadata_dict)
|
||||
metadata = MicroagentMetadata(**metadata_dict)
|
||||
except Exception as e:
|
||||
raise MicroAgentValidationError(f'Error loading metadata: {e}') from e
|
||||
raise MicroagentValidationError(f'Error loading metadata: {e}') from e
|
||||
|
||||
# Create appropriate subclass based on type
|
||||
subclass_map = {
|
||||
MicroAgentType.KNOWLEDGE: KnowledgeMicroAgent,
|
||||
MicroAgentType.REPO_KNOWLEDGE: RepoMicroAgent,
|
||||
MicroAgentType.TASK: TaskMicroAgent,
|
||||
MicroagentType.KNOWLEDGE: KnowledgeMicroagent,
|
||||
MicroagentType.REPO_KNOWLEDGE: RepoMicroagent,
|
||||
MicroagentType.TASK: TaskMicroagent,
|
||||
}
|
||||
if metadata.type not in subclass_map:
|
||||
raise ValueError(f'Unknown microagent type: {metadata.type}')
|
||||
@ -74,7 +74,7 @@ class BaseMicroAgent(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
class KnowledgeMicroAgent(BaseMicroAgent):
|
||||
class KnowledgeMicroagent(BaseMicroagent):
|
||||
"""Knowledge micro-agents provide specialized expertise that's triggered by keywords in conversations. They help with:
|
||||
- Language best practices
|
||||
- Framework guidelines
|
||||
@ -84,8 +84,8 @@ class KnowledgeMicroAgent(BaseMicroAgent):
|
||||
|
||||
def __init__(self, **data):
|
||||
super().__init__(**data)
|
||||
if self.type != MicroAgentType.KNOWLEDGE:
|
||||
raise ValueError('KnowledgeMicroAgent must have type KNOWLEDGE')
|
||||
if self.type != MicroagentType.KNOWLEDGE:
|
||||
raise ValueError('KnowledgeMicroagent must have type KNOWLEDGE')
|
||||
|
||||
def match_trigger(self, message: str) -> str | None:
|
||||
"""Match a trigger in the message.
|
||||
@ -103,10 +103,10 @@ class KnowledgeMicroAgent(BaseMicroAgent):
|
||||
return self.metadata.triggers
|
||||
|
||||
|
||||
class RepoMicroAgent(BaseMicroAgent):
|
||||
"""MicroAgent specialized for repository-specific knowledge and guidelines.
|
||||
class RepoMicroagent(BaseMicroagent):
|
||||
"""Microagent specialized for repository-specific knowledge and guidelines.
|
||||
|
||||
RepoMicroAgents are loaded from `.openhands/microagents/repo.md` files within repositories
|
||||
RepoMicroagents are loaded from `.openhands/microagents/repo.md` files within repositories
|
||||
and contain private, repository-specific instructions that are automatically loaded when
|
||||
working with that repository. They are ideal for:
|
||||
- Repository-specific guidelines
|
||||
@ -117,23 +117,23 @@ class RepoMicroAgent(BaseMicroAgent):
|
||||
|
||||
def __init__(self, **data):
|
||||
super().__init__(**data)
|
||||
if self.type != MicroAgentType.REPO_KNOWLEDGE:
|
||||
raise ValueError('RepoMicroAgent must have type REPO_KNOWLEDGE')
|
||||
if self.type != MicroagentType.REPO_KNOWLEDGE:
|
||||
raise ValueError('RepoMicroagent must have type REPO_KNOWLEDGE')
|
||||
|
||||
|
||||
class TaskMicroAgent(BaseMicroAgent):
|
||||
"""MicroAgent specialized for task-based operations."""
|
||||
class TaskMicroagent(BaseMicroagent):
|
||||
"""Microagent specialized for task-based operations."""
|
||||
|
||||
def __init__(self, **data):
|
||||
super().__init__(**data)
|
||||
if self.type != MicroAgentType.TASK:
|
||||
raise ValueError('TaskMicroAgent must have type TASK')
|
||||
if self.type != MicroagentType.TASK:
|
||||
raise ValueError('TaskMicroagent must have type TASK')
|
||||
|
||||
|
||||
def load_microagents_from_dir(
|
||||
microagent_dir: Union[str, Path],
|
||||
) -> tuple[
|
||||
dict[str, RepoMicroAgent], dict[str, KnowledgeMicroAgent], dict[str, TaskMicroAgent]
|
||||
dict[str, RepoMicroagent], dict[str, KnowledgeMicroagent], dict[str, TaskMicroagent]
|
||||
]:
|
||||
"""Load all microagents from the given directory.
|
||||
|
||||
@ -161,12 +161,12 @@ def load_microagents_from_dir(
|
||||
if file.name == 'README.md':
|
||||
continue
|
||||
try:
|
||||
agent = BaseMicroAgent.load(file)
|
||||
if isinstance(agent, RepoMicroAgent):
|
||||
agent = BaseMicroagent.load(file)
|
||||
if isinstance(agent, RepoMicroagent):
|
||||
repo_agents[agent.name] = agent
|
||||
elif isinstance(agent, KnowledgeMicroAgent):
|
||||
elif isinstance(agent, KnowledgeMicroagent):
|
||||
knowledge_agents[agent.name] = agent
|
||||
elif isinstance(agent, TaskMicroAgent):
|
||||
elif isinstance(agent, TaskMicroagent):
|
||||
task_agents[agent.name] = agent
|
||||
logger.debug(f'Loaded agent {agent.name} from {file}')
|
||||
except Exception as e:
|
||||
|
||||
@ -3,7 +3,7 @@ from enum import Enum
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class MicroAgentType(str, Enum):
|
||||
class MicroagentType(str, Enum):
|
||||
"""Type of microagent."""
|
||||
|
||||
KNOWLEDGE = 'knowledge'
|
||||
@ -11,11 +11,11 @@ class MicroAgentType(str, Enum):
|
||||
TASK = 'task'
|
||||
|
||||
|
||||
class MicroAgentMetadata(BaseModel):
|
||||
class MicroagentMetadata(BaseModel):
|
||||
"""Metadata for all microagents."""
|
||||
|
||||
name: str = 'default'
|
||||
type: MicroAgentType = Field(default=MicroAgentType.REPO_KNOWLEDGE)
|
||||
type: MicroagentType = Field(default=MicroagentType.REPO_KNOWLEDGE)
|
||||
version: str = Field(default='1.0.0')
|
||||
agent: str = Field(default='CodeActAgent')
|
||||
triggers: list[str] = [] # optional, only exists for knowledge microagents
|
||||
|
||||
@ -50,7 +50,7 @@ from openhands.integrations.provider import (
|
||||
)
|
||||
from openhands.integrations.service_types import Repository
|
||||
from openhands.microagent import (
|
||||
BaseMicroAgent,
|
||||
BaseMicroagent,
|
||||
load_microagents_from_dir,
|
||||
)
|
||||
from openhands.runtime.plugins import (
|
||||
@ -414,13 +414,13 @@ class Runtime(FileEditRuntimeMixin):
|
||||
|
||||
def get_microagents_from_selected_repo(
|
||||
self, selected_repository: str | None
|
||||
) -> list[BaseMicroAgent]:
|
||||
) -> list[BaseMicroagent]:
|
||||
"""Load microagents from the selected repository.
|
||||
If selected_repository is None, load microagents from the current workspace.
|
||||
This is the main entry point for loading microagents.
|
||||
"""
|
||||
|
||||
loaded_microagents: list[BaseMicroAgent] = []
|
||||
loaded_microagents: list[BaseMicroagent] = []
|
||||
workspace_root = Path(self.config.workspace_mount_path_in_sandbox)
|
||||
microagents_dir = workspace_root / '.openhands' / 'microagents'
|
||||
repo_root = None
|
||||
@ -450,7 +450,7 @@ class Runtime(FileEditRuntimeMixin):
|
||||
if isinstance(obs, FileReadObservation):
|
||||
self.log('info', 'openhands_instructions microagent loaded.')
|
||||
loaded_microagents.append(
|
||||
BaseMicroAgent.load(
|
||||
BaseMicroagent.load(
|
||||
path='.openhands_instructions', file_content=obs.content
|
||||
)
|
||||
)
|
||||
|
||||
@ -19,7 +19,7 @@ from openhands.events.stream import EventStream
|
||||
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE, ProviderHandler
|
||||
from openhands.integrations.service_types import Repository
|
||||
from openhands.memory.memory import Memory
|
||||
from openhands.microagent.microagent import BaseMicroAgent
|
||||
from openhands.microagent.microagent import BaseMicroagent
|
||||
from openhands.runtime import get_runtime_cls
|
||||
from openhands.runtime.base import Runtime
|
||||
from openhands.runtime.impl.remote.remote_runtime import RemoteRuntime
|
||||
@ -407,7 +407,7 @@ class AgentSession:
|
||||
memory.set_runtime_info(self.runtime)
|
||||
|
||||
# loads microagents from repo/.openhands/microagents
|
||||
microagents: list[BaseMicroAgent] = await call_sync_from_async(
|
||||
microagents: list[BaseMicroagent] = await call_sync_from_async(
|
||||
self.runtime.get_microagents_from_selected_repo,
|
||||
selected_repository.full_name if selected_repository else None,
|
||||
)
|
||||
|
||||
@ -7,7 +7,7 @@ from conftest import (
|
||||
_load_runtime,
|
||||
)
|
||||
|
||||
from openhands.microagent import KnowledgeMicroAgent, RepoMicroAgent, TaskMicroAgent
|
||||
from openhands.microagent import KnowledgeMicroagent, RepoMicroagent, TaskMicroagent
|
||||
|
||||
|
||||
def _create_test_microagents(test_dir: str):
|
||||
@ -85,10 +85,10 @@ def test_load_microagents_with_trailing_slashes(
|
||||
|
||||
# Verify all agents are loaded
|
||||
knowledge_agents = [
|
||||
a for a in loaded_agents if isinstance(a, KnowledgeMicroAgent)
|
||||
a for a in loaded_agents if isinstance(a, KnowledgeMicroagent)
|
||||
]
|
||||
repo_agents = [a for a in loaded_agents if isinstance(a, RepoMicroAgent)]
|
||||
task_agents = [a for a in loaded_agents if isinstance(a, TaskMicroAgent)]
|
||||
repo_agents = [a for a in loaded_agents if isinstance(a, RepoMicroagent)]
|
||||
task_agents = [a for a in loaded_agents if isinstance(a, TaskMicroagent)]
|
||||
|
||||
# Check knowledge agents
|
||||
assert len(knowledge_agents) == 1
|
||||
@ -128,10 +128,10 @@ def test_load_microagents_with_selected_repo(temp_dir, runtime_cls, run_as_openh
|
||||
|
||||
# Verify all agents are loaded
|
||||
knowledge_agents = [
|
||||
a for a in loaded_agents if isinstance(a, KnowledgeMicroAgent)
|
||||
a for a in loaded_agents if isinstance(a, KnowledgeMicroagent)
|
||||
]
|
||||
repo_agents = [a for a in loaded_agents if isinstance(a, RepoMicroAgent)]
|
||||
task_agents = [a for a in loaded_agents if isinstance(a, TaskMicroAgent)]
|
||||
repo_agents = [a for a in loaded_agents if isinstance(a, RepoMicroagent)]
|
||||
task_agents = [a for a in loaded_agents if isinstance(a, TaskMicroagent)]
|
||||
|
||||
# Check knowledge agents
|
||||
assert len(knowledge_agents) == 1
|
||||
@ -181,10 +181,10 @@ Repository-specific test instructions.
|
||||
|
||||
# Verify only repo agent is loaded
|
||||
knowledge_agents = [
|
||||
a for a in loaded_agents if isinstance(a, KnowledgeMicroAgent)
|
||||
a for a in loaded_agents if isinstance(a, KnowledgeMicroagent)
|
||||
]
|
||||
repo_agents = [a for a in loaded_agents if isinstance(a, RepoMicroAgent)]
|
||||
task_agents = [a for a in loaded_agents if isinstance(a, TaskMicroAgent)]
|
||||
repo_agents = [a for a in loaded_agents if isinstance(a, RepoMicroagent)]
|
||||
task_agents = [a for a in loaded_agents if isinstance(a, TaskMicroagent)]
|
||||
|
||||
assert len(knowledge_agents) == 0
|
||||
assert len(repo_agents) == 1
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from openhands.microagent.microagent import BaseMicroAgent, RepoMicroAgent
|
||||
from openhands.microagent.types import MicroAgentType
|
||||
from openhands.microagent.microagent import BaseMicroagent, RepoMicroagent
|
||||
from openhands.microagent.types import MicroagentType
|
||||
|
||||
|
||||
def test_load_markdown_without_frontmatter():
|
||||
@ -10,13 +10,13 @@ def test_load_markdown_without_frontmatter():
|
||||
path = Path('test.md')
|
||||
|
||||
# Load the agent from content
|
||||
agent = BaseMicroAgent.load(path, content)
|
||||
agent = BaseMicroagent.load(path, content)
|
||||
|
||||
# Verify it's loaded as a repo agent with default values
|
||||
assert isinstance(agent, RepoMicroAgent)
|
||||
assert isinstance(agent, RepoMicroagent)
|
||||
assert agent.name == 'default'
|
||||
assert agent.content == content
|
||||
assert agent.type == MicroAgentType.REPO_KNOWLEDGE
|
||||
assert agent.type == MicroagentType.REPO_KNOWLEDGE
|
||||
assert agent.metadata.agent == 'CodeActAgent'
|
||||
assert agent.metadata.version == '1.0.0'
|
||||
|
||||
@ -29,16 +29,16 @@ def test_load_markdown_with_empty_frontmatter():
|
||||
path = Path('test.md')
|
||||
|
||||
# Load the agent from content
|
||||
agent = BaseMicroAgent.load(path, content)
|
||||
agent = BaseMicroagent.load(path, content)
|
||||
|
||||
# Verify it's loaded as a repo agent with default values
|
||||
assert isinstance(agent, RepoMicroAgent)
|
||||
assert isinstance(agent, RepoMicroagent)
|
||||
assert agent.name == 'default'
|
||||
assert (
|
||||
agent.content
|
||||
== '# Test Content\nThis is a test markdown file with empty frontmatter.'
|
||||
)
|
||||
assert agent.type == MicroAgentType.REPO_KNOWLEDGE
|
||||
assert agent.type == MicroagentType.REPO_KNOWLEDGE
|
||||
assert agent.metadata.agent == 'CodeActAgent'
|
||||
assert agent.metadata.version == '1.0.0'
|
||||
|
||||
@ -53,16 +53,16 @@ This is a test markdown file with partial frontmatter."""
|
||||
path = Path('test.md')
|
||||
|
||||
# Load the agent from content
|
||||
agent = BaseMicroAgent.load(path, content)
|
||||
agent = BaseMicroagent.load(path, content)
|
||||
|
||||
# Verify it uses provided name but default values for other fields
|
||||
assert isinstance(agent, RepoMicroAgent)
|
||||
assert isinstance(agent, RepoMicroagent)
|
||||
assert agent.name == 'custom_name'
|
||||
assert (
|
||||
agent.content
|
||||
== '# Test Content\nThis is a test markdown file with partial frontmatter.'
|
||||
)
|
||||
assert agent.type == MicroAgentType.REPO_KNOWLEDGE
|
||||
assert agent.type == MicroagentType.REPO_KNOWLEDGE
|
||||
assert agent.metadata.agent == 'CodeActAgent'
|
||||
assert agent.metadata.version == '1.0.0'
|
||||
|
||||
@ -80,15 +80,15 @@ This is a test markdown file with full frontmatter."""
|
||||
path = Path('test.md')
|
||||
|
||||
# Load the agent from content
|
||||
agent = BaseMicroAgent.load(path, content)
|
||||
agent = BaseMicroagent.load(path, content)
|
||||
|
||||
# Verify all provided values are used
|
||||
assert isinstance(agent, RepoMicroAgent)
|
||||
assert isinstance(agent, RepoMicroagent)
|
||||
assert agent.name == 'test_agent'
|
||||
assert (
|
||||
agent.content
|
||||
== '# Test Content\nThis is a test markdown file with full frontmatter.'
|
||||
)
|
||||
assert agent.type == MicroAgentType.REPO_KNOWLEDGE
|
||||
assert agent.type == MicroagentType.REPO_KNOWLEDGE
|
||||
assert agent.metadata.agent == 'CustomAgent'
|
||||
assert agent.metadata.version == '2.0.0'
|
||||
|
||||
@ -5,14 +5,14 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.exceptions import MicroAgentValidationError
|
||||
from openhands.core.exceptions import MicroagentValidationError
|
||||
from openhands.microagent import (
|
||||
BaseMicroAgent,
|
||||
KnowledgeMicroAgent,
|
||||
MicroAgentMetadata,
|
||||
MicroAgentType,
|
||||
RepoMicroAgent,
|
||||
TaskMicroAgent,
|
||||
BaseMicroagent,
|
||||
KnowledgeMicroagent,
|
||||
MicroagentMetadata,
|
||||
MicroagentType,
|
||||
RepoMicroagent,
|
||||
TaskMicroagent,
|
||||
load_microagents_from_dir,
|
||||
)
|
||||
|
||||
@ -26,11 +26,11 @@ def test_legacy_micro_agent_load(tmp_path):
|
||||
legacy_file = tmp_path / '.openhands_instructions'
|
||||
legacy_file.write_text(CONTENT)
|
||||
|
||||
micro_agent = BaseMicroAgent.load(legacy_file)
|
||||
assert isinstance(micro_agent, RepoMicroAgent)
|
||||
micro_agent = BaseMicroagent.load(legacy_file)
|
||||
assert isinstance(micro_agent, RepoMicroagent)
|
||||
assert micro_agent.name == 'repo_legacy'
|
||||
assert micro_agent.content == CONTENT
|
||||
assert micro_agent.type == MicroAgentType.REPO_KNOWLEDGE
|
||||
assert micro_agent.type == MicroagentType.REPO_KNOWLEDGE
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -89,14 +89,14 @@ Test task content
|
||||
|
||||
def test_knowledge_agent():
|
||||
"""Test knowledge agent functionality."""
|
||||
agent = KnowledgeMicroAgent(
|
||||
agent = KnowledgeMicroagent(
|
||||
name='test',
|
||||
content='Test content',
|
||||
metadata=MicroAgentMetadata(
|
||||
name='test', type=MicroAgentType.KNOWLEDGE, triggers=['test', 'pytest']
|
||||
metadata=MicroagentMetadata(
|
||||
name='test', type=MicroagentType.KNOWLEDGE, triggers=['test', 'pytest']
|
||||
),
|
||||
source='test.md',
|
||||
type=MicroAgentType.KNOWLEDGE,
|
||||
type=MicroagentType.KNOWLEDGE,
|
||||
)
|
||||
|
||||
assert agent.match_trigger('running a test') == 'test'
|
||||
@ -114,18 +114,18 @@ def test_load_microagents(temp_microagents_dir):
|
||||
# Check knowledge agents
|
||||
assert len(knowledge_agents) == 1
|
||||
agent = knowledge_agents['test_knowledge_agent']
|
||||
assert isinstance(agent, KnowledgeMicroAgent)
|
||||
assert isinstance(agent, KnowledgeMicroagent)
|
||||
assert 'test' in agent.triggers
|
||||
|
||||
# Check repo agents
|
||||
assert len(repo_agents) == 1
|
||||
agent = repo_agents['test_repo_agent']
|
||||
assert isinstance(agent, RepoMicroAgent)
|
||||
assert isinstance(agent, RepoMicroagent)
|
||||
|
||||
# Check task agents
|
||||
assert len(task_agents) == 1
|
||||
agent = task_agents['test_task']
|
||||
assert isinstance(agent, TaskMicroAgent)
|
||||
assert isinstance(agent, TaskMicroagent)
|
||||
|
||||
|
||||
def test_invalid_agent_type(temp_microagents_dir):
|
||||
@ -141,8 +141,8 @@ Invalid agent content
|
||||
"""
|
||||
(temp_microagents_dir / 'invalid.md').write_text(invalid_agent)
|
||||
|
||||
with pytest.raises(MicroAgentValidationError):
|
||||
BaseMicroAgent.load(temp_microagents_dir / 'invalid.md')
|
||||
with pytest.raises(MicroagentValidationError):
|
||||
BaseMicroagent.load(temp_microagents_dir / 'invalid.md')
|
||||
|
||||
|
||||
def test_load_microagents_with_nested_dirs(temp_microagents_dir):
|
||||
@ -172,7 +172,7 @@ Testing nested directory loading.
|
||||
# Check that we can find the nested agent
|
||||
assert len(knowledge_agents) == 2 # Original + nested
|
||||
agent = knowledge_agents['nested_knowledge_agent']
|
||||
assert isinstance(agent, KnowledgeMicroAgent)
|
||||
assert isinstance(agent, KnowledgeMicroagent)
|
||||
assert 'nested' in agent.triggers
|
||||
|
||||
|
||||
@ -203,5 +203,5 @@ Testing loading with trailing slashes.
|
||||
# Check that we can find the agent despite trailing slashes
|
||||
assert len(knowledge_agents) == 2 # Original + trailing
|
||||
agent = knowledge_agents['trailing_knowledge_agent']
|
||||
assert isinstance(agent, KnowledgeMicroAgent)
|
||||
assert isinstance(agent, KnowledgeMicroagent)
|
||||
assert 'trailing' in agent.triggers
|
||||
|
||||
@ -6,7 +6,7 @@ import pytest
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.message import Message, TextContent
|
||||
from openhands.events.observation.agent import MicroagentKnowledge
|
||||
from openhands.microagent import BaseMicroAgent
|
||||
from openhands.microagent import BaseMicroagent
|
||||
from openhands.utils.prompt import PromptManager, RepositoryInfo, RuntimeInfo
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ def test_prompt_manager_file_not_found(prompt_dir):
|
||||
"""Test PromptManager behavior when a template file is not found."""
|
||||
# Test with a non-existent template
|
||||
with pytest.raises(FileNotFoundError):
|
||||
BaseMicroAgent.load(
|
||||
BaseMicroagent.load(
|
||||
os.path.join(prompt_dir, 'micro', 'non_existent_microagent.md')
|
||||
)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user