Project Monitor agent: LLM-powered project status reports with wiki+Gitea integration
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user