hermes - ✅(Solved) Fix honcho: peerName in config should win over platform user ID for single-user setups [3 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#14984Fetched 2026-04-24 10:43:48
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
labeled ×4

Honcho has no native peer aliasing/merging API (confirmed). The only correct solution is at the application layer.

For single-user setups (the vast majority of Hermes personal deployments), peerName in config unambiguously identifies the user — there's no reason to let the platform-native ID override it. For multi-user bots, the current behavior is correct.

Root Cause

Honcho has no native peer aliasing/merging API (confirmed). The only correct solution is at the application layer.

For single-user setups (the vast majority of Hermes personal deployments), peerName in config unambiguously identifies the user — there's no reason to let the platform-native ID override it. For multi-user bots, the current behavior is correct.

Fix Action

Fix / Workaround

Current Workaround (fragile)

Patching source files and re-applying them in post-update.sh. Breaks on anchor text changes upstream.

PR fix notes

PR #15162: fix(honcho): pinPeerName opt-in keeps memory unified across platforms (#14984)

Description (problem / solution / changelog)

What does this PR do?

Fixes #14984: when Hermes runs under a gateway (Telegram, Discord, Slack, ...) and Honcho is the active memory provider, the platform-native user ID (Telegram UID, Discord snowflake, ...) always wins over the `peer_name` configured in `honcho.json`. That's correct for multi-user bots — each user needs their own peer scope — but it's wrong for the vast majority of personal Hermes deployments where `peerName` is an unambiguous identity.

The failure mode: one physical user talks to their Hermes over Telegram, Discord, and Slack and ends up as three separate Honcho peers. Memory, peer-card, and dialectic context all fork per-platform.

Fix

New `pinPeerName` boolean on the host config, default `false` (preserves existing multi-user behaviour). When `true` and `peerName` is set, the configured peer_name beats the gateway's runtime identity.

```json { "peerName": "Igor", "hosts": { "hermes": { "pinPeerName": true } } } ```

Resolution order becomes (pinned case):

inputchosen user_peer_id
`runtime_user_peer_name`skipped (opt-in flag active)
`config.peer_name`WINS — `"Igor"`
session-key fallbackunreached

Config parsing follows the same host-block-overrides-root pattern as every other flag in `HonchoClientConfig.from_global_config` (the existing `_resolve_bool` helper).

Safety rail: `pinPeerName=true` with no `peerName` set is a no-op — otherwise the user peer would silently collapse to the session-key fallback and lose per-user scoping entirely. Explicit regression test for this.

Files changed

  • `plugins/memory/honcho/client.py`: new `pin_peer_name` field on `HonchoClientConfig`, parsed in `from_global_config` with host-block-overrides-root semantics via the existing `_resolve_bool` helper. No other behaviour touched.
  • `plugins/memory/honcho/session.py`: one-liner gate in `get_or_create` — `if self._runtime_user_peer_name and not pin_peer_name:`. Uses `getattr(..., "pin_peer_name", False)` as a defensive fallback so callers building partial config objects (several test fixtures across the codebase do this) don't break.
  • `tests/honcho_plugin/test_pin_peer_name.py`: 13 new tests in 3 classes covering config parsing, peer resolution order, and the cross-platform unification outcome.

Related Issue

Fixes #14984

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✅ Tests (adding or improving test coverage)

Test plan

  • `tests/honcho_plugin/test_pin_peer_name.py` — 13 new tests pass
  • Full honcho_plugin suite — 244 passed, 3 pre-existing skips, 0 regressions
  • `tests/test_honcho_client_config.py` — 7 existing config tests still pass
  • Default behaviour verified: runtime ID still wins when `pinPeerName` unset (regression guard — a silent drift here would merge memory across users of multi-user bots)

Test coverage detail

Group 1 — Config parsing (`TestPinPeerNameConfigParsing`, 5 tests)

  • `test_default_is_false` — `HonchoClientConfig()` defaults to `pin_peer_name=False`
  • `test_root_level_true` — `pinPeerName: true` at root parses correctly
  • `test_host_block_true` — `hosts.hermes.pinPeerName: true` parses correctly
  • `test_host_block_overrides_root` — host `false` overrides root `true` (matches every other flag)
  • `test_explicit_false_parses` — `pinPeerName: false` resolves to `False`

Group 2 — Peer resolution order (`TestPeerResolutionOrder`, 6 tests)

  • `test_runtime_wins_when_pin_is_false` — multi-user regression guard
  • `test_config_wins_when_pin_is_true` — the #14984 fix
  • `test_pin_noop_when_peer_name_missing` — no silent collapse
  • `test_runtime_missing_falls_back_to_peer_name` — CLI-mode unchanged
  • `test_everything_missing_falls_back_to_session_key` — deepest fallback intact
  • `test_pin_does_not_affect_assistant_peer` — flag is user-peer-scoped only

Group 3 — Cross-platform unification (`TestCrossPlatformMemoryUnification`, 2 tests)

  • `test_telegram_and_discord_collapse_to_one_peer_when_pinned` — the user-visible outcome
  • `test_multiuser_default_keeps_platforms_separate` — negative control, a regression here would silently merge unrelated users' memory

Not in scope

  • A UX polish where a warning fires if `pinPeerName` is set but `peerName` isn't — deliberately left out since the no-op path is already the safe behaviour; we can add a one-time log if the maintainers want it.
  • Per-host pinning with different peer_names — current design says "if pinned, use the config peer_name for this host block" which is sufficient for the reported use case.

Changed files

  • plugins/memory/honcho/client.py (modified, +12/-0)
  • plugins/memory/honcho/session.py (modified, +19/-2)
  • tests/honcho_plugin/test_pin_peer_name.py (added, +307/-0)

PR #15340: fix(honcho): pinPeerName opt-in keeps memory unified across platforms

Description (problem / solution / changelog)

Adopts #15162 by @briandevans with original authorship preserved.

Fixes #14984, #14401.

pinPeerName: true in host config makes configured peerName win over gateway-threaded runtime_user_peer_name. Default false preserves existing multi-user bot behavior. Second commit tightens the guard to is True so MagicMock fixtures don't trip it.

  • plugins/memory/honcho/client.py: +12
  • plugins/memory/honcho/session.py: +19 -2
  • tests/honcho_plugin/test_pin_peer_name.py: +307 (13 new tests)

240/240 honcho_plugin tests pass locally.

Changed files

  • plugins/memory/honcho/client.py (modified, +12/-0)
  • plugins/memory/honcho/session.py (modified, +19/-2)
  • tests/honcho_plugin/test_pin_peer_name.py (added, +307/-0)

PR #15381: fix(honcho): bug-fix consolidation — 7 upstream PRs, preserved authorship

Description (problem / solution / changelog)

Consolidates seven Honcho bug fixes from the open PR queue into one stack. Each upstream PR is a single commit (two for #15162 which itself was two) with original author + date preserved.

Tracked fixes (in cherry-pick order):

  • #15162 @briandevans — pinPeerName opt-in keeps memory unified across platforms (fixes #14984, #14401)
  • #13931 @Sanjays2402 — truncate resolve_session_name output to Honcho's 100-char limit (fixes #13868)
  • #13510 @hekaru-agent — thread-safe session cache via RLock (fixes #5102; off-topic cron/jobs.py hunk dropped, small conflict with pinPeerName guard resolved keeping both)
  • #13672 @dontcallmejames — memory-context leak boundary hardening (fixes #5719; only the boundary-fix commits 503fa1b9 + e11bbd98 adopted, the unrelated update-command and conclusions-query commits dropped)
  • #13320 @HiddenPuppy — HOME-aware config fallback path resolution (fixes #13283)
  • #14881 @sasha-id — CLI credential guard accepts self-hosted baseUrl-only configs
  • #13623 @twozle — default SDK HTTP timeout to 30s

Dropped from the original queue as already-shipped or not applicable:

  • #1878 — context_tokens budget already implemented at plugins/memory/honcho/__init__.py:684 (_truncate_to_budget). Can be closed upstream.

Files touched (9 commits total):

  • plugins/memory/honcho/client.py
  • plugins/memory/honcho/session.py
  • plugins/memory/honcho/init.py
  • plugins/memory/honcho/cli.py
  • hermes_state.py
  • run_agent.py
  • tests across honcho_plugin/, run_agent/, test_hermes_state.py

1442 of 1443 tests pass across honcho_plugin + run_agent + hermes_state. The single failure (tests/run_agent/test_tool_arg_coercion.py::TestCoerceNumber::test_inf_stays_string_for_integer_only) is a preexisting flake on main, unrelated to these changes.

Also landed separately and merged earlier (not part of this PR):

  • #7193 on_turn_start() hook — already wired at run_agent.py:9223. Close issue.
  • #7192 on_pre_compress() return value — still broken at run_agent.py:7791. Keep open.

Changed files

  • agent/memory_manager.py (modified, +111/-0)
  • gateway/run.py (modified, +9/-0)
  • hermes_state.py (modified, +6/-1)
  • plugins/memory/honcho/__init__.py (modified, +5/-2)
  • plugins/memory/honcho/cli.py (modified, +21/-2)
  • plugins/memory/honcho/client.py (modified, +67/-3)
  • plugins/memory/honcho/session.py (modified, +61/-36)
  • run_agent.py (modified, +50/-5)
  • tests/agent/test_streaming_context_scrubber.py (added, +150/-0)
  • tests/gateway/test_vision_memory_leak.py (added, +99/-0)
  • tests/honcho_plugin/test_cli.py (modified, +66/-0)
  • tests/honcho_plugin/test_client.py (modified, +112/-3)
  • tests/honcho_plugin/test_pin_peer_name.py (added, +307/-0)
  • tests/honcho_plugin/test_session.py (modified, +33/-0)
  • tests/run_agent/test_run_agent.py (modified, +14/-0)
  • tests/run_agent/test_run_agent_codex_responses.py (modified, +94/-0)
  • tests/test_hermes_state.py (modified, +18/-0)

Code Example

if self._runtime_user_peer_name:
    user_peer_id = self._sanitize_id(self._runtime_user_peer_name)  # ← platform ID wins
elif self._config and self._config.peer_name:
    user_peer_id = self._sanitize_id(self._config.peer_name)

---

{
  "peerName": "Igor",
  "hosts": {
    "hermes": {
      "pinPeerName": true
    }
  }
}

---

if self._runtime_user_peer_name and not (self._config and self._config.pin_peer_name):
    user_peer_id = self._sanitize_id(self._runtime_user_peer_name)
elif self._config and self._config.peer_name:
    user_peer_id = self._sanitize_id(self._config.peer_name)
RAW_BUFFERClick to expand / collapse

Problem

When Honcho is enabled, the gateway passes the raw platform user ID (e.g. Telegram numeric UID 86701400, Discord ID 1348750102029926454) as runtime_user_peer_name into the Honcho plugin. This is resolved to the peer ID with highest priority, overriding peerName set in honcho.json.

The result: a single user gets 3+ separate Honcho peers — one per platform — with fragmented memory and no cross-platform context continuity.

File: plugins/memory/honcho/session.py, lines ~280-290

if self._runtime_user_peer_name:
    user_peer_id = self._sanitize_id(self._runtime_user_peer_name)  # ← platform ID wins
elif self._config and self._config.peer_name:
    user_peer_id = self._sanitize_id(self._config.peer_name)

Context

Honcho has no native peer aliasing/merging API (confirmed). The only correct solution is at the application layer.

For single-user setups (the vast majority of Hermes personal deployments), peerName in config unambiguously identifies the user — there's no reason to let the platform-native ID override it. For multi-user bots, the current behavior is correct.

Proposed Fix

Add a pinPeerName (or singleUser) boolean to the host config block. When true, peerName always wins over runtime_user_peer_name.

honcho.json:

{
  "peerName": "Igor",
  "hosts": {
    "hermes": {
      "pinPeerName": true
    }
  }
}

session.py:

if self._runtime_user_peer_name and not (self._config and self._config.pin_peer_name):
    user_peer_id = self._sanitize_id(self._runtime_user_peer_name)
elif self._config and self._config.peer_name:
    user_peer_id = self._sanitize_id(self._config.peer_name)

This is a one-line change in session.py + one field added to HonchoClientConfig + one field parsed in from_global_config. No breaking change for multi-user setups (default false).

Current Workaround (fragile)

Patching source files and re-applying them in post-update.sh. Breaks on anchor text changes upstream.

extent analysis

TL;DR

To resolve the issue, add a pinPeerName boolean to the host config block in honcho.json and update the session.py file to prioritize peerName over runtime_user_peer_name when pinPeerName is true.

Guidance

  • Update honcho.json to include the pinPeerName field in the host config block, setting it to true for single-user setups.
  • Modify session.py to check for the pinPeerName field and use peerName when it is true, as shown in the proposed fix.
  • Verify that the change resolves the issue by checking that a single user is no longer assigned multiple Honcho peers.
  • Consider the implications of this change for multi-user bots, where the current behavior is correct, and ensure that the default false value for pinPeerName does not introduce issues.

Example

if self._runtime_user_peer_name and not (self._config and self._config.pin_peer_name):
    user_peer_id = self._sanitize_id(self._runtime_user_peer_name)
elif self._config and self._config.peer_name:
    user_peer_id = self._sanitize_id(self._config.peer_name)

Notes

This solution assumes that the pinPeerName field is correctly parsed from the honcho.json file and that the session.py update is applied correctly. Additionally, this change may not be suitable for all use cases, particularly multi-user bots, where the current behavior is intended.

Recommendation

Apply the proposed workaround by adding the pinPeerName field to honcho.json and updating session.py, as this provides a targeted solution to the issue without introducing breaking changes for multi-user setups.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix honcho: peerName in config should win over platform user ID for single-user setups [3 pull requests, 1 participants]