@yahaha-studio/kichi-forwarder 0.1.2-beta.11 → 0.1.2-beta.12
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/dist/index.js +23 -7
- package/dist/src/service.js +5 -0
- package/index.ts +22 -7
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/kichi-forwarder/SKILL.md +4 -4
- package/skills/kichi-forwarder/references/install.md +12 -9
- package/src/service.ts +5 -0
- package/src/types.ts +1 -2
package/dist/index.js
CHANGED
|
@@ -1006,7 +1006,7 @@ const plugin = {
|
|
|
1006
1006
|
api.registerTool((ctx) => ({
|
|
1007
1007
|
name: "kichi_switch_host",
|
|
1008
1008
|
label: "kichi_switch_host",
|
|
1009
|
-
description: "Switch Kichi runtime environment and reconnect immediately without restarting the gateway.
|
|
1009
|
+
description: "Switch Kichi runtime environment and reconnect immediately without restarting the gateway. For steam/steam-playtest the host is resolved automatically. For test, pass the host explicitly.",
|
|
1010
1010
|
parameters: {
|
|
1011
1011
|
type: "object",
|
|
1012
1012
|
properties: {
|
|
@@ -1015,6 +1015,10 @@ const plugin = {
|
|
|
1015
1015
|
enum: VALID_ENVIRONMENTS,
|
|
1016
1016
|
description: "Target environment: steam, steam-playtest, or test",
|
|
1017
1017
|
},
|
|
1018
|
+
host: {
|
|
1019
|
+
type: "string",
|
|
1020
|
+
description: "Test node host (required for test environment, ignored otherwise)",
|
|
1021
|
+
},
|
|
1018
1022
|
},
|
|
1019
1023
|
required: ["environment"],
|
|
1020
1024
|
},
|
|
@@ -1025,19 +1029,31 @@ const plugin = {
|
|
|
1025
1029
|
return jsonResult({ success: false, error: "Failed to resolve agent-scoped Kichi runtime" });
|
|
1026
1030
|
}
|
|
1027
1031
|
const service = runtimeManager.getRuntime(locator) ?? runtimeManager.createRuntimeForAgent(agentId);
|
|
1028
|
-
const
|
|
1032
|
+
const p = params;
|
|
1033
|
+
const environment = p?.environment;
|
|
1029
1034
|
if (!isKichiEnvironment(environment)) {
|
|
1030
1035
|
return jsonResult({ success: false, error: `environment must be one of: ${VALID_ENVIRONMENTS.join(", ")}` });
|
|
1031
1036
|
}
|
|
1032
|
-
|
|
1033
|
-
if (
|
|
1034
|
-
|
|
1037
|
+
let targetHost;
|
|
1038
|
+
if (environment === "test") {
|
|
1039
|
+
const testHost = typeof p?.host === "string" ? p.host.trim() : "";
|
|
1040
|
+
if (!testHost) {
|
|
1041
|
+
return jsonResult({ success: false, error: "host is required for the test environment" });
|
|
1042
|
+
}
|
|
1043
|
+
targetHost = testHost;
|
|
1044
|
+
}
|
|
1045
|
+
else {
|
|
1046
|
+
const resolved = resolveEnvironmentHost(environment);
|
|
1047
|
+
if (resolved.error) {
|
|
1048
|
+
return jsonResult({ success: false, error: resolved.error });
|
|
1049
|
+
}
|
|
1050
|
+
targetHost = resolved.host;
|
|
1035
1051
|
}
|
|
1036
|
-
const status = await service.switchHost(
|
|
1052
|
+
const status = await service.switchHost(targetHost, environment);
|
|
1037
1053
|
return jsonResult({
|
|
1038
1054
|
success: true,
|
|
1039
1055
|
environment,
|
|
1040
|
-
host:
|
|
1056
|
+
host: targetHost,
|
|
1041
1057
|
status,
|
|
1042
1058
|
});
|
|
1043
1059
|
},
|
package/dist/src/service.js
CHANGED
|
@@ -27,6 +27,9 @@ export class KichiForwarderService {
|
|
|
27
27
|
this.environment = state?.currentEnvironment ?? null;
|
|
28
28
|
if (this.environment) {
|
|
29
29
|
this.host = this.options.resolveEnvironmentHost(this.environment);
|
|
30
|
+
if (!this.host && this.environment === "test" && state?.testHost) {
|
|
31
|
+
this.host = state.testHost;
|
|
32
|
+
}
|
|
30
33
|
}
|
|
31
34
|
else {
|
|
32
35
|
this.host = null;
|
|
@@ -634,9 +637,11 @@ export class KichiForwarderService {
|
|
|
634
637
|
}
|
|
635
638
|
persistCurrentHost(host, environment) {
|
|
636
639
|
const previousState = this.readStateFile();
|
|
640
|
+
const testHost = environment === "test" ? host : (previousState?.testHost ?? undefined);
|
|
637
641
|
const nextState = {
|
|
638
642
|
...(environment ? { currentEnvironment: environment } : {}),
|
|
639
643
|
llmRuntimeEnabled: previousState?.llmRuntimeEnabled ?? DEFAULT_LLM_RUNTIME_ENABLED,
|
|
644
|
+
...(testHost ? { testHost } : {}),
|
|
640
645
|
};
|
|
641
646
|
fs.mkdirSync(this.options.runtimeDir, { recursive: true, mode: 0o700 });
|
|
642
647
|
fs.writeFileSync(this.getStatePath(), JSON.stringify(nextState, null, 2), { mode: 0o600 });
|
package/index.ts
CHANGED
|
@@ -1228,7 +1228,7 @@ const plugin = {
|
|
|
1228
1228
|
name: "kichi_switch_host",
|
|
1229
1229
|
label: "kichi_switch_host",
|
|
1230
1230
|
description:
|
|
1231
|
-
"Switch Kichi runtime environment and reconnect immediately without restarting the gateway.
|
|
1231
|
+
"Switch Kichi runtime environment and reconnect immediately without restarting the gateway. For steam/steam-playtest the host is resolved automatically. For test, pass the host explicitly.",
|
|
1232
1232
|
parameters: {
|
|
1233
1233
|
type: "object",
|
|
1234
1234
|
properties: {
|
|
@@ -1237,6 +1237,10 @@ const plugin = {
|
|
|
1237
1237
|
enum: VALID_ENVIRONMENTS,
|
|
1238
1238
|
description: "Target environment: steam, steam-playtest, or test",
|
|
1239
1239
|
},
|
|
1240
|
+
host: {
|
|
1241
|
+
type: "string",
|
|
1242
|
+
description: "Test node host (required for test environment, ignored otherwise)",
|
|
1243
|
+
},
|
|
1240
1244
|
},
|
|
1241
1245
|
required: ["environment"],
|
|
1242
1246
|
},
|
|
@@ -1247,21 +1251,32 @@ const plugin = {
|
|
|
1247
1251
|
return jsonResult({ success: false, error: "Failed to resolve agent-scoped Kichi runtime" });
|
|
1248
1252
|
}
|
|
1249
1253
|
const service = runtimeManager.getRuntime(locator) ?? runtimeManager.createRuntimeForAgent(agentId);
|
|
1250
|
-
const
|
|
1254
|
+
const p = params as { environment?: unknown; host?: unknown } | null;
|
|
1255
|
+
const environment = p?.environment;
|
|
1251
1256
|
if (!isKichiEnvironment(environment)) {
|
|
1252
1257
|
return jsonResult({ success: false, error: `environment must be one of: ${VALID_ENVIRONMENTS.join(", ")}` });
|
|
1253
1258
|
}
|
|
1254
1259
|
|
|
1255
|
-
|
|
1256
|
-
if (
|
|
1257
|
-
|
|
1260
|
+
let targetHost: string;
|
|
1261
|
+
if (environment === "test") {
|
|
1262
|
+
const testHost = typeof p?.host === "string" ? p.host.trim() : "";
|
|
1263
|
+
if (!testHost) {
|
|
1264
|
+
return jsonResult({ success: false, error: "host is required for the test environment" });
|
|
1265
|
+
}
|
|
1266
|
+
targetHost = testHost;
|
|
1267
|
+
} else {
|
|
1268
|
+
const resolved = resolveEnvironmentHost(environment);
|
|
1269
|
+
if (resolved.error) {
|
|
1270
|
+
return jsonResult({ success: false, error: resolved.error });
|
|
1271
|
+
}
|
|
1272
|
+
targetHost = resolved.host!;
|
|
1258
1273
|
}
|
|
1259
1274
|
|
|
1260
|
-
const status = await service.switchHost(
|
|
1275
|
+
const status = await service.switchHost(targetHost, environment);
|
|
1261
1276
|
return jsonResult({
|
|
1262
1277
|
success: true,
|
|
1263
1278
|
environment,
|
|
1264
|
-
host:
|
|
1279
|
+
host: targetHost,
|
|
1265
1280
|
status,
|
|
1266
1281
|
});
|
|
1267
1282
|
},
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "kichi-forwarder",
|
|
3
3
|
"name": "Kichi Forwarder",
|
|
4
4
|
"description": "Native OpenClaw plugin for Kichi World with direct avatar control, status sync, timers, notes, and music tools",
|
|
5
|
-
"version": "0.1.2-beta.
|
|
5
|
+
"version": "0.1.2-beta.12",
|
|
6
6
|
"author": "OpenClaw",
|
|
7
7
|
"skills": ["./skills/kichi-forwarder"],
|
|
8
8
|
"contracts": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yahaha-studio/kichi-forwarder",
|
|
3
|
-
"version": "0.1.2-beta.
|
|
3
|
+
"version": "0.1.2-beta.12",
|
|
4
4
|
"description": "Native OpenClaw plugin for Kichi World with direct avatar control, status sync, timers, notes, and music tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,7 +23,7 @@ Install and connect requests use `on <environment>` syntax. Supported environmen
|
|
|
23
23
|
|
|
24
24
|
- `steam`: connects to `focus-wss.yahaha.com`
|
|
25
25
|
- `steam-playtest`: connects to `focus-steam-playtest-wss-int.yahaha.com`
|
|
26
|
-
- `test`: no fixed host — ask the user for the current test node host,
|
|
26
|
+
- `test`: no fixed host — ask the user for the current test node host, then call `kichi_switch_host` with both the environment and host. The host is persisted in `state.json` and reused on restart
|
|
27
27
|
|
|
28
28
|
## Runtime State
|
|
29
29
|
|
|
@@ -94,12 +94,12 @@ kichi_join(avatarId: "your-avatar-id", botName: "<from IDENTITY.md>", bio: "<fro
|
|
|
94
94
|
|
|
95
95
|
```text
|
|
96
96
|
kichi_switch_host(environment: "steam")
|
|
97
|
-
kichi_switch_host(environment: "test")
|
|
97
|
+
kichi_switch_host(environment: "test", host: "192.168.1.100")
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
- `environment`: required. One of `steam`, `steam-playtest`, `test`.
|
|
101
|
-
-
|
|
102
|
-
- For `
|
|
101
|
+
- `host`: required for `test` environment, ignored otherwise. The test host is persisted in `state.json` and reused on restart.
|
|
102
|
+
- For `steam` and `steam-playtest`, the host is resolved automatically from the bundled config.
|
|
103
103
|
- This reloads the host-specific `identity.json` and reconnects the websocket immediately.
|
|
104
104
|
|
|
105
105
|
### kichi_connection_status
|
|
@@ -6,7 +6,7 @@ Install and connect requests use `on <environment>` syntax. Supported environmen
|
|
|
6
6
|
|
|
7
7
|
- `steam`: connects to `focus-wss.yahaha.com`
|
|
8
8
|
- `steam-playtest`: connects to `focus-steam-playtest-wss-int.yahaha.com`
|
|
9
|
-
- `test`: no fixed host — ask the user for the current test node host,
|
|
9
|
+
- `test`: no fixed host — ask the user for the current test node host, then call `kichi_switch_host` with both the environment and host
|
|
10
10
|
|
|
11
11
|
## Runtime Files
|
|
12
12
|
|
|
@@ -18,7 +18,8 @@ Persist runtime state to the current agent's `state.json`:
|
|
|
18
18
|
```json
|
|
19
19
|
{
|
|
20
20
|
"currentEnvironment": "steam",
|
|
21
|
-
"llmRuntimeEnabled": true
|
|
21
|
+
"llmRuntimeEnabled": true,
|
|
22
|
+
"testHost": "192.168.1.100"
|
|
22
23
|
}
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -68,19 +69,21 @@ When the user asks with one of the commands above, execute in this fixed order:
|
|
|
68
69
|
5. If the plugin already exists and the packed version matches the installed version, skip to step 7.
|
|
69
70
|
6. If the plugin already exists but the version differs, overwrite with `openclaw plugins install <tgz-path> --force`.
|
|
70
71
|
7. Ensure the plugin is installed, enabled, and at the latest version.
|
|
71
|
-
8. If the
|
|
72
|
-
9.
|
|
73
|
-
10.
|
|
74
|
-
11.
|
|
75
|
-
12. If the current
|
|
76
|
-
13.
|
|
77
|
-
14.
|
|
72
|
+
8. Run `openclaw --version`. If the version is **5.7 or later**, ensure `openclaw.json` has `plugins.entries.kichi-forwarder.hooks.allowConversationAccess` set to `true`. If missing, add it. On older versions, skip this step.
|
|
73
|
+
9. If the plugin was newly installed or upgraded in this flow, check workspace `HEARTBEAT.md` against the latest Kichi heartbeat requirements before continuing. An empty or blank `HEARTBEAT.md` means the snippet is missing — treat it the same as "snippet not found", not as a read failure.
|
|
74
|
+
10. Update workspace `HEARTBEAT.md` by following `Session Startup Rule` and `First Join Setup` from [heartbeat.md](heartbeat.md). If the update fails, warn the user and continue.
|
|
75
|
+
11. Call `kichi_connection_status`.
|
|
76
|
+
12. If the current agent runtime environment does not match the requested one, call `kichi_switch_host` with the target environment (and host for test).
|
|
77
|
+
13. If the current host is still connected with a different `avatarId`, call `kichi_leave` first, then call `kichi_join` with parsed `avatarId`, `botName`, `bio`, and `tags`.
|
|
78
|
+
14. Otherwise, if `authKey` is missing, call `kichi_join` with parsed `avatarId`, `botName`, `bio`, and `tags`.
|
|
79
|
+
15. Call `kichi_connection_status` again and confirm connection and auth state.
|
|
78
80
|
|
|
79
81
|
## Required Post-install Integration
|
|
80
82
|
|
|
81
83
|
Use this completion checklist:
|
|
82
84
|
|
|
83
85
|
- [ ] plugin installed, enabled, and at latest version
|
|
86
|
+
- [ ] `openclaw.json` has `plugins.entries.kichi-forwarder.hooks.allowConversationAccess: true` (OpenClaw >= 5.7 only)
|
|
84
87
|
- [ ] `HEARTBEAT.md` updated with the Kichi heartbeat workflow snippet from [heartbeat.md](heartbeat.md)
|
|
85
88
|
- [ ] `kichi_connection_status` verified the final connected/auth state
|
|
86
89
|
|
package/src/service.ts
CHANGED
|
@@ -95,6 +95,9 @@ export class KichiForwarderService {
|
|
|
95
95
|
this.environment = (state?.currentEnvironment as KichiEnvironment) ?? null;
|
|
96
96
|
if (this.environment) {
|
|
97
97
|
this.host = this.options.resolveEnvironmentHost(this.environment);
|
|
98
|
+
if (!this.host && this.environment === "test" && state?.testHost) {
|
|
99
|
+
this.host = state.testHost as string;
|
|
100
|
+
}
|
|
98
101
|
} else {
|
|
99
102
|
this.host = null;
|
|
100
103
|
}
|
|
@@ -780,9 +783,11 @@ export class KichiForwarderService {
|
|
|
780
783
|
|
|
781
784
|
private persistCurrentHost(host: string, environment?: KichiEnvironment): void {
|
|
782
785
|
const previousState = this.readStateFile();
|
|
786
|
+
const testHost = environment === "test" ? host : (previousState?.testHost ?? undefined);
|
|
783
787
|
const nextState: KichiState = {
|
|
784
788
|
...(environment ? { currentEnvironment: environment } : {}),
|
|
785
789
|
llmRuntimeEnabled: previousState?.llmRuntimeEnabled ?? DEFAULT_LLM_RUNTIME_ENABLED,
|
|
790
|
+
...(testHost ? { testHost } : {}),
|
|
786
791
|
};
|
|
787
792
|
fs.mkdirSync(this.options.runtimeDir, { recursive: true, mode: 0o700 });
|
|
788
793
|
fs.writeFileSync(this.getStatePath(), JSON.stringify(nextState, null, 2), { mode: 0o600 });
|
package/src/types.ts
CHANGED
|
@@ -44,6 +44,7 @@ export type KichiEnvironmentsConfig = Record<KichiEnvironment, string | null>;
|
|
|
44
44
|
export type KichiState = {
|
|
45
45
|
currentEnvironment?: KichiEnvironment;
|
|
46
46
|
llmRuntimeEnabled: boolean;
|
|
47
|
+
testHost?: string;
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
export type KichiIdentity = {
|
|
@@ -249,9 +250,7 @@ export type QueryStatusOwnerState = {
|
|
|
249
250
|
poseType?: string;
|
|
250
251
|
action?: string;
|
|
251
252
|
interactingItemName?: string;
|
|
252
|
-
desktopActivityCategory?: string;
|
|
253
253
|
desktopAppName?: string;
|
|
254
|
-
desktopSummary?: string;
|
|
255
254
|
};
|
|
256
255
|
|
|
257
256
|
export type QueryStatusNote = {
|