- Phase 1: Infrastructure (state, prompts, registry) - Phase 2: Execution engine (AI adapters, security classifier, executors) - Phase 3: Agent integration (graph nodes, routing) - Phase 4: Streaming interaction (PTY terminal, WebSocket) - Phase 5: Frontend integration (Vue components)
273 lines
9.3 KiB
Python
273 lines
9.3 KiB
Python
from app.agents.prompts import SUB_COMMANDER_PROMPTS_BY_KEY
|
|
from app.agents.registry.models import (
|
|
AgentManifest,
|
|
CapabilityManifest,
|
|
PermissionClass,
|
|
SideEffectScope,
|
|
SpecialistTemplateManifest,
|
|
SubCommanderManifest,
|
|
)
|
|
from app.agents.state import AgentRole
|
|
from app.agents.tools import SUB_COMMANDER_TOOLSETS
|
|
|
|
|
|
TOP_LEVEL_AGENT_DEFAULT_SUB_COMMANDERS: dict[str, tuple[str, ...]] = {
|
|
AgentRole.MASTER.value: (),
|
|
AgentRole.SCHEDULE_PLANNER.value: (
|
|
"schedule_analysis",
|
|
"schedule_planning",
|
|
),
|
|
AgentRole.EXECUTOR.value: (
|
|
"executor_tasks",
|
|
"executor_forum",
|
|
),
|
|
AgentRole.LIBRARIAN.value: (
|
|
"librarian_retrieval",
|
|
"librarian_graph",
|
|
),
|
|
AgentRole.ANALYST.value: (
|
|
"analyst_progress",
|
|
"analyst_insights",
|
|
),
|
|
AgentRole.CODE_COMMANDER.value: (),
|
|
}
|
|
|
|
TOP_LEVEL_AGENT_DISPLAY_NAMES: dict[str, str] = {
|
|
AgentRole.MASTER.value: "Master",
|
|
AgentRole.SCHEDULE_PLANNER.value: "Schedule Planner",
|
|
AgentRole.EXECUTOR.value: "Executor",
|
|
AgentRole.LIBRARIAN.value: "Librarian",
|
|
AgentRole.ANALYST.value: "Analyst",
|
|
AgentRole.CODE_COMMANDER.value: "Code Commander",
|
|
}
|
|
|
|
TOP_LEVEL_AGENT_ROUTING_HINTS: dict[str, tuple[str, ...]] = {
|
|
AgentRole.MASTER.value: (
|
|
"Route user requests to the most suitable top-level runtime agent or answer directly.",
|
|
),
|
|
AgentRole.SCHEDULE_PLANNER.value: (
|
|
"Handle planning-oriented requests using schedule analysis and schedule planning sub-commanders.",
|
|
),
|
|
AgentRole.EXECUTOR.value: (
|
|
"Handle execution-oriented requests using task and forum sub-commanders.",
|
|
),
|
|
AgentRole.LIBRARIAN.value: (
|
|
"Handle knowledge retrieval and graph-context requests using librarian sub-commanders.",
|
|
),
|
|
AgentRole.ANALYST.value: (
|
|
"Handle reporting and insight requests using analyst sub-commanders.",
|
|
),
|
|
AgentRole.CODE_COMMANDER.value: (
|
|
"Handle code writing and execution tasks using AI CLI adapters.",
|
|
),
|
|
}
|
|
|
|
TOP_LEVEL_AGENT_ALLOWED_SPAWN_ROLES: dict[str, tuple[str, ...]] = {
|
|
AgentRole.MASTER.value: (
|
|
AgentRole.SCHEDULE_PLANNER.value,
|
|
AgentRole.EXECUTOR.value,
|
|
AgentRole.LIBRARIAN.value,
|
|
AgentRole.ANALYST.value,
|
|
AgentRole.CODE_COMMANDER.value,
|
|
),
|
|
AgentRole.SCHEDULE_PLANNER.value: (AgentRole.SCHEDULE_PLANNER.value,),
|
|
AgentRole.EXECUTOR.value: (AgentRole.EXECUTOR.value,),
|
|
AgentRole.LIBRARIAN.value: (AgentRole.LIBRARIAN.value,),
|
|
AgentRole.ANALYST.value: (AgentRole.ANALYST.value,),
|
|
AgentRole.CODE_COMMANDER.value: (),
|
|
}
|
|
|
|
SUB_COMMANDER_PARENT_AGENT_IDS: dict[str, str] = {
|
|
"schedule_analysis": AgentRole.SCHEDULE_PLANNER.value,
|
|
"schedule_planning": AgentRole.SCHEDULE_PLANNER.value,
|
|
"executor_tasks": AgentRole.EXECUTOR.value,
|
|
"executor_forum": AgentRole.EXECUTOR.value,
|
|
"librarian_retrieval": AgentRole.LIBRARIAN.value,
|
|
"librarian_graph": AgentRole.LIBRARIAN.value,
|
|
"analyst_progress": AgentRole.ANALYST.value,
|
|
"analyst_insights": AgentRole.ANALYST.value,
|
|
}
|
|
|
|
|
|
BUILTIN_AGENT_MANIFESTS: tuple[AgentManifest, ...] = tuple(
|
|
AgentManifest(
|
|
agent_id=role.value,
|
|
display_name=TOP_LEVEL_AGENT_DISPLAY_NAMES[role.value],
|
|
role_value=role.value,
|
|
system_prompt_key=role.value,
|
|
routing_hints=list(TOP_LEVEL_AGENT_ROUTING_HINTS[role.value]),
|
|
default_sub_commanders=list(TOP_LEVEL_AGENT_DEFAULT_SUB_COMMANDERS[role.value]),
|
|
can_spawn_children=bool(TOP_LEVEL_AGENT_ALLOWED_SPAWN_ROLES[role.value]),
|
|
allowed_spawn_role_values=list(TOP_LEVEL_AGENT_ALLOWED_SPAWN_ROLES[role.value]),
|
|
skill_context_key=role.value.replace("agent_", ""),
|
|
)
|
|
for role in AgentRole
|
|
)
|
|
|
|
|
|
_capability_tool_names = tuple(
|
|
dict.fromkeys(tool.name for tools in SUB_COMMANDER_TOOLSETS.values() for tool in tools)
|
|
)
|
|
|
|
_CAPABILITY_METADATA_BY_TOOL_NAME: dict[str, dict[str, object]] = {
|
|
"get_tasks": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"get_schedule_day": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"resolve_time_expression": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"search_knowledge": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"hybrid_search": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"get_knowledge_graph_context": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"get_forum_posts": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"scan_forum_for_instructions": {
|
|
"permission_class": PermissionClass.READ,
|
|
"side_effect_scope": SideEffectScope.NONE,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"web_search": {
|
|
"permission_class": PermissionClass.EXTERNAL,
|
|
"side_effect_scope": SideEffectScope.NETWORK,
|
|
"supports_retry": True,
|
|
"idempotent": True,
|
|
"safe_for_parallel_use": True,
|
|
"requires_confirmation": False,
|
|
},
|
|
"create_task": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
"update_task_status": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
"create_todo": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
"create_schedule_task": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
"create_reminder": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
"create_goal": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
"create_forum_post": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
"build_knowledge_graph": {
|
|
"permission_class": PermissionClass.WRITE,
|
|
"side_effect_scope": SideEffectScope.LOCAL_STATE,
|
|
"supports_retry": False,
|
|
"idempotent": False,
|
|
"safe_for_parallel_use": False,
|
|
"requires_confirmation": True,
|
|
},
|
|
}
|
|
|
|
BUILTIN_CAPABILITY_MANIFESTS: tuple[CapabilityManifest, ...] = tuple(
|
|
CapabilityManifest(
|
|
capability_id=tool_name,
|
|
tool_name=tool_name,
|
|
**dict(_CAPABILITY_METADATA_BY_TOOL_NAME.get(tool_name, {})),
|
|
)
|
|
for tool_name in _capability_tool_names
|
|
)
|
|
|
|
|
|
BUILTIN_SUB_COMMANDER_MANIFESTS: tuple[SubCommanderManifest, ...] = tuple(
|
|
SubCommanderManifest(
|
|
sub_commander_id=sub_commander_id,
|
|
parent_agent_id=SUB_COMMANDER_PARENT_AGENT_IDS[sub_commander_id],
|
|
prompt_text=SUB_COMMANDER_PROMPTS_BY_KEY[sub_commander_id],
|
|
capability_ids=list(dict.fromkeys(tool.name for tool in tools)),
|
|
)
|
|
for sub_commander_id, tools in SUB_COMMANDER_TOOLSETS.items()
|
|
)
|
|
|
|
|
|
BUILTIN_SPECIALIST_TEMPLATE_MANIFESTS: tuple[SpecialistTemplateManifest, ...] = ()
|