Commit graph

8 commits

Author SHA1 Message Date
Erosika
1a8e67076a fix(honcho): cover pinUserPeer + aiPeer edge cases in setup, clone, and gateway cache
Three related regressions stemming from the pinUserPeer alias landing:

- Setup wizard read host-only fields when detecting current shape but the
  parser supports root-level config and gives host pinUserPeer higher
  precedence than pinPeerName. Re-running setup could mis-detect shape
  and silently flip routing. Detection now uses the same resolver order
  as HonchoClientConfig, and each shape branch scrubs every peer-mapping
  key before writing so a stale pinUserPeer=false can't outrank a freshly
  written pinPeerName=true. Multi no longer auto-writes
  userPeerAliases={} (was silently masking root-level baselines).

- clone_honcho_for_profile inherited pinPeerName but not pinUserPeer, so
  a default profile configured with the newer key produced cloned
  profiles without the pin.

- Gateway cache-busting signature fingerprinted Honcho user-peer fields
  but not ai_peer. Since HonchoSessionManager freezes cfg.ai_peer at
  init, mid-flight aiPeer edits kept assistant writes on the old peer
  until an unrelated cache eviction. ai_peer is now part of the
  signature.
2026-05-27 10:49:33 -07:00
Erosika
939499beed chore(honcho): trim PR-history narration from docs and tests
Remove "PR #14984 / #27371 / #1969" references and "the original key /
legacy / backwards-compatible / Port #N" narration from the honcho
plugin README, tests, and one stale code comment. These artefacts age
poorly: they describe how a change happened rather than what the code
does today, and they tax readers who weren't around for the original
work.

Also drop a dangling reference to scratch/memory-plugin-ux-specs.md in
__init__.py — the file isn't in the repo or git history.

No behaviour change.
2026-05-27 10:49:33 -07:00
Erosika
6feb2afd50 fix(honcho): plug pinPeerName transition gaps
Three correctness gaps when honcho.json's identity-mapping config changes
mid-flight:

1. The gateway's agent cache signature ignored honcho identity keys, so
   editing peerName / pinPeerName / userPeerAliases / runtimePeerPrefix
   was silently dropped until an unrelated cache eviction. Extend
   _extract_cache_busting_config to fingerprint the resolved honcho
   config so the AIAgent rebuilds on the next message.

2. cmd_setup let single → multi flips orphan the pinned-pool history
   under peerName without warning. Detect the transition, warn that
   runtime users will resolve to fresh empty peers, and auto-steer to
   hybrid (alias the operator's runtime IDs back to peerName) so the
   operator's own continuity survives. yes / no overrides available.

3. README didn't document the orphaning behaviour. Add a "Migrating
   single → multi" callout under Deployment shapes.

Tests:
- TestPinTransition (test_pin_peer_name.py): fresh-manager flip resolves
  to runtime, in-process flip is gated by the per-key session cache
  (documents the gateway-cache-must-bust contract), 3 cache-bust
  signature tests for pin / aliases / prefix.
- TestProfilePeerUniqueness: two profiles pinned to distinct peerNames
  resolve to distinct peers; host-level peerName overrides root when
  pinned.
- test_single_to_multi_steers_to_hybrid_by_default and
  test_single_to_multi_yes_override_keeps_multi (test_cli.py): wizard
  guard end-to-end coverage.
2026-05-27 10:49:33 -07:00
erosika
3cf5e8225d refactor(honcho): accept pinUserPeer as backwards-compatible alias for pinPeerName
The original key 'pinPeerName' from #14984 is ambiguous: a fresh
reader can't tell whether it pins the user peer or the AI peer from
the name alone.  The resolver only ever pins the user-side
(_resolve_user_peer_id short-circuits when pin_peer_name is true; the
AI peer is already pinned by construction via aiPeer).

Add 'pinUserPeer' as the canonical alias.  Both keys land on the
same internal pin_peer_name field; precedence is host pinUserPeer →
host pinPeerName → root pinUserPeer → root pinPeerName → default.
Host-level always beats root-level regardless of alias, so a host
block can still explicitly disable a root-level pin even via the new
key.

Make _resolve_bool variadic so it can express the four-value
precedence chain.  All existing callers pass two positional args +
default keyword, which the new signature accepts unchanged.

Internal var name (pin_peer_name) stays the same to keep the
cherry-picked #27371 commits clean and avoid a noisy rename diff.
2026-05-27 10:49:33 -07:00
mavrickdeveloper
30b391ab36 Avoid Honcho runtime peer collisions
(cherry picked from commit 4ae3c1a228)
2026-05-27 10:49:33 -07:00
mavrickdeveloper
382b1fc1b6 Cover Honcho runtime peer edge cases
(cherry picked from commit d89a57ea40)
2026-05-27 10:49:33 -07:00
mavrickdeveloper
2e3c6627ce Add Honcho runtime peer mapping
(cherry picked from commit 864cdb3d2e)
2026-05-27 10:49:33 -07:00
Brian D. Evans
d03c6fcc45 fix(honcho): pinPeerName opt-in keeps memory unified across platforms (#14984)
When a gateway drives Hermes (Telegram, Discord, Slack, ...), it passes the
platform-native user ID as ``runtime_user_peer_name`` into the Honcho
session manager.  That ID wins over ``peer_name`` in ``honcho.json``, so a
single user who connects over three platforms ends up as three separate
Honcho peers — one per platform — with fragmented memory and no cross-
platform context continuity.

For multi-user bots this is correct (and must not change): each user gets
their own peer scope.  For the vast majority of personal Hermes deployments
the configured ``peer_name`` is an unambiguous identity, though, so the
reporter asked for an opt-in knob that pins the user peer to that value.

Fix: new ``pinPeerName`` boolean on the host config, default ``false``.
When ``true`` AND ``peerName`` is set, the configured peer_name beats the
gateway's runtime identity; every other resolution case is unchanged.

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

  session.py (resolution order, pinned case):
    runtime_user_peer_name  →  skipped (opt-in flag active)
    config.peer_name        →  WINS   "Igor"
    session-key fallback    →  unreached

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

Tests (tests/honcho_plugin/test_pin_peer_name.py — 13 cases, 5 groups):
- Config parsing: default, root true, host-block true, host overrides
  root, explicit false.
- Peer resolution: runtime wins by default (regression guard for multi-
  user bots), config wins when pinned, pin-without-peer_name is a no-op
  (prevents silent peer-id collapse to session-key fallback), CLI path
  where runtime is absent, deepest fallback intact, assistant peer
  untouched by the flag.
- Cross-platform unification: Telegram UID + Discord snowflake collapse
  to one peer when pinned; negative control confirms two distinct
  runtime IDs still produce two peers when unpinned.

244 honcho_plugin tests pass, 3 pre-existing skips, zero regressions.

Defensive detail: session.py uses ``getattr(self._config, "pin_peer_name",
False)`` so callers building partial config objects (several test fixtures
across the codebase do this) don't break if they haven't updated yet.
Runtime cost: one attr lookup per new session.

Closes #14984

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:37:33 -07:00