Files
loom/backend/app/api/v1/executor.py
T
2026-04-24 17:46:03 +08:00

73 lines
2.6 KiB
Python

"""执行器健康状态聚合接口。"""
from __future__ import annotations
import shutil
import sys
from fastapi import APIRouter, Depends
from sqlalchemy import func, select
from app.core.config import settings
from app.core.deps import DbDep, require_perm
from app.core.exceptions import ok
from app.models import LLMProvider, LLMUsage, Skill, Task
from app.services import lobster_config_service
router = APIRouter(prefix="/executors", tags=["executor"])
@router.get("/status", dependencies=[Depends(require_perm("system:executor:view"))])
async def executor_status(db: DbDep) -> dict:
lobster_eff = await lobster_config_service.load_effective(db)
lobster_tasks = (await db.execute(
select(func.count()).select_from(Task).where(Task.executor_type == "LOBSTER")
)).scalar() or 0
script_tasks = (await db.execute(
select(func.count()).select_from(Task).where(Task.executor_type == "SCRIPT")
)).scalar() or 0
providers_active = (await db.execute(
select(func.count()).select_from(LLMProvider).where(LLMProvider.status == "ACTIVE")
)).scalar() or 0
llm_calls = (await db.execute(select(func.count(LLMUsage.id)))).scalar() or 0
llm_cost = float((await db.execute(select(func.sum(LLMUsage.cost_usd)))).scalar() or 0)
skill_total = (await db.execute(select(func.count(Skill.id)))).scalar() or 0
node = "localhost/subprocess"
python_bin = sys.executable
node_bin = shutil.which("node")
bash_bin = shutil.which("bash")
return ok({
"lobster": {
"configured": not lobster_eff.is_mock,
"mode": "real" if not lobster_eff.is_mock else "mock",
"api_base": lobster_eff.api_base or "(未配置)",
"api_base_source": lobster_eff.api_base_source,
"api_key_source": lobster_eff.api_key_source,
"timeout_seconds": lobster_eff.timeout_seconds,
"poll_interval_seconds": lobster_eff.poll_interval_seconds,
"callback_configured": bool(lobster_eff.callback_secret),
"callback_source": lobster_eff.callback_secret_source,
"task_count": int(lobster_tasks),
},
"script": {
"mode": "subprocess",
"node": node,
"python": python_bin,
"node_bin": node_bin,
"bash_bin": bash_bin,
"task_count": int(script_tasks),
},
"llm": {
"providers_active": int(providers_active),
"total_calls": int(llm_calls),
"total_cost_usd": round(llm_cost, 6),
},
"meta": {
"skill_total": int(skill_total),
"app_env": settings.APP_ENV,
},
})