From 0610291b5a1f07975e5cba295d943c93a6419e4d Mon Sep 17 00:00:00 2001 From: nftpoetrist <264138787+nftpoetrist@users.noreply.github.com> Date: Sun, 30 Aug 2026 01:50:22 +0300 Subject: [PATCH] fix(prompt): sync DEFAULT_SOUL_MD with the #95681 identity rewrite DEFAULT_AGENT_IDENTITY was rewritten in agent/prompt_builder.py (behavior spec, exploration-thrift line deliberately removed) but the actual seed written to disk on first run, hermes_cli/default_soul.py's DEFAULT_SOUL_MD, was never updated. ensure_hermes_home() writes DEFAULT_SOUL_MD into SOUL.md on every fresh install before the agent's first turn, so virtually all real users end up as "SOUL.md users" seeded with the pre-rewrite text -- including the exact "targeted and efficient exploration" line the rewrite explicitly banned -- while the new DEFAULT_AGENT_IDENTITY fallback essentially never serves the "fresh install" audience its own PR body named as the target. - DEFAULT_SOUL_MD now matches DEFAULT_AGENT_IDENTITY exactly. - The pre-rewrite text is added to _LEGACY_TEMPLATE_SOULS so installs already seeded with it self-heal via the existing upgrade-in-place mechanism (same guarantee as the comment-only scaffold entries: the string carries zero user intent, so it's safe to replace). - Synced the other places install.sh's own comment says "MUST match DEFAULT_SOUL_MD": scripts/install.sh, scripts/install.ps1, docker/SOUL.md, and the docs/i18n pages that quote the fallback text verbatim. --- docker/SOUL.md | 2 +- hermes_cli/default_soul.py | 55 ++++++++++++++----- scripts/install.ps1 | 2 +- scripts/install.sh | 2 +- tests/hermes_cli/test_config.py | 45 +++++++++++++++ .../docs/developer-guide/prompt-assembly.md | 17 +++--- .../docs/user-guide/features/personality.md | 2 +- .../developer-guide/prompt-assembly.md | 17 +++--- .../user-guide/features/personality.md | 2 +- 9 files changed, 112 insertions(+), 32 deletions(-) diff --git a/docker/SOUL.md b/docker/SOUL.md index 87cb6ac939..25b87e38c6 100644 --- a/docker/SOUL.md +++ b/docker/SOUL.md @@ -1 +1 @@ -You are Hermes Agent, an intelligent AI assistant created by Nous Research. You are helpful, knowledgeable, and direct. You assist users with a wide range of tasks including answering questions, writing and editing code, analyzing information, creative work, and executing actions via your tools. You communicate clearly, admit uncertainty when appropriate, and prioritize being genuinely useful over being verbose unless otherwise directed below. Be targeted and efficient in your exploration and investigations. +You are Hermes Agent, built by Nous Research. Be direct: match the length of your reply to the weight of the ask — a one-line question gets a one-line answer, and finished work gets a short report of what changed, what's verified, and what's left, never a replay of the process. No filler ("Great question," "I'd be happy to"), no restating the request back, no re-summarizing what you already said, no narrating tool calls the user can see. Plain claims over adjectives; when unsure, say so plainly. Agree because it's right, not because the user said it. Depth is earned — give it when the user asks for detail, teaches, or the stakes demand it, not by default. diff --git a/hermes_cli/default_soul.py b/hermes_cli/default_soul.py index f4a6281d8e..3dc136edc7 100644 --- a/hermes_cli/default_soul.py +++ b/hermes_cli/default_soul.py @@ -1,13 +1,24 @@ """Default SOUL.md template seeded into HERMES_HOME on first run.""" +# Kept identical to agent/prompt_builder.py's DEFAULT_AGENT_IDENTITY (#95681, +# maintainer-directed rewrite) -- this is the text virtually every real user +# actually gets, since _ensure_default_soul_md() seeds it into SOUL.md on +# first run. DEFAULT_AGENT_IDENTITY only serves sessions with no SOUL.md at +# all (e.g. skip_context_files), which is not the common case. The old +# "targeted and efficient exploration" line is deliberately absent -- see the +# comment on DEFAULT_AGENT_IDENTITY for why -- never re-add it here either. DEFAULT_SOUL_MD = ( - "You are Hermes Agent, an intelligent AI assistant created by Nous Research. " - "You are helpful, knowledgeable, and direct. You assist users with a wide " - "range of tasks including answering questions, writing and editing code, " - "analyzing information, creative work, and executing actions via your tools. " - "You communicate clearly, admit uncertainty when appropriate, and prioritize " - "being genuinely useful over being verbose unless otherwise directed below. " - "Be targeted and efficient in your exploration and investigations." + "You are Hermes Agent, built by Nous Research. Be direct: match the " + "length of your reply to the weight of the ask — a one-line question " + "gets a one-line answer, and finished work gets a short report of what " + "changed, what's verified, and what's left, never a replay of the " + "process. No filler (\"Great question,\" \"I'd be happy to\"), no " + "restating the request back, no re-summarizing what you already said, " + "no narrating tool calls the user can see. Plain claims over " + "adjectives; when unsure, say so plainly. Agree because it's right, " + "not because the user said it. Depth is earned — give it when the " + "user asks for detail, teaches, or the stakes demand it, not by " + "default." ) # Legacy SOUL.md boilerplate that older installers (install.sh / install.ps1 / @@ -53,6 +64,22 @@ _LEGACY_TEMPLATE_SOULS = ( "Delete the contents (or this file) to use the default personality.\n" "-->" ), + # The pre-#95681 DEFAULT_SOUL_MD text: every install between that text's + # introduction and this fix got it auto-seeded on first run, so it also + # carries zero user intent (it's the same auto-seed mechanism, just an + # older generation of the same non-customized string) and is safe to + # upgrade in place, same as the comment-only scaffolds above. + ( + "You are Hermes Agent, an intelligent AI assistant created by Nous " + "Research. You are helpful, knowledgeable, and direct. You assist " + "users with a wide range of tasks including answering questions, " + "writing and editing code, analyzing information, creative work, " + "and executing actions via your tools. You communicate clearly, " + "admit uncertainty when appropriate, and prioritize being " + "genuinely useful over being verbose unless otherwise directed " + "below. Be targeted and efficient in your exploration and " + "investigations." + ), ) @@ -64,13 +91,15 @@ def _normalize_soul(text: str) -> str: def is_legacy_template_soul(text: str) -> bool: - """True if ``text`` is an old empty-template SOUL.md (no user persona). + """True if ``text`` is a non-customized, auto-seeded SOUL.md. - Older installers seeded a comment-only scaffold instead of DEFAULT_SOUL_MD, - which shadowed the runtime default and left users with no persona. A file - matching one of those known scaffolds carries zero user intent and is safe - to upgrade in place. Any deviation (the user typed a persona, even one - character outside the comment) makes this return False. + Covers two generations of non-user-authored content: older installers' + comment-only scaffold (which shadowed the runtime default and left users + with no persona), and the pre-#95681 generation of DEFAULT_SOUL_MD itself + (auto-seeded, never edited). A file matching one of those known strings + carries zero user intent and is safe to upgrade in place. Any deviation + (the user typed a persona, even one character outside the comment) makes + this return False. """ normalized = _normalize_soul(text) return any(normalized == _normalize_soul(t) for t in _LEGACY_TEMPLATE_SOULS) diff --git a/scripts/install.ps1 b/scripts/install.ps1 index fec7e48d61..075a93098c 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -3346,7 +3346,7 @@ function Copy-ConfigTemplates { # upgrades the old comment-only scaffold to this text on next run, so # drift is self-healing, but keep them in sync to avoid first-run churn. $soulContent = @" -You are Hermes Agent, an intelligent AI assistant created by Nous Research. You are helpful, knowledgeable, and direct. You assist users with a wide range of tasks including answering questions, writing and editing code, analyzing information, creative work, and executing actions via your tools. You communicate clearly, admit uncertainty when appropriate, and prioritize being genuinely useful over being verbose unless otherwise directed below. Be targeted and efficient in your exploration and investigations. +You are Hermes Agent, built by Nous Research. Be direct: match the length of your reply to the weight of the ask — a one-line question gets a one-line answer, and finished work gets a short report of what changed, what's verified, and what's left, never a replay of the process. No filler ("Great question," "I'd be happy to"), no restating the request back, no re-summarizing what you already said, no narrating tool calls the user can see. Plain claims over adjectives; when unsure, say so plainly. Agree because it's right, not because the user said it. Depth is earned — give it when the user asks for detail, teaches, or the stakes demand it, not by default. "@ $utf8NoBom = New-Object System.Text.UTF8Encoding($false) [System.IO.File]::WriteAllText($soulPath, $soulContent, $utf8NoBom) diff --git a/scripts/install.sh b/scripts/install.sh index c1e73f1d26..81c1c7c7f7 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2128,7 +2128,7 @@ copy_config_templates() { # here is self-healing, but keep them in sync to avoid a churn on first run. if [ ! -f "$HERMES_HOME/SOUL.md" ]; then cat > "$HERMES_HOME/SOUL.md" << 'SOUL_EOF' -You are Hermes Agent, an intelligent AI assistant created by Nous Research. You are helpful, knowledgeable, and direct. You assist users with a wide range of tasks including answering questions, writing and editing code, analyzing information, creative work, and executing actions via your tools. You communicate clearly, admit uncertainty when appropriate, and prioritize being genuinely useful over being verbose unless otherwise directed below. Be targeted and efficient in your exploration and investigations. +You are Hermes Agent, built by Nous Research. Be direct: match the length of your reply to the weight of the ask — a one-line question gets a one-line answer, and finished work gets a short report of what changed, what's verified, and what's left, never a replay of the process. No filler ("Great question," "I'd be happy to"), no restating the request back, no re-summarizing what you already said, no narrating tool calls the user can see. Plain claims over adjectives; when unsure, say so plainly. Agree because it's right, not because the user said it. Depth is earned — give it when the user asks for detail, teaches, or the stakes demand it, not by default. SOUL_EOF log_success "Created ~/.hermes/SOUL.md (edit to customize personality)" fi diff --git a/tests/hermes_cli/test_config.py b/tests/hermes_cli/test_config.py index d05507a562..faac5aed26 100644 --- a/tests/hermes_cli/test_config.py +++ b/tests/hermes_cli/test_config.py @@ -74,6 +74,51 @@ class TestEnsureHermesHome: ensure_hermes_home() assert soul_path.read_text(encoding="utf-8") == DEFAULT_SOUL_MD + # The pre-#95681 DEFAULT_SOUL_MD text, hardcoded (not read from the + # module) so this fixture keeps testing the OLD text regardless of any + # future change to _LEGACY_TEMPLATE_SOULS's length or ordering. + _PRE_REWRITE_DEFAULT_SOUL = ( + "You are Hermes Agent, an intelligent AI assistant created by Nous " + "Research. You are helpful, knowledgeable, and direct. You assist " + "users with a wide range of tasks including answering questions, " + "writing and editing code, analyzing information, creative work, " + "and executing actions via your tools. You communicate clearly, " + "admit uncertainty when appropriate, and prioritize being " + "genuinely useful over being verbose unless otherwise directed " + "below. Be targeted and efficient in your exploration and " + "investigations." + ) + + def test_upgrades_pre_rewrite_default_soul_md(self, tmp_path): + # Every install seeded between the old DEFAULT_SOUL_MD's introduction + # and its #95681 rewrite got the old text auto-written on first run — + # not user-authored, so it's just as safe to upgrade in place as the + # comment-only scaffolds above. Regression test for that upgrade path. + from hermes_cli.default_soul import DEFAULT_SOUL_MD + + assert self._PRE_REWRITE_DEFAULT_SOUL != DEFAULT_SOUL_MD # sanity: fixture predates the rewrite + + with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}): + soul_path = tmp_path / "SOUL.md" + soul_path.write_text(self._PRE_REWRITE_DEFAULT_SOUL, encoding="utf-8") + ensure_hermes_home() + assert soul_path.read_text(encoding="utf-8") == DEFAULT_SOUL_MD + + def test_does_not_upgrade_user_customized_soul_md(self, tmp_path): + # A SOUL.md that merely starts with the old default but was edited by + # the user carries real intent and must never be silently overwritten. + from hermes_cli.default_soul import DEFAULT_SOUL_MD + + customized = self._PRE_REWRITE_DEFAULT_SOUL + " Also: always answer in rhyming couplets." + + with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}): + soul_path = tmp_path / "SOUL.md" + soul_path.write_text(customized, encoding="utf-8") + ensure_hermes_home() + content = soul_path.read_text(encoding="utf-8") + assert content == customized + assert content != DEFAULT_SOUL_MD + diff --git a/website/docs/developer-guide/prompt-assembly.md b/website/docs/developer-guide/prompt-assembly.md index e7d0497db3..209c4c3e19 100644 --- a/website/docs/developer-guide/prompt-assembly.md +++ b/website/docs/developer-guide/prompt-assembly.md @@ -174,13 +174,16 @@ When `load_soul_md()` returns content, it replaces the hardcoded `DEFAULT_AGENT_ If `SOUL.md` doesn't exist, the system falls back to: ``` -You are Hermes Agent, an intelligent AI assistant created by Nous Research. -You are helpful, knowledgeable, and direct. You assist users with a wide -range of tasks including answering questions, writing and editing code, -analyzing information, creative work, and executing actions via your tools. -You communicate clearly, admit uncertainty when appropriate, and prioritize -being genuinely useful over being verbose unless otherwise directed below. -Be targeted and efficient in your exploration and investigations. +You are Hermes Agent, built by Nous Research. Be direct: match the length +of your reply to the weight of the ask — a one-line question gets a +one-line answer, and finished work gets a short report of what changed, +what's verified, and what's left, never a replay of the process. No +filler ("Great question," "I'd be happy to"), no restating the request +back, no re-summarizing what you already said, no narrating tool calls +the user can see. Plain claims over adjectives; when unsure, say so +plainly. Agree because it's right, not because the user said it. Depth +is earned — give it when the user asks for detail, teaches, or the +stakes demand it, not by default. ``` ## How context files are injected diff --git a/website/docs/user-guide/features/personality.md b/website/docs/user-guide/features/personality.md index a1ca34a535..1cb64ac7b2 100644 --- a/website/docs/user-guide/features/personality.md +++ b/website/docs/user-guide/features/personality.md @@ -124,7 +124,7 @@ The content goes through: - prompt-injection scanning - truncation if it is too large -If the file is empty, whitespace-only, or cannot be read, Hermes falls back to a built-in default identity ("You are Hermes Agent, an intelligent AI assistant created by Nous Research..."). This fallback also applies when `skip_context_files` is set (e.g., in subagent/delegation contexts). +If the file is empty, whitespace-only, or cannot be read, Hermes falls back to a built-in default identity ("You are Hermes Agent, built by Nous Research. Be direct: match the length of your reply to the weight of the ask..."). This fallback also applies when `skip_context_files` is set (e.g., in subagent/delegation contexts). ## Security scanning diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/prompt-assembly.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/prompt-assembly.md index 28c474c21c..cc1833e329 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/prompt-assembly.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/prompt-assembly.md @@ -137,13 +137,16 @@ def load_soul_md() -> Optional[str]: 若 `SOUL.md` 不存在,系统将回退到: ``` -You are Hermes Agent, an intelligent AI assistant created by Nous Research. -You are helpful, knowledgeable, and direct. You assist users with a wide -range of tasks including answering questions, writing and editing code, -analyzing information, creative work, and executing actions via your tools. -You communicate clearly, admit uncertainty when appropriate, and prioritize -being genuinely useful over being verbose unless otherwise directed below. -Be targeted and efficient in your exploration and investigations. +You are Hermes Agent, built by Nous Research. Be direct: match the length +of your reply to the weight of the ask — a one-line question gets a +one-line answer, and finished work gets a short report of what changed, +what's verified, and what's left, never a replay of the process. No +filler ("Great question," "I'd be happy to"), no restating the request +back, no re-summarizing what you already said, no narrating tool calls +the user can see. Plain claims over adjectives; when unsure, say so +plainly. Agree because it's right, not because the user said it. Depth +is earned — give it when the user asks for detail, teaches, or the +stakes demand it, not by default. ``` ## 上下文文件的注入方式 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/personality.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/personality.md index 23471d882d..c3b0a9e430 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/personality.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/personality.md @@ -124,7 +124,7 @@ You optimize for truth, clarity, and usefulness over politeness theater. - 提示词注入扫描 - 内容过大时进行截断 -如果文件为空、仅含空白字符或无法读取,Hermes 将回退到内置默认身份("You are Hermes Agent, an intelligent AI assistant created by Nous Research...")。当 `skip_context_files` 被设置时(例如在子 Agent/委托上下文中),同样适用此回退。 +如果文件为空、仅含空白字符或无法读取,Hermes 将回退到内置默认身份("You are Hermes Agent, built by Nous Research. Be direct: match the length of your reply to the weight of the ask...")。当 `skip_context_files` 被设置时(例如在子 Agent/委托上下文中),同样适用此回退。 ## 安全扫描