model_routes.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. """模型信息与运行时配置路由。"""
  2. from __future__ import annotations
  3. import asyncio
  4. from fastapi import APIRouter, HTTPException
  5. import config
  6. from agents import agent_factory, agent_registry, model_factory
  7. from api.models import ThinkingUpdateRequest
  8. from obs import get_logger
  9. logger = get_logger(__name__)
  10. router = APIRouter(tags=["模型"])
  11. @router.get("/model")
  12. async def get_model_info():
  13. """当前模型配置、工具清单与组装摘要。"""
  14. return {
  15. **model_factory.describe(),
  16. "agent": agent_factory.describe(),
  17. "generation": agent_registry.generation(),
  18. }
  19. @router.get("/model/tools")
  20. async def get_tools():
  21. """工具清单(按分组),用于前端展示「agent 会什么」。"""
  22. from tools import registry
  23. registry.load_builtin_tools()
  24. return registry.describe()
  25. @router.post("/model/thinking")
  26. async def set_thinking(payload: ThinkingUpdateRequest):
  27. """切换思考级别。
  28. 思考级别烧在模型实例里,改它必须**重建 agent**——所以这里调
  29. ``invalidate()`` 让下次请求重新编译,而不是原地改配置。重建期间
  30. (百毫秒级) 的在途请求继续用旧实例,不受影响。
  31. """
  32. level = payload.level.strip().lower()
  33. if level not in model_factory.VALID_THINKING_LEVELS:
  34. raise HTTPException(
  35. status_code=400,
  36. detail={
  37. "code": "invalid_level",
  38. "message": f"level 只能是 {' | '.join(model_factory.VALID_THINKING_LEVELS)}",
  39. },
  40. )
  41. if level == model_factory.normalize_thinking(None):
  42. return {"changed": False, "thinking": level, "message": "级别未变化"}
  43. # 级别来自环境变量,运行时改只能改进程内状态 + 失效重建
  44. config.THINKING_LEVEL = level
  45. generation = await asyncio.to_thread(agent_registry.invalidate)
  46. logger.info("思考级别切换为 %s,agent 将于下次请求重建(generation=%d)", level, generation)
  47. return {
  48. "changed": True,
  49. "thinking": level,
  50. "generation": generation,
  51. "message": "已生效,下一个请求会使用新的模型实例",
  52. }
  53. @router.post("/model/reload")
  54. async def reload_agent():
  55. """强制重建 agent。改完 .env 里的模型/窗口配置后用这个让改动生效。"""
  56. generation = await asyncio.to_thread(agent_registry.invalidate)
  57. return {"reloaded": True, "generation": generation}