feat(windows): Windows + Python 3.14 support — CI matrix, install markers, runtime fixes#3194
Conversation
|
matrix在win上估计是用不了,上游有问题 |
|
|
||
| - 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 |
There was a problem hiding this comment.
把optional依赖硬编码在这里感觉不太好
There was a problem hiding this comment.
对,我现在的目标只是绕过去,收集完所有的问题,然后再整体出修复方案。
There was a problem hiding this comment.
删除了硬编码,在pyproject.toml判断win32
现在剩下的代码变更应该都是必要的了
505dc63 to
6010ba7
Compare
修复总结本次 PR 经过多次迭代修复,解决了以下问题: 1. Ruff Lint 错误文件:
2. 文件修改检测问题文件:
3. Windows 兼容性测试修复tests/tools/test_read_enhancements.py:
tests/tools/test_search_tools.py:
tests/tools/test_tool_validation.py:
CI 状态所有 8 个测试任务全部通过:
|
|
Thanks for PR! It is ready for review? |
6010ba7 to
c7a0d4c
Compare
|
另一个PR同样的代码跑了3次都成功:#3193 确认CI稳定了 |
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
left a comment
There was a problem hiding this comment.
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 haspytest.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 whennioisn't importable.filesystem.py: hoistedimport osto 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 classesTestFileStateHashFallbacklocks down the new "mtime unchanged, content changed" branch incheck_readusingos.utimeto reset mtime. This is the actual defense against NTFS's coarse mtime; it deserves a test that fails if someone reverts it.TestReadFileLineEndingNormalizationlocks down CRLF→LF on bytes fed throughReadFileTool, and verifies LF-only files are untouched.
test_tool_validation.py: restoredsubprocess.list2cmdline/shlex.quoteintest_exec_head_tail_truncation. The previous form happened to pass onrunneradminrunners, but any local Windows install with a user path likeC:\Users\John Doe\...would have broken on the unquotedf"{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/ -q → 1993 passed on Linux.
Three open design questions (not blockers, for follow-up)
These are yours to call; I deliberately didn't touch them:
-
ReadFileTool.executereaches intofile_state._statedirectly. The dedup logic is now duplicated betweenfile_state.is_unchanged()andReadFileTool. If you want to keep the hash-aware dedup, the cleaner shape is probably to push it intois_unchanged(..., verify_hash=True)and haveReadFileToolcall the public API again. Your call. -
I/O amplification on the dedup-hit path. Large unchanged files now get hashed on every
ReadFileToolcall (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 toos.name == 'nt'? -
python-socksas a core dep with a Windows-exclusion marker. Nothing innanobot/importspython_socksdirectly; the only reverse dep isaiohttp_socksviamatrix-nio, which is already Windows-gated. Either the dep is genuinely vestigial (delete fromdependencies) 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.
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
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
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
windows-latestto OS matrix (Windows Server, compatible with Win10/11)libolm-dev)CI Matrix
Total: 8 parallel jobs
Benefits
Related to #3188