| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- """Authenticated Dashboard API, mounted at /api/plugins/yaoyao-bot-bridge."""
- import asyncio
- import importlib.util
- from pathlib import Path
- from fastapi import APIRouter, Request
- from fastapi.responses import JSONResponse
- _spec = importlib.util.spec_from_file_location(
- "_yaoyao_bot_bridge_bootstrap", Path(__file__).parents[1] / "bootstrap.py"
- )
- if _spec is None or _spec.loader is None:
- raise ImportError("夭夭工具桥加载失败")
- _bootstrap = importlib.util.module_from_spec(_spec)
- _spec.loader.exec_module(_bootstrap)
- bridge = _bootstrap.runtime()
- router = APIRouter()
- def _error(exc):
- return JSONResponse(
- status_code=exc.status,
- content={"detail": str(exc), "code": exc.code},
- )
- async def _body(request, limit=16384):
- raw = await request.body()
- if len(raw) > limit:
- raise bridge.BridgeError("绑定请求过大", 413, "invalid_request")
- try:
- body = await request.json()
- except Exception:
- raise bridge.BridgeError("绑定请求必须是 JSON 对象", 400, "invalid_request") from None
- if not isinstance(body, dict):
- raise bridge.BridgeError("绑定请求必须是 JSON 对象", 400, "invalid_request")
- return body
- @router.post("/computer-file")
- async def computer_file(request: Request):
- try:
- identity = bridge.request_identity(request)
- body = await _body(request, 36 * 1024 * 1024)
- return await asyncio.to_thread(bridge.computer_file, identity, body)
- except bridge.BridgeError as exc:
- return _error(exc)
- except Exception:
- return JSONResponse(status_code=502, content={"code": "computer_file_failed", "detail": "Hermes 文件传输失败"})
- @router.post("/memory-extract")
- async def memory_extract(request: Request):
- try:
- bridge.request_identity(request)
- body = await _body(request, 512 * 1024)
- return await bridge.extract_memory(body.get("profile"), body.get("prompt"))
- except bridge.BridgeError as exc:
- return _error(exc)
- except Exception:
- return JSONResponse(status_code=502, content={"code": "memory_extraction_failed", "detail": "Hermes 记忆提炼失败"})
- @router.get("/capabilities")
- def capabilities(request: Request, profile: str = "default"):
- try:
- bridge.request_identity(request)
- return bridge.capabilities(profile)
- except bridge.BridgeError as exc:
- return _error(exc)
- @router.post("/bind")
- async def bind(request: Request):
- try:
- identity = bridge.request_identity(request)
- body = await _body(request)
- return await asyncio.to_thread(bridge.bind, identity, body)
- except bridge.BridgeError as exc:
- return _error(exc)
- @router.post("/unbind")
- async def unbind(request: Request):
- try:
- identity = bridge.request_identity(request)
- return bridge.unbind(identity, await _body(request))
- except bridge.BridgeError as exc:
- return _error(exc)
- @router.post("/sampling")
- async def sampling(request: Request):
- try:
- identity = bridge.request_identity(request)
- return await bridge.sampling_request(identity, await _body(request))
- except bridge.BridgeError as exc:
- return _error(exc)
- except Exception:
- return JSONResponse(status_code=502, content={"code": "sampling_failed", "detail": "Hermes MCP 采样失败"})
|