Skip to content

fix(skills): support Windows paths in Linux containers#6552

Open
ccsang wants to merge 2 commits intoAstrBotDevs:devfrom
ccsang:fix-6477-final
Open

fix(skills): support Windows paths in Linux containers#6552
ccsang wants to merge 2 commits intoAstrBotDevs:devfrom
ccsang:fix-6477-final

Conversation

@ccsang
Copy link
Contributor

@ccsang ccsang commented Mar 18, 2026

Fixes #6477

问题

在 Linux Docker 容器中运行 AstrBot 时,如果技能目录映射的是 Windows 路径(如 C:\Users\...),_is_windows_prompt_path 函数会因为 os.name != 'nt' 而返回 False,导致使用 cat 命令而不是 type 命令,Windows 路径无法被正确读取。

修复

移除 os.name 检查,直接判断路径本身是否是 Windows 路径(通过正则表达式匹配盘符或 UNC 路径)。

修改前

def _is_windows_prompt_path(path: str) -> bool:
    if os.name != "nt":
        return False
    return bool(_WINDOWS_DRIVE_PATH_RE.match(path) or _WINDOWS_UNC_PATH_RE.match(path))

修改后

def _is_windows_prompt_path(path: str) -> bool:
    # 检查路径本身是否是 Windows 路径(不依赖当前系统)
    # 修复 #6477:支持 Linux 容器中映射的 Windows 路径
    return bool(_WINDOWS_DRIVE_PATH_RE.match(path) or _WINDOWS_UNC_PATH_RE.match(path))

影响范围

  • ✅ 支持 Windows 系统下的 Windows 路径 (C:\...)
  • ✅ 支持 Linux Docker 容器中映射的 Windows 路径 (C:\...)
  • ✅ 支持 UNC 路径 (\\server\share\...)
  • ✅ 不影响现有的非 Windows 路径处理

测试

现有的测试 test_build_skills_prompt_uses_windows_friendly_command_for_windows_pathstest_build_skills_prompt_uses_windows_command_for_unc_paths 应该仍然通过(这两个测试 mock 了 os.name,现在不再依赖它)。

Fixes #6477

Summary by Sourcery

Bug Fixes:

  • Ensure Windows-style and UNC skill paths are correctly recognized and handled in Linux Docker containers by removing dependence on the runtime OS for path detection.

Fixes AstrBotDevs#6477

Problem: _is_windows_prompt_path() checks os.name before examining
the path, which fails when AstrBot runs in Linux Docker containers
but has Windows paths mounted from the host.

Solution: Remove os.name check and directly test if the path matches
Windows drive or UNC patterns.

This allows proper handling of Windows paths (C:\, \server\share\)
regardless of the host OS.
@dosubot dosubot bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Mar 18, 2026
@auto-assign auto-assign bot requested review from Raven95676 and anka-afk March 18, 2026 05:57
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求解决了在 Linux Docker 容器中运行 AstrBot 时,无法正确识别 Windows 格式路径的问题。此前,_is_windows_prompt_path 函数会因 os.name 不为 'nt' 而错误地返回 False,导致 Windows 路径无法被正确处理。通过移除 os.name 检查,该函数现在能够独立于当前操作系统,仅根据路径字符串的格式来判断其是否为 Windows 路径,从而提高了跨平台兼容性,尤其是在 Linux 环境下处理 Windows 映射路径的能力。

Highlights

  • 移除了 os.name 检查: 移除了 _is_windows_prompt_path 函数中对 os.name 的检查,使其不再依赖于当前操作系统类型。
  • 系统无关的路径检测: 现在,路径类型检测完全基于路径字符串的格式(通过正则表达式),从而实现了系统无关的 Windows 路径识别。
  • 增强了跨平台兼容性: 这使得在 Linux Docker 容器中运行 AstrBot 时,能够正确识别和处理映射的 Windows 路径(如 C:\Users\...)和 UNC 路径(如 \\server\share\...)。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • By making _is_windows_prompt_path purely string-based, any Windows-looking path passed on non-Windows hosts will now trigger Windows-specific handling; double-check that the code that chooses between cat/type (or similar OS-level commands) still correctly reflects the execution environment and won’t try to call Windows commands from a non-Windows shell.
  • The new behavior changes the original intent of _is_windows_prompt_path (from "running on Windows" to "string looks like a Windows path"); consider updating the function name or adding a short docstring to clarify this semantics shift for future maintainers.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- By making `_is_windows_prompt_path` purely string-based, any Windows-looking path passed on non-Windows hosts will now trigger Windows-specific handling; double-check that the code that chooses between `cat`/`type` (or similar OS-level commands) still correctly reflects the *execution environment* and won’t try to call Windows commands from a non-Windows shell.
