@folotoy/folotoy-openclaw-plugin 0.6.0 → 0.7.0

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/README.md CHANGED
@@ -16,6 +16,19 @@ Interactive install (scan QR code to pair your toy):
16
16
  npx @folotoy/folotoy-openclaw-plugin install
17
17
  ```
18
18
 
19
+ To install with a built-in preset (e.g. send only a single soothing reply
20
+ instead of looping until the LLM responds):
21
+
22
+ ```bash
23
+ npx @folotoy/folotoy-openclaw-plugin install --preset single-soothing
24
+ ```
25
+
26
+ Available presets are bundled in `src/presets/*.json`. Currently:
27
+
28
+ | Preset | Effect |
29
+ |--------|--------|
30
+ | `single-soothing` | Sets `soothing_loop_enabled = false` so only the initial `order=1` soothing reply is sent; no further soothing replies are emitted while waiting for the LLM. |
31
+
19
32
  Or install manually:
20
33
 
21
34
  ```bash
@@ -1,6 +1,8 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import qrcode from 'qrcode-terminal';
3
3
  import { DEFAULT_MQTT_HOST, DEFAULT_MQTT_PORT } from '../config.js';
4
+ import { getInstallSpec, getPluginName } from './package-info.js';
5
+ import { loadPreset, listPresets } from './preset.js';
4
6
  const PAIR_API_BASE = process.env.PAIR_API_BASE ?? 'https://pair.folotoy.cn';
5
7
  const POLL_INTERVAL_MS = 3000;
6
8
  const POLL_TIMEOUT_MS = 300_000; // 5 minutes
@@ -25,8 +27,9 @@ function installPlugin() {
25
27
  catch {
26
28
  // ignore
27
29
  }
28
- console.log('Installing FoloToy plugin...');
29
- execSync('openclaw plugins install @folotoy/folotoy-openclaw-plugin', { stdio: 'inherit' });
30
+ const spec = getInstallSpec();
31
+ console.log(`Installing FoloToy plugin (${spec})...`);
32
+ execSync(`openclaw plugins install ${spec}`, { stdio: 'inherit' });
30
33
  }
31
34
  async function createSession() {
32
35
  const res = await fetch(`${PAIR_API_BASE}/api/pair`, { method: 'POST' });
@@ -73,7 +76,7 @@ function restartGateway() {
73
76
  console.warn('⚠ Failed to restart gateway. You can restart manually: openclaw gateway restart');
74
77
  }
75
78
  }
76
- function writeConfig(result) {
79
+ function writeConfig(result, preset = {}) {
77
80
  execSync(`openclaw config set channels.folotoy.flow direct`, { stdio: 'pipe' });
78
81
  execSync(`openclaw config set channels.folotoy.toy_sn ${result.toy_sn}`, { stdio: 'pipe' });
79
82
  execSync(`openclaw config set channels.folotoy.toy_key ${result.toy_key}`, { stdio: 'pipe' });
@@ -81,15 +84,45 @@ function writeConfig(result) {
81
84
  const mqttPort = result.mqtt_port ?? DEFAULT_MQTT_PORT;
82
85
  execSync(`openclaw config set channels.folotoy.mqtt_host ${mqttHost}`, { stdio: 'pipe' });
83
86
  execSync(`openclaw config set channels.folotoy.mqtt_port ${mqttPort}`, { stdio: 'pipe' });
87
+ for (const [key, value] of Object.entries(preset)) {
88
+ execSync(`openclaw config set channels.folotoy.${key} ${value}`, { stdio: 'pipe' });
89
+ }
90
+ }
91
+ function parsePresetArg(argv) {
92
+ for (let i = 0; i < argv.length; i++) {
93
+ const arg = argv[i];
94
+ if (arg === '--preset') {
95
+ const value = argv[i + 1];
96
+ if (!value || value.startsWith('--')) {
97
+ throw new Error('--preset requires a name (e.g. --preset single-soothing)');
98
+ }
99
+ return value;
100
+ }
101
+ if (arg && arg.startsWith('--preset=')) {
102
+ return arg.slice('--preset='.length);
103
+ }
104
+ }
105
+ return undefined;
84
106
  }
85
107
  // ── Main ───────────────────────────────────────────────
86
108
  async function main() {
87
- const command = process.argv[2];
109
+ const argv = process.argv.slice(2);
110
+ const command = argv[0];
88
111
  if (command !== 'install') {
89
- console.log('Usage: npx @folotoy/folotoy-openclaw-plugin install');
112
+ const presets = listPresets();
113
+ console.log(`Usage: npx ${getPluginName()} install [--preset <name>]`);
114
+ if (presets.length)
115
+ console.log(`Available presets: ${presets.join(', ')}`);
90
116
  process.exit(command ? 1 : 0);
91
117
  }
118
+ // Resolve preset before any side effects (pairing, plugin install) so a bad
119
+ // preset name fails fast without making the user scan a QR.
120
+ const presetName = parsePresetArg(argv.slice(1));
121
+ const preset = presetName ? loadPreset(presetName) : {};
92
122
  console.log('🧸 FoloToy OpenClaw Plugin Installer\n');
123
+ if (presetName) {
124
+ console.log(`Using preset: ${presetName} → ${JSON.stringify(preset)}\n`);
125
+ }
93
126
  // Step 1: check prerequisites
94
127
  console.log('Checking openclaw...');
95
128
  checkOpenClaw();
@@ -107,7 +140,7 @@ async function main() {
107
140
  const result = await pollSession(session.session_id);
108
141
  // Step 6: write config
109
142
  console.log('\nWriting configuration...');
110
- writeConfig(result);
143
+ writeConfig(result, preset);
111
144
  // Step 7: restart gateway
112
145
  console.log('\nRestarting gateway...');
113
146
  restartGateway();
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare function findPackageRoot(): string;
2
+ export declare function getPluginName(): string;
3
+ export declare function getPluginVersion(): string;
4
+ /**
5
+ * Returns the npm spec string `<name>@<version>` to pass to
6
+ * `openclaw plugins install`. Pinning the exact version prevents OpenClaw
7
+ * from rejecting the install when `latest` happens to point at a prerelease
8
+ * — without this, `openclaw plugins install <bare-name>` resolves through
9
+ * the `latest` dist-tag and refuses prereleases for safety.
10
+ */
11
+ export declare function getInstallSpec(): string;
12
+ //# sourceMappingURL=package-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-info.d.ts","sourceRoot":"","sources":["../../src/cli/package-info.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,IAAI,MAAM,CAQxC;AAkBD,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -0,0 +1,42 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ export function findPackageRoot() {
5
+ let dir = dirname(fileURLToPath(import.meta.url));
6
+ while (true) {
7
+ if (existsSync(join(dir, 'package.json')))
8
+ return dir;
9
+ const parent = dirname(dir);
10
+ if (parent === dir)
11
+ throw new Error('package.json not found while resolving package root');
12
+ dir = parent;
13
+ }
14
+ }
15
+ let cached;
16
+ function readPackageInfo() {
17
+ if (cached)
18
+ return cached;
19
+ const pkg = JSON.parse(readFileSync(join(findPackageRoot(), 'package.json'), 'utf8'));
20
+ if (typeof pkg.name !== 'string' || typeof pkg.version !== 'string') {
21
+ throw new Error('package.json is missing name or version');
22
+ }
23
+ cached = { name: pkg.name, version: pkg.version };
24
+ return cached;
25
+ }
26
+ export function getPluginName() {
27
+ return readPackageInfo().name;
28
+ }
29
+ export function getPluginVersion() {
30
+ return readPackageInfo().version;
31
+ }
32
+ /**
33
+ * Returns the npm spec string `<name>@<version>` to pass to
34
+ * `openclaw plugins install`. Pinning the exact version prevents OpenClaw
35
+ * from rejecting the install when `latest` happens to point at a prerelease
36
+ * — without this, `openclaw plugins install <bare-name>` resolves through
37
+ * the `latest` dist-tag and refuses prereleases for safety.
38
+ */
39
+ export function getInstallSpec() {
40
+ return `${getPluginName()}@${getPluginVersion()}`;
41
+ }
42
+ //# sourceMappingURL=package-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-info.js","sourceRoot":"","sources":["../../src/cli/package-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,UAAU,eAAe;IAC7B,IAAI,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACjD,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,GAAG,CAAA;QACrD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC3B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;QAC1F,GAAG,GAAG,MAAM,CAAA;IACd,CAAC;AACH,CAAC;AAID,IAAI,MAA+B,CAAA;AAEnC,SAAS,eAAe;IACtB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CACrB,CAAA;IAC1C,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;IAC5D,CAAC;IACD,MAAM,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAA;IACjD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,eAAe,EAAE,CAAC,IAAI,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,eAAe,EAAE,CAAC,OAAO,CAAA;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,GAAG,aAAa,EAAE,IAAI,gBAAgB,EAAE,EAAE,CAAA;AACnD,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const PRESET_WHITELIST: readonly ["soothing_loop_enabled"];
2
+ export type PresetKey = (typeof PRESET_WHITELIST)[number];
3
+ export type Preset = Partial<Record<PresetKey, boolean>>;
4
+ export declare function listPresets(dir?: string): string[];
5
+ export declare function loadPreset(name: string, dir?: string): Preset;
6
+ //# sourceMappingURL=preset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/cli/preset.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,oCAAqC,CAAA;AAClE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AACzD,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;AAMxD,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAoB,GAAG,MAAM,EAAE,CAM/D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAoB,GAAG,MAAM,CAiC1E"}
@@ -0,0 +1,45 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { findPackageRoot } from './package-info.js';
4
+ export const PRESET_WHITELIST = ['soothing_loop_enabled'];
5
+ function presetDir() {
6
+ return join(findPackageRoot(), 'src', 'presets');
7
+ }
8
+ export function listPresets(dir = presetDir()) {
9
+ if (!existsSync(dir))
10
+ return [];
11
+ return readdirSync(dir)
12
+ .filter((f) => f.endsWith('.json'))
13
+ .map((f) => f.slice(0, -'.json'.length))
14
+ .sort();
15
+ }
16
+ export function loadPreset(name, dir = presetDir()) {
17
+ const file = join(dir, `${name}.json`);
18
+ if (!existsSync(file)) {
19
+ const available = listPresets(dir);
20
+ throw new Error(`Preset "${name}" not found. Available: ${available.length ? available.join(', ') : '(none)'}`);
21
+ }
22
+ let parsed;
23
+ try {
24
+ parsed = JSON.parse(readFileSync(file, 'utf8'));
25
+ }
26
+ catch (err) {
27
+ throw new Error(`Preset "${name}" is not valid JSON: ${err.message}`);
28
+ }
29
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
30
+ throw new Error(`Preset "${name}" must be a JSON object`);
31
+ }
32
+ const allowed = PRESET_WHITELIST;
33
+ const result = {};
34
+ for (const [key, value] of Object.entries(parsed)) {
35
+ if (!allowed.includes(key)) {
36
+ throw new Error(`Preset "${name}" has unknown key "${key}". Allowed: ${PRESET_WHITELIST.join(', ')}`);
37
+ }
38
+ if (typeof value !== 'boolean') {
39
+ throw new Error(`Preset "${name}" key "${key}" must be a boolean (got ${typeof value})`);
40
+ }
41
+ result[key] = value;
42
+ }
43
+ return result;
44
+ }
45
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../../src/cli/preset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEnD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,uBAAuB,CAAU,CAAA;AAIlE,SAAS,SAAS;IAChB,OAAO,IAAI,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAc,SAAS,EAAE;IACnD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAC/B,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SACvC,IAAI,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,MAAc,SAAS,EAAE;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,OAAO,CAAC,CAAA;IACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;QAClC,MAAM,IAAI,KAAK,CACb,WAAW,IAAI,2BAA2B,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAC/F,CAAA;IACH,CAAC;IAED,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,wBAAyB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IAClF,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,yBAAyB,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,OAAO,GAAG,gBAAqC,CAAA;IACrD,MAAM,MAAM,GAAW,EAAE,CAAA;IACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAiC,CAAC,EAAE,CAAC;QAC7E,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,sBAAsB,GAAG,eAAe,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACvG,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,UAAU,GAAG,4BAA4B,OAAO,KAAK,GAAG,CAAC,CAAA;QAC1F,CAAC;QACD,MAAM,CAAC,GAAgB,CAAC,GAAG,KAAK,CAAA;IAClC,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
package/dist/config.d.ts CHANGED
@@ -31,7 +31,6 @@ export type FlatChannelConfig = {
31
31
  sentence_split_delimiters?: string;
32
32
  soothing_loop_enabled?: boolean;
33
33
  soothing_loop_interval_ms?: number;
34
- soothing_loop_max_count?: number;
35
34
  };
36
35
  export declare const DEFAULT_API_URL = "https://api.folotoy.cn";
37
36
  export declare const DEFAULT_MQTT_HOST: string;
@@ -41,7 +40,6 @@ export declare const DEFAULT_SUMMARY_MAX_CHARS = 200;
41
40
  export declare const DEFAULT_SENTENCE_SPLIT_ENABLED = true;
42
41
  export declare const DEFAULT_SENTENCE_SPLIT_DELIMITERS = "\uFF01\u3002\uFF1F\uFF1B!.?;~";
43
42
  export declare const DEFAULT_SOOTHING_LOOP_ENABLED = true;
44
- export declare const DEFAULT_SOOTHING_LOOP_INTERVAL_MS = 200;
45
- export declare const DEFAULT_SOOTHING_LOOP_MAX_COUNT = 3;
43
+ export declare const DEFAULT_SOOTHING_LOOP_INTERVAL_MS = 3000;
46
44
  export declare function flatToPluginConfig(flat: FlatChannelConfig): PluginConfig;
47
45
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,KAAK,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,eAAe,GAAG,eAAe,CAAA;IACvC,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;CACF,CAAA;AAED,8DAA8D;AAC9D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,eAAe,2BAA2B,CAAA;AACvD,eAAO,MAAM,iBAAiB,QAAgD,CAAA;AAC9E,eAAO,MAAM,iBAAiB,OAAO,CAAA;AACrC,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAC3C,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAC5C,eAAO,MAAM,8BAA8B,OAAO,CAAA;AAClD,eAAO,MAAM,iCAAiC,kCAAc,CAAA;AAC5D,eAAO,MAAM,6BAA6B,OAAO,CAAA;AACjD,eAAO,MAAM,iCAAiC,MAAM,CAAA;AACpD,eAAO,MAAM,+BAA+B,IAAI,CAAA;AAEhD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,YAAY,CAaxE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,KAAK,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,eAAe,GAAG,eAAe,CAAA;IACvC,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;CACF,CAAA;AAED,8DAA8D;AAC9D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,yBAAyB,CAAC,EAAE,MAAM,CAAA;CACnC,CAAA;AAED,eAAO,MAAM,eAAe,2BAA2B,CAAA;AACvD,eAAO,MAAM,iBAAiB,QAAkD,CAAA;AAChF,eAAO,MAAM,iBAAiB,OAAO,CAAA;AACrC,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAC3C,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAC5C,eAAO,MAAM,8BAA8B,OAAO,CAAA;AAClD,eAAO,MAAM,iCAAiC,kCAAc,CAAA;AAC5D,eAAO,MAAM,6BAA6B,OAAO,CAAA;AACjD,eAAO,MAAM,iCAAiC,OAAO,CAAA;AAErD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,YAAY,CAaxE"}
package/dist/config.js CHANGED
@@ -1,13 +1,12 @@
1
1
  export const DEFAULT_API_URL = 'https://api.folotoy.cn';
2
- export const DEFAULT_MQTT_HOST = process.env.FOLOTOY_MQTT_HOST ?? 'f.qrc92.cn';
2
+ export const DEFAULT_MQTT_HOST = process.env.FOLOTOY_MQTT_HOST ?? 'f.folotoy.cn';
3
3
  export const DEFAULT_MQTT_PORT = 1883;
4
4
  export const DEFAULT_SUMMARY_ENABLED = true;
5
5
  export const DEFAULT_SUMMARY_MAX_CHARS = 200;
6
6
  export const DEFAULT_SENTENCE_SPLIT_ENABLED = true;
7
7
  export const DEFAULT_SENTENCE_SPLIT_DELIMITERS = '!。?;!.?;~';
8
8
  export const DEFAULT_SOOTHING_LOOP_ENABLED = true;
9
- export const DEFAULT_SOOTHING_LOOP_INTERVAL_MS = 200;
10
- export const DEFAULT_SOOTHING_LOOP_MAX_COUNT = 3;
9
+ export const DEFAULT_SOOTHING_LOOP_INTERVAL_MS = 3000;
11
10
  export function flatToPluginConfig(flat) {
12
11
  const flow = flat.flow ?? 'direct';
13
12
  const auth = flow === 'api'
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAuCA,MAAM,CAAC,MAAM,eAAe,GAAG,wBAAwB,CAAA;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,YAAY,CAAA;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AACrC,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAA;AAC3C,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAC5C,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAA;AAClD,MAAM,CAAC,MAAM,iCAAiC,GAAG,WAAW,CAAA;AAC5D,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAA;AACjD,MAAM,CAAC,MAAM,iCAAiC,GAAG,GAAG,CAAA;AACpD,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAA;AAEhD,MAAM,UAAU,kBAAkB,CAAC,IAAuB;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAA;IAClC,MAAM,IAAI,GAAG,IAAI,KAAK,KAAK;QACzB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAc,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE;QAC5H,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAA;IAEvF,OAAO;QACL,IAAI;QACJ,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,iBAAiB;YACzC,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,iBAAiB;SAC1C;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAsCA,MAAM,CAAC,MAAM,eAAe,GAAG,wBAAwB,CAAA;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,cAAc,CAAA;AAChF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AACrC,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAA;AAC3C,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAC5C,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAA;AAClD,MAAM,CAAC,MAAM,iCAAiC,GAAG,WAAW,CAAA;AAC5D,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAA;AACjD,MAAM,CAAC,MAAM,iCAAiC,GAAG,IAAI,CAAA;AAErD,MAAM,UAAU,kBAAkB,CAAC,IAAuB;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAA;IAClC,MAAM,IAAI,GAAG,IAAI,KAAK,KAAK;QACzB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAc,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE;QAC5H,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAA;IAEvF,OAAO;QACL,IAAI;QACJ,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,iBAAiB;YACzC,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,iBAAiB;SAC1C;KACF,CAAA;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { resolveCredentials, createMqttClient, buildInboundTopic, buildOutboundTopic, buildNotificationTopic } from './mqtt.js';
2
2
  import { createSoothingPicker } from './soothing.js';
3
3
  import { stripMarkdown } from './strip-markdown.js';
4
- import { DEFAULT_MQTT_HOST, DEFAULT_MQTT_PORT, DEFAULT_SUMMARY_ENABLED, DEFAULT_SUMMARY_MAX_CHARS, DEFAULT_SENTENCE_SPLIT_ENABLED, DEFAULT_SENTENCE_SPLIT_DELIMITERS, DEFAULT_SOOTHING_LOOP_ENABLED, DEFAULT_SOOTHING_LOOP_INTERVAL_MS, DEFAULT_SOOTHING_LOOP_MAX_COUNT, flatToPluginConfig } from './config.js';
4
+ import { DEFAULT_MQTT_HOST, DEFAULT_MQTT_PORT, DEFAULT_SUMMARY_ENABLED, DEFAULT_SUMMARY_MAX_CHARS, DEFAULT_SENTENCE_SPLIT_ENABLED, DEFAULT_SENTENCE_SPLIT_DELIMITERS, DEFAULT_SOOTHING_LOOP_ENABLED, DEFAULT_SOOTHING_LOOP_INTERVAL_MS, flatToPluginConfig } from './config.js';
5
5
  // Per-account MQTT clients and msgId counters
6
6
  const activeClients = new Map();
7
7
  // Subagent reference, set at plugin registration
@@ -35,7 +35,6 @@ const folotoyChannel = {
35
35
  sentence_split_delimiters: { type: 'string', default: DEFAULT_SENTENCE_SPLIT_DELIMITERS },
36
36
  soothing_loop_enabled: { type: 'boolean', default: DEFAULT_SOOTHING_LOOP_ENABLED },
37
37
  soothing_loop_interval_ms: { type: 'number', default: DEFAULT_SOOTHING_LOOP_INTERVAL_MS },
38
- soothing_loop_max_count: { type: 'number', default: DEFAULT_SOOTHING_LOOP_MAX_COUNT },
39
38
  },
40
39
  },
41
40
  uiHints: {
@@ -52,7 +51,6 @@ const folotoyChannel = {
52
51
  sentence_split_delimiters: { label: 'Sentence Delimiters' },
53
52
  soothing_loop_enabled: { label: 'Enable Soothing Loop' },
54
53
  soothing_loop_interval_ms: { label: 'Soothing Loop Interval (ms)' },
55
- soothing_loop_max_count: { label: 'Soothing Loop Max Count' },
56
54
  },
57
55
  },
58
56
  config: {
@@ -101,7 +99,6 @@ const folotoyChannel = {
101
99
  const sentenceSplitDelimiters = account.sentence_split_delimiters ?? DEFAULT_SENTENCE_SPLIT_DELIMITERS;
102
100
  const soothingLoopEnabled = account.soothing_loop_enabled ?? DEFAULT_SOOTHING_LOOP_ENABLED;
103
101
  const soothingLoopIntervalMs = account.soothing_loop_interval_ms ?? DEFAULT_SOOTHING_LOOP_INTERVAL_MS;
104
- const soothingLoopMaxCount = account.soothing_loop_max_count ?? DEFAULT_SOOTHING_LOOP_MAX_COUNT;
105
102
  client.on('message', (_topic, payload) => {
106
103
  let msg;
107
104
  try {
@@ -154,37 +151,37 @@ const folotoyChannel = {
154
151
  let totalSentChars = 0;
155
152
  let firstSentenceFlushed = false;
156
153
  let llmStarted = false;
157
- // Send soothing replies while waiting for the LLM to start responding.
158
- // Once any LLM chunk arrives, stop immediately. Max 5 soothing messages.
159
- let soothingTimer = null;
160
- let soothingCount = 0;
154
+ // Soothing loop: check every 200ms if LLM has started responding.
155
+ // If not, send a soothing reply at a pace matching TTS playback
156
+ // (controlled by soothingLoopIntervalMs). Keeps running until LLM
157
+ // returns its first chunk — no fixed max count.
158
+ let soothingCheckTimer = null;
159
+ let lastSoothingSentAt = 0;
161
160
  const stopSoothingLoop = () => {
162
- if (soothingTimer) {
163
- clearTimeout(soothingTimer);
164
- soothingTimer = null;
161
+ if (soothingCheckTimer) {
162
+ clearInterval(soothingCheckTimer);
163
+ soothingCheckTimer = null;
165
164
  }
166
165
  };
167
- const resetSoothingTimer = () => {
168
- if (!soothingLoopEnabled || llmStarted || soothingCount >= soothingLoopMaxCount)
169
- return;
170
- if (soothingTimer)
171
- clearTimeout(soothingTimer);
172
- soothingTimer = setTimeout(() => {
173
- if (llmStarted || soothingCount >= soothingLoopMaxCount)
166
+ if (soothingLoopEnabled) {
167
+ soothingCheckTimer = setInterval(() => {
168
+ if (llmStarted) {
169
+ stopSoothingLoop();
174
170
  return;
175
- soothingCount++;
176
- order++;
177
- const extraAck = {
178
- msgId,
179
- identifier: 'chat_output',
180
- outParams: { content: soothingPick(), recording_id, order, is_finished: false },
181
- };
182
- client.publish(outboundTopic, JSON.stringify(extraAck));
183
- // Restart timer in case LLM stays silent even longer
184
- resetSoothingTimer();
185
- }, soothingLoopIntervalMs);
186
- };
187
- resetSoothingTimer();
171
+ }
172
+ const now = Date.now();
173
+ if (now - lastSoothingSentAt >= soothingLoopIntervalMs) {
174
+ lastSoothingSentAt = now;
175
+ order++;
176
+ const extraAck = {
177
+ msgId,
178
+ identifier: 'chat_output',
179
+ outParams: { content: soothingPick(), recording_id, order, is_finished: false },
180
+ };
181
+ client.publish(outboundTopic, JSON.stringify(extraAck));
182
+ }
183
+ }, 200);
184
+ }
188
185
  // First sentence: split purely by punctuation (fast first response).
189
186
  // Subsequent sentences: require a minimum length that grows with each
190
187
  // sentence (base 20 chars, +10 per sentence), so later chunks are longer.
@@ -320,10 +317,7 @@ const folotoyChannel = {
320
317
  }
321
318
  }
322
319
  finally {
323
- if (soothingTimer) {
324
- clearTimeout(soothingTimer);
325
- soothingTimer = null;
326
- }
320
+ stopSoothingLoop();
327
321
  order++;
328
322
  const finishMsg = {
329
323
  msgId,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAC/H,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,iCAAiC,EAAE,6BAA6B,EAAE,iCAAiC,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAsB/Q,8CAA8C;AAC9C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAqE,CAAA;AAElG,iDAAiD;AACjD,IAAI,QAA+C,CAAA;AAEnD,MAAM,cAAc,GAAqC;IACvD,EAAE,EAAE,SAAS;IACb,IAAI,EAAE;QACJ,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,SAAS;QAChB,cAAc,EAAE,SAAS;QACzB,QAAQ,EAAE,mBAAmB;QAC7B,KAAK,EAAE,qDAAqD;KAC7D;IACD,YAAY,EAAE;QACZ,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB;IACD,YAAY,EAAE;QACZ,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE;gBACpE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC3B,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,wBAAwB,EAAE;gBAC9D,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC3B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACzD,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACzD,eAAe,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,EAAE;gBACtE,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,yBAAyB,EAAE;gBACzE,sBAAsB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,8BAA8B,EAAE;gBACpF,yBAAyB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iCAAiC,EAAE;gBACzF,qBAAqB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,6BAA6B,EAAE;gBAClF,yBAAyB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iCAAiC,EAAE;aAC1F;SACF;QACD,OAAO,EAAE;YACP,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;YAC5B,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;YAC3B,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE;YAC9C,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,yBAAyB,EAAE;YACrE,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE;YAC9C,SAAS,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,EAAE;YACjE,SAAS,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;YACjC,eAAe,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE;YAC5C,iBAAiB,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE;YACtD,sBAAsB,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE;YAC9D,yBAAyB,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE;YAC3D,qBAAqB,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;YACxD,yBAAyB,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE;SACpE;KACF;IACD,MAAM,EAAE;QACN,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE;YACtB,MAAM,OAAO,GAAI,GAAgF;iBAC9F,QAAQ,EAAE,OAAO,CAAA;YACpB,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACnC,CAAC;QACD,cAAc,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE;YAClC,MAAM,OAAO,GAAI,GAAgF;iBAC9F,QAAQ,EAAE,OAAO,CAAA;YACpB,OAAO,OAAO,IAAK,EAAwB,CAAA;QAC7C,CAAC;QACD,gBAAgB,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;YAC5B,MAAM,EAAE,GAAI,GAAgF;gBAC1F,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAA;YAC7B,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC9B,CAAC;KACF;IACD,OAAO,EAAE;QACP,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC1B,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA;YAEzE,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,GAAG,EAAE,IAAI,EAAE,CAAC,yDAAyD,CAAC,CAAA;gBACtE,OAAM;YACR,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpB,GAAG,EAAE,IAAI,EAAE,CAAC,kDAAkD,CAAC,CAAA;gBAC/D,OAAM;YACR,CAAC;YAED,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;YAC9C,GAAG,EAAE,IAAI,EAAE,CAAC,6BAA6B,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAA;YAC3F,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,CAAA;YACxD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;YAC9D,MAAM,YAAY,GAAG,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YAC1D,MAAM,aAAa,GAAG,kBAAkB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YAE5D,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAA;YAClF,GAAG,EAAE,IAAI,EAAE,CAAC,2CAA2C,YAAY,EAAE,CAAC,CAAA;YAEtE,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE;gBACrC,IAAI,GAAG;oBAAE,GAAG,EAAE,KAAK,EAAE,CAAC,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;YAC9D,CAAC,CAAC,CAAA;YAEF,MAAM,cAAc,GAAG,OAAO,CAAC,eAAe,IAAI,uBAAuB,CAAA;YACzE,MAAM,eAAe,GAAG,OAAO,CAAC,iBAAiB,IAAI,yBAAyB,CAAA;YAC9E,MAAM,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,IAAI,8BAA8B,CAAA;YAC7F,MAAM,uBAAuB,GAAG,OAAO,CAAC,yBAAyB,IAAI,iCAAiC,CAAA;YACtG,MAAM,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,IAAI,6BAA6B,CAAA;YAC1F,MAAM,sBAAsB,GAAG,OAAO,CAAC,yBAAyB,IAAI,iCAAiC,CAAA;YAErG,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;gBACvC,IAAI,GAAmB,CAAA;gBACvB,IAAI,CAAC;oBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAmB,CAAA;gBACxD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAM;gBACR,CAAC;gBACD,IAAI,GAAG,CAAC,UAAU,KAAK,YAAY,IAAI,OAAO,GAAG,CAAC,WAAW,EAAE,IAAI,KAAK,QAAQ;oBAAE,OAAM;gBAExF,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,GAAG,GAAG,CAAA;gBAC1D,IAAI,KAAK,GAAG,CAAC,CAAA;gBAEb,6EAA6E;gBAC7E,MAAM,YAAY,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;gBAE/C,uEAAuE;gBACvE,oCAAoC;gBACpC,MAAM,MAAM,GAAoB;oBAC9B,KAAK;oBACL,UAAU,EAAE,aAAa;oBACzB,SAAS,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE;iBAChF,CAAA;gBACD,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;gBAErD,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,QAAiB,EAAE,EAAE,EAAE,WAAW,CAAC,MAAM,EAAE,CAAA;gBAChE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,oBAAoB,CAAC;oBAC7D,OAAO,EAAE,MAAM;oBACf,OAAO,EAAE,SAAS;oBAClB,SAAS;oBACT,IAAI;oBACJ,OAAO,EAAE,kBAAkB;iBAC5B,CAAC,CAAA;gBAEF,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,sBAAsB,CAAC;oBAC7D,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,WAAW,CAAC,MAAM;oBACxB,EAAE,EAAE,WAAW,CAAC,MAAM;oBACtB,UAAU,EAAE,UAAU;oBACtB,SAAS,EAAE,SAAS;oBACpB,QAAQ,EAAE,SAAS;oBACnB,OAAO,EAAE,SAAS;oBAClB,kBAAkB,EAAE,SAAS;oBAC7B,aAAa,EAAE,WAAW,CAAC,MAAM;iBAClC,CAAC,CAAA;gBAEF,mFAAmF;gBACnF,KAAK,CAAC,KAAK,IAAI,EAAE;oBACf,oEAAoE;oBACpE,+DAA+D;oBAC/D,MAAM,mBAAmB,GAAG,oBAAoB;wBAC9C,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,uBAAuB,CAAC,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,GAAG,CAAC;wBACrF,CAAC,CAAC,IAAI,CAAA;oBACR,IAAI,cAAc,GAAG,EAAE,CAAA;oBACvB,IAAI,cAAc,GAAG,CAAC,CAAA;oBACtB,IAAI,oBAAoB,GAAG,KAAK,CAAA;oBAChC,IAAI,UAAU,GAAG,KAAK,CAAA;oBAEtB,kEAAkE;oBAClE,gEAAgE;oBAChE,kEAAkE;oBAClE,gDAAgD;oBAChD,IAAI,kBAAkB,GAA0C,IAAI,CAAA;oBACpE,IAAI,kBAAkB,GAAG,CAAC,CAAA;oBAC1B,MAAM,gBAAgB,GAAG,GAAG,EAAE;wBAC5B,IAAI,kBAAkB,EAAE,CAAC;4BAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;4BAAC,kBAAkB,GAAG,IAAI,CAAA;wBAAC,CAAC;oBAC1F,CAAC,CAAA;oBACD,IAAI,mBAAmB,EAAE,CAAC;wBACxB,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;4BACpC,IAAI,UAAU,EAAE,CAAC;gCACf,gBAAgB,EAAE,CAAA;gCAClB,OAAM;4BACR,CAAC;4BACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;4BACtB,IAAI,GAAG,GAAG,kBAAkB,IAAI,sBAAsB,EAAE,CAAC;gCACvD,kBAAkB,GAAG,GAAG,CAAA;gCACxB,KAAK,EAAE,CAAA;gCACP,MAAM,QAAQ,GAAoB;oCAChC,KAAK;oCACL,UAAU,EAAE,aAAa;oCACzB,SAAS,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE;iCAChF,CAAA;gCACD,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;4BACzD,CAAC;wBACH,CAAC,EAAE,GAAG,CAAC,CAAA;oBACT,CAAC;oBAED,qEAAqE;oBACrE,sEAAsE;oBACtE,0EAA0E;oBAC1E,IAAI,aAAa,GAAG,CAAC,CAAA;oBACrB,MAAM,iBAAiB,GAAG,GAAG,EAAE;wBAC7B,IAAI,aAAa,KAAK,CAAC;4BAAE,OAAO,CAAC,CAAA,CAAC,6BAA6B;wBAC/D,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAA;oBACrD,CAAC,CAAA;oBAED,MAAM,eAAe,GAAG,GAAG,CAAA,CAAC,6DAA6D;oBAEzF,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,EAAE;wBAC3C,aAAa,EAAE,CAAA;wBACf,IAAI,CAAC,oBAAoB;4BAAE,oBAAoB,GAAG,IAAI,CAAA;wBACtD,KAAK,EAAE,CAAA;wBACP,cAAc,IAAI,QAAQ,CAAC,MAAM,CAAA;wBACjC,MAAM,MAAM,GAAoB;4BAC9B,KAAK;4BACL,UAAU,EAAE,aAAa;4BACzB,SAAS,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE;yBAC1E,CAAA;wBACD,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;oBACvD,CAAC,CAAA;oBAED,MAAM,cAAc,GAAG,GAAG,EAAE;wBAC1B,IAAI,CAAC,mBAAmB;4BAAE,OAAM;wBAChC,OAAO,IAAI,EAAE,CAAC;4BACZ,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;4BAClC,iEAAiE;4BACjE,IAAI,GAAG,GAAG,CAAC,CAAC,CAAA;4BACZ,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAA;4BAC1C,IAAI,UAAU,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC;gCACvC,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;gCAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;gCAC7C,IAAI,KAAK,KAAK,CAAC,CAAC;oCAAE,GAAG,GAAG,UAAU,GAAG,KAAK,CAAA;4BAC5C,CAAC;4BACD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gCACf,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;gCACxD,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;gCAC9C,IAAI,QAAQ;oCAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;gCACvC,SAAQ;4BACV,CAAC;4BACD,2DAA2D;4BAC3D,IAAI,cAAc,CAAC,MAAM,IAAI,eAAe,EAAE,CAAC;gCAC7C,yDAAyD;gCACzD,IAAI,MAAM,GAAG,eAAe,CAAA;gCAC5B,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;gCAClE,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;gCAClE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;gCAChD,IAAI,SAAS,GAAG,eAAe,GAAG,CAAC;oCAAE,MAAM,GAAG,SAAS,GAAG,CAAC,CAAA;gCAC3D,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;gCACvD,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;gCAC7C,IAAI,QAAQ;oCAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;gCACvC,SAAQ;4BACV,CAAC;4BACD,MAAK;wBACP,CAAC;oBACH,CAAC,CAAA;oBAED,MAAM,UAAU,GAAG;wBACjB,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;wBAC1B,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;wBAC1B,cAAc,EAAE,CAAC,OAA0B,EAAE,EAAE;4BAC7C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gCACjB,IAAI,CAAC,UAAU,EAAE,CAAC;oCAChB,UAAU,GAAG,IAAI,CAAA;oCACjB,gBAAgB,EAAE,CAAA;gCACpB,CAAC;gCACD,cAAc,IAAI,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gCAC7C,cAAc,EAAE,CAAA;4BAClB,CAAC;4BACD,OAAO,IAAI,CAAA;wBACb,CAAC;wBACD,WAAW,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;wBAC3B,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;wBACxD,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;qBACvB,CAAA;oBACD,IAAI,CAAC;wBACH,MAAM,cAAc,CAAC,KAAK,CAAC,mBAAmB,CAAC;4BAC7C,UAAU;4BACV,GAAG,EAAE,GAAG,EAAE,CACR,cAAc,CAAC,KAAK,CAAC,uBAAuB,CAAC;gCAC3C,GAAG,EAAE,UAAU;gCACf,GAAG;gCACH,UAAU;6BACX,CAAC;yBACL,CAAC,CAAA;wBAEF,2DAA2D;wBAC3D,IAAI,SAAS,GAAG,cAAc,CAAC,IAAI,EAAE,CAAA;wBACrC,IAAI,SAAS,EAAE,CAAC;4BACd,2EAA2E;4BAC3E,IAAI,cAAc,IAAI,QAAQ,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,eAAe,EAAE,CAAC;gCACxF,IAAI,CAAC;oCACH,MAAM,iBAAiB,GAAG,mBAAmB,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;oCACtE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC;wCACnC,UAAU,EAAE,iBAAiB;wCAC7B,OAAO,EAAE;4CACP,oGAAoG;4CACpG,uCAAuC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,GAAG,cAAc,CAAC,cAAc;4CACnG,qGAAqG;4CACrG,EAAE;4CACF,qBAAqB;4CACrB,SAAS;4CACT,sBAAsB;yCACvB,CAAC,IAAI,CAAC,IAAI,CAAC;wCACZ,OAAO,EAAE,KAAK;qCACf,CAAC,CAAA;oCACF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAA;oCACtE,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;wCAC3B,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;wCACnG,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAoD,CAAA;wCAChG,MAAM,WAAW,GAAG,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,IAAI,CAAA;wCACrD,IAAI,WAAW;4CAAE,SAAS,GAAG,WAAW,CAAA;oCAC1C,CAAC;oCACD,MAAM,QAAQ,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gCACjF,CAAC;gCAAC,OAAO,GAAG,EAAE,CAAC;oCACb,GAAG,EAAE,IAAI,EAAE,CAAC,oCAAoC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;oCAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,GAAG,cAAc,CAAC,CAAA;oCACnE,SAAS,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,KAAK,CAAA;gCAC1D,CAAC;4BACH,CAAC;4BAED,KAAK,EAAE,CAAA;4BACP,MAAM,MAAM,GAAoB;gCAC9B,KAAK;gCACL,UAAU,EAAE,aAAa;gCACzB,SAAS,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE;6BAC3E,CAAA;4BACD,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;wBACvD,CAAC;oBACH,CAAC;4BAAS,CAAC;wBACT,gBAAgB,EAAE,CAAA;wBAClB,KAAK,EAAE,CAAA;wBACP,MAAM,SAAS,GAAoB;4BACjC,KAAK;4BACL,UAAU,EAAE,aAAa;4BACzB,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE;yBACnE,CAAA;wBACD,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAA;oBAC1D,CAAC;gBACH,CAAC,CAAC,EAAE,CAAA;YACN,CAAC,CAAC,CAAA;YAEF,uCAAuC;YACvC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACnC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;oBACzC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;oBAC/B,MAAM,CAAC,GAAG,EAAE,CAAA;oBACZ,GAAG,EAAE,IAAI,EAAE,CAAC,0BAA0B,CAAC,CAAA;oBACvC,OAAO,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAC1B,0DAA0D;QAC5D,CAAC;KACF;IAED,WAAW,EAAE;QACX,gBAAgB,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;YAC5B,MAAM,OAAO,GAAI,GAAgF;gBAC/F,EAAE,QAAQ,EAAE,OAAO,CAAA;YACrB,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,IAAI,UAAU,CAAA;YACxC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;YACtB,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAA;YAC3D,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAA;YAC5C,MAAM,MAAM,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;YAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YAC/D,MAAM,QAAQ,GAAG,GAAG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;YACzC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YACrD,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAA;YAC5K,OAAO;gBACL,qDAAqD,EAAE,oBAAoB,QAAQ,KAAK,EAAE,uMAAuM;gBACjS;oBACE,0EAA0E;oBAC1E,oEAAoE,QAAQ,kBAAkB;oBAC9F,yDAAyD,QAAQ,EAAE;oBACnE,0FAA0F;oBAC1F,oCAAoC;oBACpC,oEAAoE,EAAE,0BAA0B;oBAChG,kGAAkG,QAAQ,8IAA8I,EAAE,2CAA2C;iBACtS,CAAC,IAAI,CAAC,IAAI,CAAC;aACb,CAAA;QACH,CAAC;KACF;IAED,SAAS,EAAE;QACT,cAAc,EAAE;YACd,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI;YACvB,IAAI,EAAE,oCAAoC;SAC3C;KACF;IAGD,QAAQ,EAAE;QACR,YAAY,EAAE,QAAQ;QACtB,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;YAC7B,IAAI,EAAE;gBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;YAC/B,MAAM,OAAO,GAAI,GAAgF;gBAC/F,EAAE,QAAQ,EAAE,OAAO,CAAA;YACrB,IAAI,OAAO,EAAE,MAAM;gBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;YAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,kCAAkC,CAAC,EAAE,CAAA;QAC5E,CAAC;QACD,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;YACtC,MAAM,GAAG,GAAG,SAAS,IAAI,SAAS,CAAA;YAClC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAA;YAC3E,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,GAAG,CAAC,CAAA;YAEzE,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;YAC/B,MAAM,QAAQ,GAAwB;gBACpC,KAAK;gBACL,UAAU,EAAE,mBAAmB;gBAC/B,SAAS,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE;aACzC,CAAA;YACD,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;YACjE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;QACzD,CAAC;KACF;CACF,CAAA;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAwC;IACxF,MAAM,GAAG,GAAG,SAAS,IAAI,SAAS,CAAA;IAClC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,GAAG,CAAC,CAAA;IAEzE,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;IAC/B,MAAM,QAAQ,GAAwB;QACpC,KAAK;QACL,UAAU,EAAE,mBAAmB;QAC/B,SAAS,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE;KACzC,CAAA;IACD,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;IACjE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;AACzD,CAAC;AAED,eAAe,CAAC,GAAsB,EAAE,EAAE;IACxC,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAA;IAC/B,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAA;AACjD,CAAC,CAAA"}
@@ -2,7 +2,7 @@
2
2
  "id": "folotoy-openclaw-plugin",
3
3
  "name": "FoloToy",
4
4
  "description": "Empower your FoloToy with OpenClaw AI capabilities.",
5
- "version": "0.6.0",
5
+ "version": "0.6.2",
6
6
  "channels": ["folotoy"],
7
7
  "configSchema": {
8
8
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@folotoy/folotoy-openclaw-plugin",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Empower your FoloToy with OpenClaw AI capabilities.",
5
5
  "keywords": [
6
6
  "folotoy",
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { readFileSync } from 'node:fs'
3
+ import { join } from 'node:path'
4
+ import {
5
+ findPackageRoot,
6
+ getInstallSpec,
7
+ getPluginName,
8
+ getPluginVersion,
9
+ } from '../cli/package-info.js'
10
+
11
+ describe('package-info', () => {
12
+ it('findPackageRoot resolves to a directory containing package.json', () => {
13
+ const root = findPackageRoot()
14
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
15
+ expect(typeof pkg.name).toBe('string')
16
+ expect(typeof pkg.version).toBe('string')
17
+ })
18
+
19
+ it('getPluginName matches package.json name', () => {
20
+ const root = findPackageRoot()
21
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
22
+ expect(getPluginName()).toBe(pkg.name)
23
+ })
24
+
25
+ it('getPluginVersion matches package.json version', () => {
26
+ const root = findPackageRoot()
27
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
28
+ expect(getPluginVersion()).toBe(pkg.version)
29
+ })
30
+
31
+ it('getInstallSpec is "<name>@<version>" — pins the exact version so OpenClaw will install prereleases', () => {
32
+ expect(getInstallSpec()).toBe(`${getPluginName()}@${getPluginVersion()}`)
33
+ // Sanity: it must contain an `@` separator after the scope's leading `@`.
34
+ const spec = getInstallSpec()
35
+ const lastAt = spec.lastIndexOf('@')
36
+ expect(lastAt).toBeGreaterThan(0)
37
+ expect(spec.slice(lastAt + 1)).toMatch(/^\d+\.\d+\.\d+/)
38
+ })
39
+ })
@@ -0,0 +1,85 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest'
2
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3
+ import { tmpdir } from 'node:os'
4
+ import { join } from 'node:path'
5
+ import { listPresets, loadPreset, PRESET_WHITELIST } from '../cli/preset.js'
6
+
7
+ let dir: string
8
+
9
+ beforeEach(() => {
10
+ dir = mkdtempSync(join(tmpdir(), 'preset-test-'))
11
+ })
12
+
13
+ afterEach(() => {
14
+ rmSync(dir, { recursive: true, force: true })
15
+ })
16
+
17
+ function writePreset(name: string, body: unknown): void {
18
+ writeFileSync(join(dir, `${name}.json`), JSON.stringify(body))
19
+ }
20
+
21
+ describe('loadPreset', () => {
22
+ it('returns parsed preset for whitelisted boolean key', () => {
23
+ writePreset('single-soothing', { soothing_loop_enabled: false })
24
+ expect(loadPreset('single-soothing', dir)).toEqual({ soothing_loop_enabled: false })
25
+ })
26
+
27
+ it('throws when preset file does not exist, listing available presets', () => {
28
+ writePreset('alpha', { soothing_loop_enabled: true })
29
+ writePreset('beta', { soothing_loop_enabled: false })
30
+ expect(() => loadPreset('missing', dir)).toThrow(/Preset "missing" not found.*alpha, beta/)
31
+ })
32
+
33
+ it('throws when preset has unknown key', () => {
34
+ writePreset('bad', { soothing_loop_enabled: false, summary_enabled: true })
35
+ expect(() => loadPreset('bad', dir)).toThrow(/unknown key "summary_enabled"/)
36
+ })
37
+
38
+ it('throws when whitelisted key has wrong type', () => {
39
+ writePreset('bad', { soothing_loop_enabled: 'false' })
40
+ expect(() => loadPreset('bad', dir)).toThrow(/must be a boolean \(got string\)/)
41
+ })
42
+
43
+ it('throws when JSON is not an object', () => {
44
+ writeFileSync(join(dir, 'arr.json'), '[1, 2, 3]')
45
+ expect(() => loadPreset('arr', dir)).toThrow(/must be a JSON object/)
46
+ })
47
+
48
+ it('throws when JSON is malformed', () => {
49
+ writeFileSync(join(dir, 'bad.json'), '{ not json')
50
+ expect(() => loadPreset('bad', dir)).toThrow(/not valid JSON/)
51
+ })
52
+
53
+ it('whitelist contains only soothing_loop_enabled (current scope)', () => {
54
+ expect(PRESET_WHITELIST).toEqual(['soothing_loop_enabled'])
55
+ })
56
+ })
57
+
58
+ describe('shipped presets', () => {
59
+ it('single-soothing resolves from default package presets dir and disables the soothing loop', () => {
60
+ expect(loadPreset('single-soothing')).toEqual({ soothing_loop_enabled: false })
61
+ })
62
+
63
+ it('lists single-soothing among the default presets', () => {
64
+ expect(listPresets()).toContain('single-soothing')
65
+ })
66
+ })
67
+
68
+ describe('listPresets', () => {
69
+ it('returns sorted preset names without .json extension', () => {
70
+ writePreset('zeta', {})
71
+ writePreset('alpha', {})
72
+ writePreset('beta', {})
73
+ expect(listPresets(dir)).toEqual(['alpha', 'beta', 'zeta'])
74
+ })
75
+
76
+ it('returns empty array for nonexistent directory', () => {
77
+ expect(listPresets(join(dir, 'does-not-exist'))).toEqual([])
78
+ })
79
+
80
+ it('ignores non-json files', () => {
81
+ writePreset('valid', {})
82
+ writeFileSync(join(dir, 'README.md'), 'hi')
83
+ expect(listPresets(dir)).toEqual(['valid'])
84
+ })
85
+ })
@@ -1,6 +1,8 @@
1
1
  import { execSync } from 'node:child_process'
2
2
  import qrcode from 'qrcode-terminal'
3
3
  import { DEFAULT_MQTT_HOST, DEFAULT_MQTT_PORT } from '../config.js'
4
+ import { getInstallSpec, getPluginName } from './package-info.js'
5
+ import { loadPreset, listPresets, type Preset } from './preset.js'
4
6
 
5
7
  const PAIR_API_BASE = process.env.PAIR_API_BASE ?? 'https://pair.folotoy.cn'
6
8
  const POLL_INTERVAL_MS = 3000
@@ -40,8 +42,9 @@ function installPlugin(): void {
40
42
  } catch {
41
43
  // ignore
42
44
  }
43
- console.log('Installing FoloToy plugin...')
44
- execSync('openclaw plugins install @folotoy/folotoy-openclaw-plugin', { stdio: 'inherit' })
45
+ const spec = getInstallSpec()
46
+ console.log(`Installing FoloToy plugin (${spec})...`)
47
+ execSync(`openclaw plugins install ${spec}`, { stdio: 'inherit' })
45
48
  }
46
49
 
47
50
  async function createSession(): Promise<CreateSessionResponse> {
@@ -95,7 +98,10 @@ function restartGateway(): void {
95
98
  }
96
99
  }
97
100
 
98
- function writeConfig(result: { toy_sn: string; toy_key: string; mqtt_host?: string; mqtt_port?: number }): void {
101
+ function writeConfig(
102
+ result: { toy_sn: string; toy_key: string; mqtt_host?: string; mqtt_port?: number },
103
+ preset: Preset = {},
104
+ ): void {
99
105
  execSync(`openclaw config set channels.folotoy.flow direct`, { stdio: 'pipe' })
100
106
  execSync(`openclaw config set channels.folotoy.toy_sn ${result.toy_sn}`, { stdio: 'pipe' })
101
107
  execSync(`openclaw config set channels.folotoy.toy_key ${result.toy_key}`, { stdio: 'pipe' })
@@ -104,19 +110,51 @@ function writeConfig(result: { toy_sn: string; toy_key: string; mqtt_host?: stri
104
110
  const mqttPort = result.mqtt_port ?? DEFAULT_MQTT_PORT
105
111
  execSync(`openclaw config set channels.folotoy.mqtt_host ${mqttHost}`, { stdio: 'pipe' })
106
112
  execSync(`openclaw config set channels.folotoy.mqtt_port ${mqttPort}`, { stdio: 'pipe' })
113
+
114
+ for (const [key, value] of Object.entries(preset)) {
115
+ execSync(`openclaw config set channels.folotoy.${key} ${value}`, { stdio: 'pipe' })
116
+ }
117
+ }
118
+
119
+ function parsePresetArg(argv: readonly string[]): string | undefined {
120
+ for (let i = 0; i < argv.length; i++) {
121
+ const arg = argv[i]
122
+ if (arg === '--preset') {
123
+ const value = argv[i + 1]
124
+ if (!value || value.startsWith('--')) {
125
+ throw new Error('--preset requires a name (e.g. --preset single-soothing)')
126
+ }
127
+ return value
128
+ }
129
+ if (arg && arg.startsWith('--preset=')) {
130
+ return arg.slice('--preset='.length)
131
+ }
132
+ }
133
+ return undefined
107
134
  }
108
135
 
109
136
  // ── Main ───────────────────────────────────────────────
110
137
 
111
138
  async function main() {
112
- const command = process.argv[2]
139
+ const argv = process.argv.slice(2)
140
+ const command = argv[0]
113
141
 
114
142
  if (command !== 'install') {
115
- console.log('Usage: npx @folotoy/folotoy-openclaw-plugin install')
143
+ const presets = listPresets()
144
+ console.log(`Usage: npx ${getPluginName()} install [--preset <name>]`)
145
+ if (presets.length) console.log(`Available presets: ${presets.join(', ')}`)
116
146
  process.exit(command ? 1 : 0)
117
147
  }
118
148
 
149
+ // Resolve preset before any side effects (pairing, plugin install) so a bad
150
+ // preset name fails fast without making the user scan a QR.
151
+ const presetName = parsePresetArg(argv.slice(1))
152
+ const preset: Preset = presetName ? loadPreset(presetName) : {}
153
+
119
154
  console.log('🧸 FoloToy OpenClaw Plugin Installer\n')
155
+ if (presetName) {
156
+ console.log(`Using preset: ${presetName} → ${JSON.stringify(preset)}\n`)
157
+ }
120
158
 
121
159
  // Step 1: check prerequisites
122
160
  console.log('Checking openclaw...')
@@ -140,7 +178,7 @@ async function main() {
140
178
 
141
179
  // Step 6: write config
142
180
  console.log('\nWriting configuration...')
143
- writeConfig(result)
181
+ writeConfig(result, preset)
144
182
 
145
183
  // Step 7: restart gateway
146
184
  console.log('\nRestarting gateway...')
@@ -0,0 +1,48 @@
1
+ import { existsSync, readFileSync } from 'node:fs'
2
+ import { dirname, join } from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
4
+
5
+ export function findPackageRoot(): string {
6
+ let dir = dirname(fileURLToPath(import.meta.url))
7
+ while (true) {
8
+ if (existsSync(join(dir, 'package.json'))) return dir
9
+ const parent = dirname(dir)
10
+ if (parent === dir) throw new Error('package.json not found while resolving package root')
11
+ dir = parent
12
+ }
13
+ }
14
+
15
+ type PackageInfo = { name: string; version: string }
16
+
17
+ let cached: PackageInfo | undefined
18
+
19
+ function readPackageInfo(): PackageInfo {
20
+ if (cached) return cached
21
+ const pkg = JSON.parse(
22
+ readFileSync(join(findPackageRoot(), 'package.json'), 'utf8'),
23
+ ) as { name?: unknown; version?: unknown }
24
+ if (typeof pkg.name !== 'string' || typeof pkg.version !== 'string') {
25
+ throw new Error('package.json is missing name or version')
26
+ }
27
+ cached = { name: pkg.name, version: pkg.version }
28
+ return cached
29
+ }
30
+
31
+ export function getPluginName(): string {
32
+ return readPackageInfo().name
33
+ }
34
+
35
+ export function getPluginVersion(): string {
36
+ return readPackageInfo().version
37
+ }
38
+
39
+ /**
40
+ * Returns the npm spec string `<name>@<version>` to pass to
41
+ * `openclaw plugins install`. Pinning the exact version prevents OpenClaw
42
+ * from rejecting the install when `latest` happens to point at a prerelease
43
+ * — without this, `openclaw plugins install <bare-name>` resolves through
44
+ * the `latest` dist-tag and refuses prereleases for safety.
45
+ */
46
+ export function getInstallSpec(): string {
47
+ return `${getPluginName()}@${getPluginVersion()}`
48
+ }
@@ -0,0 +1,54 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs'
2
+ import { join } from 'node:path'
3
+ import { findPackageRoot } from './package-info.js'
4
+
5
+ export const PRESET_WHITELIST = ['soothing_loop_enabled'] as const
6
+ export type PresetKey = (typeof PRESET_WHITELIST)[number]
7
+ export type Preset = Partial<Record<PresetKey, boolean>>
8
+
9
+ function presetDir(): string {
10
+ return join(findPackageRoot(), 'src', 'presets')
11
+ }
12
+
13
+ export function listPresets(dir: string = presetDir()): string[] {
14
+ if (!existsSync(dir)) return []
15
+ return readdirSync(dir)
16
+ .filter((f) => f.endsWith('.json'))
17
+ .map((f) => f.slice(0, -'.json'.length))
18
+ .sort()
19
+ }
20
+
21
+ export function loadPreset(name: string, dir: string = presetDir()): Preset {
22
+ const file = join(dir, `${name}.json`)
23
+ if (!existsSync(file)) {
24
+ const available = listPresets(dir)
25
+ throw new Error(
26
+ `Preset "${name}" not found. Available: ${available.length ? available.join(', ') : '(none)'}`,
27
+ )
28
+ }
29
+
30
+ let parsed: unknown
31
+ try {
32
+ parsed = JSON.parse(readFileSync(file, 'utf8'))
33
+ } catch (err) {
34
+ throw new Error(`Preset "${name}" is not valid JSON: ${(err as Error).message}`)
35
+ }
36
+
37
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
38
+ throw new Error(`Preset "${name}" must be a JSON object`)
39
+ }
40
+
41
+ const allowed = PRESET_WHITELIST as readonly string[]
42
+ const result: Preset = {}
43
+ for (const [key, value] of Object.entries(parsed as Record<string, unknown>)) {
44
+ if (!allowed.includes(key)) {
45
+ throw new Error(`Preset "${name}" has unknown key "${key}". Allowed: ${PRESET_WHITELIST.join(', ')}`)
46
+ }
47
+ if (typeof value !== 'boolean') {
48
+ throw new Error(`Preset "${name}" key "${key}" must be a boolean (got ${typeof value})`)
49
+ }
50
+ result[key as PresetKey] = value
51
+ }
52
+
53
+ return result
54
+ }
package/src/config.ts CHANGED
@@ -34,19 +34,17 @@ export type FlatChannelConfig = {
34
34
  sentence_split_delimiters?: string
35
35
  soothing_loop_enabled?: boolean
36
36
  soothing_loop_interval_ms?: number
37
- soothing_loop_max_count?: number
38
37
  }
39
38
 
40
39
  export const DEFAULT_API_URL = 'https://api.folotoy.cn'
41
- export const DEFAULT_MQTT_HOST = process.env.FOLOTOY_MQTT_HOST ?? 'f.qrc92.cn'
40
+ export const DEFAULT_MQTT_HOST = process.env.FOLOTOY_MQTT_HOST ?? 'f.folotoy.cn'
42
41
  export const DEFAULT_MQTT_PORT = 1883
43
42
  export const DEFAULT_SUMMARY_ENABLED = true
44
43
  export const DEFAULT_SUMMARY_MAX_CHARS = 200
45
44
  export const DEFAULT_SENTENCE_SPLIT_ENABLED = true
46
45
  export const DEFAULT_SENTENCE_SPLIT_DELIMITERS = '!。?;!.?;~'
47
46
  export const DEFAULT_SOOTHING_LOOP_ENABLED = true
48
- export const DEFAULT_SOOTHING_LOOP_INTERVAL_MS = 200
49
- export const DEFAULT_SOOTHING_LOOP_MAX_COUNT = 3
47
+ export const DEFAULT_SOOTHING_LOOP_INTERVAL_MS = 3000
50
48
 
51
49
  export function flatToPluginConfig(flat: FlatChannelConfig): PluginConfig {
52
50
  const flow = flat.flow ?? 'direct'
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@ import type { OpenClawPluginApi, ChannelPlugin, PluginRuntime } from 'openclaw/p
2
2
  import { resolveCredentials, createMqttClient, buildInboundTopic, buildOutboundTopic, buildNotificationTopic } from './mqtt.js'
3
3
  import { createSoothingPicker } from './soothing.js'
4
4
  import { stripMarkdown } from './strip-markdown.js'
5
- import { DEFAULT_MQTT_HOST, DEFAULT_MQTT_PORT, DEFAULT_SUMMARY_ENABLED, DEFAULT_SUMMARY_MAX_CHARS, DEFAULT_SENTENCE_SPLIT_ENABLED, DEFAULT_SENTENCE_SPLIT_DELIMITERS, DEFAULT_SOOTHING_LOOP_ENABLED, DEFAULT_SOOTHING_LOOP_INTERVAL_MS, DEFAULT_SOOTHING_LOOP_MAX_COUNT, flatToPluginConfig } from './config.js'
5
+ import { DEFAULT_MQTT_HOST, DEFAULT_MQTT_PORT, DEFAULT_SUMMARY_ENABLED, DEFAULT_SUMMARY_MAX_CHARS, DEFAULT_SENTENCE_SPLIT_ENABLED, DEFAULT_SENTENCE_SPLIT_DELIMITERS, DEFAULT_SOOTHING_LOOP_ENABLED, DEFAULT_SOOTHING_LOOP_INTERVAL_MS, flatToPluginConfig } from './config.js'
6
6
  import type { FlatChannelConfig } from './config.js'
7
7
  import type { MqttClient } from 'mqtt'
8
8
 
@@ -59,7 +59,6 @@ const folotoyChannel: ChannelPlugin<FlatChannelConfig> = {
59
59
  sentence_split_delimiters: { type: 'string', default: DEFAULT_SENTENCE_SPLIT_DELIMITERS },
60
60
  soothing_loop_enabled: { type: 'boolean', default: DEFAULT_SOOTHING_LOOP_ENABLED },
61
61
  soothing_loop_interval_ms: { type: 'number', default: DEFAULT_SOOTHING_LOOP_INTERVAL_MS },
62
- soothing_loop_max_count: { type: 'number', default: DEFAULT_SOOTHING_LOOP_MAX_COUNT },
63
62
  },
64
63
  },
65
64
  uiHints: {
@@ -76,7 +75,6 @@ const folotoyChannel: ChannelPlugin<FlatChannelConfig> = {
76
75
  sentence_split_delimiters: { label: 'Sentence Delimiters' },
77
76
  soothing_loop_enabled: { label: 'Enable Soothing Loop' },
78
77
  soothing_loop_interval_ms: { label: 'Soothing Loop Interval (ms)' },
79
- soothing_loop_max_count: { label: 'Soothing Loop Max Count' },
80
78
  },
81
79
  },
82
80
  config: {
@@ -130,7 +128,6 @@ const folotoyChannel: ChannelPlugin<FlatChannelConfig> = {
130
128
  const sentenceSplitDelimiters = account.sentence_split_delimiters ?? DEFAULT_SENTENCE_SPLIT_DELIMITERS
131
129
  const soothingLoopEnabled = account.soothing_loop_enabled ?? DEFAULT_SOOTHING_LOOP_ENABLED
132
130
  const soothingLoopIntervalMs = account.soothing_loop_interval_ms ?? DEFAULT_SOOTHING_LOOP_INTERVAL_MS
133
- const soothingLoopMaxCount = account.soothing_loop_max_count ?? DEFAULT_SOOTHING_LOOP_MAX_COUNT
134
131
 
135
132
  client.on('message', (_topic, payload) => {
136
133
  let msg: InboundMessage
@@ -189,31 +186,34 @@ const folotoyChannel: ChannelPlugin<FlatChannelConfig> = {
189
186
  let firstSentenceFlushed = false
190
187
  let llmStarted = false
191
188
 
192
- // Send soothing replies while waiting for the LLM to start responding.
193
- // Once any LLM chunk arrives, stop immediately. Max 5 soothing messages.
194
- let soothingTimer: ReturnType<typeof setTimeout> | null = null
195
- let soothingCount = 0
189
+ // Soothing loop: check every 200ms if LLM has started responding.
190
+ // If not, send a soothing reply at a pace matching TTS playback
191
+ // (controlled by soothingLoopIntervalMs). Keeps running until LLM
192
+ // returns its first chunk — no fixed max count.
193
+ let soothingCheckTimer: ReturnType<typeof setInterval> | null = null
194
+ let lastSoothingSentAt = 0
196
195
  const stopSoothingLoop = () => {
197
- if (soothingTimer) { clearTimeout(soothingTimer); soothingTimer = null }
196
+ if (soothingCheckTimer) { clearInterval(soothingCheckTimer); soothingCheckTimer = null }
198
197
  }
199
- const resetSoothingTimer = () => {
200
- if (!soothingLoopEnabled || llmStarted || soothingCount >= soothingLoopMaxCount) return
201
- if (soothingTimer) clearTimeout(soothingTimer)
202
- soothingTimer = setTimeout(() => {
203
- if (llmStarted || soothingCount >= soothingLoopMaxCount) return
204
- soothingCount++
205
- order++
206
- const extraAck: OutboundMessage = {
207
- msgId,
208
- identifier: 'chat_output',
209
- outParams: { content: soothingPick(), recording_id, order, is_finished: false },
198
+ if (soothingLoopEnabled) {
199
+ soothingCheckTimer = setInterval(() => {
200
+ if (llmStarted) {
201
+ stopSoothingLoop()
202
+ return
203
+ }
204
+ const now = Date.now()
205
+ if (now - lastSoothingSentAt >= soothingLoopIntervalMs) {
206
+ lastSoothingSentAt = now
207
+ order++
208
+ const extraAck: OutboundMessage = {
209
+ msgId,
210
+ identifier: 'chat_output',
211
+ outParams: { content: soothingPick(), recording_id, order, is_finished: false },
212
+ }
213
+ client.publish(outboundTopic, JSON.stringify(extraAck))
210
214
  }
211
- client.publish(outboundTopic, JSON.stringify(extraAck))
212
- // Restart timer in case LLM stays silent even longer
213
- resetSoothingTimer()
214
- }, soothingLoopIntervalMs)
215
+ }, 200)
215
216
  }
216
- resetSoothingTimer()
217
217
 
218
218
  // First sentence: split purely by punctuation (fast first response).
219
219
  // Subsequent sentences: require a minimum length that grows with each
@@ -347,7 +347,7 @@ const folotoyChannel: ChannelPlugin<FlatChannelConfig> = {
347
347
  client.publish(outboundTopic, JSON.stringify(outMsg))
348
348
  }
349
349
  } finally {
350
- if (soothingTimer) { clearTimeout(soothingTimer); soothingTimer = null }
350
+ stopSoothingLoop()
351
351
  order++
352
352
  const finishMsg: OutboundMessage = {
353
353
  msgId,
@@ -0,0 +1,3 @@
1
+ {
2
+ "soothing_loop_enabled": false
3
+ }