@yoooclaw/phone-notifications 1.11.2-beta.4 → 1.11.4-beta.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/dist/index.cjs +135 -3
- package/dist/index.cjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -299,6 +299,14 @@ var init_env = __esm({
|
|
|
299
299
|
init_credentials();
|
|
300
300
|
init_host();
|
|
301
301
|
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
|
+
},
|
|
302
310
|
test: {
|
|
303
311
|
lightApiUrl: "https://openclaw-service-test.yoooclaw.com/api/message/tob/sendMessage",
|
|
304
312
|
relayTunnelUrl: "wss://openclaw-service-test.yoooclaw.com/message/messages/ws/plugin",
|
|
@@ -5472,7 +5480,7 @@ function readBuildInjectedVersion() {
|
|
|
5472
5480
|
if (false) {
|
|
5473
5481
|
return void 0;
|
|
5474
5482
|
}
|
|
5475
|
-
const version = "1.11.
|
|
5483
|
+
const version = "1.11.4-beta.0".trim();
|
|
5476
5484
|
return version || void 0;
|
|
5477
5485
|
}
|
|
5478
5486
|
function readPluginVersionFromPackageJson() {
|
|
@@ -7343,7 +7351,7 @@ function resolveUpdateChannel(params) {
|
|
|
7343
7351
|
if (params.currentVersion.includes("-")) {
|
|
7344
7352
|
return "beta";
|
|
7345
7353
|
}
|
|
7346
|
-
return params.envName === "
|
|
7354
|
+
return params.envName === "production" ? "latest" : "beta";
|
|
7347
7355
|
}
|
|
7348
7356
|
|
|
7349
7357
|
// src/update/index.ts
|
|
@@ -11994,6 +12002,7 @@ var WsProxy = class {
|
|
|
11994
12002
|
// src/tunnel/proxy.ts
|
|
11995
12003
|
var RELAY_TUNNEL_GATEWAY_CLIENT_INSTANCE_ID = "phone-notifications-relay-tunnel";
|
|
11996
12004
|
var MAX_AUTO_PAIRING_APPROVALS = 3;
|
|
12005
|
+
var RECENT_ABORTED_CHAT_RUN_TTL_MS = 6e4;
|
|
11997
12006
|
var approveDevicePairingPromise = null;
|
|
11998
12007
|
var approveDevicePairingWarned = false;
|
|
11999
12008
|
function formatErrorMessage(err2) {
|
|
@@ -12049,6 +12058,10 @@ var TunnelProxy = class {
|
|
|
12049
12058
|
gatewayWsAutoPairingApprovals = 0;
|
|
12050
12059
|
/** 等待 Gateway WS 握手完成后发送的帧队列 */
|
|
12051
12060
|
gatewayWsPending = [];
|
|
12061
|
+
/** 记录已转发到 Gateway 的 req 元信息,便于回包时做定向处理。 */
|
|
12062
|
+
gatewayReqMetaById = /* @__PURE__ */ new Map();
|
|
12063
|
+
/** 最近由用户手动中断的 chat.run,用于过滤 runtime 误补发的 synthetic failure。 */
|
|
12064
|
+
recentAbortedChatRuns = /* @__PURE__ */ new Map();
|
|
12052
12065
|
/** 设备身份,用于 Gateway connect 握手 */
|
|
12053
12066
|
deviceIdentity;
|
|
12054
12067
|
stateDir;
|
|
@@ -12102,6 +12115,8 @@ var TunnelProxy = class {
|
|
|
12102
12115
|
this.gatewayWsReconnectRequested = false;
|
|
12103
12116
|
this.gatewayWsAutoPairingApprovals = 0;
|
|
12104
12117
|
this.gatewayWsPending = [];
|
|
12118
|
+
this.gatewayReqMetaById.clear();
|
|
12119
|
+
this.recentAbortedChatRuns.clear();
|
|
12105
12120
|
}
|
|
12106
12121
|
// ─── Gateway RPC WebSocket ───
|
|
12107
12122
|
pushGatewayPending(payload, reason) {
|
|
@@ -12122,6 +12137,10 @@ var TunnelProxy = class {
|
|
|
12122
12137
|
/** 处理 Relay 转发的 Gateway RPC 请求帧,原样通过 WebSocket 发给本地 Gateway */
|
|
12123
12138
|
handleReqFrame(frame) {
|
|
12124
12139
|
const payload = JSON.stringify(frame);
|
|
12140
|
+
this.gatewayReqMetaById.set(frame.id, {
|
|
12141
|
+
method: frame.method,
|
|
12142
|
+
sessionKey: this.normalizeSessionKey(frame.params?.sessionKey)
|
|
12143
|
+
});
|
|
12125
12144
|
this.opts.logger.info(
|
|
12126
12145
|
`TunnelProxy: req id=${frame.id} method=${frame.method} \u2192 gateway WS (${payload.length} chars)`
|
|
12127
12146
|
);
|
|
@@ -12241,6 +12260,116 @@ var TunnelProxy = class {
|
|
|
12241
12260
|
}
|
|
12242
12261
|
}
|
|
12243
12262
|
// ─── Gateway RPC WebSocket lifecycle ───
|
|
12263
|
+
normalizeSessionKey(value) {
|
|
12264
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
12265
|
+
}
|
|
12266
|
+
normalizeRunId(value) {
|
|
12267
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
12268
|
+
}
|
|
12269
|
+
pruneRecentAbortedChatRuns(now = Date.now()) {
|
|
12270
|
+
for (const [runId, entry] of this.recentAbortedChatRuns) {
|
|
12271
|
+
if (now - entry.abortedAtMs > RECENT_ABORTED_CHAT_RUN_TTL_MS) {
|
|
12272
|
+
this.recentAbortedChatRuns.delete(runId);
|
|
12273
|
+
}
|
|
12274
|
+
}
|
|
12275
|
+
}
|
|
12276
|
+
rememberRecentAbortedChatRun(runId, sessionKey) {
|
|
12277
|
+
const normalizedRunId = this.normalizeRunId(runId);
|
|
12278
|
+
const normalizedSessionKey = this.normalizeSessionKey(sessionKey);
|
|
12279
|
+
if (!normalizedRunId || !normalizedSessionKey) return;
|
|
12280
|
+
this.pruneRecentAbortedChatRuns();
|
|
12281
|
+
this.recentAbortedChatRuns.set(normalizedRunId, {
|
|
12282
|
+
sessionKey: normalizedSessionKey,
|
|
12283
|
+
abortedAtMs: Date.now()
|
|
12284
|
+
});
|
|
12285
|
+
}
|
|
12286
|
+
getAssistantMessageText(message) {
|
|
12287
|
+
if (!message || typeof message !== "object") return "";
|
|
12288
|
+
if (typeof message.text === "string") return message.text;
|
|
12289
|
+
if (!Array.isArray(message.content)) return "";
|
|
12290
|
+
return message.content.filter(
|
|
12291
|
+
(item) => item && typeof item === "object" && item.type === "text" && typeof item.text === "string"
|
|
12292
|
+
).map((item) => item.text).join("");
|
|
12293
|
+
}
|
|
12294
|
+
looksLikeSyntheticAbortFailureText(text) {
|
|
12295
|
+
const normalized = text.trim().toLowerCase();
|
|
12296
|
+
if (!normalized) return false;
|
|
12297
|
+
return normalized.includes("agent failed before reply:") && normalized.includes("aborted") && normalized.includes("openclaw logs --follow");
|
|
12298
|
+
}
|
|
12299
|
+
isSyntheticAbortHistoryMessage(message, sessionKey) {
|
|
12300
|
+
const text = this.getAssistantMessageText(message);
|
|
12301
|
+
if (!this.looksLikeSyntheticAbortFailureText(text)) return false;
|
|
12302
|
+
const messageTimestamp = typeof message?.timestamp === "number" ? message.timestamp : null;
|
|
12303
|
+
const now = Date.now();
|
|
12304
|
+
this.pruneRecentAbortedChatRuns(now);
|
|
12305
|
+
for (const entry of this.recentAbortedChatRuns.values()) {
|
|
12306
|
+
if (entry.sessionKey !== sessionKey) continue;
|
|
12307
|
+
if (messageTimestamp === null) return true;
|
|
12308
|
+
if (Math.abs(messageTimestamp - entry.abortedAtMs) <= RECENT_ABORTED_CHAT_RUN_TTL_MS) {
|
|
12309
|
+
return true;
|
|
12310
|
+
}
|
|
12311
|
+
}
|
|
12312
|
+
return false;
|
|
12313
|
+
}
|
|
12314
|
+
maybeRewriteGatewayFrame(text, frame) {
|
|
12315
|
+
this.pruneRecentAbortedChatRuns();
|
|
12316
|
+
if (frame?.type === "event" && frame?.event === "chat" && frame?.payload?.state === "aborted") {
|
|
12317
|
+
this.rememberRecentAbortedChatRun(
|
|
12318
|
+
frame.payload?.runId,
|
|
12319
|
+
frame.payload?.sessionKey
|
|
12320
|
+
);
|
|
12321
|
+
return text;
|
|
12322
|
+
}
|
|
12323
|
+
if (frame?.type === "ack" && frame?.ok === false && typeof frame?.id === "string") {
|
|
12324
|
+
this.gatewayReqMetaById.delete(frame.id);
|
|
12325
|
+
return text;
|
|
12326
|
+
}
|
|
12327
|
+
let reqMeta;
|
|
12328
|
+
if (frame?.type === "res" && typeof frame?.id === "string") {
|
|
12329
|
+
reqMeta = this.gatewayReqMetaById.get(frame.id);
|
|
12330
|
+
this.gatewayReqMetaById.delete(frame.id);
|
|
12331
|
+
}
|
|
12332
|
+
if (frame?.type === "res" && frame?.ok === true && reqMeta?.method === "chat.abort") {
|
|
12333
|
+
const runIds = Array.isArray(frame?.payload?.runIds) ? frame.payload.runIds : [];
|
|
12334
|
+
for (const runId of runIds) {
|
|
12335
|
+
this.rememberRecentAbortedChatRun(runId, reqMeta.sessionKey);
|
|
12336
|
+
}
|
|
12337
|
+
return text;
|
|
12338
|
+
}
|
|
12339
|
+
if (frame?.type === "event" && frame?.event === "chat" && frame?.payload?.state === "final") {
|
|
12340
|
+
const runId = this.normalizeRunId(frame?.payload?.runId);
|
|
12341
|
+
const assistantText = this.getAssistantMessageText(frame?.payload?.message);
|
|
12342
|
+
const recentAbort = runId ? this.recentAbortedChatRuns.get(runId) : void 0;
|
|
12343
|
+
if (recentAbort && this.looksLikeSyntheticAbortFailureText(assistantText)) {
|
|
12344
|
+
this.opts.logger.info(
|
|
12345
|
+
`TunnelProxy: suppressing synthetic abort failure final for runId=${runId}`
|
|
12346
|
+
);
|
|
12347
|
+
return null;
|
|
12348
|
+
}
|
|
12349
|
+
return text;
|
|
12350
|
+
}
|
|
12351
|
+
if (frame?.type === "res" && frame?.ok === true && reqMeta?.method === "chat.history" && Array.isArray(frame?.payload?.messages)) {
|
|
12352
|
+
const sessionKey = this.normalizeSessionKey(frame?.payload?.sessionKey) ?? reqMeta.sessionKey;
|
|
12353
|
+
if (!sessionKey) return text;
|
|
12354
|
+
const filteredMessages = frame.payload.messages.filter(
|
|
12355
|
+
(message) => !this.isSyntheticAbortHistoryMessage(message, sessionKey)
|
|
12356
|
+
);
|
|
12357
|
+
if (filteredMessages.length === frame.payload.messages.length) {
|
|
12358
|
+
return text;
|
|
12359
|
+
}
|
|
12360
|
+
this.opts.logger.info(
|
|
12361
|
+
`TunnelProxy: removed ${frame.payload.messages.length - filteredMessages.length} synthetic abort history message(s) for session=${sessionKey}`
|
|
12362
|
+
);
|
|
12363
|
+
return JSON.stringify({
|
|
12364
|
+
...frame,
|
|
12365
|
+
payload: {
|
|
12366
|
+
...frame.payload,
|
|
12367
|
+
messages: filteredMessages
|
|
12368
|
+
}
|
|
12369
|
+
});
|
|
12370
|
+
}
|
|
12371
|
+
return text;
|
|
12372
|
+
}
|
|
12244
12373
|
/** 确保到本地 Gateway 的 RPC WebSocket 已连接且握手完成 */
|
|
12245
12374
|
ensureGatewayWs() {
|
|
12246
12375
|
if (this.gatewayWsReady && this.gatewayWs?.readyState === wrapper_default.OPEN)
|
|
@@ -12325,7 +12454,10 @@ var TunnelProxy = class {
|
|
|
12325
12454
|
ws.close();
|
|
12326
12455
|
return;
|
|
12327
12456
|
}
|
|
12328
|
-
this.
|
|
12457
|
+
const rewritten = this.maybeRewriteGatewayFrame(text, frame);
|
|
12458
|
+
if (rewritten !== null) {
|
|
12459
|
+
this.opts.client.sendRaw(rewritten);
|
|
12460
|
+
}
|
|
12329
12461
|
});
|
|
12330
12462
|
ws.on("close", (code, reason) => {
|
|
12331
12463
|
const wasReady = this.gatewayWsReady;
|