File size: 1,742 Bytes
f778c12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Compaction notifier hook sends notifications when session compaction occurs.
import { asFiniteNumber } from "@openclaw/normalization-core/number-coercion";
import type { HookHandler } from "../../hooks.js";

/** Read optional numeric compaction metadata without trusting hook context shape. */
function readOptionalNumber(context: Record<string, unknown>, key: string): number | undefined {
  const value = context[key];
  return asFiniteNumber(value);
}

/** Session compaction hook that emits short user-visible progress messages. */
const handler: HookHandler = async (event) => {
  try {
    const context = event.context;

    if (event.type === "session" && event.action === "compact:before") {
      const messageCount = readOptionalNumber(context, "messageCount");
      const messageSuffix =
        messageCount !== undefined && messageCount >= 0 ? ` (${messageCount} messages)` : "";
      event.messages.push(
        `🧹 Compacting context${messageSuffix} so I can continue without losing history…`,
      );
      return;
    }

    if (event.type === "session" && event.action === "compact:after") {
      const tokensBefore = readOptionalNumber(context, "tokensBefore");
      const tokensAfter = readOptionalNumber(context, "tokensAfter");
      const tokenDelta =
        tokensBefore !== undefined && tokensAfter !== undefined
          ? ` (${tokensBefore.toLocaleString()} → ${tokensAfter.toLocaleString()} tokens)`
          : "";
      event.messages.push(`✅ Context compacted${tokenDelta}. Continuing from where I left off.`);
    }
  } catch (error) {
    console.warn(
      `[compaction-notifier] failed: ${error instanceof Error ? error.message : String(error)}`,
    );
  }
};

export default handler;