from __future__ import annotations from fastapi import APIRouter from pydantic import BaseModel from app.services.agent_control import AgentControlService from app.services.project_activity import ProjectActivityService router = APIRouter(prefix="/api/agent-control", tags=["agent-control"]) _service = AgentControlService() _activity = ProjectActivityService() def _effective(record: dict) -> str: return record.get("manual_text") or record.get("inferred_text") or record.get("default_text", "") def _profile_response(project_id: str): profile = _service.get_profile(project_id) return { **profile, "student": {**profile["student"], "text": _effective(profile["student"])}, "project": {**profile["project"], "text": _effective(profile["project"])}, } def _skills_response(project_id: str): raw = _service.get_skills(project_id) skills = [] for agent_id, record in raw.get("skills", {}).items(): skills.append({ "id": agent_id, "agent_id": agent_id, "title": agent_id.replace("_", " ").title(), "procedure": _effective(record), **record, }) return {**raw, "skills": skills, "skills_by_id": raw.get("skills", {})} class ProfileUpdateRequest(BaseModel): project_id: str scope: str = "student" text: str source: str = "manual" class SkillUpdateRequest(BaseModel): project_id: str text: str = "" procedure: str = "" source: str = "manual" class ResetRequest(BaseModel): project_id: str scope: str = "all" class PreviewRequest(BaseModel): project_id: str agent_id: str = "tutor" @router.get("/profile") def get_profile(project_id: str): return _profile_response(project_id) @router.put("/profile") def update_profile(req: ProfileUpdateRequest): scope = "project" if req.scope == "project" else "student" source = "inferred" if req.source == "inferred" else "manual" _service.update_profile(req.project_id, scope=scope, text=req.text, source=source) _activity.record(req.project_id, "settings", f"ResearchMate Settings saved {scope} profile") return _profile_response(req.project_id) @router.get("/skills") def get_skills(project_id: str): return _skills_response(project_id) @router.put("/skills/{skill_id}") def update_skill(skill_id: str, req: SkillUpdateRequest): source = "inferred" if req.source == "inferred" else "manual" _service.update_skill(req.project_id, skill_id, req.procedure or req.text, source=source) _activity.record(req.project_id, "settings", f"ResearchMate Settings saved {skill_id} skill") return _skills_response(req.project_id) @router.get("/evolution") def get_evolution(project_id: str): return {"project_id": project_id, "items": _service.get_evolution(project_id)} @router.post("/reset") def reset(req: ResetRequest): result = _service.reset(req.project_id, scope=req.scope) _activity.record(req.project_id, "settings", f"ResearchMate Settings reset {req.scope}") return result @router.post("/preview") def preview(req: PreviewRequest): return _service.preview(req.project_id, agent_id=req.agent_id)