diff --git a/api/app/config/default_free_plan.py b/api/app/config/default_free_plan.py index cb975dcc..409b4f7b 100644 --- a/api/app/config/default_free_plan.py +++ b/api/app/config/default_free_plan.py @@ -1,35 +1,77 @@ """ 社区版默认免费套餐配置 当无法从 SaaS 版获取 premium 模块时,使用此配置作为兜底 + +可通过环境变量覆盖配额配置,格式:QUOTA_ +例如:QUOTA_END_USER_QUOTA=100 """ -DEFAULT_FREE_PLAN = { - "name": "记忆体验版", - "name_en": "Memory Experience", - "category": "saas_personal", - "tier_level": 0, - "version": "1.0", - "status": True, - "price": 0, - "billing_cycle": "permanent_free", - "core_value": "感受永久记忆", - "core_value_en": "Experience Permanent Memory", - "tech_support": "社群交流", - "tech_support_en": "Community Support", - "sla_compliance": "无", - "sla_compliance_en": "None", - "page_customization": "无", - "page_customization_en": "None", - "theme_color": "#64748B", - "quotas": { - "workspace_quota": 10, - "skill_quota": 50, - "app_quota": 20, - "knowledge_capacity_quota": 30, - "memory_engine_quota": 10, - "end_user_quota": 50, - "ontology_project_quota": 30, - "model_quota": 10, - "api_ops_rate_limit": 50, - }, -} +import os + + +def _get_quota_from_env(): + """从环境变量获取配额配置""" + quota_keys = [ + "workspace_quota", + "skill_quota", + "app_quota", + "knowledge_capacity_quota", + "memory_engine_quota", + "end_user_quota", + "ontology_project_quota", + "model_quota", + "api_ops_rate_limit", + ] + quotas = {} + for key in quota_keys: + env_key = f"QUOTA_{key.upper()}" + env_value = os.getenv(env_key) + if env_value is not None: + try: + quotas[key] = float(env_value) if '.' in env_value else int(env_value) + except ValueError: + pass + return quotas + + +def _build_default_free_plan(): + """构建默认免费套餐配置""" + base = { + "name": "记忆体验版", + "name_en": "Memory Experience", + "category": "saas_personal", + "tier_level": 0, + "version": "1.0", + "status": True, + "price": 0, + "billing_cycle": "permanent_free", + "core_value": "感受永久记忆", + "core_value_en": "Experience Permanent Memory", + "tech_support": "社群交流", + "tech_support_en": "Community Support", + "sla_compliance": "无", + "sla_compliance_en": "None", + "page_customization": "无", + "page_customization_en": "None", + "theme_color": "#64748B", + "quotas": { + "workspace_quota": 1, + "skill_quota": 5, + "app_quota": 2, + "knowledge_capacity_quota": 0.3, + "memory_engine_quota": 1, + "end_user_quota": 1, + "ontology_project_quota": 3, + "model_quota": 1, + "api_ops_rate_limit": 50, + }, + } + + env_quotas = _get_quota_from_env() + if env_quotas: + base["quotas"].update(env_quotas) + + return base + + +DEFAULT_FREE_PLAN = _build_default_free_plan() diff --git a/api/app/controllers/app_controller.py b/api/app/controllers/app_controller.py index f7fdc90f..e13d3c2b 100644 --- a/api/app/controllers/app_controller.py +++ b/api/app/controllers/app_controller.py @@ -271,18 +271,17 @@ def update_agent_config( return success(data=app_schema.AgentConfig.model_validate(cfg)) -@router.post("/{app_id}/config/reset", summary="重置 Agent 配置为默认状态") +@router.post("/{app_id}/model/parameters/reset", summary="获取 Agent 模型参数默认配置") @cur_workspace_access_guard() -def reset_agent_config( +def reset_agent_model_parameters( app_id: uuid.UUID, db: Session = Depends(get_db), current_user=Depends(get_current_user), ): workspace_id = current_user.current_workspace_id service = AppService(db) - cfg = service.reset_agent_config(app_id=app_id, workspace_id=workspace_id) - cfg = enrich_agent_config(cfg) - return success(data=app_schema.AgentConfig.model_validate(cfg), msg="Agent 配置已重置为默认状态") + model_parameters = service.get_default_model_parameters(app_id=app_id) + return success(data=model_parameters, msg="获取 Agent 模型参数默认配置") @router.get("/{app_id}/config", summary="获取 Agent 配置") diff --git a/api/app/services/app_service.py b/api/app/services/app_service.py index 549af761..c4023b0e 100644 --- a/api/app/services/app_service.py +++ b/api/app/services/app_service.py @@ -1452,20 +1452,46 @@ class AppService: logger.debug("配置不存在,返回默认模板", extra={"app_id": str(app_id)}) return self._create_default_agent_config(app_id) + def get_default_model_parameters( + self, + *, + app_id: uuid.UUID, + ) -> "ModelParameters": + """获取 Agent 默认模型参数(不修改数据库) + + Args: + app_id: 应用ID + + Returns: + ModelParameters: 默认模型参数 + """ + logger.info("获取 Agent 默认模型参数", extra={"app_id": str(app_id)}) + + app = self._get_app_or_404(app_id) + + if app.type != "agent": + raise BusinessException("只有 Agent 类型应用支持 Agent 配置", BizCode.APP_TYPE_NOT_SUPPORTED) + + from app.schemas.app_schema import ModelParameters + default_model_parameters = ModelParameters() + + logger.info("获取 Agent 默认模型参数成功", extra={"app_id": str(app_id)}) + return default_model_parameters + def reset_agent_config( self, *, app_id: uuid.UUID, workspace_id: Optional[uuid.UUID] = None - ) -> AgentConfig: - """仅将 Agent 模型参数重置为默认值(不影响其他配置) + ) -> "ModelParameters": + """将 Agent 模型参数重置为默认值(不影响其他配置) Args: app_id: 应用ID workspace_id: 工作空间ID(用于权限验证) Returns: - AgentConfig: 重置后的配置对象 + ModelParameters: 重置后的模型参数 """ logger.info("重置 Agent 模型参数为默认值", extra={"app_id": str(app_id)}) @@ -1476,21 +1502,14 @@ class AppService: self._validate_app_writable(app, workspace_id) + from app.schemas.app_schema import ModelParameters + default_model_parameters = ModelParameters() + stmt = select(AgentConfig).where(AgentConfig.app_id == app_id, AgentConfig.is_active.is_(True)).order_by( AgentConfig.updated_at.desc()) agent_cfg: Optional[AgentConfig] = self.db.scalars(stmt).first() now = datetime.datetime.now() - default_model_parameters = { - "temperature": 0.7, - "max_tokens": 2000, - "top_p": 1.0, - "frequency_penalty": 0.0, - "presence_penalty": 0.0, - "n": 1, - "stop": None - } - if agent_cfg: agent_cfg.default_model_config_id = None agent_cfg.model_parameters = default_model_parameters @@ -1508,10 +1527,9 @@ class AppService: self.db.add(agent_cfg) self.db.commit() - self.db.refresh(agent_cfg) logger.info("Agent 模型参数重置成功", extra={"app_id": str(app_id)}) - return agent_cfg + return default_model_parameters def _create_default_agent_config(self, app_id: uuid.UUID) -> AgentConfig: """创建默认的 Agent 配置模板(不保存到数据库)