79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""智能体引导(bootstrap)路由。
|
|
|
|
返回"所有用户首次启动 / 每次登录都必须初始化的官方预置智能体"定义 ——
|
|
由运营端管理后台配置(official_agents 表),不再硬编码。
|
|
这是全局定义(对所有用户相同),因此**公开**(无需登录),本地据此在首次启动
|
|
和每次登录时初始化本地 workspace,避免本地硬编码默认智能体。
|
|
|
|
支持 ``?scope=`` 过滤身份级别:opc(桌面端)/park(园区端)/operator(运营端)/all。
|
|
默认 opc(桌面端是主要消费方;旧客户端无参请求仍返回桌面端集合)。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json as _json
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from starlette.requests import Request
|
|
|
|
from ..dependencies import get_db
|
|
from ...infrastructure.repositories import Database
|
|
|
|
router = APIRouter(tags=["bootstrap"])
|
|
|
|
_DOC_KEYS = ("soul", "profile", "heartbeat", "memory")
|
|
|
|
|
|
def _parse_docs(raw: str) -> dict:
|
|
"""解析文档 JSON 字段;失败时返回空对象(不影响下发)。"""
|
|
try:
|
|
data = _json.loads(raw or "{}")
|
|
except (ValueError, TypeError):
|
|
return {}
|
|
if not isinstance(data, dict):
|
|
return {}
|
|
return {
|
|
"user": str(data.get("user", "") or ""),
|
|
"server": str(data.get("server", "") or ""),
|
|
}
|
|
|
|
|
|
def _match_scope(agent_scope: str, requested: str) -> bool:
|
|
"""agent.scope 是否覆盖请求 scope:all 覆盖一切;逗号分隔列表含请求值。"""
|
|
agent_scope = (agent_scope or "opc").strip()
|
|
if not agent_scope or agent_scope == "all":
|
|
return True
|
|
return requested in [s.strip() for s in agent_scope.split(",")]
|
|
|
|
|
|
@router.get("/agent-bootstrap", summary="必初始化官方智能体定义")
|
|
async def agent_bootstrap(
|
|
request: Request,
|
|
db: Database = Depends(get_db),
|
|
):
|
|
"""返回服务端配置的官方预置智能体(启用中),供桌面端登录/启动同步。"""
|
|
scope = (request.query_params.get("scope") or "opc").strip() or "opc"
|
|
if scope == "all":
|
|
scope = "opc" # all 请求场景按全量:下放时以列表值过滤
|
|
seeds = await db.official_agents.active()
|
|
out = []
|
|
for seed in seeds:
|
|
if not _match_scope(seed.get("scope", "opc"), scope):
|
|
continue
|
|
docs = {k: _parse_docs(seed.get(k) or "{}") for k in _DOC_KEYS}
|
|
out.append(
|
|
{
|
|
"id": seed["id"],
|
|
"name": seed["name"],
|
|
"description": seed.get("description", ""),
|
|
"language": seed.get("language", "zh"),
|
|
"model_name": seed.get("model_name", ""),
|
|
"template_type": seed.get("template_type", "common"),
|
|
"deletable": seed.get("deletable", True),
|
|
"use_fixed_soul": seed.get("use_fixed_soul", False),
|
|
"scope": seed.get("scope", "opc"),
|
|
"documents": docs,
|
|
}
|
|
)
|
|
return out
|