Project Monitor agent: LLM-powered project status reports with wiki+Gitea integration

This commit is contained in:
2026-04-13 14:38:52 +00:00
parent b48028dd91
commit 1ddc2a009c
8 changed files with 574 additions and 7 deletions
+27
View File
@@ -328,6 +328,7 @@ def list_catalog(user: dict = Depends(require_auth), db: Session = Depends(get_d
"category": e.category, "config_schema": e.config_schema or {},
"default_config": e.default_config or {},
"supports_schedule": e.supports_schedule, "is_sub_agent": e.is_sub_agent,
"requires_llm": e.requires_llm,
"enabled": e.id in user_instance_ids,
} for e in entries]
@@ -381,6 +382,14 @@ def create_instance(data: InstanceCreate, user: dict = Depends(require_auth), db
catalog = db.query(AgentCatalog).filter(AgentCatalog.id == data.catalog_id).first()
if not catalog:
raise HTTPException(status_code=404, detail="Agent type not found in catalog")
# Enforce LLM requirement
if catalog.requires_llm:
u = db.query(User).filter(User.id == user["user_id"]).first()
user_llm = u.llm_config or {} if u else {}
has_user_llm = bool(user_llm.get("api_key"))
has_system_llm = db.query(LLMProvider).filter(LLMProvider.is_default == True).first() is not None
if not has_user_llm and not has_system_llm:
raise HTTPException(status_code=400, detail="This agent requires an LLM provider. Configure one via the LLM button in the header.")
config = {**(catalog.default_config or {}), **data.config}
inst = AgentInstance(
user_id=user["user_id"],
@@ -482,11 +491,29 @@ def trigger_instance(instance_id: int, user: dict = Depends(require_auth), db: S
subprocess.Popen(cmd, env=env, cwd=agent_dir)
return {"status": "triggered", "message": f"Running {catalog_id} for {u.display_name}"}
if catalog_id == "project-monitor":
config_json = json.dumps(inst.config or {}).replace("'", "\\'")
cmd = ["python3", "-c",
f"import sys, json; sys.path.insert(0, '{agent_dir}'); "
f"from project_monitor import run; "
f"run(json.loads('{config_json}'), user_id={user['user_id']}, instance_id={instance_id})"]
subprocess.Popen(cmd, env=env, cwd=agent_dir)
return {"status": "triggered", "message": f"Running project monitor: {inst.name}"}
return {"status": "error", "message": f"Manual trigger not yet supported for {catalog_id}"}
# --- Internal endpoints (no auth, for agent scripts) ---
@app.get("/api/instances/by-user/{user_id}")
def get_user_instances(user_id: int, catalog_id: str = None, db: Session = Depends(get_db)):
"""Internal: get a user's instances, optionally filtered by catalog type."""
query = db.query(AgentInstance).filter(AgentInstance.user_id == user_id, AgentInstance.status == "active")
if catalog_id:
query = query.filter(AgentInstance.catalog_id == catalog_id)
instances = query.all()
return [{"id": i.id, "catalog_id": i.catalog_id, "name": i.name, "config": i.config or {}} for i in instances]
@app.get("/api/instances/{instance_id}/config")
def get_instance_config(instance_id: int, db: Session = Depends(get_db)):
inst = db.query(AgentInstance).filter(AgentInstance.id == instance_id).first()