Skip to content
Open
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
7 changes: 6 additions & 1 deletion astrbot/core/tools/computer_tools/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
from astrbot.core.astr_agent_context import AstrAgentContext
from astrbot.core.utils.astrbot_path import get_astrbot_workspaces_path

UNKNOWN_WORKSPACE_NAME = "unknown"


def normalize_umo_for_workspace(umo: str) -> str:
"""Convert a UMO into a safe per-session workspace directory name."""
normalized = re.sub(r"[^A-Za-z0-9._-]+", "_", umo.strip())
return normalized or "unknown"
if not normalized.strip("._-"):
return UNKNOWN_WORKSPACE_NAME
return normalized


def workspace_root(umo: str) -> Path:
Expand Down
67 changes: 67 additions & 0 deletions tests/unit/test_computer_workspace_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from pathlib import Path

import pytest

from astrbot.core.tools.computer_tools import util as computer_util


def test_normalize_umo_for_workspace_preserves_normal_session_names() -> None:
assert (
computer_util.normalize_umo_for_workspace("qq:GroupMessage:1000")
== "qq_GroupMessage_1000"
)
assert (
computer_util.normalize_umo_for_workspace("platform.user-1")
== "platform.user-1"
)


def test_normalize_umo_for_workspace_rejects_dot_only_values() -> None:
assert (
computer_util.normalize_umo_for_workspace(".")
== computer_util.UNKNOWN_WORKSPACE_NAME
)
assert (
computer_util.normalize_umo_for_workspace("..")
== computer_util.UNKNOWN_WORKSPACE_NAME
)
assert (
computer_util.normalize_umo_for_workspace("...")
== computer_util.UNKNOWN_WORKSPACE_NAME
)
assert (
computer_util.normalize_umo_for_workspace(" _._ ")
== computer_util.UNKNOWN_WORKSPACE_NAME
)


@pytest.mark.parametrize(
"unsafe_umo",
[
".",
"..",
"...",
" _._ ",
"/",
"//",
" / / ",
],
)
def test_workspace_root_for_unsafe_umo_stays_under_workspaces(
unsafe_umo: str,
monkeypatch,
tmp_path: Path,
) -> None:
workspaces_root = tmp_path / "workspaces"
monkeypatch.setattr(
computer_util,
"get_astrbot_workspaces_path",
lambda: str(workspaces_root),
)

root = computer_util.workspace_root(unsafe_umo)

assert root == (workspaces_root / computer_util.UNKNOWN_WORKSPACE_NAME).resolve(
strict=False
)
assert root.is_relative_to(workspaces_root.resolve(strict=False))