Skip to content

Commit d9a74f4

Browse files
committed
fix(openclaw/plugin): correct plugin hook API usage
- api.on() is correct (confirmed from types.d.ts) - api.pluginConfig is the right path for plugin config (not api.config.plugins.entries...) - agent_end and before_compaction are void hooks — cannot inject context - nudge: moved into before_prompt_build as persistent per-turn reminder - compact: before_compaction writes ~/.mnemon/.compact-pending flag; before_prompt_build reads and consumes it on the next turn
1 parent 3c615ff commit d9a74f4

1 file changed

Lines changed: 53 additions & 39 deletions

File tree

  • internal/setup/assets/openclaw/plugin
Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import { execSync } from "child_process";
2+
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs";
3+
import { homedir } from "os";
4+
import { join } from "path";
5+
6+
const COMPACT_FLAG = join(homedir(), ".mnemon", ".compact-pending");
27

38
/**
49
* Extract a focused recall query from the user's prompt.
@@ -7,7 +12,6 @@ import { execSync } from "child_process";
712
*/
813
function extractQuery(prompt) {
914
if (!prompt || typeof prompt !== "string") return "";
10-
// Take the first 200 chars, collapse whitespace
1115
return prompt.slice(0, 200).replace(/\s+/g, " ").trim();
1216
}
1317

@@ -31,56 +35,66 @@ function recall(query) {
3135
}
3236

3337
export default function register(api) {
34-
const cfg = api.config?.plugins?.entries?.mnemon?.config ?? {};
38+
// api.pluginConfig holds plugins.entries.mnemon.config from openclaw.json
39+
const cfg = api.pluginConfig ?? {};
3540
const remind = cfg.remind !== false; // default on
3641
const nudge = cfg.nudge !== false; // default on
3742
const compact = cfg.compact === true; // default off
3843

39-
// ── Remind (before_prompt_build) ──────────────────────────────
40-
// Per-message: inject recall results + remember reminder.
41-
// Equivalent to Claude Code's UserPromptSubmit hook.
42-
if (remind) {
43-
api.on("before_prompt_build", async (event) => {
44-
const query = extractQuery(event.prompt);
45-
const memories = recall(query);
44+
// ── before_compaction (void) ──────────────────────────────────
45+
// Cannot inject context directly — write a flag file instead.
46+
// before_prompt_build will pick it up on the next turn.
47+
if (compact) {
48+
api.on("before_compaction", async () => {
49+
try {
50+
writeFileSync(COMPACT_FLAG, String(Date.now()), "utf-8");
51+
} catch {
52+
// ignore write failure
53+
}
54+
});
55+
}
4656

57+
// ── before_prompt_build ───────────────────────────────────────
58+
// Handles: remind (recall + remember reminder) + nudge reminder
59+
// + compact flag consumption.
60+
if (remind || nudge || compact) {
61+
api.on("before_prompt_build", async (event) => {
4762
const parts = [];
4863

49-
if (memories) {
50-
parts.push(`[mnemon] Relevant memories:\n${memories}`);
64+
// Compact flag: was compaction triggered since last turn?
65+
if (compact && existsSync(COMPACT_FLAG)) {
66+
try { unlinkSync(COMPACT_FLAG); } catch { /* ignore */ }
67+
parts.push(
68+
"[mnemon] Context compaction starting. Review this session and remember the most valuable insights (up to 5) before context is compressed. Delegate to Task sub-agents now."
69+
);
5170
}
5271

53-
parts.push(
54-
"[mnemon] Evaluate: recall needed? After responding, evaluate: remember needed?"
55-
);
56-
57-
return { prependContext: parts.join("\n\n") };
58-
});
59-
}
72+
if (remind) {
73+
const query = extractQuery(event.prompt);
74+
const memories = recall(query);
75+
if (memories) {
76+
parts.push(`[mnemon] Relevant memories:\n${memories}`);
77+
}
78+
parts.push(
79+
"[mnemon] Evaluate: recall needed? After responding, evaluate: remember needed?"
80+
);
81+
}
6082

61-
// ── Nudge (agent_end) ─────────────────────────────────────────
62-
// After agent replies: nudge to consider a remember sub-agent.
63-
if (nudge) {
64-
api.on("agent_end", async (event) => {
65-
const lastMsg = event?.lastAssistantMessage ?? "";
66-
// Stay silent if agent already mentioned memory operations
67-
if (/mnemon remember|sub-agent.*remember|Stored.*imp=/i.test(lastMsg)) {
68-
return;
83+
if (nudge) {
84+
parts.push(
85+
"[mnemon] Consider: does this exchange warrant a remember sub-agent?"
86+
);
6987
}
70-
return {
71-
nudge: "[mnemon] Consider: does this exchange warrant a remember sub-agent?",
72-
};
73-
});
74-
}
7588

76-
// ── Compact (before_compaction) ───────────────────────────────
77-
// Before context compaction: prompt to save key insights.
78-
if (compact) {
79-
api.on("before_compaction", async () => {
80-
return {
81-
prependContext:
82-
"[mnemon] Context compaction starting. Review this session and remember the most valuable insights (up to 5) before context is compressed. Delegate to Task sub-agents now.",
83-
};
89+
if (parts.length === 0) return;
90+
return { prependContext: parts.join("\n\n") };
8491
});
8592
}
93+
94+
// ── agent_end (void — no return value supported) ──────────────
95+
// Placeholder for future diagnostics; memory evaluation is handled
96+
// by the LLM itself via the before_prompt_build nudge above.
97+
api.on("agent_end", async () => {
98+
// no-op
99+
});
86100
}

0 commit comments

Comments
 (0)