""" EPEEKit 集中配置。 所有可调参数从环境变量读取,每次调用实时读取(不缓存),确保 load_dotenv() 后生效。 """ import os from typing import Any def get_llm_max_iterations() -> int: return int(os.getenv("LLM_MAX_ITERATIONS", "5")) # ─── LLM 模型注册表 ───────────────────────────────────── # # 每个模型的配置说明: # id — 前端/API 使用的短 ID # name — 显示名称 # provider — API 提供者(对应 _get_client 的分发键) # model_id — 传给 OpenAI SDK 的 model 参数 # description — 前端下拉列表说明文字 # vision — 是否支持多模态图片输入 LLM_MODELS: dict[str, dict[str, Any]] = { "gpt-5.4": { "id": "gpt-5.4", "name": "GPT-5.4", "provider": "vectorengine", "model_id": "gpt-5.4", "description": "知识工作与计算机操控最强,1M 上下文", "vision": True, }, "claude-sonnet-4-6": { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6", "provider": "vectorengine", "model_id": "claude-sonnet-4-6", "description": "高性价比编码与日常任务", "vision": True, }, "claude-opus-4-6": { "id": "claude-opus-4-6", "name": "Claude Opus 4.6", "provider": "vectorengine", "model_id": "claude-opus-4-6", "description": "编码与专家级推理最强,128K 输出", "vision": True, }, "gemini-3.1-pro-preview": { "id": "gemini-3.1-pro-preview", "name": "Gemini 3.1 Pro", "provider": "vectorengine", "model_id": "gemini-3.1-pro-preview", "description": "推理最强、价格最低,2M 上下文", "vision": True, }, "glm-4.7": { "id": "glm-4.7", "name": "GLM-4.7", "provider": "vectorengine", "model_id": "glm-4.7", "description": "智谱 AI,中文能力突出,免费额度", "vision": False, }, "gpt-4o-mini": { "id": "gpt-4o-mini", "name": "GPT-4o Mini", "provider": "vectorengine", "model_id": "gpt-4o-mini", "description": "轻量快速、高性价比", "vision": True, }, "deepseek-chat": { "id": "deepseek-chat", "name": "DeepSeek Chat", "provider": "deepseek", "model_id": "deepseek-chat", "description": "中文对话优化(直连)", "vision": False, }, } def get_default_llm_model_id() -> str: """返回 .env 中配置的默认 LLM 短 ID,不在注册表中则回退到 gpt-5.4。""" env_model = os.getenv("LLM_MODEL", "gpt-5.4") if env_model in LLM_MODELS: return env_model return "gpt-5.4" def get_llm_model_config(model_id: str | None = None) -> dict[str, Any]: """根据短 ID 获取 LLM 模型配置,未指定或不存在则使用默认模型。""" if model_id and model_id in LLM_MODELS: return LLM_MODELS[model_id] return LLM_MODELS[get_default_llm_model_id()] def get_llm_models_list() -> list[dict]: """返回前端下拉列表所需的 LLM 模型摘要信息。""" return [ { "id": cfg["id"], "name": cfg["name"], "description": cfg["description"], "vision": cfg.get("vision", False), } for cfg in LLM_MODELS.values() ] # ─── 图像模型注册表 ───────────────────────────────────── # # 每个模型的配置说明: # id — 前端/API 使用的短 ID # name — 显示名称 # provider — 生成服务提供者(对应 image_gen.py 中的 Provider) # model_id — Replicate 上的完整模型 ID # description — 前端下拉列表中的说明文字 # supports_ref_image — 是否原生支持参考图输入(IP-Adapter 等) # ref_image_param — 传给 Replicate 的参考图参数名(模型间可能不同) # num_images_param — 批量生成参数名(Flux 用 num_outputs,Kolors 用 number_of_images) # default_params — 默认推理参数 IMAGE_MODELS: dict[str, dict[str, Any]] = { "gpt-image-1.5": { "id": "gpt-image-1.5", "name": "GPT Image 1.5", "provider": "openai", "model_id": "gpt-image-1.5", "description": "OpenAI 最强生图,文字渲染与 prompt 理解最佳,支持多图参考", "supports_ref_image": True, "max_ref_images": 16, "default_params": { "size": "1024x1024", "quality": "high", }, }, "gemini-3.1-flash-image": { "id": "gemini-3.1-flash-image", "name": "Gemini 3.1 Flash Image", "provider": "gemini_native", "model_id": "gemini-3.1-flash-image-preview", "description": "Google 原生生图,速度快、价格低,支持多图参考(最多 14 张)", "supports_ref_image": True, "max_ref_images": 14, "default_params": {}, }, "flux-schnell": { "id": "flux-schnell", "name": "Flux Schnell", "provider": "replicate", "model_id": "black-forest-labs/flux-schnell", "description": "快速生成,适合快速迭代", "supports_ref_image": False, "num_images_param": "num_outputs", "default_params": { "aspect_ratio": "1:1", "output_format": "png", }, }, "flux-dev": { "id": "flux-dev", "name": "Flux Dev", "provider": "replicate", "model_id": "black-forest-labs/flux-dev", "description": "高质量生成,细节更好", "supports_ref_image": False, "num_images_param": "num_outputs", "default_params": { "aspect_ratio": "1:1", "output_format": "png", }, }, "sdxl": { "id": "sdxl", "name": "Stable Diffusion XL", "provider": "replicate", "model_id": "stability-ai/sdxl:39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b", "description": "经典 SDXL,支持 negative prompt", "supports_ref_image": False, "num_images_param": "num_outputs", "default_params": { "width": 1024, "height": 1024, "num_inference_steps": 50, "guidance_scale": 7.5, }, }, "instant-style": { "id": "instant-style", "name": "InstantStyle", "provider": "replicate", "model_id": "jyoung105/instant-style:c6f01e12f31cb99f9ee774a78992a71294f630a6f433d9aecfdc33b816fc4baa", "description": "强风格迁移,画风还原度高(较慢)", "supports_ref_image": True, "ref_image_param": "style_image", "num_images_param": "num_outputs", "default_params": { "width": 1024, "height": 1024, "num_inference_steps": 30, "guidance_scale": 5, "style_strength": 1.0, "block_mode": "style-only", "adapter_mode": "original", }, }, "kolors-ipadapter": { "id": "kolors-ipadapter", "name": "Kolors IP-Adapter", "provider": "replicate", "model_id": "fofr/kolors-with-ipadapter:5a1a92b2c0f81813225d48ed8e411813da41aa84e7582fb705d1af46eea36eed", "description": "风格参考生成,上传参考图效果最佳", "supports_ref_image": True, "ref_image_param": "image", "num_images_param": "number_of_images", "default_params": { "width": 1024, "height": 1024, "steps": 25, "cfg": 4, "ip_adapter_weight": 0.8, "ip_adapter_weight_type": "style transfer precise", "output_format": "png", }, }, } def get_default_image_model_id() -> str: """返回 .env 中配置的默认模型短 ID,若不在注册表中则回退到 flux-schnell。""" env_model = os.getenv("IMAGE_MODEL", "flux-schnell") for mid, cfg in IMAGE_MODELS.items(): if cfg["model_id"] == env_model or mid == env_model: return mid return "flux-schnell" def get_image_model_config(model_id: str | None = None) -> dict[str, Any]: """根据短 ID 获取模型配置,未指定或不存在则使用默认模型。""" if model_id and model_id in IMAGE_MODELS: return IMAGE_MODELS[model_id] return IMAGE_MODELS[get_default_image_model_id()] def get_ref_image_model_id() -> str | None: """返回有参考图时推荐使用的模型 ID(第一个 supports_ref_image=True 的模型)。""" for mid, cfg in IMAGE_MODELS.items(): if cfg.get("supports_ref_image"): return mid return None def get_image_models_list() -> list[dict]: """返回前端下拉列表所需的模型摘要信息。""" return [ { "id": cfg["id"], "name": cfg["name"], "description": cfg["description"], "supports_ref_image": cfg.get("supports_ref_image", False), } for cfg in IMAGE_MODELS.values() ] # ─── 记忆系统配置 ───────────────────────────────────── def get_deepseek_api_key() -> str: return os.getenv("DEEPSEEK_API_KEY", "") def get_ollama_base_url() -> str: return os.getenv("OLLAMA_BASE_URL", "http://localhost:11434") def get_mem0_embedding_model() -> str: return os.getenv("MEM0_EMBEDDING_MODEL", "nomic-embed-text") def get_max_recent_turns() -> int: return int(os.getenv("MAX_RECENT_TURNS", "20")) # ─── 图像输出配置 ───────────────────────────────────── def get_image_aspect_ratio() -> str: return os.getenv("IMAGE_ASPECT_RATIO", "1:1") def get_image_output_format() -> str: return os.getenv("IMAGE_OUTPUT_FORMAT", "png")