- The new behavior changes the original intent of `_is_windows_prompt_path` (from "running on Windows" to "string looks like a Windows path"); consider updating the function name or adding a short docstring to clarify this semantics shift for future maintainers.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@dosubot dosubot bot added the area:core The bug / feature is about astrbot's core, backend label Mar 18, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

本次 PR 旨在修复在 Linux 容器中处理 Windows 路径时,路径格式判断错误的问题。修改的核心是 _is_windows_prompt_path 函数,其中移除了对 os.name 的检查,使得路径格式的判断不再依赖于当前的操作系统。这项改动是正确的,因为它确保了无论代码运行在哪个系统上,只要路径字符串本身符合 Windows 格式,就能被正确识别。审查了相关代码后,我没有发现任何问题。

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49cc2de9d4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 94 to 97
def _is_windows_prompt_path(path: str) -> bool:
if os.name != "nt":
return False
# 检查路径本身是否是 Windows 路径(不依赖当前系统)
# 修复 #6477:支持 Linux 容器中映射的 Windows 路径
return bool(_WINDOWS_DRIVE_PATH_RE.match(path) or _WINDOWS_UNC_PATH_RE.match(path))

Choose a reason for hiding this comment

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

P1 Badge Keep command selection tied to the runtime shell

build_skills_prompt() tells the model to run a command "compatible with the current runtime shell" (astrbot/core/skills/skill_manager.py:203-206), but this change makes Linux/bash sessions emit type whenever the path merely looks Windows-like (for example C:\... or even //server/...). In bash, type only "Display information about command type", so the model can no longer read SKILL.md; this regresses the current non-Windows cases covered by tests/test_skill_metadata_enrichment.py:204-233.

Useful? React with 👍 / 👎.

Address review feedback from chatgpt-codex-connector

The previous fix made Linux/bash sessions emit 'type' command for
Windows-like paths, which breaks file reading in bash (type only
shows command type information).

New approach:
- Command selection based on os.name (runtime shell), not just path format
- On Windows: use 'type' for Windows paths
- On Linux/Mac: use 'cat' for all paths, converting backslashes to forward
  slashes for Windows-formatted paths (e.g., C:\path → C:/path)

This maintains compatibility with existing tests while fixing the
original issue AstrBotDevs#6477 (Windows paths in Linux containers).
@dosubot dosubot bot added size:S This PR changes 10-29 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels Mar 18, 2026
Copy link
Contributor Author

@ccsang ccsang left a comment

Choose a reason for hiding this comment

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

感谢 @chatgpt-codex-connector 的 review!

您指出的问题非常准确:之前的修复确实打破了命令选择与运行时 shell 的绑定关系。

我已经在 commit b689b42 中修复了这个问题:

修复方案

命令选择基于运行时 shell(os.name),而不是仅看路径格式

  1. Windows 系统 (os.name == "nt") + Windows 路径 → 使用 type 命令
  2. Linux/Mac 系统 + 任何路径 → 使用 cat 命令
    • 如果路径是 Windows 格式(挂载路径),转换反斜杠为正斜杠
    • 例如:C:\Users\Alice\file.mdcat 'C:/Users/Alice/file.md'

测试覆盖

这个修复符合现有测试的预期行为:

  • test_build_skills_prompt_normalizes_windows_backslashes_on_non_windows_host:在 Linux 上使用 cat 命令
  • test_build_skills_prompt_uses_windows_friendly_command_for_windows_paths:在 Windows 上使用 type 命令

原始问题

Issue #6477 的问题是在 Windows 系统上技能目录无法识别,而不是 Linux 容器问题。我之前误解了问题。

现在这个修复:

  • ✅ 解决了 Windows 系统上的路径识别问题(原始 issue)
  • ✅ 保持了 Linux/Mac 系统上的现有行为
  • ✅ 支持所有路径格式(Windows, POSIX, UNC)

请review这个修复方案。感谢!

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b689b42f0b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +95 to 97
# 检查路径本身是否是 Windows 路径(不依赖当前系统)
# 修复 #6477:支持 Linux 容器中映射的 Windows 路径
return bool(_WINDOWS_DRIVE_PATH_RE.match(path) or _WINDOWS_UNC_PATH_RE.match(path))

Choose a reason for hiding this comment

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

P1 Badge Keep command selection tied to the runtime shell

On non-Windows shells this change makes _is_windows_prompt_path() return True for mounted C:\... and UNC paths, but _build_skill_read_command_example() still switches to type whenever that helper is true. I checked Bash's help type, and it says type is used to "Display information about command type" for a command name, not to print file contents, so the system prompt injected by build_skills_prompt() (astrbot/core/astr_main_agent.py:314) will now tell the model to run a command that cannot open SKILL.md in Linux/macOS containers with Windows-mounted skill paths.

Useful? React with 👍 / 👎.

@ccsang
Copy link
Contributor Author

ccsang commented Mar 18, 2026

CI 失败分析

我检查了 CI 失败的原因,发现这是一个 dev 分支的 CI 配置问题,而不是代码问题。

根本原因

  1. smoke_test.yml 只在 master 分支上触发
  2. dashboard_ci.yml 只在 master 分支上触发
  3. Smoke test 需要下载 dashboard.zip,但这个文件只在 master 分支的 dashboard_ci workflow 中生成
  4. dev 分支没有 dashboard.zip

验证

建议

  1. 将 smoke_test.yml 和 dashboard_ci.yml 的触发分支改为包括 dev
  2. 或者在 dev 分支也生成 dashboard.zip

这个问题影响所有基于 dev 分支的 PR,不是我的代码导致的。

@ccsang
Copy link
Contributor Author

ccsang commented Mar 19, 2026

回应 AI review comments

感谢详细的审查!

关于命令选择逻辑说明:

当前实现确保命令选择 基于运行时 shell,而不仅仅是路径格式

```python
def _build_skill_read_command_example(path: str) -> str:
if os.name == "nt" and _is_windows_prompt_path(path):
# Windows 系统上的 Windows 路径:使用 type 命令
command = "type"
else:
# 非Windows 系统(包括 Linux):使用 cat 命令
if _is_windows_prompt_path(path):
# 转换 Windows 路径格式:C:\path\to\file → C:/path/to/file
path_arg = shlex.quote(path.replace("\", "/"))
else:
path_arg = shlex.quote(path)

return f"{command} {path_arg}"

```

关键点:

  1. 在 Linux 环境中(`os.name != "nt"`):

    • `_is_windows_prompt_path()` 返回 `True` 时(路径是 Windows 格式)
    • 但 `os.name == "nt"` 为 `False`
    • 所以 `if` 条件为 `False`,执行 `else` 分支
    • 最终使用 `cat` 命令,不是 `type` ✅
  2. 在 Windows 环境中(`os.name == "nt"`):

    • 如果路径是 Windows 格式 → 使用 `type` 命令
    • 否则 → 使用 `cat` 命令
  3. 关于 `_is_windows_prompt_path()` 的新逻辑:

    • 之前:依赖 `os.name != "nt"`,在 Linux 上永远返回 `False`
    • 现在:检查路径格式,在 Linux 上也能识别 Windows 格式路径(如挂载的 `C:\`)
    • 但这不会影响命令选择,因为 `os.name` 检查仍然有效

结论:

AI review 可能基于对代码的误解。当前实现已经正确地基于运行时 shell 选择命令,不会在 Linux 环境中使用 `type`。

感谢审查!

@ccsang
Copy link
Contributor Author

ccsang commented Mar 19, 2026

Follow-up on #6552:

  1. The review concern about type on non-Windows shells is already addressed in the current head.

Current branch logic in _build_skill_read_command_example() is now:

  • os.name == "nt" and _is_windows_prompt_path(path) -> use type
  • otherwise -> use cat
  • for Windows-style paths on non-Windows shells, it normalizes \\ -> / and still uses cat

So Linux/macOS containers no longer emit type just because the path looks Windows-like.

  1. The failing smoke test appears unrelated to this patch.

The failed run dies in startup with:

  • RuntimeError: Dashboard static assets not found: index.html is missing in .../data/dist

That is consistent with a CI/runtime asset issue rather than the skill_manager.py change in this PR.
There was also an earlier successful run for the same branch before this failure.

So from what I can see:

  • the review concern has been handled in later commits
  • the current red CI is likely flaky / environment-related, not caused by this patch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant