fix: delete agent 500 error + dynamic personality + deployment guide
- Fix delete agent 500: clean up FK records (agent_llm_logs, permissions, schedules, executions, team_members) and unbind goals/tasks before delete - Remove hardcoded personality templates in Android, replace with dynamic system prompt generation from name + description - Set promptSectionsEnabled=false to bypass PromptComposer for personality - Add Tencent Cloud Linux deployment guide (Docker Compose) - Accumulated backend service updates, frontend UI fixes, Android app changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,12 @@ import logging
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from app.services.tool_registry import tool_registry
|
||||
from app.agent_runtime.permissions import (
|
||||
PermissionChecker,
|
||||
PermissionLevel,
|
||||
PermissionAction,
|
||||
AutoApproveRule,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -32,7 +38,10 @@ class AgentToolManager:
|
||||
exclude_tools: Optional[List[str]] = None,
|
||||
cache_enabled: bool = True,
|
||||
cache_tool_whitelist: Optional[List[str]] = None,
|
||||
cache_ttl_ms: int = 3600000):
|
||||
cache_ttl_ms: int = 3600000,
|
||||
permission_level: str = "default",
|
||||
auto_approve_rules: Optional[List[Dict[str, Any]]] = None,
|
||||
deny_tools: Optional[List[str]] = None):
|
||||
self._include_tools: set = set(include_tools or [])
|
||||
self._exclude_tools: set = set(exclude_tools or [])
|
||||
self._cache_enabled = cache_enabled
|
||||
@@ -40,6 +49,25 @@ class AgentToolManager:
|
||||
self._cache_ttl_s = max(1, int(cache_ttl_ms / 1000))
|
||||
self._cache_store: Dict[str, str] = {} # 内存 fallback
|
||||
|
||||
# Permission checker (P3 — 参考 Claude Code Tool.ts)
|
||||
try:
|
||||
_perm_level = PermissionLevel(permission_level)
|
||||
except ValueError:
|
||||
_perm_level = PermissionLevel.DEFAULT
|
||||
_auto_rules = [
|
||||
AutoApproveRule(
|
||||
tool_pattern=r.get("tool_pattern", "*"),
|
||||
param_conditions=r.get("param_conditions"),
|
||||
description=r.get("description", ""),
|
||||
)
|
||||
for r in (auto_approve_rules or [])
|
||||
]
|
||||
self._permission = PermissionChecker(
|
||||
level=_perm_level,
|
||||
auto_approve_rules=_auto_rules,
|
||||
deny_rules=deny_tools or [],
|
||||
)
|
||||
|
||||
def _is_cacheable(self, tool_name: str) -> bool:
|
||||
"""判断工具结果是否可缓存。"""
|
||||
if not self._cache_enabled:
|
||||
@@ -116,6 +144,20 @@ class AgentToolManager:
|
||||
Returns:
|
||||
工具执行结果的字符串表示
|
||||
"""
|
||||
# 权限检查 (P3)
|
||||
perm = self._permission.check(name, args)
|
||||
if perm.action == PermissionAction.DENY:
|
||||
err = json.dumps({"error": perm.message}, ensure_ascii=False)
|
||||
logger.warning("工具 %s 被权限系统拒绝: %s", name, perm.message)
|
||||
return err
|
||||
if perm.action == PermissionAction.ASK:
|
||||
err = json.dumps({
|
||||
"error": f"工具 {name} 需要用户确认: {perm.message}",
|
||||
"requires_confirmation": True,
|
||||
}, ensure_ascii=False)
|
||||
logger.info("工具 %s 需用户确认: %s", name, perm.message)
|
||||
return err
|
||||
|
||||
# 缓存检查
|
||||
if self._is_cacheable(name):
|
||||
ck = self._cache_key(name, args)
|
||||
|
||||
Reference in New Issue
Block a user