Selector de agentes
This commit is contained in:
@@ -33,6 +33,7 @@ class CreateSessionRequest(BaseModel):
|
||||
default_factory=dict,
|
||||
description="Per-project env vars for MCP servers (e.g. ACAI_WEB_URL, ACAI_PROJECT_DIR)",
|
||||
)
|
||||
agent_id: str = "acai"
|
||||
|
||||
|
||||
class CreateSessionResponse(BaseModel):
|
||||
@@ -43,6 +44,7 @@ class CreateSessionResponse(BaseModel):
|
||||
class SendMessageRequest(BaseModel):
|
||||
message: str
|
||||
stream: bool = False
|
||||
agent_id: str | None = None
|
||||
|
||||
|
||||
class SessionResponse(BaseModel):
|
||||
@@ -53,6 +55,7 @@ class SessionResponse(BaseModel):
|
||||
completed_tasks: list[str] = Field(default_factory=list)
|
||||
created_at: str
|
||||
updated_at: str
|
||||
agent_id: str = "acai"
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@@ -70,6 +73,7 @@ def set_dependencies(
|
||||
sse_emitter: Any,
|
||||
claude_emitter: Any = None,
|
||||
mcp_registry: Any = None,
|
||||
agent_registry: Any = None,
|
||||
) -> None:
|
||||
_deps["storage"] = storage
|
||||
_deps["model_adapter"] = model_adapter
|
||||
@@ -78,6 +82,7 @@ def set_dependencies(
|
||||
_deps["sse"] = sse_emitter
|
||||
_deps["claude_sse"] = claude_emitter
|
||||
_deps["mcp_registry"] = mcp_registry
|
||||
_deps["agent_registry"] = agent_registry
|
||||
|
||||
|
||||
def _get_storage():
|
||||
@@ -92,7 +97,11 @@ def _get_mcp_registry():
|
||||
return _deps["mcp_registry"]
|
||||
|
||||
|
||||
def _build_orchestrator(mcp_manager) -> OrchestratorEngine:
|
||||
def _get_agent_registry():
|
||||
return _deps["agent_registry"]
|
||||
|
||||
|
||||
def _build_orchestrator(mcp_manager, agent_profile) -> OrchestratorEngine:
|
||||
"""Build an orchestrator with a session-specific MCPManager."""
|
||||
return OrchestratorEngine(
|
||||
model_adapter=_deps["model_adapter"],
|
||||
@@ -100,6 +109,7 @@ def _build_orchestrator(mcp_manager) -> OrchestratorEngine:
|
||||
mcp_client=mcp_manager,
|
||||
memory_store=_deps["memory_store"],
|
||||
sse_emitter=_deps["sse"],
|
||||
agent_profile=agent_profile,
|
||||
)
|
||||
|
||||
|
||||
@@ -109,12 +119,18 @@ def _build_orchestrator(mcp_manager) -> OrchestratorEngine:
|
||||
|
||||
@router.post("/sessions", response_model=CreateSessionResponse, status_code=201)
|
||||
async def create_session(body: CreateSessionRequest) -> CreateSessionResponse:
|
||||
# Validar agent_id en el registry
|
||||
agent_reg = _get_agent_registry()
|
||||
if agent_reg and not agent_reg.get(body.agent_id):
|
||||
raise HTTPException(status_code=400, detail="Agent not found")
|
||||
|
||||
storage = _get_storage()
|
||||
session = SessionState(
|
||||
project_profile=body.project_profile,
|
||||
immutable_rules=body.immutable_rules,
|
||||
metadata=body.metadata,
|
||||
)
|
||||
session.agent_id = body.agent_id
|
||||
# Store mcp_env in session metadata for reconnection
|
||||
if body.mcp_env:
|
||||
session.metadata["mcp_env"] = body.mcp_env
|
||||
@@ -161,8 +177,22 @@ async def send_message(
|
||||
mcp_env = session.metadata.get("mcp_env", {})
|
||||
mcp_manager = await registry.create_for_session(session_id, mcp_env)
|
||||
|
||||
# Cambiar agente mid-session si se solicita
|
||||
if body.agent_id and body.agent_id != session.agent_id:
|
||||
agent_reg_check = _get_agent_registry()
|
||||
if agent_reg_check and agent_reg_check.get(body.agent_id):
|
||||
session.agent_id = body.agent_id
|
||||
|
||||
# Resolver agent profile desde el registry
|
||||
agent_reg = _get_agent_registry()
|
||||
agent_profile = None
|
||||
if agent_reg:
|
||||
agent_profile = agent_reg.get(session.agent_id)
|
||||
if not agent_profile:
|
||||
agent_profile = agent_reg.get(agent_reg.default_agent_id)
|
||||
|
||||
from ..mcp.manager import MCPManager
|
||||
orchestrator = _build_orchestrator(mcp_manager or MCPManager())
|
||||
orchestrator = _build_orchestrator(mcp_manager or MCPManager(), agent_profile)
|
||||
|
||||
if body.stream:
|
||||
asyncio.create_task(_execute_and_persist(orchestrator, storage, session, body.message))
|
||||
@@ -258,6 +288,7 @@ async def get_session(session_id: str) -> SessionResponse:
|
||||
completed_tasks=session.completed_tasks,
|
||||
created_at=session.created_at.isoformat(),
|
||||
updated_at=session.updated_at.isoformat(),
|
||||
agent_id=session.agent_id,
|
||||
)
|
||||
|
||||
|
||||
@@ -320,6 +351,46 @@ async def get_context_debug(session_id: str) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# GET /agents
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@router.get("/agents")
|
||||
async def list_agents() -> dict[str, Any]:
|
||||
"""Lista todos los agentes disponibles."""
|
||||
registry = _get_agent_registry()
|
||||
return {
|
||||
"agents": registry.list_agents(),
|
||||
"default": registry.default_agent_id,
|
||||
}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# GET /agents/{agent_id}
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@router.get("/agents/{agent_id}")
|
||||
async def get_agent(agent_id: str) -> dict[str, Any]:
|
||||
"""Detalle completo de un agente, incluyendo system prompt."""
|
||||
registry = _get_agent_registry()
|
||||
profile = registry.get(agent_id)
|
||||
if not profile:
|
||||
raise HTTPException(status_code=404, detail="Agent not found")
|
||||
return {
|
||||
"id": profile.name,
|
||||
"display_name": profile.display_name,
|
||||
"description": profile.description,
|
||||
"icon": profile.icon,
|
||||
"category": profile.category,
|
||||
"temperature": profile.temperature,
|
||||
"max_tokens": profile.max_tokens,
|
||||
"model_id": profile.model_id,
|
||||
"system_prompt": profile.system_prompt,
|
||||
"context_sections": profile.context_sections,
|
||||
"stream_deltas": profile.stream_deltas,
|
||||
}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Knowledge Base
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user