Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions astrbot/core/computer/tools/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@
}


def _check_admin_permission(context: ContextWrapper[AstrAgentContext]) -> str | None:
cfg = context.context.context.get_config(
umo=context.context.event.unified_msg_origin
)
provider_settings = cfg.get("provider_settings", {})
require_admin = provider_settings.get("computer_use_require_admin", True)
if require_admin and context.context.event.role != "admin":
return (
"error: Permission denied. Python execution is only allowed for admin users. "
"Tell user to set admins in `AstrBot WebUI -> Config -> General Config` by adding their user ID to the admins list if they need this feature."
f"User's ID is: {context.context.event.get_sender_id()}. User's ID can be found by using /sid command."
)
return None


async def handle_result(result: dict, event: AstrMessageEvent) -> ToolExecResult:
data = result.get("data", {})
output = data.get("output", {})
Expand Down Expand Up @@ -66,6 +81,8 @@ class PythonTool(FunctionTool):
async def call(
self, context: ContextWrapper[AstrAgentContext], code: str, silent: bool = False
) -> ToolExecResult:
if permission_error := _check_admin_permission(context):
Comment on lines 81 to +84
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): call 方法被标注为返回 ToolExecResult,但在权限检查失败时现在可能会返回一个普通字符串。

由于 _check_admin_permission 的返回类型是 str | None,这些 call 方法现在在某些情况下会返回一个裸的 str,而不是声明的 ToolExecResult。除非 ToolExecResult 明确允许 str,否则这会破坏函数的契约,并且可能会让期望获得结构化结果的调用方感到困惑。请将该错误包装成一个符合 ToolExecResult 结构的值,或者扩展 ToolExecResult 以包含这种情况,并相应地更新调用方。

Original comment in English

issue (bug_risk): The call method is annotated to return ToolExecResult but can now return a plain string on permission failure.

Because _check_admin_permission returns str | None, these call methods now sometimes return a bare str instead of the annotated ToolExecResult. Unless ToolExecResult explicitly permits str, this breaks the function’s contract and may confuse callers expecting a structured result. Please either wrap the error in a ToolExecResult-shaped value or extend ToolExecResult to include this case and update callers accordingly.

return permission_error
sb = await get_booter(
context.context.context,
context.context.event.unified_msg_origin,
Expand All @@ -87,12 +104,8 @@ class LocalPythonTool(FunctionTool):
async def call(
self, context: ContextWrapper[AstrAgentContext], code: str, silent: bool = False
) -> ToolExecResult:
if context.context.event.role != "admin":
return (
"error: Permission denied. Local Python execution is only allowed for admin users. "
"Tell user to set admins in `AstrBot WebUI -> Config -> General Config` by adding their user ID to the admins list if they need this feature."
f"User's ID is: {context.context.event.get_sender_id()}. User's ID can be found by using /sid command."
)
if permission_error := _check_admin_permission(context):
return permission_error
sb = get_local_booter()
try:
result = await sb.python.exec(code, silent=silent)
Expand Down
23 changes: 17 additions & 6 deletions astrbot/core/computer/tools/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@
from ..computer_client import get_booter, get_local_booter


def _check_admin_permission(context: ContextWrapper[AstrAgentContext]) -> str | None:
cfg = context.context.context.get_config(
umo=context.context.event.unified_msg_origin
)
provider_settings = cfg.get("provider_settings", {})
require_admin = provider_settings.get("computer_use_require_admin", True)
if require_admin and context.context.event.role != "admin":
return (
"error: Permission denied. Shell execution is only allowed for admin users. "
"Tell user to set admins in `AstrBot WebUI -> Config -> General Config` by adding their user ID to the admins list if they need this feature."
f"User's ID is: {context.context.event.get_sender_id()}. User's ID can be found by using /sid command."
)
return None


@dataclass
class ExecuteShellTool(FunctionTool):
name: str = "astrbot_execute_shell"
Expand Down Expand Up @@ -46,12 +61,8 @@ async def call(
background: bool = False,
env: dict = {},
) -> ToolExecResult:
if context.context.event.role != "admin":
return (
"error: Permission denied. Local shell execution is only allowed for admin users. "
"Tell user to set admins in `AstrBot WebUI -> Config -> General Config` by adding their user ID to the admins list if they need this feature."
f"User's ID is: {context.context.event.get_sender_id()}. User's ID can be found by using /sid command."
)
if permission_error := _check_admin_permission(context):
return permission_error

if self.is_local:
sb = get_local_booter()
Expand Down
6 changes: 6 additions & 0 deletions astrbot/core/config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
"add_cron_tools": True,
},
"computer_use_runtime": "local",
"computer_use_require_admin": True,
"sandbox": {
"booter": "shipyard",
"shipyard_endpoint": "",
Expand Down Expand Up @@ -2737,6 +2738,11 @@ class ChatProviderTemplate(TypedDict):
"labels": ["无", "本地", "沙箱"],
"hint": "选择 Computer Use 运行环境。",
},
"provider_settings.computer_use_require_admin": {
"description": "需要 AstrBot 管理员权限",
"type": "bool",
"hint": "开启后,需要 AstrBot 管理员权限才能调用使用电脑能力。在平台配置->管理员中可添加管理员。使用 /sid 指令查看管理员 ID。",
},
"provider_settings.sandbox.booter": {
"description": "沙箱环境驱动器",
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@
"description": "Computer Use Runtime",
"hint": "sandbox means running in a sandbox environment, local means running in a local environment, none means disabling Computer Use. If skills are uploaded, choosing none will cause them to not be usable by the Agent."
},
"computer_use_require_admin": {
"description": "Require AstrBot Admin Permission",
"hint": "When enabled, AstrBot admin permission is required to use computer capabilities. Admins can be added in Platform Config. Use the /sid command to view admin IDs."
},
"sandbox": {
"booter": {
"description": "Sandbox Environment Driver"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@
"description": "运行环境",
"hint": "sandbox 代表在沙箱环境中运行, local 代表在本地环境中运行, none 代表不启用。如果上传了 skills,选择 none 会导致其无法被 Agent 正常使用。"
},
"computer_use_require_admin": {
"description": "需要 AstrBot 管理员权限",
"hint": "开启后,需要 AstrBot 管理员权限才能调用使用电脑能力。在平台配置->管理员中可添加管理员。使用 /sid 指令查看管理员 ID。"
},
"sandbox": {
"booter": {
"description": "沙箱环境驱动器"
Expand Down