From f883c1469d3df260e01834c22a8f4e0bef3c0a1a Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 16 Apr 2026 19:35:52 +0800 Subject: [PATCH] feat(quota management): add end-user quota check for shared conversations fix(default free plan): adjust free plan quota limits feat(application service): add functionality to reset Agent model parameters to default values --- api/app/config/default_free_plan.py | 16 ++--- api/app/controllers/app_controller.py | 14 +++++ .../controllers/public_share_controller.py | 2 + api/app/core/quota_manager.py | 12 ++++ api/app/services/app_service.py | 61 +++++++++++++++++++ 5 files changed, 97 insertions(+), 8 deletions(-) diff --git a/api/app/config/default_free_plan.py b/api/app/config/default_free_plan.py index 4b357236..cb975dcc 100644 --- a/api/app/config/default_free_plan.py +++ b/api/app/config/default_free_plan.py @@ -22,14 +22,14 @@ DEFAULT_FREE_PLAN = { "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, + "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, }, } diff --git a/api/app/controllers/app_controller.py b/api/app/controllers/app_controller.py index 34449bb5..f7fdc90f 100644 --- a/api/app/controllers/app_controller.py +++ b/api/app/controllers/app_controller.py @@ -271,6 +271,20 @@ def update_agent_config( return success(data=app_schema.AgentConfig.model_validate(cfg)) +@router.post("/{app_id}/config/reset", summary="重置 Agent 配置为默认状态") +@cur_workspace_access_guard() +def reset_agent_config( + 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 配置已重置为默认状态") + + @router.get("/{app_id}/config", summary="获取 Agent 配置") @cur_workspace_access_guard() def get_agent_config( diff --git a/api/app/controllers/public_share_controller.py b/api/app/controllers/public_share_controller.py index ddd31071..049535b5 100644 --- a/api/app/controllers/public_share_controller.py +++ b/api/app/controllers/public_share_controller.py @@ -10,6 +10,7 @@ from sqlalchemy.orm import Session from app.core.error_codes import BizCode from app.core.exceptions import BusinessException from app.core.logging_config import get_business_logger +from app.core.quota_manager import check_end_user_quota from app.core.response_utils import success, fail from app.db import get_db, get_db_read from app.dependencies import get_share_user_id, ShareTokenData @@ -308,6 +309,7 @@ def get_conversation( "/chat", summary="发送消息(支持流式和非流式)" ) +@check_end_user_quota async def chat( payload: conversation_schema.ChatRequest, share_data: ShareTokenData = Depends(get_share_user_id), diff --git a/api/app/core/quota_manager.py b/api/app/core/quota_manager.py index 6c02ac7a..0e0053a0 100644 --- a/api/app/core/quota_manager.py +++ b/api/app/core/quota_manager.py @@ -55,6 +55,18 @@ def _get_tenant_id_from_kwargs(db: Session, kwargs: dict): if workspace: return workspace.tenant_id + share_data = kwargs.get("share_data") + if share_data and hasattr(share_data, 'share_token'): + from app.models.workspace_model import Workspace + from app.models.app_model import App + share_token = share_data.share_token + from app.models.release_share_model import ReleaseShare + share_record = db.query(ReleaseShare).filter(ReleaseShare.share_token == share_token).first() + if share_record: + app = db.query(App).filter(App.id == share_record.app_id, App.is_active.is_(True)).first() + if app: + return app.workspace.tenant_id + return None diff --git a/api/app/services/app_service.py b/api/app/services/app_service.py index 534ab8d0..549af761 100644 --- a/api/app/services/app_service.py +++ b/api/app/services/app_service.py @@ -1452,6 +1452,67 @@ class AppService: logger.debug("配置不存在,返回默认模板", extra={"app_id": str(app_id)}) return self._create_default_agent_config(app_id) + def reset_agent_config( + self, + *, + app_id: uuid.UUID, + workspace_id: Optional[uuid.UUID] = None + ) -> AgentConfig: + """仅将 Agent 模型参数重置为默认值(不影响其他配置) + + Args: + app_id: 应用ID + workspace_id: 工作空间ID(用于权限验证) + + Returns: + AgentConfig: 重置后的配置对象 + """ + 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) + + self._validate_app_writable(app, workspace_id) + + 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 + agent_cfg.updated_at = now + else: + agent_cfg = AgentConfig( + id=uuid.uuid4(), + app_id=app_id, + default_model_config_id=None, + model_parameters=default_model_parameters, + is_active=True, + created_at=now, + updated_at=now, + ) + 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 + def _create_default_agent_config(self, app_id: uuid.UUID) -> AgentConfig: """创建默认的 Agent 配置模板(不保存到数据库)