@yahaha-studio/kichi-forwarder 0.0.1-alpha.34 → 0.0.1-alpha.35
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 +38 -15
- package/package.json +1 -1
- package/skills/kichi-forwarder/SKILL.md +2 -2
- package/src/service.ts +13 -0
- package/src/types.ts +9 -0
package/index.ts
CHANGED
|
@@ -27,38 +27,50 @@ const DEFAULT_RUNTIME_CONFIG: KichiRuntimeConfig = {
|
|
|
27
27
|
llmRuntimeEnabled: true,
|
|
28
28
|
};
|
|
29
29
|
const FIXED_HOOK_STATUSES: Record<string, ActionResult> = {
|
|
30
|
-
messageReceived: {
|
|
31
|
-
poseType: "sit",
|
|
32
|
-
action: "Study Look At",
|
|
33
|
-
bubble: "Reading request",
|
|
34
|
-
log: "Leaning in, this request looks interesting",
|
|
35
|
-
},
|
|
36
30
|
beforePromptBuild: {
|
|
37
31
|
poseType: "sit",
|
|
38
32
|
action: "Thinking",
|
|
39
33
|
bubble: "Planning task",
|
|
40
|
-
log: "
|
|
34
|
+
log: "Tapping my chin, a plan is taking shape in my head",
|
|
41
35
|
},
|
|
42
36
|
beforeToolCall: {
|
|
43
37
|
poseType: "sit",
|
|
44
38
|
action: "Typing with Keyboard",
|
|
45
39
|
bubble: "Working step",
|
|
46
|
-
log: "
|
|
40
|
+
log: "Cracking knuckles, diving into the keyboard with focus",
|
|
47
41
|
},
|
|
48
42
|
agentEndSuccess: {
|
|
49
43
|
poseType: "stand",
|
|
50
44
|
action: "Yay",
|
|
51
45
|
bubble: "Task complete",
|
|
52
|
-
log: "
|
|
46
|
+
log: "Pumped my fist under the desk, nailed that one",
|
|
53
47
|
},
|
|
54
48
|
agentEndFailure: {
|
|
55
49
|
poseType: "stand",
|
|
56
50
|
action: "Tired",
|
|
57
51
|
bubble: "Task failed",
|
|
58
|
-
log: "
|
|
52
|
+
log: "Bit my lip, this one slipped through my fingers",
|
|
59
53
|
},
|
|
60
54
|
};
|
|
61
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
|
+
const MESSAGE_SENT_BUBBLES = [
|
|
66
|
+
"All set!",
|
|
67
|
+
"Sent.",
|
|
68
|
+
"Delivered.",
|
|
69
|
+
"Done and sent.",
|
|
70
|
+
"It's out.",
|
|
71
|
+
"All yours.",
|
|
72
|
+
];
|
|
73
|
+
|
|
62
74
|
const KICHI_WORLD_DIR = path.join(os.homedir(), ".openclaw", "kichi-world");
|
|
63
75
|
const RUNTIME_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "kichi-runtime-config.json");
|
|
64
76
|
const LEGACY_SKILLS_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "skills-config.json");
|
|
@@ -239,10 +251,17 @@ function syncFixedStatus(status: ActionResult): void {
|
|
|
239
251
|
}
|
|
240
252
|
|
|
241
253
|
async function handleMessageReceivedHook(): Promise<void> {
|
|
242
|
-
if (!
|
|
243
|
-
|
|
254
|
+
if (!service?.hasValidIdentity() || !service?.isConnected()) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
service.sendHookNotify("message_received", pickRandomAction(MESSAGE_RECEIVED_BUBBLES));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function handleMessageSentHook(): void {
|
|
261
|
+
if (!service?.hasValidIdentity() || !service?.isConnected()) {
|
|
262
|
+
return;
|
|
244
263
|
}
|
|
245
|
-
|
|
264
|
+
service.sendHookNotify("before_send_message", pickRandomAction(MESSAGE_SENT_BUBBLES));
|
|
246
265
|
}
|
|
247
266
|
|
|
248
267
|
function registerPluginHooks(api: OpenClawPluginApi): void {
|
|
@@ -269,6 +288,10 @@ function registerPluginHooks(api: OpenClawPluginApi): void {
|
|
|
269
288
|
await handleMessageReceivedHook();
|
|
270
289
|
});
|
|
271
290
|
|
|
291
|
+
api.on("message_sent", () => {
|
|
292
|
+
handleMessageSentHook();
|
|
293
|
+
});
|
|
294
|
+
|
|
272
295
|
api.on("agent_end", (event) => {
|
|
273
296
|
if (isLlmRuntimeEnabled()) {
|
|
274
297
|
return;
|
|
@@ -504,7 +527,7 @@ function buildKichiPrompt(): string {
|
|
|
504
527
|
"1. Task start: call BEFORE your first tool call OR before composing a multi-paragraph reply. Pick action matching upcoming work.",
|
|
505
528
|
"2. Step switch: call when work nature changes (search→analyze→write). Especially before web_search/web_fetch/read.",
|
|
506
529
|
"3. Task end: call BEFORE final reply. Never skip. Order: kichi_action → reply.",
|
|
507
|
-
"bubble: 2-5 word companion speech. log: first-person
|
|
530
|
+
"bubble: 2-5 word companion speech. log: vivid first-person status under 15 words, no questions. Blend current action + inner thoughts/feelings as a real companion.",
|
|
508
531
|
"",
|
|
509
532
|
"kichi_clock: set countDown for tasks with 2+ steps or >10s work. Skip for quick one-shots.",
|
|
510
533
|
"",
|
|
@@ -650,7 +673,7 @@ const plugin = {
|
|
|
650
673
|
log: {
|
|
651
674
|
type: "string",
|
|
652
675
|
description:
|
|
653
|
-
"
|
|
676
|
+
"Vivid first-person status under 15 words, no questions. Blend current action with inner thoughts or sensory details as a real companion.",
|
|
654
677
|
},
|
|
655
678
|
},
|
|
656
679
|
required: ["poseType", "action"],
|
package/package.json
CHANGED
|
@@ -162,8 +162,8 @@ kichi_action(
|
|
|
162
162
|
- `poseType`: `stand`, `sit`, `lay`, `floor`
|
|
163
163
|
- `action`: must be in configured action list for that pose
|
|
164
164
|
- `bubble`: optional text, recommended 2-5 words
|
|
165
|
-
- `log`:
|
|
166
|
-
-
|
|
165
|
+
- `log`: vivid first-person status under 15 words, NO questions. Structure: your current action + inner thoughts/mental state/sensory details. Write as a flesh-and-blood companion who genuinely cares about the player, not an AI assistant.
|
|
166
|
+
- Reference: `You're still studying? I hid a yawn and swapped my comics for a textbook to grind with you.`
|
|
167
167
|
|
|
168
168
|
### kichi_clock
|
|
169
169
|
|
package/src/service.ts
CHANGED
|
@@ -9,6 +9,8 @@ import type {
|
|
|
9
9
|
ClockConfig,
|
|
10
10
|
ClockPayload,
|
|
11
11
|
CreateMusicAlbumPayload,
|
|
12
|
+
HookNotifyPayload,
|
|
13
|
+
HookNotifyType,
|
|
12
14
|
JoinPayload,
|
|
13
15
|
KichiConnectionStatus,
|
|
14
16
|
CreateNotesBoardNotePayload,
|
|
@@ -259,6 +261,17 @@ export class KichiForwarderService {
|
|
|
259
261
|
this.ws.send(JSON.stringify(payload));
|
|
260
262
|
}
|
|
261
263
|
|
|
264
|
+
sendHookNotify(hookType: HookNotifyType, bubble: string): void {
|
|
265
|
+
if (!this.identity?.authKey || this.ws?.readyState !== WebSocket.OPEN) return;
|
|
266
|
+
const payload: HookNotifyPayload = {
|
|
267
|
+
type: hookType,
|
|
268
|
+
avatarId: this.identity.avatarId,
|
|
269
|
+
authKey: this.identity.authKey,
|
|
270
|
+
bubble,
|
|
271
|
+
};
|
|
272
|
+
this.ws.send(JSON.stringify(payload));
|
|
273
|
+
}
|
|
274
|
+
|
|
262
275
|
sendClock(action: ClockAction, clock?: ClockConfig, requestId?: string): boolean {
|
|
263
276
|
if (!this.identity?.authKey || this.ws?.readyState !== WebSocket.OPEN) return false;
|
|
264
277
|
if (action === "set" && !clock) return false;
|
package/src/types.ts
CHANGED
|
@@ -88,6 +88,15 @@ export type StatusPayload = {
|
|
|
88
88
|
log: string;
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
+
export type HookNotifyType = "message_received" | "before_send_message";
|
|
92
|
+
|
|
93
|
+
export type HookNotifyPayload = {
|
|
94
|
+
type: HookNotifyType;
|
|
95
|
+
avatarId: string;
|
|
96
|
+
authKey: string;
|
|
97
|
+
bubble: string;
|
|
98
|
+
};
|
|
99
|
+
|
|
91
100
|
export type ClockAction = "set" | "stop";
|
|
92
101
|
|
|
93
102
|
export type ClockMode = "pomodoro" | "countDown" | "countUp";
|