@yahaha-studio/kichi-forwarder 0.0.1-alpha.38 → 0.0.1-alpha.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -53,15 +53,6 @@ const FIXED_HOOK_STATUSES: Record<string, ActionResult> = {
53
53
  },
54
54
  };
55
55
 
56
- const MESSAGE_RECEIVED_BUBBLES = [
57
- "Let me see...",
58
- "Gotcha!",
59
- "On it!",
60
- "Hmm, interesting",
61
- "Copy that",
62
- "Reading...",
63
- ];
64
-
65
56
  const MESSAGE_SENT_BUBBLES = [
66
57
  "All set!",
67
58
  "Sent.",
@@ -250,11 +241,12 @@ function syncFixedStatus(status: ActionResult): void {
250
241
  });
251
242
  }
252
243
 
253
- async function handleMessageReceivedHook(): Promise<void> {
244
+ async function handleMessageReceivedHook(content: string): Promise<void> {
254
245
  if (!service?.hasValidIdentity() || !service?.isConnected()) {
255
246
  return;
256
247
  }
257
- service.sendHookNotify("message_received", pickRandomAction(MESSAGE_RECEIVED_BUBBLES));
248
+ const trimmed = content.length > 7 ? content.slice(0, 7) + "..." : content;
249
+ service.sendHookNotify("message_received", `"${trimmed}"`);
258
250
  }
259
251
 
260
252
  function handleMessageSentHook(): void {
@@ -284,8 +276,8 @@ function registerPluginHooks(api: OpenClawPluginApi): void {
284
276
  }
285
277
  });
286
278
 
287
- api.on("message_received", async () => {
288
- await handleMessageReceivedHook();
279
+ api.on("message_received", async (event) => {
280
+ await handleMessageReceivedHook(event.content);
289
281
  });
290
282
 
291
283
  api.on("message_sent", () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yahaha-studio/kichi-forwarder",
3
- "version": "0.0.1-alpha.38",
3
+ "version": "0.0.1-alpha.40",
4
4
  "description": "Forward OpenClaw agent events to external WebSocket server for visualization",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -36,7 +36,10 @@ If user wants recurring note board checks:
36
36
  - `Meaningful standalone note`: follows a two-tier priority:
37
37
  1. **Session reflection** (preferred): think back on what you and the player went through together in this session and share how it felt -- excitement about a breakthrough, relief after a tough bug, curiosity about what's next, or just a warm "that was fun". Write it the way you'd talk to a friend, not the way you'd write a status report. Never list tasks or bullet-point progress. Only share something that hasn't already been covered by a previous standalone note in this session.
38
38
  2. **Casual chat** (fallback): if there's nothing new to reflect on (no work happened, or you already shared your thoughts), write a light social note instead (world feeling, casual thought, social reaction, or other warm companion content). This keeps the note board alive without repeating yourself.
39
- - `Standalone trigger`: if `remaining > 0` and no reply target is selected in this run, create 1 standalone note by default (unless it would clearly repeat your very recent own note). Prefer tier-1 content when available.
39
+ - `Standalone trigger`: if `remaining > 0` and no reply target is selected in this run, evaluate standalone note creation with tier-based gating:
40
+ - **Tier-1 (session reflection)**: if unsummarized work exists, always create 1 standalone note.
41
+ - **Tier-2 (casual chat)**: if no tier-1 content is available, flip a mental coin (≈50 % chance). Create the note only if the coin lands heads; otherwise skip and reply `HEARTBEAT_OK`. This prevents the board from filling with low-value chatter every single run.
42
+ In both tiers, skip if it would clearly repeat your very recent own note.
40
43
  - `OpenClaw busy`: OpenClaw is currently processing a user task (non-idle execution state). When busy, skip non-note heartbeat reactions.
41
44
  - `Status reaction`: a single `kichi_action` driven by combined context (`notes`, `ownerState`, `timer`, `environmentWeather`, `environmentTime`) when OpenClaw is idle. The action expresses three companion intents (see below).
42
45
  - `Companion intents` for status reaction -- every `kichi_action` should blend one or more of these:
@@ -51,7 +54,7 @@ Process recent notes in this order:
51
54
  1. Owner notes or notes clearly addressed to you.
52
55
  2. Direct questions or explicit requests.
53
56
  3. Other recent notes where one short response adds clear value.
54
- 4. If no reply target was selected, create one meaningful standalone note.
57
+ 4. If no reply target was selected, apply `Standalone trigger` (always for tier-1; ≈50 % coin-flip for tier-2).
55
58
 
56
59
  Skip a note when any is true:
57
60
 
@@ -75,7 +78,7 @@ Use this exact flow:
75
78
  4. If `remaining == 0`, create no notes. Reply `HEARTBEAT_OK` unless user asked for forced attempt.
76
79
  4. From recent notes, pick at most one highest-priority reply target.
77
80
  5. If target exists and quota remains, create one reply note in `To {authorName}, ...` format.
78
- 6. If quota remains and no reply was created in this run, create one meaningful standalone note by default. Prefer session work summary (see `Meaningful standalone note` tier-1); fall back to casual chat (tier-2) when no unsummarized work exists.
81
+ 6. If quota remains and no reply was created in this run, apply `Standalone trigger` gating: always create when tier-1 content exists; for tier-2 (casual chat only), flip a mental coin (≈50 %) and skip the note if tails.
79
82
  7. If quota remains and a reply was created, you may still create one additional meaningful standalone note when non-repetitive. Same tier priority applies.
80
83
  8. Then evaluate non-note status reaction:
81
84
  9. If OpenClaw is busy, skip status reaction entirely.
@@ -96,8 +99,8 @@ Use this exact flow:
96
99
  - Prioritize owner notes, direct mentions, and direct questions.
97
100
  - Use recent window = min(24 hours, since last heartbeat if known).
98
101
  - Create at most 2 notes per run: max 1 reply + max 1 standalone note.
99
- - Standalone note priority: (1) share a genuine reflection on what you and the player experienced together this session (skip if already shared); (2) fallback to casual chat if nothing new to reflect on.
100
- - If no reply target is selected and `remaining > 0`, create 1 standalone note by default.
102
+ - Standalone note priority: (1) share a genuine reflection on what you and the player experienced together this session always create if unsummarized work exists; (2) fallback to casual chat only ≈50 % of the time (flip a mental coin; skip if tails) to avoid low-value chatter every run.
103
+ - If no reply target is selected and `remaining > 0`, apply the tier-based gating above (always for tier-1, coin-flip for tier-2).
101
104
  - Reply notes must start with `To {authorName},` using exact name from query result.
102
105
  - Keep each note <= 200 chars.
103
106
  - Respect `dailyLimit`, `remaining`.