# Auto-extracted from chat.py during Phase 1 refactor (Strangler Fig). # Source of truth: scripts/phase1_extract.py. Do not hand-merge back. from fastapi import APIRouter, Depends, HTTPException, Query, Response from sqlalchemy.orm import Session from sqlalchemy import and_, desc, asc, func from pydantic import BaseModel, Field from typing import Optional import uuid from datetime import datetime, timezone, timedelta import re import json import asyncio import math import httpx import os import logging from ..database import get_db, SessionLocal from ..models import ( User, Conversation, Message, AIModel, ModelProvider, TokenUsageLog, KnowledgeBase, KnowledgeDocument, KnowledgeDocumentChunk, EvolutionSkill, EvolutionTrajectory, MarketApp, AppPurchase, AppInstallation, MCPServer, gen_uuid ) from ..auth import get_current_user from ..platform_knowledge import get_platform_knowledge from ..mcp_client import list_mcp_tools, call_mcp_tool from ..middleware.log_service import LogService from ..capability_registry import resolve_auto_model def _resolve_market_mcp(db: Session, mcp_ids: list, user_id: str) -> list: """ 加载用户选择的 MCP 应用配置(MarketApp.type == 'mcp')。 返回: [{id, name, transport, endpoint, description}] """ if not mcp_ids: return [] mcps = db.query(MarketApp).filter( MarketApp.id.in_(mcp_ids), MarketApp.type == "mcp" ).all() results = [] for m in mcps: config = {} try: if m.skill_content: config = json.loads(m.skill_content) except Exception: config = {} results.append({ "id": m.id, "name": m.name, "transport": m.mcp_transport or config.get("transport", "stdio"), "endpoint": m.agent_endpoint or config.get("endpoint", "") or config.get("url", ""), "description": m.description or config.get("description", ""), }) return results def _resolve_active_mcp_servers(db: Session, mcp_ids: list) -> list: """ 解析用户选中的 MCP 服务连接信息(来自 mcp_servers 表,import 与后台添加通用)。 返回: [{id, name, description, transport, endpoint, url, headers}] """ if not mcp_ids: return [] servers = db.query(MCPServer).filter( MCPServer.id.in_(mcp_ids), MCPServer.is_enabled == True, ).all() out = [] for s in servers: try: headers = json.loads(s.headers) if isinstance(s.headers, str) else (s.headers or {}) except Exception: headers = {} out.append({ "id": s.id, "name": s.name, "description": s.description or "", "transport": s.transport_type or "streamable_http", "endpoint": s.url or "", "url": s.url or "", "headers": headers, }) return out def _list_enabled_mcp_servers(db: Session) -> list: """返回平台所有已启用(is_enabled=True)的 MCP 服务清单,供 AI 准确回答"平台有哪些 MCP"。""" servers = db.query(MCPServer).filter(MCPServer.is_enabled == True).all() out = [] for s in servers: try: headers = json.loads(s.headers) if isinstance(s.headers, str) else (s.headers or {}) except Exception: headers = {} out.append({ "id": s.id, "name": s.name, "description": s.description or "", "transport": s.transport_type or "streamable_http", "endpoint": s.url or "", "url": s.url or "", "headers": headers, }) return out