14 Commits

Author SHA1 Message Date
nicecuprani
06475d1138 fix(session-titles): resolve the canonical Bot Chat by exact title, never a "#N" sibling
`SessionDB.resolve_session_by_title()` prefers a "`<title> #N`" continuation over the
exact match. For the canonical Bot Chat that preference is wrong: Bot Mode identifies
that session BY its exact title, and this lookup is the only one every DM transport
shares (`hermes -p <bot> chat --in ~ -c "Bot Chat"` — used by `message_agent`,
`bot_relay` and cron delivery).

Once a numbered sibling exists (a Desktop branch of the canonical chat,
`title_source='derived'`), every teammate DM resolves to that sibling: a visible,
unmanaged session where the `message_agent` gate is off, so the addressed bot cannot
answer and the sender gets silence instead of an error.

Return the exact match when the requested title IS the canonical Bot Chat title; every
other title keeps the "newest continuation wins" behaviour untouched.

(cherry picked from commit e92638b4c53c97c48db4d9bbb2d3b6b580d289a7)
2026-09-20 10:32:40 -07:00
KoNit-K
b6207cb590 fix(state): release archived Bot Chat title 2026-09-15 04:27:32 -07:00
Teknium
53db597201 simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files
hermes_state.py: delete every '# noqa: F401 (re-exported...)' import block (hermes_state_common/errors/guard/
readpool/sessions/fts/dbfile/wal/repair/registry + agent.context_compressor _DB_PERSISTED_MARKER_KEY); keep
only the names hermes_state.py itself uses, without noqa.
hermes_state_registry.py: drop get_shared_session_db/release_shared_session_db/close_shared_session_dbs
aliases; every caller (gateway/, tools/, tui_gateway/, cron/, mcp_serve, run_agent, tests) now imports
acquire/release/close_all/release_or_close from hermes_state_registry.
hermes_state_titles.py: drop set_auto_title_if_empty shim (title_generator keeps its getattr fallback).
Re-remove shim-only names restored by 34abf954bd: latest_user_message_row_id (tests call
latest_message_row_id(key, role='user'); role-targeting assertions kept) and get_session_activity (tests
build the snapshot via agent.session_activity.build_activity_snapshot over db.get_session(sid)).
hermes_state_wal._log_once resolves its dedupe sets as module globals instead of via hermes_state;
hermes_state_repair helpers call module globals directly (tests patch hermes_state_repair.<name>).
Frozen updater surface untouched (update_cmd_maint imports only SessionDB from hermes_state).
2026-09-03 13:46:50 -07:00
Teknium
cb6cc64700 refactor(state): search/schema/registry/portability/telegram/usage/titles — inline single-use helpers, contextlib.suppress ladders, pack wrappers around unchanged SQL literals 2026-09-02 21:57:21 -07:00
Teknium
c1620901ae refactor(hermes_state): AST-neutral packing of state mixins (120 cols) 2026-09-02 19:10:31 -07:00
Teknium
d2614f435e refactor(hermes_state): AST-neutral line packing across state mixins 2026-09-02 18:30:39 -07:00
Teknium
1263a7d243 refactor(hermes_state_titles): reuse _NUMBERED_TITLE_RE, compact docstrings 2026-09-02 18:26:28 -07:00
Teknium
831f2e542c refactor(state): fold small get_messages/reaction/publish shapes; hug trailing closers (AST-identical) 2026-09-02 17:20:16 -07:00
Teknium
1991695511 refactor(state): _cooldown_row shape helper; per-model usage kwargs via field set; small folds 2026-09-02 17:17:16 -07:00
Teknium
388fe39f55 refactor(state): compact messages docstrings (WHY kept); append_message builds msg from its own kwargs 2026-09-02 17:06:57 -07:00
Teknium
8656cc31f2 refactor(state): table-driven _rows_to_conversation column copy; unify tool-call counting; collapse defensive locals 2026-09-02 16:59:58 -07:00
Teknium
52d982281c refactor(state): _stale_holder guard helper; join implicit-concat SQL fragments (AST-identical) 2026-09-02 16:44:38 -07:00
Teknium
5c3acca66b refactor(state): resume — verified messages/compression/titles/usage simplification 2026-09-02 16:37:21 -07:00
Teknium
d15c61b5dc refactor(state): split SessionDB into domain mixins and free-function modules; unify SQL boilerplate
hermes_state.py 17,220 -> 6,442 LOC. Behavior-neutral: every moved body is
AST-identical to the original, verified per extraction.

SessionDB core
- _write_sql / _write_rowcount / _read_one / _read_all replace ~120 copies of
  the `def _do(conn): conn.execute(...)` + `_execute_write(_do)` and
  `with self._read_ctx() as conn: row = conn.execute(...).fetchone()` shapes.
- _set_lineage_column replaces four copies of the recursive compression-lineage
  UPDATE (archived / pinned / hidden / last_read_at).
- _read_session_number unifies the three compression counter readers.
- Dead (zero refs repo-wide): restore_rewound, delete_gateway_routing_entries,
  _is_duplicate_replayed_user_message, SessionPortabilityMixin.get_first_assistant_text.

New mixins bound onto SessionDB via the MRO (logger name stays "hermes_state"):
  hermes_state_messages    SessionMessagesMixin       48 methods
  hermes_state_compression SessionCompressionMixin    30
  hermes_state_gateway     SessionGatewayMixin        26
  hermes_state_maintenance SessionMaintenanceMixin    13
  hermes_state_usage       SessionUsageMixin          12
  hermes_state_titles      SessionTitlesMixin         13
  hermes_state_telegram    SessionTelegramTopicsMixin 11
Origin-internal symbols resolve through a lazy `from hermes_state import ...`
inside the few methods that need them (no import cycle).

New free-function modules, every name re-imported into hermes_state so
`hermes_state.<name>` (and test monkeypatches on it) keep working; intra-module
calls to patched helpers go through the lazy origin import:
  hermes_state_repair   repair/backup/preflight (43 defs)
  hermes_state_wal      journal-mode / PRAGMA policy (33 defs)
  hermes_state_dbfile   header probes, zeroed-db quarantine, stats, holders (21 defs)

Existing mixins: search — shared FTS MATCH/LIKE builders, unified rebuild
status/step/finish engines, state_meta helpers; schema — one legacy/v23 FTS init
branch, shared _live_pk_columns, Row/tuple dual access dropped; portability —
shared _PREVIEW_RAW_SUBQUERY_SQL and _rich_row; common — single
stat_db_file_identity (was 3 copies), AUTO_VACUUM_MIN_FREELIST_RATIO.

Docstrings/comments hand-compacted (AST-identical) keeping every invariant,
ordering rule, failure mode and WHY. Schema SQL, migration order and PRAGMAs
untouched. test_repair_path_has_no_bare_connects repointed to hermes_state_repair.
2026-09-02 13:32:13 -07:00