@yahaha-studio/kichi-forwarder 0.0.1-alpha.30 → 0.0.1-alpha.31
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
|
@@ -58,17 +58,14 @@ const KICHI_WORLD_DIR = path.join(os.homedir(), ".openclaw", "kichi-world");
|
|
|
58
58
|
const RUNTIME_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "kichi-runtime-config.json");
|
|
59
59
|
const LEGACY_SKILLS_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "skills-config.json");
|
|
60
60
|
const IDENTITY_PATH = path.join(KICHI_WORLD_DIR, "identity.json");
|
|
61
|
+
const RUNTIME_ALBUM_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "album-config.json");
|
|
61
62
|
const MAX_NOTEBOARD_TEXT_LENGTH = 200;
|
|
62
|
-
const
|
|
63
|
-
const DEFAULT_ALBUM_CONFIG = loadAlbumConfig();
|
|
64
|
-
const MUSIC_TITLE_LOOKUP = new Map(
|
|
65
|
-
DEFAULT_ALBUM_CONFIG.track.map((item) => [item.name.toLowerCase(), item.name] as const),
|
|
66
|
-
);
|
|
67
|
-
const MUSIC_TITLE_ENUM = DEFAULT_ALBUM_CONFIG.track.map((item) => item.name);
|
|
68
|
-
const MUSIC_TITLE_EXAMPLES = DEFAULT_ALBUM_CONFIG.track.slice(0, 10).map((item) => item.name);
|
|
63
|
+
const BUNDLED_ALBUM_CONFIG_PATH = new URL("./config/album-config.json", import.meta.url);
|
|
69
64
|
let cachedConfig: KichiRuntimeConfig | null = null;
|
|
70
65
|
let cachedConfigMtime = 0;
|
|
71
66
|
let cachedConfigPath = "";
|
|
67
|
+
let cachedAlbumConfig: Album | null = null;
|
|
68
|
+
let cachedAlbumConfigMtime = 0;
|
|
72
69
|
let service: KichiForwarderService | null = null;
|
|
73
70
|
let pluginApi: OpenClawPluginApi | null = null;
|
|
74
71
|
|
|
@@ -93,15 +90,55 @@ function isAlbumConfig(value: unknown): value is Album {
|
|
|
93
90
|
});
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
function
|
|
97
|
-
const raw = fs.readFileSync(
|
|
93
|
+
function loadAlbumConfigFromPath(configPath: string | URL): Album {
|
|
94
|
+
const raw = fs.readFileSync(configPath, "utf-8");
|
|
98
95
|
const parsed = JSON.parse(raw) as unknown;
|
|
99
96
|
if (!isAlbumConfig(parsed)) {
|
|
100
|
-
throw new Error(
|
|
97
|
+
throw new Error(`Invalid album config at ${String(configPath)}`);
|
|
101
98
|
}
|
|
102
99
|
return parsed;
|
|
103
100
|
}
|
|
104
101
|
|
|
102
|
+
function ensureRuntimeAlbumConfig(): void {
|
|
103
|
+
fs.mkdirSync(KICHI_WORLD_DIR, { recursive: true });
|
|
104
|
+
if (!fs.existsSync(RUNTIME_ALBUM_CONFIG_PATH)) {
|
|
105
|
+
fs.copyFileSync(BUNDLED_ALBUM_CONFIG_PATH, RUNTIME_ALBUM_CONFIG_PATH);
|
|
106
|
+
pluginApi?.logger.debug("[kichi] seeded runtime album config from bundled config");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
loadAlbumConfigFromPath(RUNTIME_ALBUM_CONFIG_PATH);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
pluginApi?.logger.warn(`[kichi] invalid runtime album config, resetting from bundled config: ${error}`);
|
|
114
|
+
fs.copyFileSync(BUNDLED_ALBUM_CONFIG_PATH, RUNTIME_ALBUM_CONFIG_PATH);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function loadRuntimeAlbumConfig(): Album {
|
|
119
|
+
ensureRuntimeAlbumConfig();
|
|
120
|
+
const stat = fs.statSync(RUNTIME_ALBUM_CONFIG_PATH);
|
|
121
|
+
if (!cachedAlbumConfig || stat.mtimeMs !== cachedAlbumConfigMtime) {
|
|
122
|
+
cachedAlbumConfig = loadAlbumConfigFromPath(RUNTIME_ALBUM_CONFIG_PATH);
|
|
123
|
+
cachedAlbumConfigMtime = stat.mtimeMs;
|
|
124
|
+
}
|
|
125
|
+
return cachedAlbumConfig;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function getMusicTitleLookup(): Map<string, string> {
|
|
129
|
+
return new Map(
|
|
130
|
+
loadRuntimeAlbumConfig().track.map((item) => [item.name.toLowerCase(), item.name] as const),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function getMusicTitleEnum(): string[] {
|
|
135
|
+
return loadRuntimeAlbumConfig().track.map((item) => item.name);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function getMusicTitleExamples(): string[] {
|
|
139
|
+
return loadRuntimeAlbumConfig().track.slice(0, 10).map((item) => item.name);
|
|
140
|
+
}
|
|
141
|
+
|
|
105
142
|
function sanitizeActions(value: unknown, fallback: string[]): string[] {
|
|
106
143
|
if (!Array.isArray(value)) {
|
|
107
144
|
return fallback;
|
|
@@ -406,6 +443,7 @@ function normalizeMusicTitles(value: unknown): { titles: string[]; invalidTitles
|
|
|
406
443
|
return { titles: [], invalidTitles: [] };
|
|
407
444
|
}
|
|
408
445
|
|
|
446
|
+
const musicTitleLookup = getMusicTitleLookup();
|
|
409
447
|
const titles: string[] = [];
|
|
410
448
|
const invalidTitles: string[] = [];
|
|
411
449
|
const seen = new Set<string>();
|
|
@@ -421,7 +459,7 @@ function normalizeMusicTitles(value: unknown): { titles: string[]; invalidTitles
|
|
|
421
459
|
}
|
|
422
460
|
|
|
423
461
|
const key = trimmed.toLowerCase();
|
|
424
|
-
const canonicalTitle =
|
|
462
|
+
const canonicalTitle = musicTitleLookup.get(key);
|
|
425
463
|
if (!canonicalTitle) {
|
|
426
464
|
invalidTitles.push(trimmed);
|
|
427
465
|
continue;
|
|
@@ -439,13 +477,13 @@ function normalizeMusicTitles(value: unknown): { titles: string[]; invalidTitles
|
|
|
439
477
|
function buildMusicAlbumToolDescription(): string {
|
|
440
478
|
return [
|
|
441
479
|
"Create a custom Kichi music album.",
|
|
442
|
-
"Query status first, then choose track names from the
|
|
480
|
+
"Query status first, then choose track names from the runtime album config: Linux/macOS `~/.openclaw/kichi-world/album-config.json`; Windows `%USERPROFILE%\\.openclaw\\kichi-world\\album-config.json`.",
|
|
443
481
|
].join("\n");
|
|
444
482
|
}
|
|
445
483
|
|
|
446
484
|
function buildMusicTitlesDescription(): string {
|
|
447
485
|
return [
|
|
448
|
-
"Track names chosen from the
|
|
486
|
+
"Track names chosen from the runtime album config: Linux/macOS `~/.openclaw/kichi-world/album-config.json`; Windows `%USERPROFILE%\\.openclaw\\kichi-world\\album-config.json`.",
|
|
449
487
|
"Use exact names only; the available titles are injected into this tool schema.",
|
|
450
488
|
].join(" ");
|
|
451
489
|
}
|
|
@@ -473,7 +511,7 @@ function buildKichiPrompt(): string {
|
|
|
473
511
|
"When to use `kichi_music_album_create`:",
|
|
474
512
|
"- Call `kichi_query_status` first.",
|
|
475
513
|
"- Recommend a variable-length playlist based on weather, time, and your own personality.",
|
|
476
|
-
"- `albumTitle` is user-defined and `musicTitles` must be exact track names from the
|
|
514
|
+
"- `albumTitle` is user-defined and `musicTitles` must be exact track names from the runtime album config under the user's home directory.",
|
|
477
515
|
"",
|
|
478
516
|
"Skip all sync if:",
|
|
479
517
|
"- User says 'don't sync to Kichi' or similar",
|
|
@@ -491,7 +529,9 @@ const plugin = {
|
|
|
491
529
|
|
|
492
530
|
register(api: OpenClawPluginApi) {
|
|
493
531
|
pluginApi = api;
|
|
532
|
+
ensureRuntimeAlbumConfig();
|
|
494
533
|
registerPluginHooks(api);
|
|
534
|
+
const musicTitleEnum = getMusicTitleEnum();
|
|
495
535
|
|
|
496
536
|
api.registerService({
|
|
497
537
|
id: "kichi-forwarder",
|
|
@@ -843,7 +883,7 @@ const plugin = {
|
|
|
843
883
|
description: buildMusicTitlesDescription(),
|
|
844
884
|
items: {
|
|
845
885
|
type: "string",
|
|
846
|
-
enum:
|
|
886
|
+
enum: musicTitleEnum,
|
|
847
887
|
},
|
|
848
888
|
},
|
|
849
889
|
},
|
|
@@ -875,15 +915,15 @@ const plugin = {
|
|
|
875
915
|
return {
|
|
876
916
|
success: false,
|
|
877
917
|
error: "musicTitles must contain at least one valid track name from album-config",
|
|
878
|
-
examples:
|
|
918
|
+
examples: getMusicTitleExamples(),
|
|
879
919
|
};
|
|
880
920
|
}
|
|
881
921
|
if (invalidTitles.length > 0) {
|
|
882
922
|
return {
|
|
883
923
|
success: false,
|
|
884
924
|
error: `Unknown musicTitles: ${invalidTitles.join(", ")}`,
|
|
885
|
-
hint: "Use exact track names from
|
|
886
|
-
examples:
|
|
925
|
+
hint: "Use exact track names from the runtime album config under the user's home directory",
|
|
926
|
+
examples: getMusicTitleExamples(),
|
|
887
927
|
};
|
|
888
928
|
}
|
|
889
929
|
if (!service?.hasValidIdentity() || !service?.isConnected()) {
|
package/package.json
CHANGED
|
@@ -259,7 +259,7 @@ Parameters:
|
|
|
259
259
|
|
|
260
260
|
Track source rule:
|
|
261
261
|
|
|
262
|
-
- `musicTitles` must use exact track names from
|
|
262
|
+
- `musicTitles` must use exact track names from the runtime album config file: Linux/macOS `~/.openclaw/kichi-world/album-config.json`; Windows `%USERPROFILE%\.openclaw\kichi-world\album-config.json`
|
|
263
263
|
- do not use album names in `musicTitles`
|
|
264
264
|
|
|
265
265
|
Before create:
|
|
@@ -305,7 +305,7 @@ Hard rules:
|
|
|
305
305
|
|
|
306
306
|
1. Query first with `kichi_query_status`.
|
|
307
307
|
2. Playlist length is flexible (not fixed), but avoid empty or repetitive selections.
|
|
308
|
-
3. Select tracks from
|
|
308
|
+
3. Select tracks from the runtime album config file only: Linux/macOS `~/.openclaw/kichi-world/album-config.json`; Windows `%USERPROFILE%\.openclaw\kichi-world\album-config.json`.
|
|
309
309
|
4. Recommendation must reflect `environmentWeather` + `environmentTime` + your personality (not random picks).
|
|
310
310
|
5. Use a user-meaningful custom `albumTitle`.
|
|
311
311
|
6. If `kichi_query_status` fails or returns empty/insufficient context, skip creation.
|
|
@@ -334,6 +334,7 @@ Files:
|
|
|
334
334
|
|
|
335
335
|
- `identity.json`: `avatarId`, `authKey`
|
|
336
336
|
- `kichi-runtime-config.json`: runtime action list and `llmRuntimeEnabled`
|
|
337
|
+
- `album-config.json`: music track list for `kichi_music_album_create`; Linux/macOS path is `~/.openclaw/kichi-world/album-config.json`, Windows path is `%USERPROFILE%\.openclaw\kichi-world\album-config.json`. If missing at startup, the plugin seeds it from bundled `config/album-config.json`
|
|
337
338
|
- `skills-config.json`: legacy filename still readable for backward compatibility
|
|
338
339
|
|
|
339
340
|
## Runtime Behavior
|
|
@@ -115,4 +115,5 @@ Files:
|
|
|
115
115
|
|
|
116
116
|
- `identity.json`: `avatarId`, `authKey`
|
|
117
117
|
- `kichi-runtime-config.json`: runtime action list and `llmRuntimeEnabled`
|
|
118
|
+
- `album-config.json`: music track list used by music album creation; Linux/macOS path is `~/.openclaw/kichi-world/album-config.json`, Windows path is `%USERPROFILE%\.openclaw\kichi-world\album-config.json`. If missing at startup, the plugin seeds it from bundled `config/album-config.json`
|
|
118
119
|
- `skills-config.json`: legacy filename still readable for backward compatibility
|