Skip to content

fix(hooks): CLI 优先使用自身依赖而非宿主 PYTHONPATH - #74

Merged
TimWongUp merged 2 commits into
mainfrom
fix/hook-ignore-host-pythonpath
Nov 5, 2026
Merged

TimWongUp merged 2 commits into
mainfrom
fix/hook-ignore-host-pythonpath

Conversation

@TimWongUp

@TimWongUp TimWongUp commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

问题

Hermes 的 pre_llm_call 钩子每次都报 cannot import name 'ArgsKwargs' from 'pydantic_core._pydantic_core',Profile 和 Preferences 注入失败。

Hermes 跑在 Python 3.14 上,并用 PYTHONPATH 指向自己的依赖目录,钩子继承了这个变量。Keepygaga 跑在 3.12 上时会加载 3.14 版的 pydantic_core,二进制模块加载失败。把 Keepygaga 升到 3.14 后报错会消失,但钩子实际用的是 Hermes 的 pydantic 和 mcp,问题只是被掩盖。

改动

  • CLI 在 main() 开头把 PYTHONPATH 对应的项挪到 sys.path 末尾,路径规范化后再比较。cli.py 顶层只导入标准库,第三方依赖都在这之后才加载。写入宿主配置的钩子命令不变。
  • 挪到末尾而不是删除,这样宿主路径与自身 site-packages 重合时不会崩溃。
  • CI 矩阵和分类器加入 Python 3.14。
  • docs/hooks/hermes.md 补充这一行为。

验证

  • 3.12 和 3.14 下 pytest 都是 364 通过、4 跳过;ruff check、pyright、scripts/smoke_mcp_server.py 通过。
  • 新测试用真实配置断言注入成功,在上一版实现上失败。
  • 真实钩子命令带 Hermes 的 PYTHONPATH、在 3.12 环境运行:注入正常,pydantic 来自 Keepygaga 自己的环境。

未覆盖

  • keepygaga-mcp 入口没有这层处理,它在模块顶层就导入 mcp 和 pydantic。Hermes 下 MCP 一直正常,这个入口要改需另开任务。
  • PYTHONPATH 同时含宿主依赖和自身 site-packages 时,宿主路径仍排在前面。

🤖 Generated with Claude Code

TimWongUp and others added 2 commits November 5, 2026 16:42
Hermes 钩子继承它自己的 PYTHONPATH,Keepygaga 会加载为 Python 3.14 构建的
pydantic_core,导致 Profile 和 Preferences 注入失败。CLI 在加载依赖前去掉这个变量
及其 sys.path 项,钩子始终使用随 Keepygaga 安装的依赖。

同时把 Python 3.14 加入 CI 矩阵和分类器。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
按评审意见修正:路径规范化后再比较,宿主路径挪到末尾而不是删除,与自身
site-packages 重合时不再崩溃,也不再修改 os.environ。测试改用真实配置并断言注入成功。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TimWongUp TimWongUp changed the title fix(hooks): CLI 忽略宿主的 PYTHONPATH fix(hooks): CLI 优先使用自身依赖而非宿主 PYTHONPATH Nov 5, 2026
@TimWongUp

Copy link
Copy Markdown
Owner Author

评审记录

  • head:547531aa1f48dfe7f335f6eb8b0c2949710cf1be
  • base:2ef72c213f0b14b811bfdc6ca023e9d3979d82a0
  • 范围:git diff 2ef72c213f0b14b811bfdc6ca023e9d3979d82a0...547531aa1f48dfe7f335f6eb8b0c2949710cf1be 完整 diff
  • 等级:R1。改动局部、可恢复,已有验证,失败假设只有一个。
  • 失败假设:改写 PYTHONPATH 的处理会破坏确实依赖它的运行方式。由 correctness-reviewer(antigravity gemini-4-argon-medium,App 评审工位)覆盖,同时看了完整 diff。

Findings

# 内容 判定 处理
1 路径按字面匹配:尾斜杠、相对路径漏处理;与自身 site-packages 重合时被删除后崩溃 CONFIRMED 已修:规范化比较,挪到 sys.path 末尾而不是删除,不再修改 os.environ
2 keepygaga-mcp 入口没有这层处理,模块顶层就导入 mcp 和 pydantic PLAUSIBLE 不在本 PR 修:不是本次引入,Hermes 下 MCP 在 3.12 时一直正常;要改需换入口,另开任务
3 测试只断言没有报错文本,可能假通过 CONFIRMED 已修:真实配置,断言注入成功,覆盖两种情况,新测试在上一版实现上失败

定向复核在 547531aa1f48dfe7f335f6eb8b0c2949710cf1be 上确认 #1、#3 已解决,无新增 finding。

验证

  • 本地(547531aa1f48dfe7f335f6eb8b0c2949710cf1be):3.12 和 3.14 下 pytest 都是 364 通过、4 跳过;ruff check、pyright、smoke 通过。
  • 主路径实跑:真实钩子命令带 Hermes 的 PYTHONPATH,在 3.12 环境注入正常,pydantic 来自 Keepygaga 自己的环境。
  • CI(547531aa1f48dfe7f335f6eb8b0c2949710cf1be):macOS、Ubuntu、Windows 的 3.12 和 3.14,以及 CodeQL,全部通过。

剩余风险

@TimWongUp
TimWongUp merged commit b47c8d2 into main Nov 5, 2026
9 checks passed
@TimWongUp
TimWongUp deleted the fix/hook-ignore-host-pythonpath branch November 5, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant