Skip to content

feat(windows): Windows + Python 3.14 support — CI matrix, install markers, runtime fixes#3194

Merged
Re-bin merged 3 commits intoHKUDS:mainfrom
JiajunBernoulli:ci-add-windows-support
Apr 17, 2026
Merged

feat(windows): Windows + Python 3.14 support — CI matrix, install markers, runtime fixes#3194
Re-bin merged 3 commits intoHKUDS:mainfrom
JiajunBernoulli:ci-add-windows-support

Conversation

@JiajunBernoulli
Copy link
Copy Markdown
Contributor

Motivation

Issue #3188 revealed Python 3.14 compatibility issues, and Windows users may encounter platform-specific problems. The CI only tested Linux with Python 3.11-3.13.

Changes

  • Add windows-latest to OS matrix (Windows Server, compatible with Win10/11)
  • Add Python 3.14 to version matrix
  • Conditionally install Linux-only system dependencies (libolm-dev)

CI Matrix

OS Python Versions
ubuntu-latest 3.11, 3.12, 3.13, 3.14
windows-latest 3.11, 3.12, 3.13, 3.14

Total: 8 parallel jobs

Benefits

  • Early detection of Windows-specific issues
  • Early detection of Python 3.14 compatibility issues
  • Prevents platform-specific bugs from reaching users

Related to #3188

@chengyongru
Copy link
Copy Markdown
Collaborator

matrix在win上估计是用不了,上游有问题

Comment thread .github/workflows/ci.yml Outdated

- name: Install dependencies (Windows)
if: runner.os == 'Windows'
run: uv sync --extra api --extra wecom --extra weixin --extra discord --extra langsmith --extra pdf --extra dev
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

把optional依赖硬编码在这里感觉不太好

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

对,我现在的目标只是绕过去,收集完所有的问题,然后再整体出修复方案。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

删除了硬编码,在pyproject.toml判断win32

现在剩下的代码变更应该都是必要的了

@JiajunBernoulli JiajunBernoulli marked this pull request as draft April 16, 2026 13:38
@JiajunBernoulli JiajunBernoulli force-pushed the ci-add-windows-support branch 2 times, most recently from 505dc63 to 6010ba7 Compare April 16, 2026 15:04
@JiajunBernoulli
Copy link
Copy Markdown
Contributor Author

修复总结

本次 PR 经过多次迭代修复,解决了以下问题:

1. Ruff Lint 错误

文件: nanobot/agent/tools/filesystem.py

  • 删除未使用的 uses_crlf 变量
  • 删除未使用的 warning_msg 变量
  • 删除重复的 UTF-8 解码 try/except 代码块
  • 删除错误添加的 else 分支(会输出 "Warning: No warning detected when expected.")

2. 文件修改检测问题

文件: nanobot/agent/tools/file_state.py

  • 当 mtime 不变时也检查 content hash,以检测快速修改的情况(文件修改太快时 mtime 可能不变)

3. Windows 兼容性测试修复

tests/tools/test_read_enhancements.py:

  • 跳过 TestReadDeviceBlacklist 测试类(Windows 不存在 /dev 目录)

tests/tools/test_search_tools.py:

  • 修复 test_grep_files_with_matches 测试,使其不依赖文件系统顺序(Windows 文件系统顺序与 Linux 不同)

tests/tools/test_tool_validation.py:

  • 修复 test_exec_head_tail_truncation 测试,使用临时脚本文件替代命令行参数(解决 Windows cmd.exe 引号解析问题)

CI 状态

所有 8 个测试任务全部通过:

  • ✅ ubuntu-latest (3.11, 3.12, 3.13, 3.14)
  • ✅ windows-latest (3.11, 3.12, 3.13, 3.14)

@Re-bin
Copy link
Copy Markdown
Collaborator

Re-bin commented Apr 16, 2026

Thanks for PR!

It is ready for review?

@JiajunBernoulli JiajunBernoulli force-pushed the ci-add-windows-support branch from 6010ba7 to c7a0d4c Compare April 17, 2026 01:04
@JiajunBernoulli JiajunBernoulli marked this pull request as ready for review April 17, 2026 01:16
@JiajunBernoulli
Copy link
Copy Markdown
Contributor Author

JiajunBernoulli commented Apr 17, 2026

另一个PR同样的代码跑了3次都成功:#3193

确认CI稳定了

Re-bin added 2 commits April 17, 2026 07:40
Follow-ups from review of HKUDS#3194:

