From d713f0209d70db427b6f5a65d9a40fe791167b24 Mon Sep 17 00:00:00 2001 From: xuhd Date: Wed, 3 Jun 2026 16:34:19 +0800 Subject: [PATCH] feat(curator): restrict per-user config to archiving thresholds only --- .../backend/app/gateway/routers/skills.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/offline-backend-20260512/backend/app/gateway/routers/skills.py b/offline-backend-20260512/backend/app/gateway/routers/skills.py index fee8949e..0e48b222 100644 --- a/offline-backend-20260512/backend/app/gateway/routers/skills.py +++ b/offline-backend-20260512/backend/app/gateway/routers/skills.py @@ -2329,14 +2329,14 @@ class CuratorConfigResponse(BaseModel): class CuratorConfigRequest(BaseModel): - """Payload for updating skill_evolution overrides. + """Payload for updating per-user skill evolution overrides. - All fields are required so the frontend always sends a complete config; - backend writes the entire payload to skill_evolution.json atomically. + Users may only adjust archiving thresholds. All other settings (enabled, + interval, model, timeouts) are global and controlled via config.yaml. """ - enabled: bool = Field(..., description="Whether the agent can create and modify skills under skills/custom.") - curator: CuratorSubConfig + stale_after_days: int = Field(..., ge=1, description="Days of inactivity before a skill is marked stale.") + archive_after_days: int = Field(..., ge=1, description="Days of inactivity before a stale skill is archived.") class CuratorLogRecord(BaseModel): @@ -2386,21 +2386,22 @@ async def get_curator_config(request: Request) -> CuratorConfigResponse: @router.put("/curator/config", response_model=CuratorConfigResponse, summary="Update Skill Evolution Config") async def update_curator_config(body: CuratorConfigRequest, request: Request) -> CuratorConfigResponse: - """Persist per-user overrides to ``users/{user_id}/skill_evolution.json`` - and return the effective merged config. + """Persist per-user archiving thresholds to ``users/{user_id}/skill_evolution.json``. - The payload is validated against the ``SkillEvolutionConfig`` shape; unknown - fields are rejected. + Only ``stale_after_days`` and ``archive_after_days`` are user-editable. + All other settings (enabled, interval, model, timeouts) are global and + read from config.yaml; users cannot override them here. """ try: - from deerflow.config.skill_evolution_config import SkillEvolutionConfig from deerflow.config.skill_evolution_runtime import load_skill_evolution_config_for_user, save_user_overrides user_id = _current_user_id(request) - payload = body.model_dump() - # Round-trip through SkillEvolutionConfig to ensure persisted shape stays valid. - SkillEvolutionConfig.model_validate(payload) - save_user_overrides(user_id, payload) + save_user_overrides(user_id, { + "curator": { + "stale_after_days": body.stale_after_days, + "archive_after_days": body.archive_after_days, + } + }) return _build_curator_config_response(load_skill_evolution_config_for_user(user_id)) except HTTPException: raise