fix: replace hardcoded ~/.hermes paths with get_hermes_home() for profile support - #3575
Merged
Conversation
Two changes to improve tool reliability, especially for OpenAI GPT models:
1. GPT tool-use enforcement prompt: Adds GPT_TOOL_USE_GUIDANCE to the
system prompt when the model name contains 'gpt' and tools are loaded.
This addresses a known behavioral pattern where GPT models describe
intended actions ('I will run the tests') instead of actually making
tool calls. Inspired by similar steering in OpenCode (beast.txt) and
Cline (GPT-5.1 variant).
2. Budget warning history stripping: Budget pressure warnings injected by
_get_budget_warning() into tool results are now stripped when
conversation history is replayed via run_conversation(). Previously,
these turn-scoped signals persisted across turns, causing models to
avoid tool calls in all subsequent messages after any turn that hit
the 70-90% iteration threshold.
…file support Prep for the upcoming profiles feature — each profile is a separate HERMES_HOME directory, so all paths must respect the env var. Fixes: - gateway/platforms/matrix.py: Matrix E2EE store was hardcoded to ~/.hermes/matrix/store, ignoring HERMES_HOME. Now uses get_hermes_home() so each profile gets its own Matrix state. - gateway/platforms/telegram.py: Two locations reading config.yaml via Path.home()/.hermes instead of get_hermes_home(). DM topic thread_id persistence and hot-reload would read the wrong config in a profile. - tools/file_tools.py: Security path for hub index blocking was hardcoded to ~/.hermes, would miss the actual profile's hub cache. - hermes_cli/gateway.py: Service naming now uses the profile name (hermes-gateway-coder) instead of a cryptic hash suffix. Extracted _profile_suffix() helper shared by systemd and launchd. - hermes_cli/gateway.py: Launchd plist path and Label now scoped per profile (ai.hermes.gateway-coder.plist). Previously all profiles would collide on the same plist file on macOS. - hermes_cli/gateway.py: Launchd plist now includes HERMES_HOME in EnvironmentVariables — was missing entirely, making custom HERMES_HOME broken on macOS launchd (pre-existing bug). - All launchctl commands in gateway.py, main.py, status.py updated to use get_launchd_label() instead of hardcoded string. Test fixes: DM topic tests now set HERMES_HOME env var alongside Path.home() mock. Launchd test uses get_launchd_label() for expected commands.
This was referenced Mar 29, 2026
ethernet8023
added a commit
that referenced
this pull request
Aug 11, 2026
- no-hardcoded-hermes-home: the Known Pitfalls rule (source of 5 bugs in PR #3575). flags Path.home()/'.hermes' + expanduser variants in production code; a get_hermes_home()/HERMES_HOME mention within 8 lines counts as a guard hint (fallbacks and deliberate HOME anchors like the desktop-ssh token root pass untouched), '# hermes-home: ok' is the explicit override. found and fixed one real bug: the telegram adapter's gmail-triage script path ignored the active profile. - no-ansi-erase-eol: \033[K leaks as literal ?[K under prompt_toolkit patch_stdout; comments documenting the pitfall are exempt. - skill-frontmatter-standards: the HARDLINE authoring rules that were review-only — description <=60 chars/ends with period/no marketing words, name present, platforms: required when skill scripts import POSIX-only primitives. live tree already clean on all three.
ethernet8023
added a commit
that referenced
this pull request
Aug 14, 2026
- no-hardcoded-hermes-home: the Known Pitfalls rule (source of 5 bugs in PR #3575). flags Path.home()/'.hermes' + expanduser variants in production code; a get_hermes_home()/HERMES_HOME mention within 8 lines counts as a guard hint (fallbacks and deliberate HOME anchors like the desktop-ssh token root pass untouched), '# hermes-home: ok' is the explicit override. found and fixed one real bug: the telegram adapter's gmail-triage script path ignored the active profile. - no-ansi-erase-eol: \033[K leaks as literal ?[K under prompt_toolkit patch_stdout; comments documenting the pitfall are exempt. - skill-frontmatter-standards: the HARDLINE authoring rules that were review-only — description <=60 chars/ends with period/no marketing words, name present, platforms: required when skill scripts import POSIX-only primitives. live tree already clean on all three.
zons-zhaozhy
pushed a commit
to zons-zhaozhy/hermes-agent
that referenced
this pull request
Aug 17, 2026
…d content, tool_args, profile-aware marker 影响面 [源码确认]: - agent/tool_executor.py execute_tool_calls_sequential — 单工具调用(写工具 最常见形态)必走路径,此前零 gate 接线 - agent/tool_executor.py execute_tool_calls_segmented — SimpleNamespace segment 视图丢 content,_scan_four_axis(None) 首行 return - agent/read_think_gate.py + plugins/four-axis-guard — marker 路径硬编码 Path.home()/.hermes,违反 profile 规约(PR NousResearch#3575 同类) 原意图 git log 851bdcf: 双防线设计——Gate 扫描 assistant content 四轴证据写 marker,插件读 marker 拦写工具。不变量: gate crash 永不阻断执行;同一 assistant_message 只 check 一次;四轴证据按 turn 累积。 根因: 03ddfe1 恢复了并发路径+agent_init+turn_context 三接线,但漏了 sequential 路径(单调用必经)与 segmented 的 content 传递;check_batch 三处 均未传 tool_args,terminal 写文件检测死。 修复: - segmented: segment 视图补 content 属性 - sequential: 补 check_batch 接线,block 经 scope_block 通道注入(12 处 消费点,tool-scope 优先、gate 不覆盖已有 block) - 并发/顺序两路径 check_batch 均传 tool_args - marker 路径+豁免前缀改 get_hermes_home() 延迟解析(gate 写端+插件读端 一致) - 新增 tests/agent/test_read_think_gate_wiring.py 10 项回归锁四缺口 - guardrail_runtime 测试隔离 gate(正交关注点,config read_think_gate.enabled=false) 风险: 并发竞争下 marker 竞写为最后写者胜,可恢复(git revert 单 commit)。 tests: 4393 passed (tests/agent/ 全量 + tool_call 相关), 新增 10 wiring 回归全绿
19 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Prep work for the upcoming profiles feature. Profiles give each agent its own HERMES_HOME directory, so all path references must respect the
HERMES_HOMEenv var rather than hardcoding~/.hermes.Changes
Hardcoded path fixes (3 files):
gateway/platforms/matrix.py— Matrix E2EE store was hardcoded to~/.hermes/matrix/store. Now usesget_hermes_home().gateway/platforms/telegram.py— Two locations reading config.yaml viaPath.home()/.hermesinstead ofget_hermes_home(). DM topic persistence and hot-reload would read the wrong config.tools/file_tools.py— Security path for hub index blocking was hardcoded to~/.hermes.Service naming improvements (gateway.py):
_profile_suffix()helper: detects~/.hermes/profiles/<name>→ returns profile name; other custom paths → returns hash.get_service_name()now returnshermes-gateway-coderinstead ofhermes-gateway-a1b2c3d4for profile dirs.get_launchd_plist_path()now scoped per profile:ai.hermes.gateway-coder.plist.get_launchd_label()— all launchctl commands in gateway.py, main.py, and status.py updated to use it.macOS launchd fix (pre-existing bug):
HERMES_HOMEinEnvironmentVariables. Custom HERMES_HOME has always been broken on macOS launchd — this fixes it.Test plan
HERMES_HOMEenv var alongsidePath.home()mockget_launchd_label()for expected commands