@yahaha-studio/kichi-forwarder 0.0.1-alpha.29 → 0.0.1-alpha.30

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.
@@ -1,6 +1,4 @@
1
- import type { Album } from "./types.js";
2
-
3
- export const DEFAULT_ALBUM_CONFIG: Album = {
1
+ {
4
2
  "albumCount": 10,
5
3
  "trackCount": 58,
6
4
  "track": [
@@ -508,4 +506,4 @@ export const DEFAULT_ALBUM_CONFIG: Album = {
508
506
  ]
509
507
  }
510
508
  ]
511
- };
509
+ }
package/index.ts CHANGED
@@ -2,11 +2,11 @@ import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
5
- import { DEFAULT_ALBUM_CONFIG } from "./src/album-config.js";
6
5
  import { parse } from "./src/config.js";
7
6
  import { KichiForwarderService } from "./src/service.js";
8
7
  import type {
9
8
  ActionResult,
9
+ Album,
10
10
  ClockAction,
11
11
  ClockConfig,
12
12
  KichiRuntimeConfig,
@@ -59,9 +59,12 @@ const RUNTIME_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "kichi-runtime-config.jso
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
61
  const MAX_NOTEBOARD_TEXT_LENGTH = 200;
62
+ const ALBUM_CONFIG_PATH = new URL("./config/album-config.json", import.meta.url);
63
+ const DEFAULT_ALBUM_CONFIG = loadAlbumConfig();
62
64
  const MUSIC_TITLE_LOOKUP = new Map(
63
65
  DEFAULT_ALBUM_CONFIG.track.map((item) => [item.name.toLowerCase(), item.name] as const),
64
66
  );
67
+ const MUSIC_TITLE_ENUM = DEFAULT_ALBUM_CONFIG.track.map((item) => item.name);
65
68
  const MUSIC_TITLE_EXAMPLES = DEFAULT_ALBUM_CONFIG.track.slice(0, 10).map((item) => item.name);
66
69
  let cachedConfig: KichiRuntimeConfig | null = null;
67
70
  let cachedConfigMtime = 0;
@@ -69,6 +72,36 @@ let cachedConfigPath = "";
69
72
  let service: KichiForwarderService | null = null;
70
73
  let pluginApi: OpenClawPluginApi | null = null;
71
74
 
75
+ function isAlbumConfig(value: unknown): value is Album {
76
+ if (!value || typeof value !== "object") {
77
+ return false;
78
+ }
79
+
80
+ const config = value as Partial<Album>;
81
+ return typeof config.albumCount === "number"
82
+ && typeof config.trackCount === "number"
83
+ && Array.isArray(config.track)
84
+ && config.track.every((item) => {
85
+ if (!item || typeof item !== "object") {
86
+ return false;
87
+ }
88
+ const track = item as Record<string, unknown>;
89
+ return typeof track.album === "string"
90
+ && typeof track.name === "string"
91
+ && Array.isArray(track.tags)
92
+ && track.tags.every((tag) => typeof tag === "string");
93
+ });
94
+ }
95
+
96
+ function loadAlbumConfig(): Album {
97
+ const raw = fs.readFileSync(ALBUM_CONFIG_PATH, "utf-8");
98
+ const parsed = JSON.parse(raw) as unknown;
99
+ if (!isAlbumConfig(parsed)) {
100
+ throw new Error("Invalid album config at config/album-config.json");
101
+ }
102
+ return parsed;
103
+ }
104
+
72
105
  function sanitizeActions(value: unknown, fallback: string[]): string[] {
73
106
  if (!Array.isArray(value)) {
74
107
  return fallback;
@@ -403,6 +436,20 @@ function normalizeMusicTitles(value: unknown): { titles: string[]; invalidTitles
403
436
  return { titles, invalidTitles };
404
437
  }
405
438
 
439
+ function buildMusicAlbumToolDescription(): string {
440
+ return [
441
+ "Create a custom Kichi music album.",
442
+ "Query status first, then choose track names from the local config/album-config.json that match weather, time, and personality.",
443
+ ].join("\n");
444
+ }
445
+
446
+ function buildMusicTitlesDescription(): string {
447
+ return [
448
+ "Track names chosen from the local config/album-config.json.",
449
+ "Use exact names only; the available titles are injected into this tool schema.",
450
+ ].join(" ");
451
+ }
452
+
406
453
  function buildKichiPrompt(): string {
407
454
  return [
408
455
  "Kichi App status sync is available via `kichi_action` and `kichi_clock`.",
@@ -426,7 +473,7 @@ function buildKichiPrompt(): string {
426
473
  "When to use `kichi_music_album_create`:",
427
474
  "- Call `kichi_query_status` first.",
428
475
  "- Recommend a variable-length playlist based on weather, time, and your own personality.",
429
- "- `albumTitle` is user-defined and `musicTitles` must be exact track names from album-config.",
476
+ "- `albumTitle` is user-defined and `musicTitles` must be exact track names from the local album-config.json.",
430
477
  "",
431
478
  "Skip all sync if:",
432
479
  "- User says 'don't sync to Kichi' or similar",
@@ -779,8 +826,7 @@ const plugin = {
779
826
 
780
827
  api.registerTool({
781
828
  name: "kichi_music_album_create",
782
- description:
783
- "Create a custom Kichi music album. Query status first, then choose track names from album-config that match weather/time and personality.",
829
+ description: buildMusicAlbumToolDescription(),
784
830
  parameters: {
785
831
  type: "object",
786
832
  properties: {
@@ -794,9 +840,10 @@ const plugin = {
794
840
  },
795
841
  musicTitles: {
796
842
  type: "array",
797
- description: "Track names chosen from album-config.",
843
+ description: buildMusicTitlesDescription(),
798
844
  items: {
799
845
  type: "string",
846
+ enum: MUSIC_TITLE_ENUM,
800
847
  },
801
848
  },
802
849
  },
@@ -835,7 +882,7 @@ const plugin = {
835
882
  return {
836
883
  success: false,
837
884
  error: `Unknown musicTitles: ${invalidTitles.join(", ")}`,
838
- hint: "Use exact track names from src/album-config.ts",
885
+ hint: "Use exact track names from config/album-config.json",
839
886
  examples: MUSIC_TITLE_EXAMPLES,
840
887
  };
841
888
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yahaha-studio/kichi-forwarder",
3
- "version": "0.0.1-alpha.29",
3
+ "version": "0.0.1-alpha.30",
4
4
  "description": "Forward OpenClaw agent events to external WebSocket server for visualization",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -259,7 +259,7 @@ Parameters:
259
259
 
260
260
  Track source rule:
261
261
 
262
- - `musicTitles` must use exact track names from `src/album-config.ts` -> `DEFAULT_ALBUM_CONFIG.track[].name`
262
+ - `musicTitles` must use exact track names from `config/album-config.json` -> `track[].name`
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 `src/album-config.ts` track name list only.
308
+ 3. Select tracks from `config/album-config.json` track name list only.
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.