feat: wire semantic controls into legacy and tui v2 interfaces

This commit is contained in:
thePR0M3TH3AN committed 2026-03-02 11:52:30 -05:00
1 parent 165e2db204
commit ec407c611a
7 files changed
+532

No files matched your search

+48
View File
@@ -358,3 +358,51 @@ def test_nostr_menu_dispatches_fresh_namespace(monkeypatch):
with patch("builtins.input", side_effect=lambda *_: next(inputs)):
main.handle_nostr_menu(pm)
handler.assert_called_once_with(pm)
def test_settings_menu_dispatches_semantic_submenu(monkeypatch):
with TemporaryDirectory() as tmpdir:
tmp_path = Path(tmpdir)
pm, _, _ = setup_pm(tmp_path, monkeypatch)
inputs = iter(["18", ""])
with patch("main.handle_semantic_index_menu") as handler:
with patch("builtins.input", side_effect=lambda *_: next(inputs)):
main.handle_settings(pm)
handler.assert_called_once_with(pm)
def test_semantic_submenu_search_flow(monkeypatch, capsys):
class DummySemanticService:
def __init__(self, _pm):
self.last_query = None
def status(self):
return {"enabled": False, "built": False, "records": 0}
def set_enabled(self, enabled: bool):
return {"enabled": bool(enabled), "records": 0}
def build(self):
return {"enabled": True, "built": True, "records": 2}
def rebuild(self):
return {"enabled": True, "built": True, "records": 2}
def search(self, query: str, *, k: int = 10, kind: str | None = None):
self.last_query = query
return [{"entry_id": 1, "kind": "document", "label": "Doc", "score": 0.5}]
with TemporaryDirectory() as tmpdir:
tmp_path = Path(tmpdir)
pm, _, _ = setup_pm(tmp_path, monkeypatch)
monkeypatch.setattr(main, "SemanticIndexService", DummySemanticService)
monkeypatch.setattr(main, "pause", lambda: None)
inputs = iter(["1", "2", "4", "6", "relay docs", ""])
with patch("builtins.input", side_effect=lambda *_: next(inputs)):
main.handle_semantic_index_menu(pm)
out = capsys.readouterr().out
assert "Status: enabled=False, built=False, records=0" in out
assert "Semantic index enabled" in out
assert "Semantic index built with 2 records" in out
assert "Semantic Matches:" in out
assert "#1 [document] Doc" in out
+8
View File
@@ -560,6 +560,12 @@ async def test_tui2_matrix_actions_palette_events_and_guards() -> None:
app._run_palette_command("setting-timeout 300")
app._run_palette_command("setting-kdf-iterations 100000")
app._run_palette_command("setting-kdf-mode pbkdf2")
app._run_palette_command("semantic-status")
app._run_palette_command("semantic-enable now")
app._run_palette_command("semantic-disable now")
app._run_palette_command("semantic-build now")
app._run_palette_command("semantic-rebuild now")
app._run_palette_command("semantic-search")
app._run_palette_command("relay-list")
app._run_palette_command("npub")
app._run_palette_command("relay-add wss://relay.example")
@@ -601,6 +607,8 @@ async def test_tui2_matrix_actions_palette_events_and_guards() -> None:
app._run_palette_command("lock")
app._run_palette_command("unlock hunter2")
app._run_palette_command("search Doc")
app._run_palette_command("semantic-status")
app._run_palette_command("semantic-search notes")
app.action_focus_left()
app._run_palette_command("profile-tree-next")
app._run_palette_command("profile-tree-prev")
@@ -562,6 +562,49 @@ class FakeVaultService:
return _Resp()
class FakeSemanticService:
def __init__(self) -> None:
self.enabled = False
self.built = False
self.records = 0
self.last_query: str | None = None
def status(self):
return {
"enabled": bool(self.enabled),
"built": bool(self.built),
"records": int(self.records),
}
def set_enabled(self, enabled: bool):
self.enabled = bool(enabled)
return self.status()
def build(self):
self.built = True
self.records = 2
return self.status()
def rebuild(self):
self.built = True
self.records = 2
return self.status()
def search(self, query: str, *, k: int = 10, kind: str | None = None):
self.last_query = str(query)
if not query.strip():
return []
return [
{
"entry_id": 1,
"kind": kind or "document",
"label": "Doc",
"score": 0.7,
"excerpt": f"query={query} k={k}",
}
]
def _build_app(
service: FakeEntryService,
*,
@@ -571,6 +614,7 @@ def _build_app(
sync_service=None,
utility_service=None,
vault_service=None,
semantic_service=None,
):
holder: dict[str, object] = {}
@@ -597,6 +641,9 @@ def _build_app(
vault_service_factory=(
(lambda: vault_service) if vault_service is not None else None
),
semantic_service_factory=(
(lambda: semantic_service) if semantic_service is not None else None
),
app_hook=_hook,
)
assert launched is True
@@ -1547,6 +1594,7 @@ async def test_tui2_textual_profiles_and_settings_palette_commands() -> None:
sync = FakeSyncService()
utility = FakeUtilityService()
vault = FakeVaultService()
semantic = FakeSemanticService()
app = _build_app(
service,
profile_service=profiles,
@@ -1555,6 +1603,7 @@ async def test_tui2_textual_profiles_and_settings_palette_commands() -> None:
sync_service=sync,
utility_service=utility,
vault_service=vault,
semantic_service=semantic,
)
async with app.run_test() as pilot:
@@ -1611,6 +1660,34 @@ async def test_tui2_textual_profiles_and_settings_palette_commands() -> None:
assert config.kdf_mode == "argon2"
assert "KDF mode set to argon2" in _status_text(app)
app._run_palette_command("semantic-status")
await pilot.pause()
assert "Displayed semantic index status" in _status_text(app)
app._run_palette_command("semantic-enable")
await pilot.pause()
assert semantic.enabled is True
assert "Semantic index enabled" in _status_text(app)
app._run_palette_command("semantic-build")
await pilot.pause()
assert semantic.built is True
assert "Semantic index built" in _status_text(app)
app._run_palette_command("semantic-search relay recovery")
await pilot.pause()
assert semantic.last_query == "relay recovery"
assert "Semantic matches: 1 for 'relay recovery'" in _status_text(app)
app._run_palette_command("semantic-rebuild")
await pilot.pause()
assert "Semantic index rebuilt" in _status_text(app)
app._run_palette_command("semantic-disable")
await pilot.pause()
assert semantic.enabled is False
assert "Semantic index disabled" in _status_text(app)
app._run_palette_command("profile-add")
await pilot.pause()
assert "Created profile fp-new-1" in _status_text(app)
@@ -1763,6 +1840,10 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
await pilot.pause()
assert "Utility service unavailable" in _status_text(app)
app._run_palette_command("semantic-status")
await pilot.pause()
assert "Semantic service unavailable" in _status_text(app)
app._run_palette_command("db-export /tmp/x")
await pilot.pause()
assert "Vault service unavailable" in _status_text(app)
@@ -1831,6 +1912,14 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
await pilot.pause()
assert "Nostr service unavailable" in _status_text(app)
app._run_palette_command("semantic-enable now")
await pilot.pause()
assert "Semantic service unavailable" in _status_text(app)
app._run_palette_command("semantic-search")
await pilot.pause()
assert "Semantic service unavailable" in _status_text(app)
app._run_palette_command("npub")
await pilot.pause()
assert "Nostr service unavailable" in _status_text(app)
@@ -1855,6 +1944,7 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
vault = FakeVaultService()
nostr = FakeNostrService(["wss://r1"])
sync = FakeSyncService()
semantic = FakeSemanticService()
app = _build_app(
service,
profile_service=profiles,
@@ -1863,6 +1953,7 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
vault_service=vault,
nostr_service=nostr,
sync_service=sync,
semantic_service=semantic,
)
async with app.run_test() as pilot:
await pilot.pause()
@@ -1879,6 +1970,14 @@ async def test_tui2_textual_profiles_and_settings_palette_validation() -> None:
await pilot.pause()
assert "Usage: setting-kdf-mode <mode>" in _status_text(app)
app._run_palette_command("semantic-enable now")
await pilot.pause()
assert "Usage: semantic-enable" in _status_text(app)
app._run_palette_command("semantic-search")
await pilot.pause()
assert "Usage: semantic-search <query>" in _status_text(app)
app._run_palette_command("checksum-update nope")
await pilot.pause()
assert "Usage: checksum-update" in _status_text(app)