Files
QihuAI Design 771c8456b8 chore: normalize line endings to LF via .gitattributes
Root-cause fix for mixed CRLF/LF in the repo (no .gitattributes previously).
Adds '* text=auto eol=lf' and explicit binary rules so all future checkouts
are LF. Renormalizes all tracked text files (no logical content change).
Backup tags: image qihuaiflow:backup-lineend-20260725-121632, git backup-lineend-pre-20260725-121632.
2026-07-25 12:16:39 +08:00

241 lines
3.8 KiB
Python

# 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