""" IM Bot 真实 LLM 调用。 原实现位于 channels.py(通用频道管理模块),该模块已移除。 为保持 IM Bot(微信机器人等)正常生成回复,将 _call_real_llm 迁移至此独立模块。 行为(对齐 AI 聊天): - Issue 7:图像/视频/语音意图优先走平台媒体模型(与 AI 聊天同一套 Auto 路由), 不再对“制作图片”这类请求只回文本。 - Issue 8:默认 Auto 模型;每轮先自动发现本账号已安装且平台已部署的技能, 多个适用时由模型自行判断选 1 个最优,通过 function calling 执行。 """ import asyncio import json from typing import Optional import httpx from sqlalchemy.orm import Session from ..capability_registry import resolve_auto_model from ..models import AIModel, ModelProvider def _run_async(coro): """在同步上下文中运行协程,兼容「无事件循环」与「已有事件循环」两种场景。 IM 个人微信在独立线程中调用(无事件循环)→ asyncio.run; IM 多平台 Webhook 可能在 FastAPI 协程内调用(已有事件循环)→ 丢到线程池执行。 """ try: loop = asyncio.get_running_loop() except RuntimeError: loop = None if loop is not None and loop.is_running(): import concurrent.futures with concurrent.futures.ThreadPoolExecutor(1) as ex: return ex.submit(lambda: asyncio.run(coro)).result() return asyncio.run(coro) def _call_real_llm(db: Session, user=None, prompt: str = "", platform: str = "im", user_id: str = None) -> str: """调用七虎AI 生成回复,供 IM Bot 复用。支持媒体意图路由与已安装技能自动发现。""" try: from app.api.chat import ( _generate_media, detect_media_intent, _discover_installed_skills, _build_system_prompt, _execute_skill_tool, ) # ===== 1) 媒体意图路由(Issue 7)===== intent = detect_media_intent(prompt) if intent: ai_model = resolve_auto_model(intent, db) if ai_model: try: result = _run_async(_generate_media(db, ai_model, prompt, user_id)) except Exception as e: result = f"(媒体生成失败:{e})" if result: # IM 不渲染 HTML,把 /