Files
beaver_project/app-instance/backend-old/nanobot/agent_team/swarms_policy.py

71 lines
2.6 KiB
Python

"""Policy guardrails for swarms-generated agent team plans."""
from __future__ import annotations
from typing import Any
class SwarmsPolicy:
"""Clamp AutoSwarmBuilder output before nanobot executes it."""
allowed_swarm_types = {
# Keep this list to swarms that consume the provided nanobot agent adapters.
"GroupChat",
"SequentialWorkflow",
"ConcurrentWorkflow",
"AgentRearrange",
"MixtureOfAgents",
"HierarchicalSwarm",
}
def __init__(self, *, max_agents: int = 4, max_loops: int = 3) -> None:
self.max_agents = max(1, max_agents)
self.max_loops = max(1, max_loops)
def validate_auto_config(self, raw_config: dict[str, Any]) -> dict[str, Any]:
config = self._plain_dict(raw_config)
swarm_type = str(
config.get("swarm_type")
or config.get("type")
or config.get("architecture")
or "GroupChat"
)
if swarm_type not in self.allowed_swarm_types:
swarm_type = "GroupChat"
config["swarm_type"] = swarm_type
agents = list(config.get("agents") or [])[: self.max_agents]
config["agents"] = [self._sanitize_agent_spec(item) for item in agents]
config["max_loops"] = min(max(1, int(config.get("max_loops") or 2)), self.max_loops)
# AutoSwarmBuilder may suggest structure, not grant capabilities.
config.pop("tools", None)
config.pop("mcp_url", None)
config.pop("mcp_urls", None)
config.pop("llm_api_key", None)
config.pop("api_key", None)
return config
def _plain_dict(self, raw_config: Any) -> dict[str, Any]:
if isinstance(raw_config, dict):
return dict(raw_config)
model_dump = getattr(raw_config, "model_dump", None)
if callable(model_dump):
payload = model_dump()
return dict(payload) if isinstance(payload, dict) else {}
dict_method = getattr(raw_config, "dict", None)
if callable(dict_method):
payload = dict_method()
return dict(payload) if isinstance(payload, dict) else {}
return {}
def _sanitize_agent_spec(self, item: Any) -> dict[str, Any]:
spec = self._plain_dict(item)
return {
"agent_name": str(spec.get("agent_name") or spec.get("name") or "specialist"),
"description": str(spec.get("description") or spec.get("agent_description") or ""),
"system_prompt": str(spec.get("system_prompt") or "")[:4000],
"role": str(spec.get("role") or "worker"),
}