fix(honcho): surface the peer notice and audit the injection on the recall sync path
With recallSync on, prefetch popped only the auth notice and returned without writing the injection log. A session whose init failed for a missing user peer never told the model that memory was off, and the audit file stayed empty for every turn. The recall sync branch now pops the peer notice the way the async branch does and records each turn as injected or recall-sync-empty.
This commit is contained in:
@@ -563,9 +563,9 @@ class HonchoMemoryProvider(DialecticMixin, MemoryProvider):
|
||||
|
||||
if self._recall_sync:
|
||||
from plugins.memory.honcho.recall_sync import prefetch_sync
|
||||
notice = self._pop_auth_notice()
|
||||
result = prefetch_sync(self, query)
|
||||
return "\n\n".join(part for part in (notice, result) if part)
|
||||
notice = self._pop_auth_notice() or self._pop_peer_notice()
|
||||
payload = "\n\n".join(part for part in (notice, prefetch_sync(self, query)) if part)
|
||||
return self._log_injection("injected" if payload else "recall-sync-empty", payload)
|
||||
|
||||
first_turn_base_deadline = (time.monotonic() + self._first_turn_wait(self._FIRST_TURN_BASE_TIMEOUT)
|
||||
if self._turn_count <= 1 else None)
|
||||
|
||||
@@ -34,7 +34,7 @@ def prefetch_sync(provider, query: str) -> str:
|
||||
if provider._init_thread is not None:
|
||||
provider._init_thread.join(timeout=max(0.0, deadline - time.monotonic()))
|
||||
if not provider._session_ready():
|
||||
return provider._pop_auth_notice()
|
||||
return provider._pop_auth_notice() or provider._pop_peer_notice()
|
||||
manager = provider._manager
|
||||
if (generation is not provider._recall_generation or session != provider._session_key
|
||||
or turn != provider._turn_count or time.monotonic() >= deadline):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Opt-in current-query alignment and bounded late-worker isolation."""
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
|
||||
@@ -127,3 +128,27 @@ def test_timeout_keeps_single_flight_and_late_result_cannot_publish():
|
||||
provider._manager.get_prefetch_context = superseded
|
||||
assert provider.prefetch("Plan the garden") == ""
|
||||
assert provider._last_context_turn == provider._last_dialectic_turn == -999
|
||||
|
||||
|
||||
def test_missing_peer_notice_surfaces_once():
|
||||
provider = HonchoMemoryProvider()
|
||||
provider._config = HonchoClientConfig(timeout=0.05)
|
||||
provider._recall_sync = True
|
||||
provider._init_peer_failure = "No runtime identity or peerName"
|
||||
first = provider.prefetch("What did we decide about the schema?")
|
||||
assert "Honcho memory is off" in first
|
||||
assert "hermes honcho peer --user" in first
|
||||
assert provider.prefetch("And the index?") == ""
|
||||
|
||||
|
||||
def test_prefetch_writes_the_injection_log(tmp_path):
|
||||
provider = make_provider()
|
||||
provider._injection_log_path = str(tmp_path / "injection.log")
|
||||
provider.on_turn_start(1, "Plan the garden")
|
||||
result = provider.prefetch("Plan the garden")
|
||||
assert "base:Plan the garden" in result
|
||||
assert provider.prefetch("Plan the garden") == ""
|
||||
records = [json.loads(line) for line in (tmp_path / "injection.log").read_text().splitlines()]
|
||||
assert [r["reason"] for r in records] == ["injected", "recall-sync-empty"]
|
||||
assert records[0]["payload"] == result and records[0]["turn"] == 1
|
||||
assert records[1]["payload"] == "" and records[1]["bytes"] == 0
|
||||
|
||||
Reference in New Issue
Block a user