Skip to content

Commit 8363254

Browse files
authored
Merge pull request #134 from frostming/fix/process-out
refactor: streamline error messages and command execution in NmemClient
2 parents bbf0e8d + 5284072 commit 8363254

2 files changed

Lines changed: 35 additions & 31 deletions

File tree

nowledge-mem-bub-plugin/src/nowledge_mem_bub/client.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ def _resolve_cmd(self) -> str:
7474
if cmd:
7575
self._cmd = cmd
7676
return cmd
77-
raise NmemError(
78-
"nmem not found in PATH. Install with: pip install nmem-cli"
79-
)
77+
raise NmemError("nmem not found in PATH. Install with: pip install nmem-cli")
8078

8179
def _build_env(self) -> dict[str, str]:
8280
env = dict(os.environ)
@@ -109,17 +107,15 @@ async def _exec(
109107
stderr=asyncio.subprocess.PIPE,
110108
env=self._build_env(),
111109
)
112-
stdout, stderr = await asyncio.wait_for(
113-
proc.communicate(), timeout=timeout
114-
)
110+
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout)
115111
except asyncio.TimeoutError:
116112
proc.kill() # type: ignore[union-attr]
117113
raise NmemError(f"nmem timed out after {timeout}s")
118114
except FileNotFoundError:
119115
raise NmemError("nmem not found in PATH")
120116

121117
if proc.returncode != 0:
122-
err = stderr.decode(errors="replace").strip()
118+
err = (stderr or stdout).decode(errors="replace").strip()
123119
raise NmemError(f"nmem exited {proc.returncode}: {err}")
124120

125121
return stdout.decode(errors="replace").strip()
@@ -229,9 +225,7 @@ async def graph_expand(
229225
return result if isinstance(result, dict) else {}
230226

231227
async def graph_evolves(self, memory_id: str, limit: int = 10) -> dict:
232-
result = await self._exec_json(
233-
"g", "evolves", memory_id, "-n", str(limit)
234-
)
228+
result = await self._exec_json("g", "evolves", memory_id, "-n", str(limit))
235229
return result if isinstance(result, dict) else {}
236230

237231
# ------------------------------------------------------------------
@@ -287,14 +281,26 @@ async def create_thread(
287281
self, thread_id: str, title: str, messages_json: str
288282
) -> dict:
289283
result = await self._exec_json(
290-
"t", "create", "--id", thread_id, "-t", title,
291-
"-m", messages_json, "-s", "bub",
284+
"t",
285+
"create",
286+
"--id",
287+
thread_id,
288+
"-t",
289+
title,
290+
"-m",
291+
messages_json,
292+
"-s",
293+
"bub",
292294
)
293295
return result if isinstance(result, dict) else {}
294296

295297
async def append_thread(self, thread_id: str, messages_json: str) -> dict:
296298
result = await self._exec_json(
297-
"t", "append", thread_id, "-m", messages_json,
299+
"t",
300+
"append",
301+
thread_id,
302+
"-m",
303+
messages_json,
298304
)
299305
return result if isinstance(result, dict) else {}
300306

nowledge-mem-bub-plugin/src/nowledge_mem_bub/plugin.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@
1010

1111
import hashlib
1212
import json
13-
import logging
1413
import os
1514
from typing import Any
1615

1716
from bub import hookimpl
1817
from bub.envelope import content_of
18+
from loguru import logger
1919

2020
from .client import NmemClient, NmemError
2121

22-
logger = logging.getLogger(__name__)
23-
2422
# ---------------------------------------------------------------------------
2523
# Behavioural guidance injected into the system prompt.
2624
# Cost: ~50 tokens. Adjusts when session_context is on to avoid redundant
@@ -138,7 +136,7 @@ async def _load_memory(self, message) -> tuple[str, list[dict[str, Any]]]:
138136
# mem.context or mem.search on demand.
139137
return "", []
140138
if not self.client.is_available():
141-
logger.debug("nmem not in PATH, skipping memory load")
139+
logger.warning("nmem not in PATH, skipping memory load")
142140
return "", []
143141

144142
# Session context mode: fetch WM + recalled memories
@@ -147,15 +145,15 @@ async def _load_memory(self, message) -> tuple[str, list[dict[str, Any]]]:
147145
wm = await self.client.read_working_memory()
148146
working_memory = wm.get("content", "")
149147
except Exception as exc:
150-
logger.debug("working memory read failed: %s", exc)
148+
logger.warning("working memory read failed: {}", exc)
151149

152150
# Recall: search for memories relevant to the current message
153151
query = content_of(message)
154152
if query and len(query.strip()) > 3:
155153
try:
156154
recalled = await self.client.search(query[:500], limit=5)
157155
except Exception as exc:
158-
logger.debug("recall search failed: %s", exc)
156+
logger.warning("recall search failed: {}", exc)
159157

160158
return working_memory, recalled
161159

@@ -171,20 +169,20 @@ async def save_state(self, session_id, state, message, model_output) -> None:
171169
if not self.client.is_available():
172170
return
173171

174-
try:
175-
user_content = content_of(message)
176-
if not user_content or not model_output:
177-
return
172+
user_content = content_of(message)
173+
if not user_content or not model_output:
174+
return
178175

179-
digest = hashlib.sha1(session_id.encode()).hexdigest()[:10]
180-
thread_id = f"bub-{digest}"
176+
digest = hashlib.sha1(session_id.encode()).hexdigest()[:10]
177+
thread_id = f"bub-{digest}"
181178

182-
messages = [
183-
{"role": "user", "content": user_content[:800]},
184-
{"role": "assistant", "content": str(model_output)[:800]},
185-
]
186-
messages_json = json.dumps(messages)
179+
messages = [
180+
{"role": "user", "content": user_content[:800]},
181+
{"role": "assistant", "content": str(model_output)[:800]},
182+
]
183+
messages_json = json.dumps(messages)
187184

185+
try:
188186
if thread_id in self._known_threads:
189187
await self.client.append_thread(thread_id, messages_json)
190188
else:
@@ -200,7 +198,7 @@ async def save_state(self, session_id, state, message, model_output) -> None:
200198
self._known_threads.add(thread_id)
201199
except Exception as exc:
202200
# save_state must never raise — it runs in a finally block
203-
logger.debug("session capture failed: %s", exc)
201+
logger.warning("session capture failed: {}", exc)
204202

205203

206204
plugin = NowledgeMemPlugin()

0 commit comments

Comments
 (0)