refactor(hermes_state): drop constant-false v10 trigram branch, shared search SELECT builder

This commit is contained in:
Teknium
2026-09-02 18:28:57 -07:00
parent 1263a7d243
commit d7fe7a47fd
2 changed files with 22 additions and 43 deletions

View File

@@ -838,29 +838,10 @@ class SessionSchemaMixin:
def _run_data_migrations(self, cursor: sqlite3.Cursor, current_version: int, fts5_available: bool) -> None:
"""Version-gated chain for DATA migrations only (row backfills, version-specific
index changes); column additions never belong here. Advances schema_version at
the end unless FTS work could not complete."""
the end unless FTS5 is unavailable."""
# Renew the lease: the chain can rewrite whole tables on large DBs.
report_startup_progress(600.0, phase="state_db_data_migrations")
fts_migrations_complete = True
if current_version < 10 and SCHEMA_VERSION == 10:
# v10: one-time trigram backfill. Only when v10 itself is the target: v11+
# drops and rebuilds both FTS tables, so the backfill would only burn startup
# time and WAL space.
if fts5_available:
_fts_trigram_exists = self._fts_table_probe(cursor, "messages_fts_trigram")
if _fts_trigram_exists is False:
if self._ensure_fts_schema(cursor, "messages_fts_trigram", FTS_TRIGRAM_SQL):
cursor.execute(
"INSERT INTO messages_fts_trigram(rowid, content) "
"SELECT id, content FROM messages WHERE content IS NOT NULL"
)
else:
fts_migrations_complete = False
elif _fts_trigram_exists is None:
fts_migrations_complete = False
else:
fts_migrations_complete = False
# (v11 inline FTS re-index was superseded by v23 and removed.)
# (v10 trigram backfill and v11 inline FTS re-index were superseded by v23 and removed.)
if current_version < 16:
# v16: tag delegate subagent rows so pickers stay clean after parent deletes
# orphan them. The shared predicate excludes user-visible reset children.
@@ -936,7 +917,7 @@ class SessionSchemaMixin:
# Advance schema_version — deliberately NOT gated on the FTS opt-in (that would
# block every future migration for a user who never optimizes). FTS5 unavailable
# is the one skip: claiming current would lie.
if current_version < SCHEMA_VERSION and fts_migrations_complete and fts5_available:
if current_version < SCHEMA_VERSION and fts5_available:
cursor.execute("UPDATE schema_version SET version = ?", (SCHEMA_VERSION,))
def _migrate_v22_session_model_usage(self, cursor: sqlite3.Cursor) -> None:

View File

@@ -132,6 +132,20 @@ def _positive_int(name: str, value: Any) -> None:
raise ValueError(f"{name} must be greater than zero")
def _search_select_sql(snippet_sql: str, from_sql: str, where: List[str], order_by: str, limit_sql: str) -> str:
"""Result-row SELECT shared by the FTS and LIKE routes (SQL text is pinned)."""
return f"""
SELECT m.id, m.session_id, m.role,
{snippet_sql},
{_SEARCH_SELECT_TAIL}
FROM {from_sql}
JOIN sessions s ON s.id = m.session_id
WHERE {' AND '.join(where)}
{order_by}
{limit_sql}
"""
def _search_filter_clauses(
where: List[str], params: list, *, include_inactive: bool, source_filter: Optional[List[str]],
exclude_sources: Optional[List[str]], role_filter: Optional[List[str]],
@@ -918,17 +932,10 @@ class SessionSearchMixin:
exclude_sources=exclude_sources, role_filter=role_filter,
)
params.extend([limit, offset])
sql = f"""
SELECT m.id, m.session_id, m.role,
snippet({table}, -1, '>>>', '<<<', '...', 40) AS snippet,
{_SEARCH_SELECT_TAIL}
FROM {table}
JOIN messages m ON m.id = {table}.rowid
JOIN sessions s ON s.id = m.session_id
WHERE {' AND '.join(where)}
{order_by_sql}
LIMIT ? OFFSET ?
"""
sql = _search_select_sql(
f"snippet({table}, -1, '>>>', '<<<', '...', 40) AS snippet",
f"{table}\n JOIN messages m ON m.id = {table}.rowid", where, order_by_sql, "LIMIT ? OFFSET ?",
)
return sql, params
def _match_rows(
@@ -959,16 +966,7 @@ class SessionSearchMixin:
def _like_rows(self, where: List[str], params: list, *, order_by: str, limit_sql: str) -> List[Dict[str, Any]]:
"""Canonical-table LIKE scan; ``params[0]`` is the snippet anchor term."""
sql = f"""
SELECT m.id, m.session_id, m.role,
{_LIKE_SNIPPET_SQL},
{_SEARCH_SELECT_TAIL}
FROM messages m
JOIN sessions s ON s.id = m.session_id
WHERE {' AND '.join(where)}
{order_by}
{limit_sql}
"""
sql = _search_select_sql(_LIKE_SNIPPET_SQL, "messages m", where, order_by, limit_sql)
return [dict(row) for row in self._read_all(sql, params)]
@staticmethod