PMFlow/backend/app/api/sstc_api/ai_routing.py

131 lines
4.7 KiB
Python

from __future__ import annotations
from .shared import *
from ...services.sstc.charter_seed_utils import _safe_threshold
from ...services.sstc.entity_lookup import _ensure_project
from ...services.sstc.feishu_routing import _extract_feishu_routing_config
from ...services.sstc.signal_core import _parse_project_id
router = APIRouter(tags=["sstc"])
class AIRoutingConfigUpdateRequest(BaseModel):
cold_start_enabled: Optional[bool] = None
signal_auto_enter_threshold: Optional[float] = None
project_auto_create_threshold: Optional[float] = None
project_uncertain_threshold: Optional[float] = None
def _routing_payload(data: dict[str, Any]) -> dict[str, Any]:
return {
"cold_start_enabled": bool(data["cold_start_enabled"]),
"signal_auto_enter_threshold": round(float(data["signal_auto_enter_threshold"]), 2),
"project_auto_create_threshold": round(float(data["project_auto_create_threshold"]), 2),
"project_uncertain_threshold": round(float(data["project_uncertain_threshold"]), 2),
"tips": {
"cold_start_enabled": "开启后,所有飞书消息进入待处理,不会自动入库或自动建项。",
"signal_auto_enter_threshold": "建议范围 0.75-0.90,数值越高越保守。",
"project_auto_create_threshold": "建议范围 0.80-0.95,数值越高越严格。",
"project_uncertain_threshold": "低于该值视为低置信度,进入人工待处理。",
},
}
@router.get("/projects/{project_id}/ai-routing-config")
async def get_ai_routing_config(
project_id: str,
current_user: User = Depends(require_project_member_or_manager),
db: AsyncSession = Depends(get_db),
):
tenant_id = int(current_user.tenant_id)
pid = _parse_project_id(project_id)
svc = SSTCService(db, tenant_id=tenant_id)
await _ensure_project(svc, pid)
integration = (
await db.execute(
select(Integration).where(
and_(
Integration.tenant_id == tenant_id,
Integration.type == "feishu",
)
)
)
).scalar_one_or_none()
return success_response(_routing_payload(_extract_feishu_routing_config(integration)))
@router.put("/projects/{project_id}/ai-routing-config")
async def update_ai_routing_config(
project_id: str,
request: AIRoutingConfigUpdateRequest,
current_user: User = Depends(require_project_member_or_manager),
db: AsyncSession = Depends(get_db),
):
tenant_id = int(current_user.tenant_id)
pid = _parse_project_id(project_id)
svc = SSTCService(db, tenant_id=tenant_id)
await _ensure_project(svc, pid)
integration = (
await db.execute(
select(Integration).where(
and_(
Integration.tenant_id == tenant_id,
Integration.type == "feishu",
)
)
)
).scalar_one_or_none()
if integration is None:
integration = Integration(
tenant_id=tenant_id,
type="feishu",
config={},
is_active=True,
)
db.add(integration)
await db.flush()
current = _extract_feishu_routing_config(integration)
config = dict(current["raw"])
if request.cold_start_enabled is not None:
enabled = bool(request.cold_start_enabled)
config["cold_start_enabled"] = enabled
if request.signal_auto_enter_threshold is not None:
config["signal_auto_enter_threshold"] = _safe_threshold(
request.signal_auto_enter_threshold,
current["signal_auto_enter_threshold"],
)
if request.project_auto_create_threshold is not None:
config["project_auto_create_threshold"] = _safe_threshold(
request.project_auto_create_threshold,
current["project_auto_create_threshold"],
)
if request.project_uncertain_threshold is not None:
config["project_uncertain_threshold"] = _safe_threshold(
request.project_uncertain_threshold,
current["project_uncertain_threshold"],
)
project_threshold = _safe_threshold(
config.get("project_auto_create_threshold"),
current["project_auto_create_threshold"],
)
uncertain_threshold = min(
project_threshold,
_safe_threshold(
config.get("project_uncertain_threshold"),
current["project_uncertain_threshold"],
),
)
config["project_auto_create_threshold"] = project_threshold
config["project_uncertain_threshold"] = uncertain_threshold
integration.config = config
await db.commit()
await db.refresh(integration)
return success_response(_routing_payload(_extract_feishu_routing_config(integration)))