Skip to content

Commit 4d00b81

Browse files
committed
feat(hooks): independent precompact toggle via config + env var
Adds hooks.precompact boolean (default true). Setting false lets /compact proceed without the pre-compaction mine, independent of save_interval. Config (~/.mempalace/config.json): {"hooks": {"precompact": false}} Env var (takes precedence): MEMPALACE_HOOKS_PRECOMPACT=false Disabling save_interval does NOT disable precompact and vice versa. Closes #949. Closes #906.
1 parent 1888b67 commit 4d00b81

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

mempalace/config.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,39 @@ def hook_silent_save(self):
294294
"""Whether the stop hook saves directly (True) or blocks for MCP calls (False)."""
295295
return self._file_config.get("hooks", {}).get("silent_save", True)
296296

297+
@property
298+
def hooks_save_interval(self) -> int:
299+
"""Number of exchanges between auto-save prompts. 0 = disabled.
300+
301+
Config: {"hooks": {"save_interval": 30}}
302+
Env var (takes precedence): MEMPALACE_HOOKS_SAVE_INTERVAL=30
303+
"""
304+
env_val = os.environ.get("MEMPALACE_HOOKS_SAVE_INTERVAL", "").strip()
305+
if env_val:
306+
try:
307+
return max(0, int(env_val))
308+
except ValueError:
309+
pass
310+
val = self._file_config.get("hooks", {}).get("save_interval", 15)
311+
try:
312+
return max(0, int(val))
313+
except (TypeError, ValueError):
314+
return 15
315+
316+
@property
317+
def hooks_precompact(self) -> bool:
318+
"""Whether the precompact hook fires before context compaction. Default: True.
319+
320+
Config: {"hooks": {"precompact": false}}
321+
Env var (takes precedence): MEMPALACE_HOOKS_PRECOMPACT=false
322+
"""
323+
env_val = os.environ.get("MEMPALACE_HOOKS_PRECOMPACT", "").strip().lower()
324+
if env_val in ("0", "false", "no", "off"):
325+
return False
326+
if env_val in ("1", "true", "yes", "on"):
327+
return True
328+
return bool(self._file_config.get("hooks", {}).get("precompact", True))
329+
297330
@property
298331
def hook_desktop_toast(self):
299332
"""Whether the stop hook shows a desktop notification via notify-send."""

mempalace/hooks_cli.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,17 @@ def hook_stop(data: dict, harness: str):
596596

597597
_log(f"Session {session_id}: {exchange_count} exchanges, {since_last} since last save")
598598

599-
if since_last >= SAVE_INTERVAL and exchange_count > 0:
599+
try:
600+
from .config import MempalaceConfig
601+
save_interval = int(MempalaceConfig().hooks_save_interval)
602+
except Exception:
603+
save_interval = SAVE_INTERVAL
604+
605+
if save_interval == 0:
606+
_output({})
607+
return
608+
609+
if since_last >= save_interval and exchange_count > 0:
600610
_log(f"TRIGGERING SAVE at exchange {exchange_count}")
601611

602612
# Read hook settings from config
@@ -679,6 +689,17 @@ def hook_precompact(data: dict, harness: str):
679689

680690
_log(f"PRE-COMPACT triggered for session {session_id}")
681691

692+
try:
693+
from .config import MempalaceConfig
694+
precompact_enabled = MempalaceConfig().hooks_precompact
695+
except Exception:
696+
precompact_enabled = True
697+
698+
if not precompact_enabled:
699+
_log("Precompact hook disabled via config — skipping mine, allowing compaction")
700+
_output({})
701+
return
702+
682703
# Capture tool output via our normalize path before compaction loses it
683704
if transcript_path:
684705
_ingest_transcript(transcript_path)

0 commit comments

Comments
 (0)