{"repo": "chopinau/nexuspulse-influence-project", "files": {"python_backend/config.py": {"359daa4d119dc1551d99bc2bffda7e7afd49cae6": {"t": 1785746497.6138878, "n": 8324, "h": "70994016b7e6ee74", "c": "# -*- coding: utf-8 -*-\n\"\"\"\n微舆配置文件\n\n此模块使用 pydantic-settings 管理全局配置,支持从环境变量和 .env 文件自动加载。\n数据模型定义位置:\n- 本文件 - 配置模型定义\n\"\"\"\n\nfrom pathlib import Path\nfrom pydantic_settings import BaseSettings\nfrom pydantic import Field, ConfigDict\nfrom typing import Optional, Literal\nfrom loguru import logger\n\n\n# 计算 .env 优先级:优先当前工作目录,其次项目根目录\nPROJECT_ROOT: Path = Path(__file__).resolve().parent\nCWD_ENV: Path = Path.cwd() / \".env\"\nENV_FILE: str = str(CWD_ENV if CWD_ENV.exists() else (PROJECT_ROOT / \".env\"))\n\n\nclass Settings(BaseSettings):\n \"\"\"\n 全局配置;支持 .env 和环境变量自动加载。\n 变量名与原 config.py 大写一致,便于平滑过渡。\n \"\"\"\n # ================== Flask 服务器配置 ====================\n HOST: str = Field(\"0.0.0.0\", description=\"BETTAFISH 主机地址,例如 0.0.0.0 或 127.0.0.1\")\n PORT: int = Field(5000, description=\"Flask服务器端口号,默认5000\")\n\n # ================== 日志配置 ====================\n LOG_FILE: str = Field(\"logs/app.log\", description=\"日志文件路径\")\n\n # ================== 报告输出配置 ====================\n OUTPUT_DIR: str = Field(\"final_reports\", description=\"最终报告输出目录\")\n CHAPTER_OUTPUT_DIR: str = Field(\"final_reports/chapters\", description=\"章节中间文件输出目录\")\n DOCUMENT_IR_OUTPUT_DIR: str = Field(\"final_reports/ir\", description=\"文档中间表示输出目录\")\n\n TEMPLATE_DIR: str = Field(\"ReportEngine/report_template\", description=\"报告模板目录\")\n JSON_ERROR_LOG_DIR: str = Field(\"logs/json_errors\", description=\"JSON解析错误日志目录\")\n CHAPTER_JSON_MAX_ATTEMPTS: int = Field(3, description=\"章节JSON生成最大尝试次数\")\n\n # ====================== 数据库配置 ======================\n DB_DIALECT: str = Field(\"postgresql\", description=\"数据库类型,可选 mysql 或 postgresql;请与其他连接信息同时配置\")\n DB_HOST: str = Field(\"your_db_host\", description=\"数据库主机,例如localhost 或 127.0.0.1\")\n DB_PORT: int = Field(3306, description=\"数据库端口号,默认为3306\")\n DB_USER: str = Field(\"your_db_user\", description=\"数据库用户名\")\n DB_PASSWORD: str = Field(\"your_db_password\", description=\"数据库密码\")\n DB_NAME: str = Field(\"your_db_name\", description=\"数据库名称\")\n DB_CHARSET: str = Field(\"utf8mb4\", description=\"数据库字符集,推荐utf8mb4,兼容emoji\")\n \n # ======================= LLM 相关 =======================\n # 我们的LLM模型API赞助商有:https://aihubmix.com/?aff=8Ds9,提供了非常全面的模型api\n \n # Insight Agent(推荐Kimi,申请地址:https://platform.moonshot.cn/)\n INSIGHT_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Insight Agent(推荐 kimi-k2,官方申请地址:https://platform.moonshot.cn/)API 密钥,用于主 LLM。🚩请先按推荐配置申请并跑通,再根据需要调整 KEY、BASE_URL 与 MODEL_NAME。\")\n INSIGHT_ENGINE_BASE_URL: Optional[str] = Field(\"https://api.moonshot.cn/v1\", description=\"Insight Agent LLM BaseUrl,可根据厂商自定义\")\n INSIGHT_ENGINE_MODEL_NAME: str = Field(\"kimi-k2-0711-preview\", description=\"Insight Agent LLM 模型名称,例如 kimi-k2-0711-preview\")\n \n # Media Agent(推荐Gemini,推荐中转厂商:https://aihubmix.com/?aff=8Ds9)\n MEDIA_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Media Agent(推荐 gemini-2.5-pro,中转厂商申请地址:https://aihubmix.com/?aff=8Ds9)API 密钥\")\n MEDIA_ENGINE_BASE_URL: Optional[str] = Field(\"https://aihubmix.com/v1\", description=\"Media Agent LLM BaseUrl,可根据中转服务调整\")\n MEDIA_ENGINE_MODEL_NAME: str = Field(\"gemini-2.5-pro\", description=\"Media Agent LLM 模型名称,如 gemini-2.5-pro\")\n \n # Query Agent(推荐DeepSeek,申请地址:https://www.deepseek.com/)\n QUERY_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Query Agent(推荐 deepseek,官方申请地址:https://platform.deepseek.com/)API 密钥\")\n QUERY_ENGINE_BASE_URL: Optional[str] = Field(\"https://api.deepseek.com\", description=\"Query Agent LLM BaseUrl\")\n QUERY_ENGINE_MODEL_NAME: str = Field(\"deepseek-chat\", description=\"Query Agent LLM 模型名称,如 deepseek-reasoner\")\n \n # Report Agent(推荐Gemini,推荐中转厂商:https://aihubmix.com/?aff=8Ds9)\n REPORT_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Report Agent(推荐 gemini-2.5-pro,中转厂商申请地址:https://aihubmix.com/?aff=8Ds9)API 密钥\")\n REPORT_ENGINE_BASE_URL: Optional[str] = Field(\"https://aihubmix.com/v1\", description=\"Report Agent LLM BaseUrl,可根据中转服务调整\")\n REPORT_ENGINE_MODEL_NAME: str = Field(\"gemini-2.5-pro\", description=\"Report Agent LLM 模型名称,如 gemini-2.5-pro\")\n\n # MindSpider Agent(推荐Deepseek,官方申请地址:https://platform.deepseek.com/)\n MINDSPIDER_API_KEY: Optional[str] = Field(None, description=\"MindSpider Agent(推荐 deepseek,官方申请地址:https://platform.deepseek.com/)API 密钥\")\n MINDSPIDER_BASE_URL: Optional[str] = Field(None, description=\"MindSpider Agent BaseUrl,可按所选服务配置\")\n MINDSPIDER_MODEL_NAME: Optional[str] = Field(None, description=\"MindSpider Agent 模型名称,例如 deepseek-reasoner\")\n \n # Forum Host(Qwen3最新模型,这里我使用了硅基流动这个平台,申请地址:https://cloud.siliconflow.cn/)\n FORUM_HOST_API_KEY: Optional[str] = Field(None, description=\"Forum Host(推荐 qwen-plus,官方申请地址:https://www.aliyun.com/product/bailian)API 密钥\")\n FORUM_HOST_BASE_URL: Optional[str] = Field(None, description=\"Forum Host LLM BaseUrl,可按所选服务配置\")\n FORUM_HOST_MODEL_NAME: Optional[str] = Field(None, description=\"Forum Host LLM 模型名称,例如 qwen-plus\")\n \n # SQL keyword Optimizer(小参数Qwen3模型,这里我使用了硅基流动这个平台,申请地址:https://cloud.siliconflow.cn/)\n KEYWORD_OPTIMIZER_API_KEY: Optional[str] = Field(None, description=\"SQL Keyword Optimizer(推荐 qwen-plus,官方申请地址:https://www.aliyun.com/product/bailian)API 密钥\")\n KEYWORD_OPTIMIZER_BASE_URL: Optional[str] = Field(None, description=\"Keyword Optimizer BaseUrl,可按所选服务配置\")\n KEYWORD_OPTIMIZER_MODEL_NAME: Optional[str] = Field(None, description=\"Keyword Optimizer LLM 模型名称,例如 qwen-plus\")\n \n # ================== GraphRAG 配置 ====================\n GRAPHRAG_ENABLED: bool = Field(False, description=\"是否启用GraphRAG知识图谱功能(true/false)\")\n GRAPHRAG_MAX_QUERIES: int = Field(3, description=\"GraphRAG每个章节生成前的最大查询次数\")\n \n # ================== 网络工具配置 ====================\n # Tavily API(申请地址:https://www.tavily.com/)\n TAVILY_API_KEY: Optional[str] = Field(None, description=\"Tavily API(申请地址:https://www.tavily.com/)API密钥,用于Tavily网络搜索\")\n\n SEARCH_TOOL_TYPE: Literal[\"AnspireAPI\", \"BochaAPI\"] = Field(\"AnspireAPI\", description=\"网络搜索工具类型,支持BochaAPI或AnspireAPI两种,默认为AnspireAPI\")\n # Bocha API(申请地址:https://open.bochaai.com/)\n BOCHA_BASE_URL: Optional[str] = Field(\"https://api.bocha.cn/v1/ai-search\", description=\"Bocha AI 搜索BaseUrl或博查网页搜索BaseUrl\")\n BOCHA_WEB_SEARCH_API_KEY: Optional[str] = Field(None, description=\"Bocha API(申请地址:https://open.bochaai.com/)API密钥,用于Bocha搜索\")\n\n # Anspire AI Search API(申请地址:https://open.anspire.cn/?share_code=3E1FUOUH)\n ANSPIRE_BASE_URL: Optional[str] = Field(\"https://plugin.anspire.cn/api/ntsearch/search\", description=\"Anspire AI 搜索BaseUrl\")\n ANSPIRE_API_KEY: Optional[str] = Field(None, description=\"Anspire AI Search API(申请地址:https://open.anspire.cn/?share_code=3E1FUOUH)API密钥,用于Anspire搜索\")\n\n # ================== 飞书配置 ====================\n FEISHU_APP_ID: Optional[str] = Field(None, description=\"飞书应用 App ID,用于飞书多维表格API认证\")\n FEISHU_APP_SECRET: Optional[str] = Field(None, description=\"飞书应用 App Secret,用于飞书多维表格API认证\")\n FEISHU_APP_TOKEN: Optional[str] = Field(None, description=\"飞书多维表格 App Token,用于指定默认操作的Bitable\")\n\n \n # ================== Insight Engine 搜索配置 ====================\n DEFAULT_SEARCH_HOT_CONTENT_LIMIT: int = Field(100, description=\"热榜内容默认最大数\")\n DEFAULT_SEARCH_TOPIC_GLOBALLY_LIMIT_PER_TABLE: int = Field(50, description=\"按表全局话题最大数\")\n DEFAULT_SEARCH_TOPIC_BY_DATE_LIMIT_PER_TABLE: int = Field(100, description=\"按日期话题最大数\")\n DEFAULT_GET_COMMENTS_FOR_TOPIC_LIMIT: int = Field(500, description=\"单话题评论最大数\")\n DEFAULT_SEARCH_TOPIC_ON_PLATFORM_LIMIT: int = Field(200, description=\"平台搜索话题最大数\")\n MAX_SEARCH_RESULTS_FOR_LLM: int = Field(0, description=\"供LLM用搜索结果最大数\")\n MAX_HIGH_CONFIDENCE_SENTIMENT_RESULTS: int = Field(0, description=\"高置信度情感分析最大数\")\n MAX_REFLECTIONS: int = Field(3, description=\"最大反思次数\")\n MAX_PARAGRAPHS: int = Field(6, description=\"最大段落数\")\n SEARCH_TIMEOUT: int = Field(240, description=\"单次搜索请求超时\")\n MAX_CONTENT_LENGTH: int = Field(500000, description=\"搜索最大内容长度\")\n \n model_config = ConfigDict(\n env_file=ENV_FILE,\n env_prefix=\"\",\n case_sensitive=False,\n extra=\"allow\"\n )\n\n\n# 创建全局配置实例\nsettings = Settings()\n\n\ndef reload_settings() -> Settings:\n \"\"\"\n 重新加载配置\n \n 从 .env 文件和环境变量重新加载配置,更新全局 settings 实例。\n 用于在运行时动态更新配置。\n \n Returns:\n Settings: 新创建的配置实例\n \"\"\"\n \n global settings\n settings = Settings()\n return settings\n"}, "7a674841724d4f84a48b940bd38ca59a7d5c5598": {"t": 1785764973.657902, "n": 8324, "h": "70994016b7e6ee74", "c": "# -*- coding: utf-8 -*-\n\"\"\"\n微舆配置文件\n\n此模块使用 pydantic-settings 管理全局配置,支持从环境变量和 .env 文件自动加载。\n数据模型定义位置:\n- 本文件 - 配置模型定义\n\"\"\"\n\nfrom pathlib import Path\nfrom pydantic_settings import BaseSettings\nfrom pydantic import Field, ConfigDict\nfrom typing import Optional, Literal\nfrom loguru import logger\n\n\n# 计算 .env 优先级:优先当前工作目录,其次项目根目录\nPROJECT_ROOT: Path = Path(__file__).resolve().parent\nCWD_ENV: Path = Path.cwd() / \".env\"\nENV_FILE: str = str(CWD_ENV if CWD_ENV.exists() else (PROJECT_ROOT / \".env\"))\n\n\nclass Settings(BaseSettings):\n \"\"\"\n 全局配置;支持 .env 和环境变量自动加载。\n 变量名与原 config.py 大写一致,便于平滑过渡。\n \"\"\"\n # ================== Flask 服务器配置 ====================\n HOST: str = Field(\"0.0.0.0\", description=\"BETTAFISH 主机地址,例如 0.0.0.0 或 127.0.0.1\")\n PORT: int = Field(5000, description=\"Flask服务器端口号,默认5000\")\n\n # ================== 日志配置 ====================\n LOG_FILE: str = Field(\"logs/app.log\", description=\"日志文件路径\")\n\n # ================== 报告输出配置 ====================\n OUTPUT_DIR: str = Field(\"final_reports\", description=\"最终报告输出目录\")\n CHAPTER_OUTPUT_DIR: str = Field(\"final_reports/chapters\", description=\"章节中间文件输出目录\")\n DOCUMENT_IR_OUTPUT_DIR: str = Field(\"final_reports/ir\", description=\"文档中间表示输出目录\")\n\n TEMPLATE_DIR: str = Field(\"ReportEngine/report_template\", description=\"报告模板目录\")\n JSON_ERROR_LOG_DIR: str = Field(\"logs/json_errors\", description=\"JSON解析错误日志目录\")\n CHAPTER_JSON_MAX_ATTEMPTS: int = Field(3, description=\"章节JSON生成最大尝试次数\")\n\n # ====================== 数据库配置 ======================\n DB_DIALECT: str = Field(\"postgresql\", description=\"数据库类型,可选 mysql 或 postgresql;请与其他连接信息同时配置\")\n DB_HOST: str = Field(\"your_db_host\", description=\"数据库主机,例如localhost 或 127.0.0.1\")\n DB_PORT: int = Field(3306, description=\"数据库端口号,默认为3306\")\n DB_USER: str = Field(\"your_db_user\", description=\"数据库用户名\")\n DB_PASSWORD: str = Field(\"your_db_password\", description=\"数据库密码\")\n DB_NAME: str = Field(\"your_db_name\", description=\"数据库名称\")\n DB_CHARSET: str = Field(\"utf8mb4\", description=\"数据库字符集,推荐utf8mb4,兼容emoji\")\n \n # ======================= LLM 相关 =======================\n # 我们的LLM模型API赞助商有:https://aihubmix.com/?aff=8Ds9,提供了非常全面的模型api\n \n # Insight Agent(推荐Kimi,申请地址:https://platform.moonshot.cn/)\n INSIGHT_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Insight Agent(推荐 kimi-k2,官方申请地址:https://platform.moonshot.cn/)API 密钥,用于主 LLM。🚩请先按推荐配置申请并跑通,再根据需要调整 KEY、BASE_URL 与 MODEL_NAME。\")\n INSIGHT_ENGINE_BASE_URL: Optional[str] = Field(\"https://api.moonshot.cn/v1\", description=\"Insight Agent LLM BaseUrl,可根据厂商自定义\")\n INSIGHT_ENGINE_MODEL_NAME: str = Field(\"kimi-k2-0711-preview\", description=\"Insight Agent LLM 模型名称,例如 kimi-k2-0711-preview\")\n \n # Media Agent(推荐Gemini,推荐中转厂商:https://aihubmix.com/?aff=8Ds9)\n MEDIA_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Media Agent(推荐 gemini-2.5-pro,中转厂商申请地址:https://aihubmix.com/?aff=8Ds9)API 密钥\")\n MEDIA_ENGINE_BASE_URL: Optional[str] = Field(\"https://aihubmix.com/v1\", description=\"Media Agent LLM BaseUrl,可根据中转服务调整\")\n MEDIA_ENGINE_MODEL_NAME: str = Field(\"gemini-2.5-pro\", description=\"Media Agent LLM 模型名称,如 gemini-2.5-pro\")\n \n # Query Agent(推荐DeepSeek,申请地址:https://www.deepseek.com/)\n QUERY_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Query Agent(推荐 deepseek,官方申请地址:https://platform.deepseek.com/)API 密钥\")\n QUERY_ENGINE_BASE_URL: Optional[str] = Field(\"https://api.deepseek.com\", description=\"Query Agent LLM BaseUrl\")\n QUERY_ENGINE_MODEL_NAME: str = Field(\"deepseek-chat\", description=\"Query Agent LLM 模型名称,如 deepseek-reasoner\")\n \n # Report Agent(推荐Gemini,推荐中转厂商:https://aihubmix.com/?aff=8Ds9)\n REPORT_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Report Agent(推荐 gemini-2.5-pro,中转厂商申请地址:https://aihubmix.com/?aff=8Ds9)API 密钥\")\n REPORT_ENGINE_BASE_URL: Optional[str] = Field(\"https://aihubmix.com/v1\", description=\"Report Agent LLM BaseUrl,可根据中转服务调整\")\n REPORT_ENGINE_MODEL_NAME: str = Field(\"gemini-2.5-pro\", description=\"Report Agent LLM 模型名称,如 gemini-2.5-pro\")\n\n # MindSpider Agent(推荐Deepseek,官方申请地址:https://platform.deepseek.com/)\n MINDSPIDER_API_KEY: Optional[str] = Field(None, description=\"MindSpider Agent(推荐 deepseek,官方申请地址:https://platform.deepseek.com/)API 密钥\")\n MINDSPIDER_BASE_URL: Optional[str] = Field(None, description=\"MindSpider Agent BaseUrl,可按所选服务配置\")\n MINDSPIDER_MODEL_NAME: Optional[str] = Field(None, description=\"MindSpider Agent 模型名称,例如 deepseek-reasoner\")\n \n # Forum Host(Qwen3最新模型,这里我使用了硅基流动这个平台,申请地址:https://cloud.siliconflow.cn/)\n FORUM_HOST_API_KEY: Optional[str] = Field(None, description=\"Forum Host(推荐 qwen-plus,官方申请地址:https://www.aliyun.com/product/bailian)API 密钥\")\n FORUM_HOST_BASE_URL: Optional[str] = Field(None, description=\"Forum Host LLM BaseUrl,可按所选服务配置\")\n FORUM_HOST_MODEL_NAME: Optional[str] = Field(None, description=\"Forum Host LLM 模型名称,例如 qwen-plus\")\n \n # SQL keyword Optimizer(小参数Qwen3模型,这里我使用了硅基流动这个平台,申请地址:https://cloud.siliconflow.cn/)\n KEYWORD_OPTIMIZER_API_KEY: Optional[str] = Field(None, description=\"SQL Keyword Optimizer(推荐 qwen-plus,官方申请地址:https://www.aliyun.com/product/bailian)API 密钥\")\n KEYWORD_OPTIMIZER_BASE_URL: Optional[str] = Field(None, description=\"Keyword Optimizer BaseUrl,可按所选服务配置\")\n KEYWORD_OPTIMIZER_MODEL_NAME: Optional[str] = Field(None, description=\"Keyword Optimizer LLM 模型名称,例如 qwen-plus\")\n \n # ================== GraphRAG 配置 ====================\n GRAPHRAG_ENABLED: bool = Field(False, description=\"是否启用GraphRAG知识图谱功能(true/false)\")\n GRAPHRAG_MAX_QUERIES: int = Field(3, description=\"GraphRAG每个章节生成前的最大查询次数\")\n \n # ================== 网络工具配置 ====================\n # Tavily API(申请地址:https://www.tavily.com/)\n TAVILY_API_KEY: Optional[str] = Field(None, description=\"Tavily API(申请地址:https://www.tavily.com/)API密钥,用于Tavily网络搜索\")\n\n SEARCH_TOOL_TYPE: Literal[\"AnspireAPI\", \"BochaAPI\"] = Field(\"AnspireAPI\", description=\"网络搜索工具类型,支持BochaAPI或AnspireAPI两种,默认为AnspireAPI\")\n # Bocha API(申请地址:https://open.bochaai.com/)\n BOCHA_BASE_URL: Optional[str] = Field(\"https://api.bocha.cn/v1/ai-search\", description=\"Bocha AI 搜索BaseUrl或博查网页搜索BaseUrl\")\n BOCHA_WEB_SEARCH_API_KEY: Optional[str] = Field(None, description=\"Bocha API(申请地址:https://open.bochaai.com/)API密钥,用于Bocha搜索\")\n\n # Anspire AI Search API(申请地址:https://open.anspire.cn/?share_code=3E1FUOUH)\n ANSPIRE_BASE_URL: Optional[str] = Field(\"https://plugin.anspire.cn/api/ntsearch/search\", description=\"Anspire AI 搜索BaseUrl\")\n ANSPIRE_API_KEY: Optional[str] = Field(None, description=\"Anspire AI Search API(申请地址:https://open.anspire.cn/?share_code=3E1FUOUH)API密钥,用于Anspire搜索\")\n\n # ================== 飞书配置 ====================\n FEISHU_APP_ID: Optional[str] = Field(None, description=\"飞书应用 App ID,用于飞书多维表格API认证\")\n FEISHU_APP_SECRET: Optional[str] = Field(None, description=\"飞书应用 App Secret,用于飞书多维表格API认证\")\n FEISHU_APP_TOKEN: Optional[str] = Field(None, description=\"飞书多维表格 App Token,用于指定默认操作的Bitable\")\n\n \n # ================== Insight Engine 搜索配置 ====================\n DEFAULT_SEARCH_HOT_CONTENT_LIMIT: int = Field(100, description=\"热榜内容默认最大数\")\n DEFAULT_SEARCH_TOPIC_GLOBALLY_LIMIT_PER_TABLE: int = Field(50, description=\"按表全局话题最大数\")\n DEFAULT_SEARCH_TOPIC_BY_DATE_LIMIT_PER_TABLE: int = Field(100, description=\"按日期话题最大数\")\n DEFAULT_GET_COMMENTS_FOR_TOPIC_LIMIT: int = Field(500, description=\"单话题评论最大数\")\n DEFAULT_SEARCH_TOPIC_ON_PLATFORM_LIMIT: int = Field(200, description=\"平台搜索话题最大数\")\n MAX_SEARCH_RESULTS_FOR_LLM: int = Field(0, description=\"供LLM用搜索结果最大数\")\n MAX_HIGH_CONFIDENCE_SENTIMENT_RESULTS: int = Field(0, description=\"高置信度情感分析最大数\")\n MAX_REFLECTIONS: int = Field(3, description=\"最大反思次数\")\n MAX_PARAGRAPHS: int = Field(6, description=\"最大段落数\")\n SEARCH_TIMEOUT: int = Field(240, description=\"单次搜索请求超时\")\n MAX_CONTENT_LENGTH: int = Field(500000, description=\"搜索最大内容长度\")\n \n model_config = ConfigDict(\n env_file=ENV_FILE,\n env_prefix=\"\",\n case_sensitive=False,\n extra=\"allow\"\n )\n\n\n# 创建全局配置实例\nsettings = Settings()\n\n\ndef reload_settings() -> Settings:\n \"\"\"\n 重新加载配置\n \n 从 .env 文件和环境变量重新加载配置,更新全局 settings 实例。\n 用于在运行时动态更新配置。\n \n Returns:\n Settings: 新创建的配置实例\n \"\"\"\n \n global settings\n settings = Settings()\n return settings\n"}, "8987f47d1f1c54bb008f7bbe164da39444ad5996": {"t": 1785764975.122001, "n": 7989, "h": "8eac2567330019bb", "c": "# -*- coding: utf-8 -*-\n\"\"\"\n微舆配置文件\n\n此模块使用 pydantic-settings 管理全局配置,支持从环境变量和 .env 文件自动加载。\n数据模型定义位置:\n- 本文件 - 配置模型定义\n\"\"\"\n\nfrom pathlib import Path\nfrom pydantic_settings import BaseSettings\nfrom pydantic import Field, ConfigDict\nfrom typing import Optional, Literal\nfrom loguru import logger\n\n\n# 计算 .env 优先级:优先当前工作目录,其次项目根目录\nPROJECT_ROOT: Path = Path(__file__).resolve().parent\nCWD_ENV: Path = Path.cwd() / \".env\"\nENV_FILE: str = str(CWD_ENV if CWD_ENV.exists() else (PROJECT_ROOT / \".env\"))\n\n\nclass Settings(BaseSettings):\n \"\"\"\n 全局配置;支持 .env 和环境变量自动加载。\n 变量名与原 config.py 大写一致,便于平滑过渡。\n \"\"\"\n # ================== Flask 服务器配置 ====================\n HOST: str = Field(\"0.0.0.0\", description=\"BETTAFISH 主机地址,例如 0.0.0.0 或 127.0.0.1\")\n PORT: int = Field(5000, description=\"Flask服务器端口号,默认5000\")\n\n # ================== 日志配置 ====================\n LOG_FILE: str = Field(\"logs/app.log\", description=\"日志文件路径\")\n\n # ================== 报告输出配置 ====================\n OUTPUT_DIR: str = Field(\"final_reports\", description=\"最终报告输出目录\")\n CHAPTER_OUTPUT_DIR: str = Field(\"final_reports/chapters\", description=\"章节中间文件输出目录\")\n DOCUMENT_IR_OUTPUT_DIR: str = Field(\"final_reports/ir\", description=\"文档中间表示输出目录\")\n\n TEMPLATE_DIR: str = Field(\"ReportEngine/report_template\", description=\"报告模板目录\")\n JSON_ERROR_LOG_DIR: str = Field(\"logs/json_errors\", description=\"JSON解析错误日志目录\")\n CHAPTER_JSON_MAX_ATTEMPTS: int = Field(3, description=\"章节JSON生成最大尝试次数\")\n\n # ====================== 数据库配置 ======================\n DB_DIALECT: str = Field(\"postgresql\", description=\"数据库类型,可选 mysql 或 postgresql;请与其他连接信息同时配置\")\n DB_HOST: str = Field(\"your_db_host\", description=\"数据库主机,例如localhost 或 127.0.0.1\")\n DB_PORT: int = Field(3306, description=\"数据库端口号,默认为3306\")\n DB_USER: str = Field(\"your_db_user\", description=\"数据库用户名\")\n DB_PASSWORD: str = Field(\"your_db_password\", description=\"数据库密码\")\n DB_NAME: str = Field(\"your_db_name\", description=\"数据库名称\")\n DB_CHARSET: str = Field(\"utf8mb4\", description=\"数据库字符集,推荐utf8mb4,兼容emoji\")\n \n # ======================= LLM 相关 =======================\n # 我们的LLM模型API赞助商有:https://aihubmix.com/?aff=8Ds9,提供了非常全面的模型api\n \n # Insight Agent(推荐Kimi,申请地址:https://platform.moonshot.cn/)\n INSIGHT_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Insight Agent(推荐 kimi-k2,官方申请地址:https://platform.moonshot.cn/)API 密钥,用于主 LLM。🚩请先按推荐配置申请并跑通,再根据需要调整 KEY、BASE_URL 与 MODEL_NAME。\")\n INSIGHT_ENGINE_BASE_URL: Optional[str] = Field(\"https://api.moonshot.cn/v1\", description=\"Insight Agent LLM BaseUrl,可根据厂商自定义\")\n INSIGHT_ENGINE_MODEL_NAME: str = Field(\"kimi-k2-0711-preview\", description=\"Insight Agent LLM 模型名称,例如 kimi-k2-0711-preview\")\n \n # Media Agent(推荐Gemini,推荐中转厂商:https://aihubmix.com/?aff=8Ds9)\n MEDIA_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Media Agent(推荐 gemini-2.5-pro,中转厂商申请地址:https://aihubmix.com/?aff=8Ds9)API 密钥\")\n MEDIA_ENGINE_BASE_URL: Optional[str] = Field(\"https://aihubmix.com/v1\", description=\"Media Agent LLM BaseUrl,可根据中转服务调整\")\n MEDIA_ENGINE_MODEL_NAME: str = Field(\"gemini-2.5-pro\", description=\"Media Agent LLM 模型名称,如 gemini-2.5-pro\")\n \n # Query Agent(推荐DeepSeek,申请地址:https://www.deepseek.com/)\n QUERY_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Query Agent(推荐 deepseek,官方申请地址:https://platform.deepseek.com/)API 密钥\")\n QUERY_ENGINE_BASE_URL: Optional[str] = Field(\"https://api.deepseek.com\", description=\"Query Agent LLM BaseUrl\")\n QUERY_ENGINE_MODEL_NAME: str = Field(\"deepseek-chat\", description=\"Query Agent LLM 模型名称,如 deepseek-reasoner\")\n \n # Report Agent(推荐Gemini,推荐中转厂商:https://aihubmix.com/?aff=8Ds9)\n REPORT_ENGINE_API_KEY: Optional[str] = Field(None, description=\"Report Agent(推荐 gemini-2.5-pro,中转厂商申请地址:https://aihubmix.com/?aff=8Ds9)API 密钥\")\n REPORT_ENGINE_BASE_URL: Optional[str] = Field(\"https://aihubmix.com/v1\", description=\"Report Agent LLM BaseUrl,可根据中转服务调整\")\n REPORT_ENGINE_MODEL_NAME: str = Field(\"gemini-2.5-pro\", description=\"Report Agent LLM 模型名称,如 gemini-2.5-pro\")\n\n # MindSpider Agent(推荐Deepseek,官方申请地址:https://platform.deepseek.com/)\n MINDSPIDER_API_KEY: Optional[str] = Field(None, description=\"MindSpider Agent(推荐 deepseek,官方申请地址:https://platform.deepseek.com/)API 密钥\")\n MINDSPIDER_BASE_URL: Optional[str] = Field(None, description=\"MindSpider Agent BaseUrl,可按所选服务配置\")\n MINDSPIDER_MODEL_NAME: Optional[str] = Field(None, description=\"MindSpider Agent 模型名称,例如 deepseek-reasoner\")\n \n # Forum Host(Qwen3最新模型,这里我使用了硅基流动这个平台,申请地址:https://cloud.siliconflow.cn/)\n FORUM_HOST_API_KEY: Optional[str] = Field(None, description=\"Forum Host(推荐 qwen-plus,官方申请地址:https://www.aliyun.com/product/bailian)API 密钥\")\n FORUM_HOST_BASE_URL: Optional[str] = Field(None, description=\"Forum Host LLM BaseUrl,可按所选服务配置\")\n FORUM_HOST_MODEL_NAME: Optional[str] = Field(None, description=\"Forum Host LLM 模型名称,例如 qwen-plus\")\n \n # SQL keyword Optimizer(小参数Qwen3模型,这里我使用了硅基流动这个平台,申请地址:https://cloud.siliconflow.cn/)\n KEYWORD_OPTIMIZER_API_KEY: Optional[str] = Field(None, description=\"SQL Keyword Optimizer(推荐 qwen-plus,官方申请地址:https://www.aliyun.com/product/bailian)API 密钥\")\n KEYWORD_OPTIMIZER_BASE_URL: Optional[str] = Field(None, description=\"Keyword Optimizer BaseUrl,可按所选服务配置\")\n KEYWORD_OPTIMIZER_MODEL_NAME: Optional[str] = Field(None, description=\"Keyword Optimizer LLM 模型名称,例如 qwen-plus\")\n \n # ================== GraphRAG 配置 ====================\n GRAPHRAG_ENABLED: bool = Field(False, description=\"是否启用GraphRAG知识图谱功能(true/false)\")\n GRAPHRAG_MAX_QUERIES: int = Field(3, description=\"GraphRAG每个章节生成前的最大查询次数\")\n \n # ================== 网络工具配置 ====================\n # Tavily API(申请地址:https://www.tavily.com/)\n TAVILY_API_KEY: Optional[str] = Field(None, description=\"Tavily API(申请地址:https://www.tavily.com/)API密钥,用于Tavily网络搜索\")\n\n SEARCH_TOOL_TYPE: Literal[\"AnspireAPI\", \"BochaAPI\"] = Field(\"AnspireAPI\", description=\"网络搜索工具类型,支持BochaAPI或AnspireAPI两种,默认为AnspireAPI\")\n # Bocha API(申请地址:https://open.bochaai.com/)\n BOCHA_BASE_URL: Optional[str] = Field(\"https://api.bocha.cn/v1/ai-search\", description=\"Bocha AI 搜索BaseUrl或博查网页搜索BaseUrl\")\n BOCHA_WEB_SEARCH_API_KEY: Optional[str] = Field(None, description=\"Bocha API(申请地址:https://open.bochaai.com/)API密钥,用于Bocha搜索\")\n\n # Anspire AI Search API(申请地址:https://open.anspire.cn/?share_code=3E1FUOUH)\n ANSPIRE_BASE_URL: Optional[str] = Field(\"https://plugin.anspire.cn/api/ntsearch/search\", description=\"Anspire AI 搜索BaseUrl\")\n ANSPIRE_API_KEY: Optional[str] = Field(None, description=\"Anspire AI Search API(申请地址:https://open.anspire.cn/?share_code=3E1FUOUH)API密钥,用于Anspire搜索\")\n\n \n # ================== Insight Engine 搜索配置 ====================\n DEFAULT_SEARCH_HOT_CONTENT_LIMIT: int = Field(100, description=\"热榜内容默认最大数\")\n DEFAULT_SEARCH_TOPIC_GLOBALLY_LIMIT_PER_TABLE: int = Field(50, description=\"按表全局话题最大数\")\n DEFAULT_SEARCH_TOPIC_BY_DATE_LIMIT_PER_TABLE: int = Field(100, description=\"按日期话题最大数\")\n DEFAULT_GET_COMMENTS_FOR_TOPIC_LIMIT: int = Field(500, description=\"单话题评论最大数\")\n DEFAULT_SEARCH_TOPIC_ON_PLATFORM_LIMIT: int = Field(200, description=\"平台搜索话题最大数\")\n MAX_SEARCH_RESULTS_FOR_LLM: int = Field(0, description=\"供LLM用搜索结果最大数\")\n MAX_HIGH_CONFIDENCE_SENTIMENT_RESULTS: int = Field(0, description=\"高置信度情感分析最大数\")\n MAX_REFLECTIONS: int = Field(3, description=\"最大反思次数\")\n MAX_PARAGRAPHS: int = Field(6, description=\"最大段落数\")\n SEARCH_TIMEOUT: int = Field(240, description=\"单次搜索请求超时\")\n MAX_CONTENT_LENGTH: int = Field(500000, description=\"搜索最大内容长度\")\n \n model_config = ConfigDict(\n env_file=ENV_FILE,\n env_prefix=\"\",\n case_sensitive=False,\n extra=\"allow\"\n )\n\n\n# 创建全局配置实例\nsettings = Settings()\n\n\ndef reload_settings() -> Settings:\n \"\"\"\n 重新加载配置\n \n 从 .env 文件和环境变量重新加载配置,更新全局 settings 实例。\n 用于在运行时动态更新配置。\n \n Returns:\n Settings: 新创建的配置实例\n \"\"\"\n \n global settings\n settings = Settings()\n return settings\n"}}, "patch_report_engine_deepseek.py": {"359daa4d119dc1551d99bc2bffda7e7afd49cae6": {"t": 1785809880.3838441, "n": 2649, "h": "b6695d7e0f3a9d22", "c": "import os\n\ntarget_file = r\"D:\\my-web-app\\BettaFish\\report_engine_only.py\"\n\ntry:\n with open(target_file, \"r\", encoding=\"utf-8\") as f:\n content = f.read()\n\n old_code = \"\"\"def build_agent_config(args) -> Settings:\n \\\"\\\"\\\"基于 .env 配置并融合命令行覆盖项生成最终配置\\\"\\\"\\\"\n config_overrides: Dict[str, Any] = {}\n\n if args.graphrag_enabled is not None:\n config_overrides[\"GRAPHRAG_ENABLED\"] = args.graphrag_enabled\n if args.graphrag_max_queries is not None:\n if args.graphrag_max_queries <= 0:\n logger.warning(\"GRAPHRAG_MAX_QUERIES 必须大于 0,本次将继续使用 .env/默认值\")\n else:\n config_overrides[\"GRAPHRAG_MAX_QUERIES\"] = args.graphrag_max_queries\n\n if not config_overrides:\n return global_settings\n\n return global_settings.model_copy(update=config_overrides)\"\"\"\n\n new_code = \"\"\"def build_agent_config(args) -> Settings:\n \\\"\\\"\\\"基于 .env 配置并融合命令行覆盖项生成最终配置\\\"\\\"\\\"\n # 强制重新加载配置,确保获取最新的环境变量\n try:\n current_settings = Settings()\n except Exception as e:\n logger.warning(f\"重新加载配置失败,使用默认配置: {e}\")\n current_settings = global_settings\n\n config_overrides: Dict[str, Any] = {}\n\n # 自动适配 DeepSeek (如果用户只配了 Key 没改 URL)\n # 假设 DeepSeek Key 以 sk- 开头,且当前 Base URL 是默认的 aihubmix\n api_key = current_settings.REPORT_ENGINE_API_KEY\n base_url = current_settings.REPORT_ENGINE_BASE_URL\n \n if api_key and api_key.startswith(\"sk-\") and \"aihubmix\" in (base_url or \"\"):\n logger.info(\"🔧 检测到 DeepSeek 风格 API Key,自动切换至 DeepSeek 官方节点\")\n config_overrides[\"REPORT_ENGINE_BASE_URL\"] = \"https://api.deepseek.com\"\n config_overrides[\"REPORT_ENGINE_MODEL_NAME\"] = \"deepseek-chat\"\n\n if args.graphrag_enabled is not None:\n config_overrides[\"GRAPHRAG_ENABLED\"] = args.graphrag_enabled\n if args.graphrag_max_queries is not None:\n if args.graphrag_max_queries <= 0:\n logger.warning(\"GRAPHRAG_MAX_QUERIES 必须大于 0,本次将继续使用 .env/默认值\")\n else:\n config_overrides[\"GRAPHRAG_MAX_QUERIES\"] = args.graphrag_max_queries\n\n if not config_overrides:\n return current_settings\n\n return current_settings.model_copy(update=config_overrides)\"\"\"\n\n if old_code in content:\n new_content = content.replace(old_code, new_code)\n with open(target_file, \"w\", encoding=\"utf-8\") as f:\n f.write(new_content)\n print(\"Success: Patched report_engine_only.py\")\n else:\n print(\"Error: Could not find target code block. Content length:\", len(content))\n # Optional: Print a snippet to verify\n print(\"Snippet:\", content[539:600])\n\nexcept Exception as e:\n print(f\"File operation failed: {e}\")\n"}}}}