@yoooclaw/phone-notifications 1.11.2-beta.2 → 1.11.2-beta.4
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 +190 -54
- package/dist/index.cjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -56,6 +56,19 @@ function expandUserPath(value) {
|
|
|
56
56
|
}
|
|
57
57
|
return value;
|
|
58
58
|
}
|
|
59
|
+
function detectHostKindFromPath(value) {
|
|
60
|
+
if (!value) {
|
|
61
|
+
return void 0;
|
|
62
|
+
}
|
|
63
|
+
const normalized = value.replace(/\\/g, "/").toLowerCase();
|
|
64
|
+
if (normalized.endsWith("/.qclaw") || normalized.includes("/.qclaw/") || normalized.endsWith("/.qclow") || normalized.includes("/.qclow/")) {
|
|
65
|
+
return "qclaw";
|
|
66
|
+
}
|
|
67
|
+
if (normalized.endsWith("/.openclaw") || normalized.includes("/.openclaw/")) {
|
|
68
|
+
return "openclaw";
|
|
69
|
+
}
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
59
72
|
function candidateMetaPaths() {
|
|
60
73
|
const home = homeDir();
|
|
61
74
|
return [
|
|
@@ -97,6 +110,22 @@ function hasOpenClawMarkers() {
|
|
|
97
110
|
(0, import_node_path4.join)(baseDir, "extensions")
|
|
98
111
|
].some((candidate) => (0, import_node_fs5.existsSync)(candidate));
|
|
99
112
|
}
|
|
113
|
+
function detectHostKind() {
|
|
114
|
+
if (trimToUndefined(process.env.QCLAW_STATE_DIR) || trimToUndefined(process.env.QCLAW_CONFIG_PATH) || trimToUndefined(process.env.QCLAW_HOME)) {
|
|
115
|
+
return "qclaw";
|
|
116
|
+
}
|
|
117
|
+
const pathHintKind = detectHostKindFromPath(resolveStateDirFromEnv()) ?? detectHostKindFromPath(resolveConfigPathFromEnv());
|
|
118
|
+
if (pathHintKind) {
|
|
119
|
+
return pathHintKind;
|
|
120
|
+
}
|
|
121
|
+
if (hasOpenClawMarkers()) {
|
|
122
|
+
return "openclaw";
|
|
123
|
+
}
|
|
124
|
+
if (loadQClawMeta()) {
|
|
125
|
+
return "qclaw";
|
|
126
|
+
}
|
|
127
|
+
return "openclaw";
|
|
128
|
+
}
|
|
100
129
|
function resolveStateDir() {
|
|
101
130
|
const envDir = resolveStateDirFromEnv();
|
|
102
131
|
if (envDir) {
|
|
@@ -233,11 +262,16 @@ function readDotEnv() {
|
|
|
233
262
|
})
|
|
234
263
|
);
|
|
235
264
|
}
|
|
265
|
+
function readPersistedEnvName() {
|
|
266
|
+
const fromDotEnv = readDotEnv()["PHONE_NOTIFICATIONS_ENV"]?.trim();
|
|
267
|
+
if (fromDotEnv && VALID_ENVS.has(fromDotEnv)) return fromDotEnv;
|
|
268
|
+
return void 0;
|
|
269
|
+
}
|
|
236
270
|
function loadEnvName() {
|
|
237
271
|
const fromEnvVar = process.env.PHONE_NOTIFICATIONS_ENV?.trim();
|
|
238
272
|
if (fromEnvVar && VALID_ENVS.has(fromEnvVar)) return fromEnvVar;
|
|
239
|
-
const fromDotEnv =
|
|
240
|
-
if (fromDotEnv
|
|
273
|
+
const fromDotEnv = readPersistedEnvName();
|
|
274
|
+
if (fromDotEnv) return fromDotEnv;
|
|
241
275
|
const { env } = readCredentials();
|
|
242
276
|
if (env && VALID_ENVS.has(env)) return env;
|
|
243
277
|
return "production";
|
|
@@ -265,13 +299,13 @@ var init_env = __esm({
|
|
|
265
299
|
init_credentials();
|
|
266
300
|
init_host();
|
|
267
301
|
ENV_CONFIG = {
|
|
268
|
-
|
|
269
|
-
lightApiUrl: "https://openclaw-service-
|
|
270
|
-
relayTunnelUrl: "wss://openclaw-service-
|
|
271
|
-
appNameMapUrl: "https://openclaw-service-
|
|
272
|
-
modelProxyLongRecordingSubmitTaskUrl: "https://openclaw-service-
|
|
273
|
-
modelProxyLongRecordingQueryTaskResultBaseUrl: "https://openclaw-service-
|
|
274
|
-
accountFileDeleteUrl: "https://openclaw-service-
|
|
302
|
+
test: {
|
|
303
|
+
lightApiUrl: "https://openclaw-service-test.yoooclaw.com/api/message/tob/sendMessage",
|
|
304
|
+
relayTunnelUrl: "wss://openclaw-service-test.yoooclaw.com/message/messages/ws/plugin",
|
|
305
|
+
appNameMapUrl: "https://openclaw-service-test.yoooclaw.com/api/application-config/app-package/config-all",
|
|
306
|
+
modelProxyLongRecordingSubmitTaskUrl: "https://openclaw-service-test.yoooclaw.com/api/model-proxy/long-recording/submit-task",
|
|
307
|
+
modelProxyLongRecordingQueryTaskResultBaseUrl: "https://openclaw-service-test.yoooclaw.com/api/model-proxy/long-recording/query-task-result",
|
|
308
|
+
accountFileDeleteUrl: "https://openclaw-service-test.yoooclaw.com/api/account/file/delete"
|
|
275
309
|
},
|
|
276
310
|
production: {
|
|
277
311
|
lightApiUrl: "https://openclaw-service.yoootek.com/api/message/tob/sendMessage",
|
|
@@ -692,7 +726,7 @@ function findWhisperBinary(dataDir, logger) {
|
|
|
692
726
|
for (const name of pathNames) {
|
|
693
727
|
try {
|
|
694
728
|
const cmd = (0, import_node_os4.platform)() === "win32" ? "where" : "which";
|
|
695
|
-
const result = (0,
|
|
729
|
+
const result = (0, import_node_child_process3.execSync)(`${cmd} ${name}`, { encoding: "utf-8", stdio: "pipe" }).trim();
|
|
696
730
|
if (result) {
|
|
697
731
|
logger.info(`[whisper-local] \u627E\u5230\u7CFB\u7EDF PATH \u4E8C\u8FDB\u5236: ${result}`);
|
|
698
732
|
return result.split("\n")[0].trim();
|
|
@@ -762,7 +796,7 @@ async function transcribeWithWhisperLocal(audioFilePath, localConfig, dataDir, l
|
|
|
762
796
|
const startMs = Date.now();
|
|
763
797
|
let result;
|
|
764
798
|
try {
|
|
765
|
-
result = (0,
|
|
799
|
+
result = (0, import_node_child_process3.spawnSync)(whisperBin, args, {
|
|
766
800
|
encoding: "utf-8",
|
|
767
801
|
timeout: 60 * 60 * 1e3,
|
|
768
802
|
// 1 小时超时(5 小时录音)
|
|
@@ -817,14 +851,14 @@ function getWhisperLocalStatus(dataDir, logger) {
|
|
|
817
851
|
}
|
|
818
852
|
function detectCuda(logger) {
|
|
819
853
|
try {
|
|
820
|
-
(0,
|
|
854
|
+
(0, import_node_child_process3.execSync)("nvidia-smi", { encoding: "utf-8", stdio: "pipe", timeout: 5e3 });
|
|
821
855
|
logger.info("[whisper-local] \u68C0\u6D4B\u5230 NVIDIA GPU (nvidia-smi)");
|
|
822
856
|
return true;
|
|
823
857
|
} catch {
|
|
824
858
|
}
|
|
825
859
|
if ((0, import_node_os4.platform)() === "linux") {
|
|
826
860
|
try {
|
|
827
|
-
const ldconfig = (0,
|
|
861
|
+
const ldconfig = (0, import_node_child_process3.execSync)("ldconfig -p 2>/dev/null | grep libcudart", {
|
|
828
862
|
encoding: "utf-8",
|
|
829
863
|
stdio: "pipe",
|
|
830
864
|
timeout: 5e3
|
|
@@ -841,7 +875,7 @@ function detectCuda(logger) {
|
|
|
841
875
|
function getAvailableMemoryGB(backend, logger) {
|
|
842
876
|
if (backend === "cuda") {
|
|
843
877
|
try {
|
|
844
|
-
const output2 = (0,
|
|
878
|
+
const output2 = (0, import_node_child_process3.execSync)(
|
|
845
879
|
"nvidia-smi --query-gpu=memory.free --format=csv,noheader,nounits",
|
|
846
880
|
{ encoding: "utf-8", stdio: "pipe", timeout: 5e3 }
|
|
847
881
|
);
|
|
@@ -889,7 +923,7 @@ function detectAudioFormat(filePath) {
|
|
|
889
923
|
}
|
|
890
924
|
function convertToWav(inputPath, outputPath, actualFmt, logger) {
|
|
891
925
|
try {
|
|
892
|
-
const ffmpegResult = (0,
|
|
926
|
+
const ffmpegResult = (0, import_node_child_process3.spawnSync)("ffmpeg", [
|
|
893
927
|
"-y",
|
|
894
928
|
"-i",
|
|
895
929
|
inputPath,
|
|
@@ -913,7 +947,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
|
|
|
913
947
|
}
|
|
914
948
|
if (actualFmt === ".ogg") {
|
|
915
949
|
try {
|
|
916
|
-
const opusResult = (0,
|
|
950
|
+
const opusResult = (0, import_node_child_process3.spawnSync)(
|
|
917
951
|
"opusdec",
|
|
918
952
|
["--rate", "16000", "--mono", inputPath, outputPath],
|
|
919
953
|
{ encoding: "utf-8", timeout: 12e4, stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -942,7 +976,7 @@ function convertToWav(inputPath, outputPath, actualFmt, logger) {
|
|
|
942
976
|
}
|
|
943
977
|
}
|
|
944
978
|
try {
|
|
945
|
-
const afResult = (0,
|
|
979
|
+
const afResult = (0, import_node_child_process3.spawnSync)("afconvert", [
|
|
946
980
|
"-f",
|
|
947
981
|
"WAVE",
|
|
948
982
|
"-d",
|
|
@@ -1070,11 +1104,11 @@ function formatBytes2(bytes) {
|
|
|
1070
1104
|
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
1071
1105
|
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;
|
|
1072
1106
|
}
|
|
1073
|
-
var
|
|
1107
|
+
var import_node_child_process3, import_node_fs25, import_node_path21, import_promises3, import_node_stream2, import_node_os4, WHISPER_MODELS_DIR, WHISPER_BIN_DIR, HF_MODEL_URL_TEMPLATE, MODELSCOPE_MODEL_URL_TEMPLATE, PROBE_TIMEOUT_MS, MODEL_FILENAMES, MODEL_DISK_SIZES;
|
|
1074
1108
|
var init_whisper_local = __esm({
|
|
1075
1109
|
"src/recording/whisper-local.ts"() {
|
|
1076
1110
|
"use strict";
|
|
1077
|
-
|
|
1111
|
+
import_node_child_process3 = require("child_process");
|
|
1078
1112
|
import_node_fs25 = require("fs");
|
|
1079
1113
|
import_node_path21 = require("path");
|
|
1080
1114
|
import_promises3 = require("stream/promises");
|
|
@@ -5438,7 +5472,7 @@ function readBuildInjectedVersion() {
|
|
|
5438
5472
|
if (false) {
|
|
5439
5473
|
return void 0;
|
|
5440
5474
|
}
|
|
5441
|
-
const version = "1.11.2-beta.
|
|
5475
|
+
const version = "1.11.2-beta.4".trim();
|
|
5442
5476
|
return version || void 0;
|
|
5443
5477
|
}
|
|
5444
5478
|
function readPluginVersionFromPackageJson() {
|
|
@@ -7309,7 +7343,7 @@ function resolveUpdateChannel(params) {
|
|
|
7309
7343
|
if (params.currentVersion.includes("-")) {
|
|
7310
7344
|
return "beta";
|
|
7311
7345
|
}
|
|
7312
|
-
return params.envName === "
|
|
7346
|
+
return params.envName === "test" ? "beta" : "latest";
|
|
7313
7347
|
}
|
|
7314
7348
|
|
|
7315
7349
|
// src/update/index.ts
|
|
@@ -8539,21 +8573,98 @@ function registerLogSearch(ntf, ctx) {
|
|
|
8539
8573
|
}
|
|
8540
8574
|
|
|
8541
8575
|
// src/cli/env.ts
|
|
8576
|
+
var import_node_child_process = require("child_process");
|
|
8542
8577
|
init_env();
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8578
|
+
init_host();
|
|
8579
|
+
var GATEWAY_RESTART_TIMEOUT_MS = 3e4;
|
|
8580
|
+
var NOOP_LOGGER = {
|
|
8581
|
+
info() {
|
|
8582
|
+
},
|
|
8583
|
+
warn() {
|
|
8584
|
+
},
|
|
8585
|
+
error() {
|
|
8586
|
+
}
|
|
8587
|
+
};
|
|
8588
|
+
function buildEnvShowPayload(deps = {}) {
|
|
8589
|
+
const persistedEnv = deps.readPersistedEnvName?.() ?? readPersistedEnvName();
|
|
8590
|
+
const env = persistedEnv ?? "production";
|
|
8591
|
+
const urls = getEnvUrls(env);
|
|
8592
|
+
return {
|
|
8593
|
+
ok: true,
|
|
8594
|
+
env,
|
|
8595
|
+
source: persistedEnv ? ".env" : "default",
|
|
8596
|
+
lightApiUrl: urls.lightApiUrl,
|
|
8597
|
+
relayTunnelUrl: urls.relayTunnelUrl,
|
|
8598
|
+
availableEnvs: getAvailableEnvs()
|
|
8599
|
+
};
|
|
8600
|
+
}
|
|
8601
|
+
function triggerGatewayReloadAfterEnvSwitch(deps = {}) {
|
|
8602
|
+
const scheduleRestart = deps.scheduleGatewayRestart ?? (() => scheduleGatewayRestart(NOOP_LOGGER));
|
|
8603
|
+
const scheduled = scheduleRestart();
|
|
8604
|
+
if (scheduled.scheduled) {
|
|
8605
|
+
return {
|
|
8606
|
+
attempted: true,
|
|
8549
8607
|
ok: true,
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8608
|
+
method: "signal",
|
|
8609
|
+
message: "\u5DF2\u81EA\u52A8\u89E6\u53D1 gateway \u8FDB\u7A0B\u5185\u91CD\u8F7D"
|
|
8610
|
+
};
|
|
8611
|
+
}
|
|
8612
|
+
const hostKind = deps.detectHostKind?.() ?? detectHostKind();
|
|
8613
|
+
if (hostKind === "qclaw") {
|
|
8614
|
+
return {
|
|
8615
|
+
attempted: false,
|
|
8616
|
+
ok: false,
|
|
8617
|
+
method: "skipped",
|
|
8618
|
+
message: "\u5F53\u524D\u5BBF\u4E3B\u4E3A QClaw\uFF0C\u8BF7\u91CD\u542F QClaw \u684C\u9762\u5E94\u7528\u540E\u4F7F\u73AF\u5883\u5207\u6362\u751F\u6548"
|
|
8619
|
+
};
|
|
8620
|
+
}
|
|
8621
|
+
const hostCli = deps.hostCli?.trim() || process.env.HOST_CLI?.trim() || "openclaw";
|
|
8622
|
+
const command = `${hostCli} gateway restart`;
|
|
8623
|
+
const run = deps.spawnSync ?? import_node_child_process.spawnSync;
|
|
8624
|
+
const result = run(hostCli, ["gateway", "restart"], {
|
|
8625
|
+
encoding: "utf-8",
|
|
8626
|
+
stdio: "pipe",
|
|
8627
|
+
timeout: GATEWAY_RESTART_TIMEOUT_MS
|
|
8555
8628
|
});
|
|
8556
|
-
|
|
8629
|
+
if (!result.error && result.status === 0) {
|
|
8630
|
+
return {
|
|
8631
|
+
attempted: true,
|
|
8632
|
+
ok: true,
|
|
8633
|
+
method: "cli",
|
|
8634
|
+
command,
|
|
8635
|
+
message: `\u5DF2\u81EA\u52A8\u89E6\u53D1 ${command}`
|
|
8636
|
+
};
|
|
8637
|
+
}
|
|
8638
|
+
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
8639
|
+
const errorMessage = result.error?.message?.trim();
|
|
8640
|
+
return {
|
|
8641
|
+
attempted: true,
|
|
8642
|
+
ok: false,
|
|
8643
|
+
method: "cli",
|
|
8644
|
+
command,
|
|
8645
|
+
message: `\u5DF2\u5207\u6362\u73AF\u5883\uFF0C\u4F46\u81EA\u52A8\u91CD\u8F7D\u672A\u5B8C\u6210\uFF0C\u8BF7\u624B\u52A8\u8FD0\u884C: ${command}`,
|
|
8646
|
+
detail: stderr || errorMessage || (typeof result.status === "number" ? `exit status=${result.status}` : void 0)
|
|
8647
|
+
};
|
|
8648
|
+
}
|
|
8649
|
+
function buildEnvSwitchPayload(envName, deps = {}) {
|
|
8650
|
+
saveEnvName(envName);
|
|
8651
|
+
const urls = getEnvUrls(envName);
|
|
8652
|
+
const reload = triggerGatewayReloadAfterEnvSwitch(deps);
|
|
8653
|
+
return {
|
|
8654
|
+
ok: true,
|
|
8655
|
+
message: reload.ok ? `\u5DF2\u5207\u6362\u5230 ${envName} \u73AF\u5883\uFF0C\u5E76\u5DF2\u89E6\u53D1\u91CD\u8F7D` : `\u5DF2\u5207\u6362\u5230 ${envName} \u73AF\u5883`,
|
|
8656
|
+
env: envName,
|
|
8657
|
+
lightApiUrl: urls.lightApiUrl,
|
|
8658
|
+
relayTunnelUrl: urls.relayTunnelUrl,
|
|
8659
|
+
reload
|
|
8660
|
+
};
|
|
8661
|
+
}
|
|
8662
|
+
function registerEnvCli(ntf, deps = {}) {
|
|
8663
|
+
const env = ntf.command("env").description("\u73AF\u5883\u7BA1\u7406\uFF08\u5207\u6362 test / production\uFF09");
|
|
8664
|
+
env.command("show").description("\u663E\u793A\u5F53\u524D\u73AF\u5883\u53CA\u5BF9\u5E94\u7684\u63A5\u53E3\u5730\u5740").action(() => {
|
|
8665
|
+
output(buildEnvShowPayload(deps));
|
|
8666
|
+
});
|
|
8667
|
+
env.command("switch <env>").description("\u5207\u6362\u73AF\u5883\uFF08test / production\uFF09").action((envName) => {
|
|
8557
8668
|
const available = getAvailableEnvs();
|
|
8558
8669
|
if (!available.includes(envName)) {
|
|
8559
8670
|
exitError(
|
|
@@ -8561,15 +8672,7 @@ function registerEnvCli(ntf) {
|
|
|
8561
8672
|
`\u65E0\u6548\u7684\u73AF\u5883\u540D\u79F0: ${envName}\uFF0C\u53EF\u9009\u503C: ${available.join(", ")}`
|
|
8562
8673
|
);
|
|
8563
8674
|
}
|
|
8564
|
-
|
|
8565
|
-
const urls = getEnvUrls(envName);
|
|
8566
|
-
output({
|
|
8567
|
-
ok: true,
|
|
8568
|
-
message: `\u5DF2\u5207\u6362\u5230 ${envName} \u73AF\u5883`,
|
|
8569
|
-
env: envName,
|
|
8570
|
-
lightApiUrl: urls.lightApiUrl,
|
|
8571
|
-
relayTunnelUrl: urls.relayTunnelUrl
|
|
8572
|
-
});
|
|
8675
|
+
output(buildEnvSwitchPayload(envName, deps));
|
|
8573
8676
|
});
|
|
8574
8677
|
}
|
|
8575
8678
|
|
|
@@ -8989,7 +9092,8 @@ function registerRecList(rec, ctx) {
|
|
|
8989
9092
|
has_audio: !!r.audioFile,
|
|
8990
9093
|
has_transcript: !!r.transcriptFile,
|
|
8991
9094
|
created_at: r.metadata.created_at,
|
|
8992
|
-
updated_at: r.updatedAt
|
|
9095
|
+
updated_at: r.updatedAt,
|
|
9096
|
+
error: r.lastError ?? null
|
|
8993
9097
|
}));
|
|
8994
9098
|
output({ ok: true, total: items.length, recordings: items });
|
|
8995
9099
|
});
|
|
@@ -9022,6 +9126,7 @@ function registerRecStatus(rec, ctx) {
|
|
|
9022
9126
|
transcriptFile: entry.transcriptFile ?? null,
|
|
9023
9127
|
summaryFile: entry.summaryFile ?? null,
|
|
9024
9128
|
title: entry.title ?? null,
|
|
9129
|
+
error: entry.lastError ?? null,
|
|
9025
9130
|
ingestedAt: entry.ingestedAt,
|
|
9026
9131
|
updatedAt: entry.updatedAt
|
|
9027
9132
|
}
|
|
@@ -9154,7 +9259,7 @@ function registerRecSetup(rec, ctx) {
|
|
|
9154
9259
|
}
|
|
9155
9260
|
|
|
9156
9261
|
// src/cli/update.ts
|
|
9157
|
-
var
|
|
9262
|
+
var import_node_child_process2 = require("child_process");
|
|
9158
9263
|
var import_node_fs20 = require("fs");
|
|
9159
9264
|
var import_node_path15 = require("path");
|
|
9160
9265
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
@@ -9229,7 +9334,7 @@ async function runUpdate(ctx, opts) {
|
|
|
9229
9334
|
process.exit(1);
|
|
9230
9335
|
}
|
|
9231
9336
|
const stateDir = ctx.stateDir ?? resolveStateDir();
|
|
9232
|
-
const result = (0,
|
|
9337
|
+
const result = (0, import_node_child_process2.spawnSync)(
|
|
9233
9338
|
process.execPath,
|
|
9234
9339
|
[tmpScript, "--version", latest, "--state-dir", stateDir],
|
|
9235
9340
|
{ stdio: "inherit" }
|
|
@@ -10010,7 +10115,8 @@ var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
|
|
|
10010
10115
|
["pending_oss_upload", /* @__PURE__ */ new Set(["uploading_oss"])],
|
|
10011
10116
|
["uploading_oss", /* @__PURE__ */ new Set(["oss_uploaded"])],
|
|
10012
10117
|
["oss_uploaded", /* @__PURE__ */ new Set(["syncing_openclaw"])],
|
|
10013
|
-
["syncing_openclaw", /* @__PURE__ */ new Set(["synced"])],
|
|
10118
|
+
["syncing_openclaw", /* @__PURE__ */ new Set(["synced", "sync_failed"])],
|
|
10119
|
+
["sync_failed", /* @__PURE__ */ new Set(["syncing_openclaw"])],
|
|
10014
10120
|
["synced", /* @__PURE__ */ new Set(["transcribing"])],
|
|
10015
10121
|
["transcribing", /* @__PURE__ */ new Set(["transcribed", "transcribe_failed"])],
|
|
10016
10122
|
["transcribe_failed", /* @__PURE__ */ new Set(["transcribing"])],
|
|
@@ -10168,7 +10274,7 @@ var RecordingStorage = class {
|
|
|
10168
10274
|
const existing = this.findById(id);
|
|
10169
10275
|
if (existing) {
|
|
10170
10276
|
const sameAudioUrl = existing.metadata.oss_audio_url === metadata.oss_audio_url;
|
|
10171
|
-
const canPreserveSyncState = sameAudioUrl && !!existing.audioFile && existing.status !== "syncing_openclaw";
|
|
10277
|
+
const canPreserveSyncState = sameAudioUrl && !!existing.audioFile && existing.status !== "syncing_openclaw" && existing.status !== "sync_failed";
|
|
10172
10278
|
if (canPreserveSyncState) {
|
|
10173
10279
|
existing.metadata = metadata;
|
|
10174
10280
|
existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -10193,6 +10299,7 @@ var RecordingStorage = class {
|
|
|
10193
10299
|
existing.transcriptFile = void 0;
|
|
10194
10300
|
existing.summaryFile = void 0;
|
|
10195
10301
|
existing.title = void 0;
|
|
10302
|
+
existing.lastError = void 0;
|
|
10196
10303
|
existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10197
10304
|
this.logger.info(`\u5F55\u97F3\u5143\u6570\u636E\u5DF2\u66F4\u65B0: ${id}`);
|
|
10198
10305
|
} else {
|
|
@@ -10297,6 +10404,16 @@ var RecordingStorage = class {
|
|
|
10297
10404
|
entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10298
10405
|
this.saveIndex();
|
|
10299
10406
|
}
|
|
10407
|
+
/**
|
|
10408
|
+
* 记录最近一次失败原因;传 undefined 表示清除错误
|
|
10409
|
+
*/
|
|
10410
|
+
setLastError(recordingId, error) {
|
|
10411
|
+
const entry = this.findById(recordingId);
|
|
10412
|
+
if (!entry) return;
|
|
10413
|
+
entry.lastError = error?.trim() || void 0;
|
|
10414
|
+
entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10415
|
+
this.saveIndex();
|
|
10416
|
+
}
|
|
10300
10417
|
/**
|
|
10301
10418
|
* 读取摘要文本
|
|
10302
10419
|
*/
|
|
@@ -10565,6 +10682,9 @@ var RecordingStorage = class {
|
|
|
10565
10682
|
needsRewrite = true;
|
|
10566
10683
|
}
|
|
10567
10684
|
}
|
|
10685
|
+
if (typeof entry.lastError === "string" && entry.lastError.trim()) {
|
|
10686
|
+
compacted.lastError = entry.lastError.trim();
|
|
10687
|
+
}
|
|
10568
10688
|
return compacted;
|
|
10569
10689
|
});
|
|
10570
10690
|
const hadLargeFields = raw.recordings.some(
|
|
@@ -10763,6 +10883,7 @@ function emitRecordingStatus(recordingId, storage, logger, notifyStatus, error,
|
|
|
10763
10883
|
return;
|
|
10764
10884
|
}
|
|
10765
10885
|
const title = extras?.title?.trim() || entry.title?.trim() || entry.metadata.name?.trim() || entry.id;
|
|
10886
|
+
const persistedError = entry.lastError?.trim() || void 0;
|
|
10766
10887
|
try {
|
|
10767
10888
|
notifyStatus({
|
|
10768
10889
|
recordingId: entry.id,
|
|
@@ -10775,7 +10896,7 @@ function emitRecordingStatus(recordingId, storage, logger, notifyStatus, error,
|
|
|
10775
10896
|
summary: extras?.summary,
|
|
10776
10897
|
title,
|
|
10777
10898
|
updatedAt: entry.updatedAt,
|
|
10778
|
-
error
|
|
10899
|
+
error: error ?? persistedError
|
|
10779
10900
|
});
|
|
10780
10901
|
} catch (err2) {
|
|
10781
10902
|
logger.error(
|
|
@@ -10802,6 +10923,8 @@ async function runRecordingSyncInBackground(metadata, recordingId, storage, asrC
|
|
|
10802
10923
|
if (!downloadResult.audio.ok) {
|
|
10803
10924
|
const error = `\u97F3\u9891\u4E0B\u8F7D\u5931\u8D25: ${downloadResult.audio.error}`;
|
|
10804
10925
|
logger.error(`[recording-sync] ${error}: ${recordingId}`);
|
|
10926
|
+
storage.updateStatus(recordingId, "sync_failed");
|
|
10927
|
+
storage.setLastError(recordingId, error);
|
|
10805
10928
|
emitRecordingStatus(
|
|
10806
10929
|
recordingId,
|
|
10807
10930
|
storage,
|
|
@@ -10811,6 +10934,7 @@ async function runRecordingSyncInBackground(metadata, recordingId, storage, asrC
|
|
|
10811
10934
|
);
|
|
10812
10935
|
return;
|
|
10813
10936
|
}
|
|
10937
|
+
storage.setLastError(recordingId, void 0);
|
|
10814
10938
|
storage.setAudioFile(
|
|
10815
10939
|
recordingId,
|
|
10816
10940
|
storage.buildAudioFilename(recordingId, metadata.oss_audio_url)
|
|
@@ -10833,7 +10957,7 @@ async function runRecordingSyncInBackground(metadata, recordingId, storage, asrC
|
|
|
10833
10957
|
}
|
|
10834
10958
|
async function handleRecordingSync(recordingId, metadata, storage, asrConfig, logger, options = {}) {
|
|
10835
10959
|
const existing = storage.findById(recordingId);
|
|
10836
|
-
const shouldDownloadAndSync = !existing || existing.metadata.oss_audio_url !== metadata.oss_audio_url || !existing.audioFile || existing.status === "syncing_openclaw";
|
|
10960
|
+
const shouldDownloadAndSync = !existing || existing.metadata.oss_audio_url !== metadata.oss_audio_url || !existing.audioFile || existing.status === "syncing_openclaw" || existing.status === "sync_failed";
|
|
10837
10961
|
storage.ingest(recordingId, metadata);
|
|
10838
10962
|
if (shouldDownloadAndSync) {
|
|
10839
10963
|
runRecordingSyncInBackground(
|
|
@@ -10846,6 +10970,11 @@ async function handleRecordingSync(recordingId, metadata, storage, asrConfig, lo
|
|
|
10846
10970
|
).catch((err2) => {
|
|
10847
10971
|
const error = `\u5F55\u97F3\u540C\u6B65\u5931\u8D25: ${err2?.message ?? err2}`;
|
|
10848
10972
|
logger.error(`[recording-sync] ${error}: ${recordingId}`);
|
|
10973
|
+
const current2 = storage.findById(recordingId);
|
|
10974
|
+
if (current2?.status === "syncing_openclaw") {
|
|
10975
|
+
storage.updateStatus(recordingId, "sync_failed");
|
|
10976
|
+
}
|
|
10977
|
+
storage.setLastError(recordingId, error);
|
|
10849
10978
|
emitRecordingStatus(
|
|
10850
10979
|
recordingId,
|
|
10851
10980
|
storage,
|
|
@@ -10859,8 +10988,8 @@ async function handleRecordingSync(recordingId, metadata, storage, asrConfig, lo
|
|
|
10859
10988
|
`[recording-sync] \u5F55\u97F3\u5DF2\u5B58\u5728\u4E14\u97F3\u9891\u672A\u53D8\u5316\uFF0C\u8DF3\u8FC7\u91CD\u590D\u4E0B\u8F7D: ${recordingId}`
|
|
10860
10989
|
);
|
|
10861
10990
|
emitRecordingStatus(recordingId, storage, logger, options.notifyStatus);
|
|
10862
|
-
const
|
|
10863
|
-
if (
|
|
10991
|
+
const current2 = storage.findById(recordingId);
|
|
10992
|
+
if (current2?.status === "synced" && isAsrConfigured(asrConfig)) {
|
|
10864
10993
|
triggerTranscription(
|
|
10865
10994
|
recordingId,
|
|
10866
10995
|
storage,
|
|
@@ -10874,10 +11003,12 @@ async function handleRecordingSync(recordingId, metadata, storage, asrConfig, lo
|
|
|
10874
11003
|
});
|
|
10875
11004
|
}
|
|
10876
11005
|
}
|
|
11006
|
+
const current = storage.findById(recordingId);
|
|
10877
11007
|
return {
|
|
10878
11008
|
ok: true,
|
|
10879
11009
|
recordingId,
|
|
10880
|
-
transfer_status:
|
|
11010
|
+
transfer_status: current?.status ?? "syncing_openclaw",
|
|
11011
|
+
...current?.lastError ? { error: current.lastError } : {}
|
|
10881
11012
|
};
|
|
10882
11013
|
}
|
|
10883
11014
|
async function triggerTranscription(recordingId, storage, asrConfig, logger, options = {}) {
|
|
@@ -10893,6 +11024,7 @@ async function triggerTranscription(recordingId, storage, asrConfig, logger, opt
|
|
|
10893
11024
|
return;
|
|
10894
11025
|
}
|
|
10895
11026
|
storage.updateStatus(recordingId, "transcribing");
|
|
11027
|
+
storage.setLastError(recordingId, void 0);
|
|
10896
11028
|
emitRecordingStatus(recordingId, storage, logger, options.notifyStatus);
|
|
10897
11029
|
const audioFilePath = storage.getAudioFilePath(recordingId);
|
|
10898
11030
|
const result = await runTranscriptionWorkflow({
|
|
@@ -10944,6 +11076,7 @@ async function triggerTranscription(recordingId, storage, asrConfig, logger, opt
|
|
|
10944
11076
|
}
|
|
10945
11077
|
} else {
|
|
10946
11078
|
storage.updateStatus(recordingId, "transcribe_failed");
|
|
11079
|
+
storage.setLastError(recordingId, result.error);
|
|
10947
11080
|
emitRecordingStatus(
|
|
10948
11081
|
recordingId,
|
|
10949
11082
|
storage,
|
|
@@ -12778,6 +12911,7 @@ var RECORDING_TRANSFER_STATUSES = /* @__PURE__ */ new Set([
|
|
|
12778
12911
|
"uploading_oss",
|
|
12779
12912
|
"oss_uploaded",
|
|
12780
12913
|
"syncing_openclaw",
|
|
12914
|
+
"sync_failed",
|
|
12781
12915
|
"synced",
|
|
12782
12916
|
"transcribing",
|
|
12783
12917
|
"transcribe_failed",
|
|
@@ -12801,7 +12935,8 @@ function buildRecordingListItem(entry) {
|
|
|
12801
12935
|
audioFile: entry.audioFile,
|
|
12802
12936
|
transcriptDataFile: entry.transcriptDataFile,
|
|
12803
12937
|
transcriptFile: entry.transcriptFile,
|
|
12804
|
-
updatedAt: entry.updatedAt
|
|
12938
|
+
updatedAt: entry.updatedAt,
|
|
12939
|
+
...entry.lastError ? { error: entry.lastError } : {}
|
|
12805
12940
|
};
|
|
12806
12941
|
}
|
|
12807
12942
|
function isRelayInternalHttpRequest2(req) {
|
|
@@ -12834,7 +12969,8 @@ function buildRecordingDetail(entry, extras) {
|
|
|
12834
12969
|
transcript: extras?.transcript,
|
|
12835
12970
|
transcriptData: extras?.transcriptData,
|
|
12836
12971
|
ingestedAt: entry.ingestedAt,
|
|
12837
|
-
updatedAt: entry.updatedAt
|
|
12972
|
+
updatedAt: entry.updatedAt,
|
|
12973
|
+
...entry.lastError ? { error: entry.lastError } : {}
|
|
12838
12974
|
};
|
|
12839
12975
|
}
|
|
12840
12976
|
function registerRecordingInterfaces(deps) {
|