fix: run local python in session workspace#8792
Conversation
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The new
cwdparameter onastrbot.core.computer.olayer.python.execis only documented by the signature; consider expanding the docstring to describe its purpose and behavior (e.g., defaulting to the Astrbot root when omitted) to keep the abstraction clear for other callers. - In
local.py,cwdis normalized withos.path.abspath(cwd)but not validated; if there’s any chance of callers passing a non-existent directory, consider either creating/validating it here or explicitly documenting that the caller must ensure existence to avoid surprisingsubprocesserrors.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new `cwd` parameter on `astrbot.core.computer.olayer.python.exec` is only documented by the signature; consider expanding the docstring to describe its purpose and behavior (e.g., defaulting to the Astrbot root when omitted) to keep the abstraction clear for other callers.
- In `local.py`, `cwd` is normalized with `os.path.abspath(cwd)` but not validated; if there’s any chance of callers passing a non-existent directory, consider either creating/validating it here or explicitly documenting that the caller must ensure existence to avoid surprising `subprocess` errors.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request adds support for executing Python code within a specific working directory by introducing a cwd parameter to the Python execution methods and resolving the workspace root in the local Python tool. A unit test was also added to verify this behavior. Feedback was provided on the new unit test, pointing out a potential flakiness issue on platforms with symlinked temporary directories (such as macOS) and suggesting a robust way to resolve the workspace path consistently.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| monkeypatch.setattr( | ||
| "astrbot.core.tools.computer_tools.python.get_local_booter", | ||
| lambda: SimpleNamespace(python=SimpleNamespace(exec=python_exec)), | ||
| ) | ||
| monkeypatch.setattr( | ||
| "astrbot.core.tools.computer_tools.python.workspace_root", | ||
| lambda umo: tmp_path / umo.replace(":", "_"), | ||
| ) | ||
|
|
||
| event = SimpleNamespace( | ||
| unified_msg_origin="onebot:GroupMessage:12345", | ||
| role="admin", | ||
| get_platform_name=lambda: "onebot", | ||
| ) | ||
| context = ContextWrapper( | ||
| context=SimpleNamespace( | ||
| event=event, | ||
| context=SimpleNamespace( | ||
| get_config=lambda **_kwargs: { | ||
| "provider_settings": {"computer_use_require_admin": True} | ||
| } | ||
| ), | ||
| ), | ||
| tool_call_timeout=60, | ||
| ) | ||
|
|
||
| await tool.call(context, code="print('ok')", timeout=30) | ||
|
|
||
| workspace = tmp_path / "onebot_GroupMessage_12345" | ||
| assert workspace.is_dir() | ||
| python_exec.assert_awaited_once_with( | ||
| "print('ok')", | ||
| timeout=30, | ||
| silent=False, | ||
| cwd=str(workspace.resolve(strict=False)), | ||
| ) |
There was a problem hiding this comment.
On environments where the temporary directory path contains symlinks (such as macOS, where /var is a symlink to /private/var), the unresolved path returned by the mocked workspace_root will not match the resolved path used in the assertion (workspace.resolve(strict=False)). This can cause flaky test failures.
To make the test robust and platform-independent, we can resolve the workspace path once and use it consistently for both the mock and the assertion.
workspace = (tmp_path / "onebot_GroupMessage_12345").resolve(strict=False)
monkeypatch.setattr(
"astrbot.core.tools.computer_tools.python.get_local_booter",
lambda: SimpleNamespace(python=SimpleNamespace(exec=python_exec)),
)
monkeypatch.setattr(
"astrbot.core.tools.computer_tools.python.workspace_root",
lambda umo: workspace,
)
event = SimpleNamespace(
unified_msg_origin="onebot:GroupMessage:12345",
role="admin",
get_platform_name=lambda: "onebot",
)
context = ContextWrapper(
context=SimpleNamespace(
event=event,
context=SimpleNamespace(
get_config=lambda **_kwargs: {
"provider_settings": {"computer_use_require_admin": True}
}
),
),
tool_call_timeout=60,
)
await tool.call(context, code="print('ok')", timeout=30)
assert workspace.is_dir()
python_exec.assert_awaited_once_with(
"print('ok')",
timeout=30,
silent=False,
cwd=str(workspace),
)
Summary
Fixes #8730.
Verification
Summary by Sourcery
Ensure local Python tool execution uses the same per-session workspace as local shell commands and support passing a working directory to the local Python executor.
New Features:
Bug Fixes:
Tests: