From 8b94678d33f9d07c639dd97da820327b14918982 Mon Sep 17 00:00:00 2001 From: XuHaoran <3230105281@zju.edu.cn> Date: Sat, 2 May 2026 16:15:31 +0800 Subject: [PATCH 1/2] feat: add python tool timeout param --- astrbot/core/tools/computer_tools/python.py | 39 ++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/astrbot/core/tools/computer_tools/python.py b/astrbot/core/tools/computer_tools/python.py index e0bb6c9de6..620046bf4d 100644 --- a/astrbot/core/tools/computer_tools/python.py +++ b/astrbot/core/tools/computer_tools/python.py @@ -33,6 +33,11 @@ "description": "Whether to suppress the output of the code execution.", "default": False, }, + "timeout": { + "type": "integer", + "description": "Optional timeout in seconds for code execution. Omit or set to 0 to use tool_call_timeout.", + "default": 0, + }, }, "required": ["code"], } @@ -77,7 +82,11 @@ class PythonTool(FunctionTool): parameters: dict = field(default_factory=lambda: param_schema) async def call( - self, context: ContextWrapper[AstrAgentContext], code: str, silent: bool = False + self, + context: ContextWrapper[AstrAgentContext], + code: str, + silent: bool = False, + timeout: int = 0, ) -> ToolExecResult: if permission_error := check_admin_permission(context, "Python execution"): return permission_error @@ -85,8 +94,17 @@ async def call( context.context.context, context.context.event.unified_msg_origin, ) + effective_timeout = ( + min(timeout, context.tool_call_timeout) + if timeout > 0 + else context.tool_call_timeout + ) try: - result = await sb.python.exec(code, silent=silent) + result = await sb.python.exec( + code, + timeout=effective_timeout, + silent=silent, + ) return await handle_result(result, context.context.event) except Exception as e: return f"Error executing code: {str(e)}" @@ -104,13 +122,26 @@ class LocalPythonTool(FunctionTool): parameters: dict = field(default_factory=lambda: param_schema) async def call( - self, context: ContextWrapper[AstrAgentContext], code: str, silent: bool = False + self, + context: ContextWrapper[AstrAgentContext], + code: str, + silent: bool = False, + timeout: int = 0, ) -> ToolExecResult: if permission_error := check_admin_permission(context, "Python execution"): return permission_error sb = get_local_booter() + effective_timeout = ( + min(timeout, context.tool_call_timeout) + if timeout > 0 + else context.tool_call_timeout + ) try: - result = await sb.python.exec(code, silent=silent) + result = await sb.python.exec( + code, + timeout=effective_timeout, + silent=silent, + ) return await handle_result(result, context.context.event) except Exception as e: return f"Error executing code: {str(e)}" From 21a6d7f57358c8234df596333b89e4a864bd0a33 Mon Sep 17 00:00:00 2001 From: Weilong Liao <37870767+Soulter@users.noreply.github.com> Date: Sun, 3 May 2026 15:06:31 +0800 Subject: [PATCH 2/2] Update python.py --- astrbot/core/tools/computer_tools/python.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/astrbot/core/tools/computer_tools/python.py b/astrbot/core/tools/computer_tools/python.py index 620046bf4d..be909f6d26 100644 --- a/astrbot/core/tools/computer_tools/python.py +++ b/astrbot/core/tools/computer_tools/python.py @@ -35,8 +35,8 @@ }, "timeout": { "type": "integer", - "description": "Optional timeout in seconds for code execution. Omit or set to 0 to use tool_call_timeout.", - "default": 0, + "description": "Optional timeout in seconds for code execution.", + "default": 30, }, }, "required": ["code"], @@ -86,7 +86,7 @@ async def call( context: ContextWrapper[AstrAgentContext], code: str, silent: bool = False, - timeout: int = 0, + timeout: int = 30, ) -> ToolExecResult: if permission_error := check_admin_permission(context, "Python execution"): return permission_error @@ -126,7 +126,7 @@ async def call( context: ContextWrapper[AstrAgentContext], code: str, silent: bool = False, - timeout: int = 0, + timeout: int = 30, ) -> ToolExecResult: if permission_error := check_admin_permission(context, "Python execution"): return permission_error