mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-20 10:11:58 +00:00
fix(agent): rebuild base fts without trigram
This commit is contained in:
parent
c10aa5dc9c
commit
9ae98e07a7
2 changed files with 53 additions and 5 deletions
|
|
@ -845,9 +845,12 @@ class SessionDB:
|
|||
return int(row[0] if not isinstance(row, sqlite3.Row) else row[0])
|
||||
|
||||
@staticmethod
|
||||
def _rebuild_fts_indexes(cursor: sqlite3.Cursor) -> None:
|
||||
for table_name in ("messages_fts", "messages_fts_trigram"):
|
||||
cursor.execute(f"DELETE FROM {table_name}")
|
||||
def _rebuild_fts_indexes(
|
||||
cursor: sqlite3.Cursor,
|
||||
*,
|
||||
include_trigram: bool = True,
|
||||
) -> None:
|
||||
cursor.execute("DELETE FROM messages_fts")
|
||||
cursor.execute(
|
||||
"INSERT INTO messages_fts(rowid, content) "
|
||||
"SELECT id, "
|
||||
|
|
@ -856,6 +859,9 @@ class SessionDB:
|
|||
"COALESCE(tool_calls, '') "
|
||||
"FROM messages"
|
||||
)
|
||||
if not include_trigram:
|
||||
return
|
||||
cursor.execute("DELETE FROM messages_fts_trigram")
|
||||
cursor.execute(
|
||||
"INSERT INTO messages_fts_trigram(rowid, content) "
|
||||
"SELECT id, "
|
||||
|
|
@ -1317,8 +1323,11 @@ class SessionDB:
|
|||
cursor, "messages_fts_trigram", FTS_TRIGRAM_SQL
|
||||
)
|
||||
self._trigram_available = trigram_enabled
|
||||
if trigram_enabled and triggers_need_repair:
|
||||
self._rebuild_fts_indexes(cursor)
|
||||
if triggers_need_repair:
|
||||
self._rebuild_fts_indexes(
|
||||
cursor,
|
||||
include_trigram=trigram_enabled,
|
||||
)
|
||||
|
||||
self._conn.commit()
|
||||
|
||||
|
|
|
|||
|
|
@ -344,6 +344,45 @@ class TestSessionLifecycle:
|
|||
finally:
|
||||
restored.close()
|
||||
|
||||
def test_base_fts_rebuilds_after_trigger_repair_without_trigram(
|
||||
self, tmp_path, monkeypatch
|
||||
):
|
||||
"""Trigger repair must rebuild base FTS even when trigram is unavailable."""
|
||||
db_path = tmp_path / "state.db"
|
||||
seeded = SessionDB(db_path=db_path)
|
||||
try:
|
||||
seeded.create_session(session_id="s1", source="cli")
|
||||
seeded.append_message("s1", role="user", content="already indexed")
|
||||
for trigger in (
|
||||
"messages_fts_insert",
|
||||
"messages_fts_delete",
|
||||
"messages_fts_update",
|
||||
"messages_fts_trigram_insert",
|
||||
"messages_fts_trigram_delete",
|
||||
"messages_fts_trigram_update",
|
||||
):
|
||||
seeded._conn.execute(f"DROP TRIGGER IF EXISTS {trigger}")
|
||||
seeded._conn.commit()
|
||||
seeded.append_message("s1", role="assistant", content="repair only base needle")
|
||||
finally:
|
||||
seeded.close()
|
||||
|
||||
real_connect = sqlite3.connect
|
||||
|
||||
def connect_without_trigram(*args, **kwargs):
|
||||
kwargs["factory"] = _NoTrigramConnection
|
||||
return real_connect(*args, **kwargs)
|
||||
|
||||
monkeypatch.setattr("hermes_state.sqlite3.connect", connect_without_trigram)
|
||||
restored = SessionDB(db_path=db_path)
|
||||
try:
|
||||
assert restored._fts_enabled is True
|
||||
assert restored._trigram_available is False
|
||||
assert restored._fts_table_exists("messages_fts") is True
|
||||
assert len(restored.search_messages("needle")) == 1
|
||||
finally:
|
||||
restored.close()
|
||||
|
||||
def test_is_fts5_unavailable_error_catches_trigram_tokenizer(self):
|
||||
"""Unit test: _is_fts5_unavailable_error matches 'no such tokenizer: trigram'."""
|
||||
fts5_err = sqlite3.OperationalError("no such module: fts5")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue