diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index bb9cf93..cca11de 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -325,6 +325,49 @@ def _get_user_context(self, __user__: Optional[Dict[str, Any]]) -> Dict[str, str - `user_language`: `"en-US"` - `user_name`: `"User"` +### 用户上下文获取规范 (User Context Retrieval) + +所有插件**必须**使用 `_get_user_context` 方法来安全获取用户信息,而不是直接访问 `__user__` 参数。这是因为 `__user__` 的类型可能是 `dict`、`list`、`tuple` 或其他类型,直接调用 `.get()` 可能导致 `AttributeError`。 + +All plugins **MUST** use the `_get_user_context` method to safely retrieve user information instead of directly accessing the `__user__` parameter. This is because `__user__` can be of type `dict`, `list`, `tuple`, or other types, and directly calling `.get()` may cause `AttributeError`. + +**正确做法 (Correct):** + +```python +def _get_user_context(self, __user__: Optional[Dict[str, Any]]) -> Dict[str, str]: + """安全提取用户上下文信息。""" + if isinstance(__user__, (list, tuple)): + user_data = __user__[0] if __user__ else {} + elif isinstance(__user__, dict): + user_data = __user__ + else: + user_data = {} + + return { + "user_id": user_data.get("id", "unknown_user"), + "user_name": user_data.get("name", "User"), + "user_language": user_data.get("language", "en-US"), + } + +async def action(self, body: dict, __user__: Optional[Dict[str, Any]] = None, ...): + user_ctx = self._get_user_context(__user__) + user_id = user_ctx["user_id"] + user_name = user_ctx["user_name"] + user_language = user_ctx["user_language"] +``` + +**禁止的做法 (Prohibited):** + +```python +# ❌ 禁止: 直接调用 __user__.get() +# ❌ Prohibited: Directly calling __user__.get() +user_id = __user__.get("id") if __user__ else "default" + +# ❌ 禁止: 假设 __user__ 一定是 dict +# ❌ Prohibited: Assuming __user__ is always a dict +user_name = __user__["name"] +``` + --- ## 📦 依赖管理 (Dependencies) diff --git a/README.md b/README.md index f6b8500..51e48f3 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ Located in the `plugins/` directory, containing Python-based enhancements: - **Knowledge Card** (`knowledge-card`): Creates beautiful flashcards for learning. - **Export to Excel** (`export_to_excel`): Exports chat history to Excel files. - **Summary** (`summary`): Text summarization tool. -- **AI Agent Solver** (`ai-agent-solver`): Intelligent agent solver. #### Filters - **Async Context Compression** (`async-context-compression`): Optimizes token usage via context compression. diff --git a/README_CN.md b/README_CN.md index b67832b..0830fe6 100644 --- a/README_CN.md +++ b/README_CN.md @@ -11,7 +11,6 @@ OpenWebUI 增强功能集合。包含个人开发与收集的### 🧩 插件 (Pl - **Knowledge Card** (`knowledge-card`): 快速生成精美的学习记忆卡片。 - **Export to Excel** (`export_to_excel`): 将对话内容导出为 Excel 文件。 - **Summary** (`summary`): 文本摘要生成工具。 -- **AI Agent Solver** (`ai-agent-solver`): 智能代理解决器。 #### Filters (消息处理) - **Async Context Compression** (`async-context-compression`): 异步上下文压缩,优化 Token 使用。 diff --git a/plugins/actions/flash-card/flash_card.py b/plugins/actions/flash-card/flash_card.py index 0b7a134..1d0f524 100644 --- a/plugins/actions/flash-card/flash_card.py +++ b/plugins/actions/flash-card/flash_card.py @@ -100,6 +100,21 @@ class Action: def __init__(self): self.valves = self.Valves() + def _get_user_context(self, __user__: Optional[Dict[str, Any]]) -> Dict[str, str]: + """Extract basic user context with safe fallbacks.""" + if isinstance(__user__, (list, tuple)): + user_data = __user__[0] if __user__ else {} + elif isinstance(__user__, dict): + user_data = __user__ + else: + user_data = {} + + return { + "user_id": user_data.get("id", "unknown_user"), + "user_name": user_data.get("name", "User"), + "user_language": user_data.get("language", "en-US"), + } + async def action( self, body: dict, @@ -165,7 +180,8 @@ class Action: done=False, ) - user_id = __user__.get("id") if __user__ else "default" + user_ctx = self._get_user_context(__user__) + user_id = user_ctx["user_id"] user_obj = Users.get_user_by_id(user_id) target_model = ( diff --git a/plugins/actions/flash-card/闪记卡.py b/plugins/actions/flash-card/闪记卡.py index c697899..04c0f77 100644 --- a/plugins/actions/flash-card/闪记卡.py +++ b/plugins/actions/flash-card/闪记卡.py @@ -97,6 +97,21 @@ class Action: def __init__(self): self.valves = self.Valves() + def _get_user_context(self, __user__: Optional[Dict[str, Any]]) -> Dict[str, str]: + """安全提取用户上下文信息,支持多种输入格式。""" + if isinstance(__user__, (list, tuple)): + user_data = __user__[0] if __user__ else {} + elif isinstance(__user__, dict): + user_data = __user__ + else: + user_data = {} + + return { + "user_id": user_data.get("id", "unknown_user"), + "user_name": user_data.get("name", "用户"), + "user_language": user_data.get("language", "zh-CN"), + } + async def action( self, body: dict, @@ -156,7 +171,8 @@ class Action: __event_emitter__, "⚡ 闪记卡: 正在调用 AI 模型分析内容...", done=False ) - user_id = __user__.get("id") if __user__ else "default" + user_ctx = self._get_user_context(__user__) + user_id = user_ctx["user_id"] user_obj = Users.get_user_by_id(user_id) target_model = (