- ci.yml: drop unconditional --ignore=tests/channels/test_matrix_channel.py.
  That test file already calls pytest.importorskip("nio") at module top, so
  it self-skips on Windows (where nio isn't installed) without also hiding
  62 tests from Linux CI.

- filesystem.py: hoist `import os` to the module top and drop the duplicate
  inline import in ReadFileTool.execute. Document the CRLF->LF normalization
  as intentional (primarily a Windows UX fix so downstream StrReplace/Grep
  match consistently regardless of where the file was written).

- test_read_enhancements.py: lock down two new behaviors
  * TestFileStateHashFallback: check_read warns when content changes but
    mtime is unchanged (coarse-mtime filesystems on Windows).
  * TestReadFileLineEndingNormalization: ReadFileTool strips CRLF and
    preserves LF-only files untouched.

- test_tool_validation.py: restore list2cmdline/shlex.quote in
  test_exec_head_tail_truncation. The temp_path-based form was correct,
  but dropping the quoting broke on any Windows path containing spaces
  (e.g. C:\Users\John Doe\...). CI runners happen not to have spaces so
  this slipped through.

Tests: 1993 passed locally.
Made-with: Cursor
HKUDS#3194 adds `; sys_platform != 'win32'` markers to `matrix-nio[e2e]` so
`pip install nanobot-ai[matrix]` no longer fails on Windows — but it also
no longer installs matrix-nio there. Without this note, Windows users get
a silent half-install and discover the limitation only when the channel
crashes at startup.

Made-with: Cursor
@Re-bin Re-bin changed the title ci: add Windows and Python 3.14 support feat(windows): Windows + Python 3.14 support — CI matrix, install markers, runtime fixes Apr 17, 2026
Copy link
Copy Markdown
Collaborator

@Re-bin Re-bin left a comment

Choose a reason for hiding this comment

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

This is a solid move in the right direction — nanobot goes from "doesn't install on Windows" to "installs and the main agent loop works". That's the right kind of threshold to cross in one PR.

Thanks for iterating on the pyproject markers; that's the correct place for the Windows conditional, and the response to last round's CR was clean.

What I pushed on top

Two commits, in the spirit of "land the 90% that's uncontroversial, leave the design calls to you":

review: tighten scope and add regression tests (e199288)

  • ci.yml: dropped --ignore=tests/channels/test_matrix_channel.py. That test file already has pytest.importorskip("nio") at module top, so it self-skips on Windows without also silencing 62 tests on Linux CI. Confirmed locally: 62 pass on Linux, skips cleanly when nio isn't importable.
  • filesystem.py: hoisted import os to module top, added three lines of comment to the CRLF→LF normalization explaining it's an intentional Windows UX fix (so it doesn't read like someone's half-applied patch on future blame).
  • test_read_enhancements.py: two new test classes
    • TestFileStateHashFallback locks down the new "mtime unchanged, content changed" branch in check_read using os.utime to reset mtime. This is the actual defense against NTFS's coarse mtime; it deserves a test that fails if someone reverts it.
    • TestReadFileLineEndingNormalization locks down CRLF→LF on bytes fed through ReadFileTool, and verifies LF-only files are untouched.
  • test_tool_validation.py: restored subprocess.list2cmdline/shlex.quote in test_exec_head_tail_truncation. The previous form happened to pass on runneradmin runners, but any local Windows install with a user path like C:\Users\John Doe\... would have broken on the unquoted f"{sys.executable} {script_file}".

docs(readme): flag Matrix channel as unsupported on Windows (4c1187c)

With the ; sys_platform != 'win32' marker, pip install nanobot-ai[matrix] on Windows now succeeds but silently omits matrix-nio. That's actually a worse user experience than a hard install failure, because the breakage only surfaces at channel startup. README's Matrix section now has a NOTE pointing users at macOS/Linux/WSL2.

Full-suite verification

uv run pytest tests/ -q1993 passed on Linux.

Three open design questions (not blockers, for follow-up)

These are yours to call; I deliberately didn't touch them:

  1. ReadFileTool.execute reaches into file_state._state directly. The dedup logic is now duplicated between file_state.is_unchanged() and ReadFileTool. If you want to keep the hash-aware dedup, the cleaner shape is probably to push it into is_unchanged(..., verify_hash=True) and have ReadFileTool call the public API again. Your call.

  2. I/O amplification on the dedup-hit path. Large unchanged files now get hashed on every ReadFileTool call (where previously it was just an mtime compare). For a 10 MB file read repeatedly in an agent loop, that's real overhead. Acceptable trade-off for correctness on coarse-mtime filesystems, but worth noting — maybe gate the hash check to os.name == 'nt'?

  3. python-socks as a core dep with a Windows-exclusion marker. Nothing in nanobot/ imports python_socks directly; the only reverse dep is aiohttp_socks via matrix-nio, which is already Windows-gated. Either the dep is genuinely vestigial (delete from dependencies) or it's needed by a specific code path (add a one-line comment pinning the "why"). The current middle state is the most confusing option.

Title suggestion

The diff has meaningfully grown beyond "add CI" — it now includes pyproject install markers and three runtime behavior changes aimed at Windows users. Consider retitling to something like feat(windows): Windows + Python 3.14 support — CI matrix, install markers, runtime fixes so future git blame lands somewhere honest when someone wonders "why does ReadFileTool strip CRLFs on all platforms?".

From my side

With the two commits I pushed, this is ready to merge. The three open questions above are real but not gating — they can be a short follow-up PR after you've collected the rest of the "整体修复方案" you mentioned upstream.

@Re-bin Re-bin merged commit e9d727c into HKUDS:main Apr 17, 2026
8 checks passed
Re-bin added a commit that referenced this pull request Apr 17, 2026
Follow-ups from review of #3194:

- ci.yml: drop unconditional --ignore=tests/channels/test_matrix_channel.py.
  That test file already calls pytest.importorskip("nio") at module top, so
  it self-skips on Windows (where nio isn't installed) without also hiding
  62 tests from Linux CI.

- filesystem.py: hoist `import os` to the module top and drop the duplicate
  inline import in ReadFileTool.execute. Document the CRLF->LF normalization
  as intentional (primarily a Windows UX fix so downstream StrReplace/Grep
  match consistently regardless of where the file was written).

- test_read_enhancements.py: lock down two new behaviors
  * TestFileStateHashFallback: check_read warns when content changes but
    mtime is unchanged (coarse-mtime filesystems on Windows).
  * TestReadFileLineEndingNormalization: ReadFileTool strips CRLF and
    preserves LF-only files untouched.

- test_tool_validation.py: restore list2cmdline/shlex.quote in
  test_exec_head_tail_truncation. The temp_path-based form was correct,
  but dropping the quoting broke on any Windows path containing spaces
  (e.g. C:\Users\John Doe\...). CI runners happen not to have spaces so
  this slipped through.

Tests: 1993 passed locally.
Made-with: Cursor
@JiajunBernoulli JiajunBernoulli deleted the ci-add-windows-support branch April 18, 2026 04:22
jacob-qu pushed a commit to jacob-qu/nanobot that referenced this pull request Apr 19, 2026
Follow-ups from review of HKUDS#3194:

- ci.yml: drop unconditional --ignore=tests/channels/test_matrix_channel.py.
  That test file already calls pytest.importorskip("nio") at module top, so
  it self-skips on Windows (where nio isn't installed) without also hiding
  62 tests from Linux CI.

- filesystem.py: hoist `import os` to the module top and drop the duplicate
  inline import in ReadFileTool.execute. Document the CRLF->LF normalization
  as intentional (primarily a Windows UX fix so downstream StrReplace/Grep
  match consistently regardless of where the file was written).

- test_read_enhancements.py: lock down two new behaviors
  * TestFileStateHashFallback: check_read warns when content changes but
    mtime is unchanged (coarse-mtime filesystems on Windows).
  * TestReadFileLineEndingNormalization: ReadFileTool strips CRLF and
    preserves LF-only files untouched.

- test_tool_validation.py: restore list2cmdline/shlex.quote in
  test_exec_head_tail_truncation. The temp_path-based form was correct,
  but dropping the quoting broke on any Windows path containing spaces
  (e.g. C:\Users\John Doe\...). CI runners happen not to have spaces so
  this slipped through.

Tests: 1993 passed locally.
Made-with: Cursor
jacob-qu pushed a commit to jacob-qu/nanobot that referenced this pull request Apr 19, 2026
HKUDS#3194 adds `; sys_platform != 'win32'` markers to `matrix-nio[e2e]` so
`pip install nanobot-ai[matrix]` no longer fails on Windows — but it also
no longer installs matrix-nio there. Without this note, Windows users get
a silent half-install and discover the limitation only when the channel
crashes at startup.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants