@yoooclaw/phone-notifications 1.11.4 → 1.11.6

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.cjs CHANGED
@@ -251,6 +251,18 @@ function writeDotEnv(key, value) {
251
251
  }
252
252
  (0, import_node_fs7.writeFileSync)(path2, lines.join("\n"), "utf-8");
253
253
  }
254
+ function buildEnvUrls(host) {
255
+ const https = `https://${host}`;
256
+ const wss = `wss://${host}`;
257
+ return {
258
+ lightApiUrl: `${https}/api/message/tob/sendMessage`,
259
+ relayTunnelUrl: `${wss}/message/messages/ws/plugin`,
260
+ appNameMapUrl: `${https}/api/application-config/app-package/config-all`,
261
+ modelProxyLongRecordingSubmitTaskUrl: `${https}/api/model-proxy/long-recording/submit-task`,
262
+ modelProxyLongRecordingQueryTaskResultBaseUrl: `${https}/api/model-proxy/long-recording/query-task-result`,
263
+ accountFileDeleteUrl: `${https}/api/account/file/delete`
264
+ };
265
+ }
254
266
  function readDotEnv() {
255
267
  const path2 = resolveStateFile(".env");
256
268
  if (!(0, import_node_fs7.existsSync)(path2)) return {};
@@ -290,7 +302,7 @@ function getEnvUrls(env) {
290
302
  function getAvailableEnvs() {
291
303
  return Object.keys(ENV_CONFIG);
292
304
  }
293
- var import_node_fs7, import_node_path6, ENV_CONFIG, VALID_ENVS;
305
+ var import_node_fs7, import_node_path6, ENV_HOSTS, ENV_CONFIG, VALID_ENVS;
294
306
  var init_env = __esm({
295
307
  "src/env.ts"() {
296
308
  "use strict";
@@ -298,31 +310,15 @@ var init_env = __esm({
298
310
  import_node_path6 = require("path");
299
311
  init_credentials();
300
312
  init_host();
313
+ ENV_HOSTS = {
314
+ development: "openclaw-service-dev.yoooclaw.com",
315
+ test: "openclaw-service-test.yoooclaw.com",
316
+ production: "openclaw-service.yoooclaw.com"
317
+ };
301
318
  ENV_CONFIG = {
302
- development: {
303
- lightApiUrl: "https://openclaw-service-dev.yoooclaw.com/api/message/tob/sendMessage",
304
- relayTunnelUrl: "wss://openclaw-service-dev.yoooclaw.com/message/messages/ws/plugin",
305
- appNameMapUrl: "https://openclaw-service-dev.yoooclaw.com/api/application-config/app-package/config-all",
306
- modelProxyLongRecordingSubmitTaskUrl: "https://openclaw-service-dev.yoooclaw.com/api/model-proxy/long-recording/submit-task",
307
- modelProxyLongRecordingQueryTaskResultBaseUrl: "https://openclaw-service-dev.yoooclaw.com/api/model-proxy/long-recording/query-task-result",
308
- accountFileDeleteUrl: "https://openclaw-service-dev.yoooclaw.com/api/account/file/delete"
309
- },
310
- test: {
311
- lightApiUrl: "https://openclaw-service-test.yoooclaw.com/api/message/tob/sendMessage",
312
- relayTunnelUrl: "wss://openclaw-service-test.yoooclaw.com/message/messages/ws/plugin",
313
- appNameMapUrl: "https://openclaw-service-test.yoooclaw.com/api/application-config/app-package/config-all",
314
- modelProxyLongRecordingSubmitTaskUrl: "https://openclaw-service-test.yoooclaw.com/api/model-proxy/long-recording/submit-task",
315
- modelProxyLongRecordingQueryTaskResultBaseUrl: "https://openclaw-service-test.yoooclaw.com/api/model-proxy/long-recording/query-task-result",
316
- accountFileDeleteUrl: "https://openclaw-service-test.yoooclaw.com/api/account/file/delete"
317
- },
318
- production: {
319
- lightApiUrl: "https://openclaw-service-prod.yoooclaw.com/api/message/tob/sendMessage",
320
- relayTunnelUrl: "wss://openclaw-service-prod.yoooclaw.com/message/messages/ws/plugin",
321
- appNameMapUrl: "https://openclaw-service-prod.yoooclaw.com/api/application-config/app-package/config-all",
322
- modelProxyLongRecordingSubmitTaskUrl: "https://openclaw-service-prod.yoooclaw.com/api/model-proxy/long-recording/submit-task",
323
- modelProxyLongRecordingQueryTaskResultBaseUrl: "https://openclaw-service-prod.yoooclaw.com/api/model-proxy/long-recording/query-task-result",
324
- accountFileDeleteUrl: "https://openclaw-service-prod.yoooclaw.com/api/account/file/delete"
325
- }
319
+ development: buildEnvUrls(ENV_HOSTS.development),
320
+ test: buildEnvUrls(ENV_HOSTS.test),
321
+ production: buildEnvUrls(ENV_HOSTS.production)
326
322
  };
327
323
  VALID_ENVS = new Set(Object.keys(ENV_CONFIG));
328
324
  }
@@ -5578,7 +5574,7 @@ function readBuildInjectedVersion() {
5578
5574
  if (false) {
5579
5575
  return void 0;
5580
5576
  }
5581
- const version = "1.11.4".trim();
5577
+ const version = "1.11.6".trim();
5582
5578
  return version || void 0;
5583
5579
  }
5584
5580
  function readPluginVersionFromPackageJson() {
@@ -7215,10 +7211,21 @@ var InlineLightRuleEvaluator = class {
7215
7211
  */
7216
7212
  async evaluate(notifications) {
7217
7213
  if (notifications.length === 0) return true;
7214
+ this.reloadRegistry("before evaluation");
7218
7215
  const rules = this.registry.getEnabled();
7219
- if (rules.length === 0) return true;
7216
+ if (rules.length === 0) {
7217
+ this.logger.info(
7218
+ `lightrules: no enabled rules (notifications=${notifications.length})`
7219
+ );
7220
+ return true;
7221
+ }
7220
7222
  const matches = await this.invoker.matchNotifications(notifications, rules);
7221
- if (matches === null) return false;
7223
+ if (matches === null) {
7224
+ this.logger.warn(
7225
+ `lightrules: match failed (notifications=${notifications.length}, rules=${rules.length})`
7226
+ );
7227
+ return false;
7228
+ }
7222
7229
  if (matches.length === 0) {
7223
7230
  this.logger.info(
7224
7231
  `lightrules: 0 matches (notifications=${notifications.length}, rules=${rules.length})`
@@ -7226,12 +7233,19 @@ var InlineLightRuleEvaluator = class {
7226
7233
  return true;
7227
7234
  }
7228
7235
  const firedRules = /* @__PURE__ */ new Set();
7236
+ this.reloadRegistry("before triggering");
7229
7237
  for (const match of matches) {
7230
7238
  if (firedRules.has(match.ruleName)) continue;
7231
7239
  const rule = this.registry.get(match.ruleName);
7232
7240
  if (!rule) {
7233
7241
  this.logger.warn(
7234
- `lightrules: matched rule '${match.ruleName}' not found in registry`
7242
+ `lightrules: matched rule '${match.ruleName}' skipped - not found after reload`
7243
+ );
7244
+ continue;
7245
+ }
7246
+ if (!rule.enabled) {
7247
+ this.logger.info(
7248
+ `lightrules: matched rule '${match.ruleName}' skipped - disabled after reload`
7235
7249
  );
7236
7250
  continue;
7237
7251
  }
@@ -7244,6 +7258,15 @@ var InlineLightRuleEvaluator = class {
7244
7258
  );
7245
7259
  return true;
7246
7260
  }
7261
+ reloadRegistry(stage) {
7262
+ try {
7263
+ this.registry.reload();
7264
+ } catch (err2) {
7265
+ this.logger.warn(
7266
+ `lightrules: registry reload failed ${stage}: ${err2?.message ?? err2}`
7267
+ );
7268
+ }
7269
+ }
7247
7270
  async triggerLight(rule, notification) {
7248
7271
  let apiKey;
7249
7272
  try {
@@ -7302,6 +7325,74 @@ function summarizeContent(content) {
7302
7325
  return `${trimmed.slice(0, REASON_CONTENT_MAX)}\u2026`;
7303
7326
  }
7304
7327
 
7328
+ // src/light-rules/evaluation-scheduler.ts
7329
+ var DEFAULT_LIGHT_RULE_EVALUATION_DEBOUNCE_MS = 1e3;
7330
+ var LightRuleEvaluationScheduler = class {
7331
+ evaluator;
7332
+ logger;
7333
+ debounceMs;
7334
+ pending = [];
7335
+ timer = null;
7336
+ running = false;
7337
+ flushRequestedWhileRunning = false;
7338
+ constructor(deps) {
7339
+ this.evaluator = deps.evaluator;
7340
+ this.logger = deps.logger;
7341
+ const debounceMs = deps.options?.debounceMs ?? DEFAULT_LIGHT_RULE_EVALUATION_DEBOUNCE_MS;
7342
+ this.debounceMs = Number.isFinite(debounceMs) && debounceMs >= 0 ? debounceMs : DEFAULT_LIGHT_RULE_EVALUATION_DEBOUNCE_MS;
7343
+ }
7344
+ enqueue(notifications) {
7345
+ if (notifications.length === 0) return;
7346
+ this.pending.push(...notifications);
7347
+ this.scheduleFlush();
7348
+ }
7349
+ scheduleFlush() {
7350
+ if (this.timer !== null) return;
7351
+ this.timer = setTimeout(() => {
7352
+ this.timer = null;
7353
+ void this.drain().catch((err2) => {
7354
+ this.logger.warn(
7355
+ `lightrules: scheduled evaluation failed: ${err2?.message ?? err2}`
7356
+ );
7357
+ });
7358
+ }, this.debounceMs);
7359
+ const maybeNodeTimer = this.timer;
7360
+ maybeNodeTimer.unref?.();
7361
+ }
7362
+ async drain() {
7363
+ if (this.running) {
7364
+ this.flushRequestedWhileRunning = true;
7365
+ return;
7366
+ }
7367
+ const batch = this.pending.splice(0);
7368
+ if (batch.length === 0) return;
7369
+ this.running = true;
7370
+ try {
7371
+ await this.evaluator.evaluate(batch);
7372
+ } catch (err2) {
7373
+ this.logger.warn(
7374
+ `lightrules: evaluation failed (notifications=${batch.length}): ${err2?.message ?? err2}`
7375
+ );
7376
+ } finally {
7377
+ this.running = false;
7378
+ if (this.pending.length > 0) {
7379
+ if (this.flushRequestedWhileRunning) {
7380
+ this.flushRequestedWhileRunning = false;
7381
+ void this.drain().catch((err2) => {
7382
+ this.logger.warn(
7383
+ `lightrules: queued evaluation failed: ${err2?.message ?? err2}`
7384
+ );
7385
+ });
7386
+ } else {
7387
+ this.scheduleFlush();
7388
+ }
7389
+ } else {
7390
+ this.flushRequestedWhileRunning = false;
7391
+ }
7392
+ }
7393
+ }
7394
+ };
7395
+
7305
7396
  // src/light-rules/pi-invoker.ts
7306
7397
  var import_agent_runtime = require("openclaw/plugin-sdk/agent-runtime");
7307
7398
  var DEFAULT_PROVIDER = "anthropic";
@@ -7325,7 +7416,16 @@ var PiAiInvoker = class {
7325
7416
  */
7326
7417
  async matchNotifications(notifications, rules) {
7327
7418
  if (notifications.length === 0 || rules.length === 0) return [];
7328
- const { label, prepared } = await this.prepareCompletionModel();
7419
+ let label;
7420
+ let prepared;
7421
+ try {
7422
+ ({ label, prepared } = await this.prepareCompletionModel());
7423
+ } catch (err2) {
7424
+ this.logger.warn(
7425
+ `PiAiInvoker: prepare failed: ${err2?.message ?? String(err2)}`
7426
+ );
7427
+ return null;
7428
+ }
7329
7429
  if ("error" in prepared) {
7330
7430
  this.logger.warn(
7331
7431
  `PiAiInvoker: prepare ${label} failed: ${prepared.error}`
@@ -11203,6 +11303,12 @@ var RecordingStorage = class {
11203
11303
  if (typeof entry.lastError === "string" && entry.lastError.trim()) {
11204
11304
  compacted.lastError = entry.lastError.trim();
11205
11305
  }
11306
+ if (compacted.status === "transcribing") {
11307
+ compacted.status = "transcribe_failed";
11308
+ compacted.lastError = compacted.lastError ?? "\u8F6C\u5199\u4EFB\u52A1\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u8F6C\u5199";
11309
+ compacted.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11310
+ needsRewrite = true;
11311
+ }
11206
11312
  return compacted;
11207
11313
  });
11208
11314
  const hadLargeFields = raw.recordings.some(
@@ -11545,20 +11651,27 @@ async function triggerTranscription(recordingId, storage, asrConfig, logger, opt
11545
11651
  storage.setLastError(recordingId, void 0);
11546
11652
  emitRecordingStatus(recordingId, storage, logger, options.notifyStatus);
11547
11653
  const audioFilePath = storage.getAudioFilePath(recordingId);
11548
- const result = await runTranscriptionWorkflow({
11549
- audioFilePath,
11550
- audioOssUrl: entry.metadata.oss_audio_url,
11551
- config: asrConfig,
11552
- markers: entry.metadata.markers ?? [],
11553
- recordingName: entry.metadata.name,
11554
- durationSec: entry.metadata.duration_sec,
11555
- createdAt: entry.metadata.created_at,
11556
- transcriptDataDir: storage.getTranscriptDataDir(),
11557
- transcriptsDir: storage.getTranscriptsDir(),
11558
- summariesDir: storage.getSummariesDir(),
11559
- recordingId,
11560
- logger
11561
- });
11654
+ let result;
11655
+ try {
11656
+ result = await runTranscriptionWorkflow({
11657
+ audioFilePath,
11658
+ audioOssUrl: entry.metadata.oss_audio_url,
11659
+ config: asrConfig,
11660
+ markers: entry.metadata.markers ?? [],
11661
+ recordingName: entry.metadata.name,
11662
+ durationSec: entry.metadata.duration_sec,
11663
+ createdAt: entry.metadata.created_at,
11664
+ transcriptDataDir: storage.getTranscriptDataDir(),
11665
+ transcriptsDir: storage.getTranscriptsDir(),
11666
+ summariesDir: storage.getSummariesDir(),
11667
+ recordingId,
11668
+ logger
11669
+ });
11670
+ } catch (err2) {
11671
+ const error = `\u8F6C\u5199\u4EFB\u52A1\u5F02\u5E38: ${err2?.message ?? err2}`;
11672
+ logger.error(`[asr-trigger] ${error}: ${recordingId}`);
11673
+ result = { ok: false, error };
11674
+ }
11562
11675
  if (result.ok && result.transcriptFilename) {
11563
11676
  if (result.transcriptDataFilename) {
11564
11677
  storage.setTranscriptDataFile(recordingId, result.transcriptDataFilename);
@@ -11593,17 +11706,18 @@ async function triggerTranscription(recordingId, storage, asrConfig, logger, opt
11593
11706
  });
11594
11707
  }
11595
11708
  } else {
11709
+ const error = result.error ?? "ASR \u8F6C\u5199\u5931\u8D25";
11596
11710
  storage.updateStatus(recordingId, "transcribe_failed");
11597
- storage.setLastError(recordingId, result.error);
11711
+ storage.setLastError(recordingId, error);
11598
11712
  emitRecordingStatus(
11599
11713
  recordingId,
11600
11714
  storage,
11601
11715
  logger,
11602
11716
  options.notifyStatus,
11603
- result.error
11717
+ error
11604
11718
  );
11605
11719
  logger.error(
11606
- `[asr-trigger] \u8F6C\u5199\u5931\u8D25: ${recordingId}, error=${result.error}`
11720
+ `[asr-trigger] \u8F6C\u5199\u5931\u8D25: ${recordingId}, error=${error}`
11607
11721
  );
11608
11722
  }
11609
11723
  }
@@ -14077,6 +14191,10 @@ var index_default = {
14077
14191
  registry: lightRuleRegistry,
14078
14192
  invoker: lightRuleInvoker
14079
14193
  });
14194
+ const lightRuleEvaluationScheduler = new LightRuleEvaluationScheduler({
14195
+ evaluator: inlineLightRuleEvaluator,
14196
+ logger
14197
+ });
14080
14198
  registerStorageLifecycle({
14081
14199
  api,
14082
14200
  config,
@@ -14105,8 +14223,8 @@ var index_default = {
14105
14223
  filterNotifications,
14106
14224
  registerGatewayMethod: registerGatewayMethodWithBroadcastCapture,
14107
14225
  tunnelService,
14108
- onAfterIngest: (inserted) => {
14109
- void inlineLightRuleEvaluator.evaluate(inserted);
14226
+ onAfterIngest(inserted) {
14227
+ lightRuleEvaluationScheduler.enqueue(inserted);
14110
14228
  }
14111
14229
  });
14112
14230
  registerLightControlTool(api, logger);