"""Microsoft Teams 工具策略 (Tools Policy)。 Team/Channel 级 tools allow/deny + toolsBySender 策略。 """ from __future__ import annotations from typing import Any class ToolPolicy: def __init__(self, config: dict[str, Any] | None = None): config = config or {} self._global_allow: set[str] = set(config.get("tools_allow", [])) self._global_deny: set[str] = set(config.get("tools_deny", [])) self._tools_by_sender: dict[str, set[str]] = {} sender_tools = config.get("tools_by_sender", {}) or {} for sender_id, tools in sender_tools.items(): self._tools_by_sender[sender_id] = set(tools) def is_tool_allowed( self, tool_name: str, sender_id: str = "", team_id: str = "", channel_id: str = "", ) -> bool: sender_tools = self._tools_by_sender.get(sender_id) if sender_tools is not None: return tool_name in sender_tools if tool_name in self._global_deny: return False if self._global_allow: return tool_name in self._global_allow return True def get_allowed_tools(self, sender_id: str = "") -> list[str] | None: sender_tools = self._tools_by_sender.get(sender_id) if sender_tools is not None: return list(sender_tools) if self._global_allow: return list(self._global_allow) return None def resolve_tool_policy( config: dict[str, Any], tool_name: str, sender_id: str = "", team_id: str = "", channel_id: str = "", ) -> bool: teams_config = config.get("teams", {}) or {} team_config = (teams_config.get(team_id) or teams_config.get("*")) or {} if team_config: team_tools = team_config.get("tools", {}) or {} if tool_name in team_tools.get("deny", []): return False if team_tools.get("allow"): return tool_name in team_tools["allow"] global_deny = set(config.get("tools_deny", [])) if tool_name in global_deny: return False global_allow = set(config.get("tools_allow", [])) if global_allow: return tool_name in global_allow return True