@inline-openclaw/inline 0.0.27 → 0.0.29
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.js +690 -368
- package/dist/index.js.map +15 -16
- package/dist/inline/actions.d.ts.map +1 -1
- package/dist/inline/bot-commands-api.d.ts.map +1 -1
- package/dist/inline/bot-commands-sync.d.ts.map +1 -1
- package/dist/inline/channel.d.ts.map +1 -1
- package/dist/inline/monitor.d.ts +1 -0
- package/dist/inline/monitor.d.ts.map +1 -1
- package/dist/inline/status-issues.d.ts.map +1 -1
- package/dist/sdk-runtime-compat.d.ts +0 -26
- package/dist/sdk-runtime-compat.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/inline/command-menu-compat.d.ts +0 -24
- package/dist/inline/command-menu-compat.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -5837,7 +5837,8 @@ class ConnectionInit$Type extends import_runtime4.MessageType {
|
|
|
5837
5837
|
{ no: 1, name: "token", kind: "scalar", T: 9 },
|
|
5838
5838
|
{ no: 2, name: "build_number", kind: "scalar", opt: true, T: 5 },
|
|
5839
5839
|
{ no: 3, name: "layer", kind: "scalar", opt: true, T: 13 },
|
|
5840
|
-
{ no: 4, name: "client_version", kind: "scalar", opt: true, T: 9 }
|
|
5840
|
+
{ no: 4, name: "client_version", kind: "scalar", opt: true, T: 9 },
|
|
5841
|
+
{ no: 5, name: "os_version", kind: "scalar", opt: true, T: 9 }
|
|
5841
5842
|
]);
|
|
5842
5843
|
}
|
|
5843
5844
|
create(value) {
|
|
@@ -5864,6 +5865,9 @@ class ConnectionInit$Type extends import_runtime4.MessageType {
|
|
|
5864
5865
|
case 4:
|
|
5865
5866
|
message.clientVersion = reader.string();
|
|
5866
5867
|
break;
|
|
5868
|
+
case 5:
|
|
5869
|
+
message.osVersion = reader.string();
|
|
5870
|
+
break;
|
|
5867
5871
|
default:
|
|
5868
5872
|
let u = options.readUnknownField;
|
|
5869
5873
|
if (u === "throw")
|
|
@@ -5884,6 +5888,8 @@ class ConnectionInit$Type extends import_runtime4.MessageType {
|
|
|
5884
5888
|
writer.tag(3, import_runtime.WireType.Varint).uint32(message.layer);
|
|
5885
5889
|
if (message.clientVersion !== undefined)
|
|
5886
5890
|
writer.tag(4, import_runtime.WireType.LengthDelimited).string(message.clientVersion);
|
|
5891
|
+
if (message.osVersion !== undefined)
|
|
5892
|
+
writer.tag(5, import_runtime.WireType.LengthDelimited).string(message.osVersion);
|
|
5887
5893
|
let u = options.writeUnknownFields;
|
|
5888
5894
|
if (u !== false)
|
|
5889
5895
|
(u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -18289,6 +18295,9 @@ class PingPongService {
|
|
|
18289
18295
|
sleepTimer = null;
|
|
18290
18296
|
sleepResolver = null;
|
|
18291
18297
|
pings = new Map;
|
|
18298
|
+
lastPingAt = null;
|
|
18299
|
+
lastPongAt = null;
|
|
18300
|
+
lastTimeoutAt = null;
|
|
18292
18301
|
constructor(options) {
|
|
18293
18302
|
this.log = options?.logger ?? {};
|
|
18294
18303
|
const cryptoAny = globalThis.crypto;
|
|
@@ -18317,13 +18326,16 @@ class PingPongService {
|
|
|
18317
18326
|
return;
|
|
18318
18327
|
const nonce = this.randomNonce();
|
|
18319
18328
|
await client.sendPing(nonce);
|
|
18320
|
-
|
|
18329
|
+
const now = Date.now();
|
|
18330
|
+
this.lastPingAt = now;
|
|
18331
|
+
this.pings.set(nonce, now);
|
|
18321
18332
|
}
|
|
18322
18333
|
pong(nonce) {
|
|
18323
18334
|
const pingDate = this.pings.get(nonce);
|
|
18324
18335
|
if (!pingDate)
|
|
18325
18336
|
return;
|
|
18326
18337
|
this.pings.delete(nonce);
|
|
18338
|
+
this.lastPongAt = Date.now();
|
|
18327
18339
|
}
|
|
18328
18340
|
async loop() {
|
|
18329
18341
|
while (this.running) {
|
|
@@ -18344,11 +18356,16 @@ class PingPongService {
|
|
|
18344
18356
|
if (client.state !== "open")
|
|
18345
18357
|
return;
|
|
18346
18358
|
const now = Date.now();
|
|
18347
|
-
const
|
|
18348
|
-
if (
|
|
18359
|
+
const oldestPendingPingAt = [...this.pings.values()].reduce((oldest, timestamp) => oldest == null || timestamp < oldest ? timestamp : oldest, null);
|
|
18360
|
+
if (oldestPendingPingAt == null)
|
|
18361
|
+
return;
|
|
18362
|
+
const oldestPendingAgeMs = now - oldestPendingPingAt;
|
|
18363
|
+
if (oldestPendingAgeMs <= 30000)
|
|
18349
18364
|
return;
|
|
18350
|
-
this.
|
|
18351
|
-
|
|
18365
|
+
this.lastTimeoutAt = now;
|
|
18366
|
+
this.log.warn?.(`Ping timeout, reconnecting (pending=${this.pings.size}, oldestPendingAgeMs=${oldestPendingAgeMs}${this.lastPongAt != null ? `, lastPongAgeMs=${now - this.lastPongAt}` : ""})`);
|
|
18367
|
+
this.reset();
|
|
18368
|
+
await client.reconnect({ cause: "ping-timeout" });
|
|
18352
18369
|
}
|
|
18353
18370
|
async sleep(ms) {
|
|
18354
18371
|
if (ms <= 0)
|
|
@@ -18382,6 +18399,19 @@ class PingPongService {
|
|
|
18382
18399
|
}
|
|
18383
18400
|
return BigInt(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER));
|
|
18384
18401
|
}
|
|
18402
|
+
getDiagnostics() {
|
|
18403
|
+
const now = Date.now();
|
|
18404
|
+
const oldestPendingPingAt = [...this.pings.values()].reduce((oldest, timestamp) => oldest == null || timestamp < oldest ? timestamp : oldest, null);
|
|
18405
|
+
return {
|
|
18406
|
+
running: this.running,
|
|
18407
|
+
pendingCount: this.pings.size,
|
|
18408
|
+
lastPingAt: this.lastPingAt,
|
|
18409
|
+
lastPongAt: this.lastPongAt,
|
|
18410
|
+
lastTimeoutAt: this.lastTimeoutAt,
|
|
18411
|
+
oldestPendingPingAt,
|
|
18412
|
+
oldestPendingPingAgeMs: oldestPendingPingAt != null ? now - oldestPendingPingAt : null
|
|
18413
|
+
};
|
|
18414
|
+
}
|
|
18385
18415
|
}
|
|
18386
18416
|
var isCrypto = (value) => typeof value === "object" && value !== null && ("getRandomValues" in value) && typeof value.getRandomValues === "function";
|
|
18387
18417
|
|
|
@@ -18411,6 +18441,11 @@ class ProtocolClient {
|
|
|
18411
18441
|
reconnectionTimer = null;
|
|
18412
18442
|
authenticationTimeout = null;
|
|
18413
18443
|
listenersStarted = false;
|
|
18444
|
+
lastConnectingAt = null;
|
|
18445
|
+
lastOpenAt = null;
|
|
18446
|
+
lastTransportMessageAt = null;
|
|
18447
|
+
lastFailureAt = null;
|
|
18448
|
+
lastFailureReason = null;
|
|
18414
18449
|
constructor(options) {
|
|
18415
18450
|
this.transport = options.transport;
|
|
18416
18451
|
this.log = options.logger ?? {};
|
|
@@ -18438,7 +18473,10 @@ class ProtocolClient {
|
|
|
18438
18473
|
}
|
|
18439
18474
|
}
|
|
18440
18475
|
async reconnect(options) {
|
|
18441
|
-
await this.transport.reconnect({
|
|
18476
|
+
await this.transport.reconnect({
|
|
18477
|
+
skipDelay: options?.skipDelay,
|
|
18478
|
+
cause: options?.cause ?? this.lastFailureReason ?? "protocol-reconnect"
|
|
18479
|
+
});
|
|
18442
18480
|
}
|
|
18443
18481
|
async sendRpc(method, input = emptyRpcInput) {
|
|
18444
18482
|
this.ensureOpenForRpc();
|
|
@@ -18499,6 +18537,7 @@ class ProtocolClient {
|
|
|
18499
18537
|
});
|
|
18500
18538
|
}
|
|
18501
18539
|
async handleTransportMessage(message) {
|
|
18540
|
+
this.lastTransportMessageAt = Date.now();
|
|
18502
18541
|
switch (message.body.oneofKind) {
|
|
18503
18542
|
case "connectionOpen":
|
|
18504
18543
|
await this.connectionOpen();
|
|
@@ -18531,7 +18570,7 @@ class ProtocolClient {
|
|
|
18531
18570
|
this.pingPong.pong(message.body.pong.nonce);
|
|
18532
18571
|
break;
|
|
18533
18572
|
case "connectionError":
|
|
18534
|
-
this.handleClientFailure();
|
|
18573
|
+
this.handleClientFailure(describeConnectionError(message.body.connectionError));
|
|
18535
18574
|
break;
|
|
18536
18575
|
default:
|
|
18537
18576
|
break;
|
|
@@ -18553,11 +18592,12 @@ class ProtocolClient {
|
|
|
18553
18592
|
this.startAuthenticationTimeout();
|
|
18554
18593
|
} catch (error) {
|
|
18555
18594
|
this.log.error?.("Failed to authenticate", error);
|
|
18556
|
-
this.handleClientFailure();
|
|
18595
|
+
this.handleClientFailure(`authenticate failed: ${summarizeError(error)}`);
|
|
18557
18596
|
}
|
|
18558
18597
|
}
|
|
18559
18598
|
async connectionOpen() {
|
|
18560
18599
|
this.state = "open";
|
|
18600
|
+
this.lastOpenAt = Date.now();
|
|
18561
18601
|
await this.events.send({ type: "open" });
|
|
18562
18602
|
this.stopAuthenticationTimeout();
|
|
18563
18603
|
if (this.reconnectionTimer) {
|
|
@@ -18569,7 +18609,9 @@ class ProtocolClient {
|
|
|
18569
18609
|
this.resendPendingRpcRequests();
|
|
18570
18610
|
}
|
|
18571
18611
|
async connecting() {
|
|
18612
|
+
this.pingPong.stop();
|
|
18572
18613
|
this.state = "connecting";
|
|
18614
|
+
this.lastConnectingAt = Date.now();
|
|
18573
18615
|
await this.events.send({ type: "connecting" });
|
|
18574
18616
|
}
|
|
18575
18617
|
async reset() {
|
|
@@ -18583,7 +18625,7 @@ class ProtocolClient {
|
|
|
18583
18625
|
this.authenticationTimeout = setTimeout(() => {
|
|
18584
18626
|
if (this.state === "open")
|
|
18585
18627
|
return;
|
|
18586
|
-
this.handleClientFailure();
|
|
18628
|
+
this.handleClientFailure("authentication timeout after 10000ms");
|
|
18587
18629
|
}, 1e4);
|
|
18588
18630
|
}
|
|
18589
18631
|
stopAuthenticationTimeout() {
|
|
@@ -18592,19 +18634,23 @@ class ProtocolClient {
|
|
|
18592
18634
|
clearTimeout(this.authenticationTimeout);
|
|
18593
18635
|
this.authenticationTimeout = null;
|
|
18594
18636
|
}
|
|
18595
|
-
handleClientFailure() {
|
|
18637
|
+
handleClientFailure(reason = "connection failure") {
|
|
18596
18638
|
this.pingPong.stop();
|
|
18597
18639
|
this.stopAuthenticationTimeout();
|
|
18598
18640
|
this.state = "connecting";
|
|
18641
|
+
this.lastFailureAt = Date.now();
|
|
18642
|
+
this.lastFailureReason = reason;
|
|
18599
18643
|
if (this.reconnectionTimer) {
|
|
18600
18644
|
clearTimeout(this.reconnectionTimer);
|
|
18601
18645
|
}
|
|
18602
18646
|
this.connectionAttemptNo = this.connectionAttemptNo + 1 >>> 0;
|
|
18647
|
+
const delayMs = Math.round(this.getReconnectionDelay() * 1000);
|
|
18648
|
+
this.log.warn?.(`Protocol reconnect scheduled (attempt=${this.connectionAttemptNo}, delayMs=${delayMs}, reason=${reason})`);
|
|
18603
18649
|
this.reconnectionTimer = setTimeout(() => {
|
|
18604
18650
|
if (this.state === "open")
|
|
18605
18651
|
return;
|
|
18606
18652
|
this.reconnect({ skipDelay: true });
|
|
18607
|
-
},
|
|
18653
|
+
}, delayMs);
|
|
18608
18654
|
}
|
|
18609
18655
|
getReconnectionDelay() {
|
|
18610
18656
|
const attemptNo = this.connectionAttemptNo;
|
|
@@ -18690,11 +18736,25 @@ class ProtocolClient {
|
|
|
18690
18736
|
pending.sending = true;
|
|
18691
18737
|
this.transport.send(pending.message).catch((error) => {
|
|
18692
18738
|
this.log.warn?.("Failed to send RPC request; waiting for reconnect", error);
|
|
18693
|
-
this.handleClientFailure();
|
|
18739
|
+
this.handleClientFailure(`rpc send failed: ${summarizeError(error)}`);
|
|
18694
18740
|
}).finally(() => {
|
|
18695
18741
|
pending.sending = false;
|
|
18696
18742
|
});
|
|
18697
18743
|
}
|
|
18744
|
+
getDiagnostics() {
|
|
18745
|
+
return {
|
|
18746
|
+
state: this.state,
|
|
18747
|
+
connectionAttemptNo: this.connectionAttemptNo,
|
|
18748
|
+
pendingRpcCount: this.pendingRpcRequests.size,
|
|
18749
|
+
lastConnectingAt: this.lastConnectingAt,
|
|
18750
|
+
lastOpenAt: this.lastOpenAt,
|
|
18751
|
+
lastTransportMessageAt: this.lastTransportMessageAt,
|
|
18752
|
+
lastFailureAt: this.lastFailureAt,
|
|
18753
|
+
lastFailureReason: this.lastFailureReason,
|
|
18754
|
+
ping: this.pingPong.getDiagnostics(),
|
|
18755
|
+
transport: typeof this.transport.getDiagnostics === "function" ? this.transport.getDiagnostics() : null
|
|
18756
|
+
};
|
|
18757
|
+
}
|
|
18698
18758
|
}
|
|
18699
18759
|
var normalizeRpcTimeoutMs = (timeoutMs, fallback) => {
|
|
18700
18760
|
const resolved = timeoutMs === undefined ? fallback : timeoutMs;
|
|
@@ -18715,6 +18775,18 @@ class ProtocolClientError extends Error {
|
|
|
18715
18775
|
this.name = `ProtocolClientError:${code}`;
|
|
18716
18776
|
}
|
|
18717
18777
|
}
|
|
18778
|
+
function summarizeError(error) {
|
|
18779
|
+
if (error instanceof Error) {
|
|
18780
|
+
return `${error.name}: ${error.message}`;
|
|
18781
|
+
}
|
|
18782
|
+
return String(error);
|
|
18783
|
+
}
|
|
18784
|
+
function describeConnectionError(error) {
|
|
18785
|
+
const value = typeof error === "object" && error !== null ? error : null;
|
|
18786
|
+
const code = typeof value?.code === "number" ? value.code : null;
|
|
18787
|
+
const message = typeof value?.message === "string" && value.message.trim() ? value.message.trim() : "unknown";
|
|
18788
|
+
return `server connection error${code != null ? ` (code=${code})` : ""}: ${message}`;
|
|
18789
|
+
}
|
|
18718
18790
|
|
|
18719
18791
|
// ../../node_modules/.bun/ws@8.20.0/node_modules/ws/wrapper.mjs
|
|
18720
18792
|
var import_stream = __toESM(require_stream(), 1);
|
|
@@ -18746,6 +18818,18 @@ class WebSocketTransport {
|
|
|
18746
18818
|
connectionAttemptNo = 0;
|
|
18747
18819
|
socket = null;
|
|
18748
18820
|
reconnectionTimer = null;
|
|
18821
|
+
lastConnectStartedAt = null;
|
|
18822
|
+
lastConnectedAt = null;
|
|
18823
|
+
lastDisconnectedAt = null;
|
|
18824
|
+
lastMessageAt = null;
|
|
18825
|
+
lastCloseCode = null;
|
|
18826
|
+
lastCloseReason = null;
|
|
18827
|
+
lastErrorAt = null;
|
|
18828
|
+
lastErrorMessage = null;
|
|
18829
|
+
lastReconnectScheduledAt = null;
|
|
18830
|
+
lastReconnectDelayMs = null;
|
|
18831
|
+
lastReconnectCause = null;
|
|
18832
|
+
reconnectCount = 0;
|
|
18749
18833
|
constructor(options) {
|
|
18750
18834
|
this.url = options.url;
|
|
18751
18835
|
this.log = options.logger ?? {};
|
|
@@ -18777,7 +18861,13 @@ class WebSocketTransport {
|
|
|
18777
18861
|
this.cleanUpPreviousConnection();
|
|
18778
18862
|
this.connectionAttemptNo = this.connectionAttemptNo + 1 >>> 0;
|
|
18779
18863
|
const delaySeconds = this.getReconnectionDelaySeconds(this.connectionAttemptNo);
|
|
18780
|
-
|
|
18864
|
+
const delayMs = Math.round(delaySeconds * 1000);
|
|
18865
|
+
const cause = options?.cause?.trim() || "unspecified";
|
|
18866
|
+
this.lastReconnectScheduledAt = Date.now();
|
|
18867
|
+
this.lastReconnectDelayMs = delayMs;
|
|
18868
|
+
this.lastReconnectCause = cause;
|
|
18869
|
+
this.reconnectCount += 1;
|
|
18870
|
+
this.log.warn?.(`WebSocket reconnect scheduled (attempt=${this.connectionAttemptNo}, delayMs=${delayMs}, cause=${cause})`);
|
|
18781
18871
|
this.reconnectionTimer = setTimeout(() => {
|
|
18782
18872
|
this.reconnectionTimer = null;
|
|
18783
18873
|
if (this.state === "idle" || this.state === "connected")
|
|
@@ -18821,6 +18911,7 @@ class WebSocketTransport {
|
|
|
18821
18911
|
async openConnection() {
|
|
18822
18912
|
if (this.state === "idle")
|
|
18823
18913
|
return;
|
|
18914
|
+
this.lastConnectStartedAt = Date.now();
|
|
18824
18915
|
const socket = new import_websocket.default(this.url);
|
|
18825
18916
|
this.socket = socket;
|
|
18826
18917
|
socket.on("open", () => {
|
|
@@ -18843,6 +18934,8 @@ class WebSocketTransport {
|
|
|
18843
18934
|
return;
|
|
18844
18935
|
this.connectionAttemptNo = 0;
|
|
18845
18936
|
this.state = "connected";
|
|
18937
|
+
this.lastConnectedAt = Date.now();
|
|
18938
|
+
this.lastDisconnectedAt = null;
|
|
18846
18939
|
await this.events.send({ type: "connected" });
|
|
18847
18940
|
}
|
|
18848
18941
|
async handleMessage(socket, data) {
|
|
@@ -18851,6 +18944,7 @@ class WebSocketTransport {
|
|
|
18851
18944
|
try {
|
|
18852
18945
|
const payload = this.coerceBinary(data);
|
|
18853
18946
|
const message = ServerProtocolMessage.fromBinary(payload);
|
|
18947
|
+
this.lastMessageAt = Date.now();
|
|
18854
18948
|
await this.events.send({ type: "message", message });
|
|
18855
18949
|
} catch (error) {
|
|
18856
18950
|
this.log.error?.("Failed to decode message", error);
|
|
@@ -18870,16 +18964,24 @@ class WebSocketTransport {
|
|
|
18870
18964
|
return;
|
|
18871
18965
|
if (this.state === "idle")
|
|
18872
18966
|
return;
|
|
18873
|
-
|
|
18874
|
-
|
|
18967
|
+
const reasonText = stringifyCloseReason(reason);
|
|
18968
|
+
this.lastDisconnectedAt = Date.now();
|
|
18969
|
+
this.lastCloseCode = code;
|
|
18970
|
+
this.lastCloseReason = reasonText;
|
|
18971
|
+
const connectedForMs = this.lastConnectedAt != null ? Math.max(0, this.lastDisconnectedAt - this.lastConnectedAt) : null;
|
|
18972
|
+
this.log.warn?.(`WebSocket closed (code=${code}, reason=${reasonText || "none"}${connectedForMs != null ? `, connectedForMs=${connectedForMs}` : ""})`);
|
|
18973
|
+
await this.reconnect({ cause: `socket-close:${code}${reasonText ? `:${reasonText}` : ""}` });
|
|
18875
18974
|
}
|
|
18876
18975
|
async handleError(socket, error) {
|
|
18877
18976
|
if (this.socket !== socket)
|
|
18878
18977
|
return;
|
|
18879
18978
|
if (this.state === "idle")
|
|
18880
18979
|
return;
|
|
18881
|
-
|
|
18882
|
-
|
|
18980
|
+
const summary = summarizeError2(error);
|
|
18981
|
+
this.lastErrorAt = Date.now();
|
|
18982
|
+
this.lastErrorMessage = summary;
|
|
18983
|
+
this.log.error?.(`WebSocket error: ${summary}`);
|
|
18984
|
+
await this.reconnect({ cause: `socket-error:${summary}` });
|
|
18883
18985
|
}
|
|
18884
18986
|
async setIdle() {
|
|
18885
18987
|
if (this.state === "idle")
|
|
@@ -18893,6 +18995,46 @@ class WebSocketTransport {
|
|
|
18893
18995
|
this.state = "connecting";
|
|
18894
18996
|
await this.events.send({ type: "connecting" });
|
|
18895
18997
|
}
|
|
18998
|
+
getDiagnostics() {
|
|
18999
|
+
return {
|
|
19000
|
+
kind: "websocket",
|
|
19001
|
+
url: redactUrlForDiagnostics(this.url),
|
|
19002
|
+
state: this.state,
|
|
19003
|
+
connectionAttemptNo: this.connectionAttemptNo,
|
|
19004
|
+
reconnectCount: this.reconnectCount,
|
|
19005
|
+
lastConnectStartedAt: this.lastConnectStartedAt,
|
|
19006
|
+
lastConnectedAt: this.lastConnectedAt,
|
|
19007
|
+
lastDisconnectedAt: this.lastDisconnectedAt,
|
|
19008
|
+
lastMessageAt: this.lastMessageAt,
|
|
19009
|
+
lastCloseCode: this.lastCloseCode,
|
|
19010
|
+
lastCloseReason: this.lastCloseReason,
|
|
19011
|
+
lastErrorAt: this.lastErrorAt,
|
|
19012
|
+
lastErrorMessage: this.lastErrorMessage,
|
|
19013
|
+
lastReconnectScheduledAt: this.lastReconnectScheduledAt,
|
|
19014
|
+
lastReconnectDelayMs: this.lastReconnectDelayMs,
|
|
19015
|
+
lastReconnectCause: this.lastReconnectCause,
|
|
19016
|
+
socketReadyState: this.socket?.readyState ?? null
|
|
19017
|
+
};
|
|
19018
|
+
}
|
|
19019
|
+
}
|
|
19020
|
+
function stringifyCloseReason(reason) {
|
|
19021
|
+
const text = reason.toString("utf8").trim();
|
|
19022
|
+
return text;
|
|
19023
|
+
}
|
|
19024
|
+
function summarizeError2(error) {
|
|
19025
|
+
if (error instanceof Error) {
|
|
19026
|
+
const code = typeof error.code === "string" ? error.code : null;
|
|
19027
|
+
return code ? `${error.name}: ${error.message} (code=${code})` : `${error.name}: ${error.message}`;
|
|
19028
|
+
}
|
|
19029
|
+
return String(error);
|
|
19030
|
+
}
|
|
19031
|
+
function redactUrlForDiagnostics(raw) {
|
|
19032
|
+
try {
|
|
19033
|
+
const url = new URL(raw);
|
|
19034
|
+
return `${url.protocol}//${url.host}${url.pathname}`;
|
|
19035
|
+
} catch {
|
|
19036
|
+
return raw;
|
|
19037
|
+
}
|
|
18896
19038
|
}
|
|
18897
19039
|
|
|
18898
19040
|
// ../sdk/dist/sdk/types.js
|
|
@@ -19047,6 +19189,7 @@ class InlineSdkClient {
|
|
|
19047
19189
|
saveInFlight = null;
|
|
19048
19190
|
catchUpInFlightByChatId = new Map;
|
|
19049
19191
|
catchUpRequestedByChatId = new Map;
|
|
19192
|
+
userCatchUpInFlight = null;
|
|
19050
19193
|
constructor(options) {
|
|
19051
19194
|
this.options = options;
|
|
19052
19195
|
this.log = options.logger ?? noopLogger;
|
|
@@ -19114,6 +19257,13 @@ class InlineSdkClient {
|
|
|
19114
19257
|
await this.flushStateSave();
|
|
19115
19258
|
await this.protocol.stopTransport();
|
|
19116
19259
|
}
|
|
19260
|
+
getDiagnostics() {
|
|
19261
|
+
return {
|
|
19262
|
+
started: this.started,
|
|
19263
|
+
baseUrl: this.httpBaseUrl,
|
|
19264
|
+
protocol: this.protocol.getDiagnostics()
|
|
19265
|
+
};
|
|
19266
|
+
}
|
|
19117
19267
|
rejectOpen(error) {
|
|
19118
19268
|
this.openRejecter?.(error);
|
|
19119
19269
|
this.openResolver = null;
|
|
@@ -19126,7 +19276,8 @@ class InlineSdkClient {
|
|
|
19126
19276
|
return {
|
|
19127
19277
|
version: 1,
|
|
19128
19278
|
...this.state.dateCursor != null ? { dateCursor: this.state.dateCursor } : {},
|
|
19129
|
-
...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {}
|
|
19279
|
+
...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {},
|
|
19280
|
+
...this.state.lastUserSeq != null ? { lastUserSeq: this.state.lastUserSeq } : {}
|
|
19130
19281
|
};
|
|
19131
19282
|
}
|
|
19132
19283
|
async getMe() {
|
|
@@ -19392,6 +19543,7 @@ class InlineSdkClient {
|
|
|
19392
19543
|
this.openResolver = null;
|
|
19393
19544
|
this.openRejecter = null;
|
|
19394
19545
|
this.initializeDateCursor();
|
|
19546
|
+
this.requestCatchUpUser();
|
|
19395
19547
|
}
|
|
19396
19548
|
async initializeDateCursor() {
|
|
19397
19549
|
const date = this.state.dateCursor ?? nowSeconds();
|
|
@@ -19490,6 +19642,10 @@ class InlineSdkClient {
|
|
|
19490
19642
|
}
|
|
19491
19643
|
case "messageActionInvoked": {
|
|
19492
19644
|
const payload = update.update.messageActionInvoked;
|
|
19645
|
+
if (this.shouldSkipUserSeq(seq)) {
|
|
19646
|
+
return;
|
|
19647
|
+
}
|
|
19648
|
+
this.bumpUserSeq(seq);
|
|
19493
19649
|
await this.eventStream.send({
|
|
19494
19650
|
kind: "message.action.invoke",
|
|
19495
19651
|
interactionId: payload.interactionId,
|
|
@@ -19505,6 +19661,10 @@ class InlineSdkClient {
|
|
|
19505
19661
|
}
|
|
19506
19662
|
case "messageActionAnswered": {
|
|
19507
19663
|
const payload = update.update.messageActionAnswered;
|
|
19664
|
+
if (this.shouldSkipUserSeq(seq)) {
|
|
19665
|
+
return;
|
|
19666
|
+
}
|
|
19667
|
+
this.bumpUserSeq(seq);
|
|
19508
19668
|
await this.eventStream.send({
|
|
19509
19669
|
kind: "message.action.answered",
|
|
19510
19670
|
interactionId: payload.interactionId,
|
|
@@ -19551,6 +19711,86 @@ class InlineSdkClient {
|
|
|
19551
19711
|
this.scheduleStateSave();
|
|
19552
19712
|
}
|
|
19553
19713
|
}
|
|
19714
|
+
shouldSkipUserSeq(seq) {
|
|
19715
|
+
if (!Number.isFinite(seq))
|
|
19716
|
+
return false;
|
|
19717
|
+
const lastUserSeq = this.state.lastUserSeq ?? 0;
|
|
19718
|
+
return seq > 0 && seq <= lastUserSeq;
|
|
19719
|
+
}
|
|
19720
|
+
bumpUserSeq(seq) {
|
|
19721
|
+
if (!Number.isFinite(seq) || seq <= 0)
|
|
19722
|
+
return;
|
|
19723
|
+
const prev = this.state.lastUserSeq ?? 0;
|
|
19724
|
+
if (seq > prev) {
|
|
19725
|
+
this.state.lastUserSeq = seq;
|
|
19726
|
+
this.scheduleStateSave();
|
|
19727
|
+
}
|
|
19728
|
+
}
|
|
19729
|
+
requestCatchUpUser() {
|
|
19730
|
+
const lastUserSeq = this.state.lastUserSeq ?? 0;
|
|
19731
|
+
if (lastUserSeq <= 0) {
|
|
19732
|
+
return;
|
|
19733
|
+
}
|
|
19734
|
+
if (this.userCatchUpInFlight) {
|
|
19735
|
+
return;
|
|
19736
|
+
}
|
|
19737
|
+
this.userCatchUpInFlight = this.doCatchUpUser(lastUserSeq).catch((error) => {
|
|
19738
|
+
this.log.warn?.("GET_UPDATES user catch-up failed; continuing live delivery", {
|
|
19739
|
+
error: extractErrorMessage(error)
|
|
19740
|
+
});
|
|
19741
|
+
}).finally(() => {
|
|
19742
|
+
this.userCatchUpInFlight = null;
|
|
19743
|
+
});
|
|
19744
|
+
}
|
|
19745
|
+
async doCatchUpUser(startSeq) {
|
|
19746
|
+
let cursor = startSeq;
|
|
19747
|
+
while (true) {
|
|
19748
|
+
const result = await this.invoke(Method.GET_UPDATES, {
|
|
19749
|
+
oneofKind: "getUpdates",
|
|
19750
|
+
getUpdates: GetUpdatesInput.create({
|
|
19751
|
+
bucket: UpdateBucket.create({
|
|
19752
|
+
type: {
|
|
19753
|
+
oneofKind: "user",
|
|
19754
|
+
user: {}
|
|
19755
|
+
}
|
|
19756
|
+
}),
|
|
19757
|
+
startSeq: BigInt(cursor),
|
|
19758
|
+
totalLimit: defaultCatchUpTotalLimit
|
|
19759
|
+
})
|
|
19760
|
+
});
|
|
19761
|
+
const payload = result.getUpdates;
|
|
19762
|
+
const deliveredSeq = Number(payload.seq ?? 0n);
|
|
19763
|
+
if (!Number.isSafeInteger(deliveredSeq)) {
|
|
19764
|
+
this.log.warn?.("GET_UPDATES user catch-up returned non-integer seq; aborting", { deliveredSeq });
|
|
19765
|
+
return;
|
|
19766
|
+
}
|
|
19767
|
+
if (payload.resultType === GetUpdatesResult_ResultType.TOO_LONG) {
|
|
19768
|
+
this.log.warn?.("GET_UPDATES user catch-up too long; fast-forwarding cursor", { seq: deliveredSeq });
|
|
19769
|
+
this.bumpUserSeq(deliveredSeq);
|
|
19770
|
+
if (payload.date !== 0n) {
|
|
19771
|
+
this.state.dateCursor = payload.date;
|
|
19772
|
+
}
|
|
19773
|
+
this.scheduleStateSave();
|
|
19774
|
+
return;
|
|
19775
|
+
}
|
|
19776
|
+
for (const update of payload.updates) {
|
|
19777
|
+
await this.handleUpdate(update);
|
|
19778
|
+
}
|
|
19779
|
+
this.bumpUserSeq(deliveredSeq);
|
|
19780
|
+
if (payload.date !== 0n) {
|
|
19781
|
+
this.state.dateCursor = payload.date;
|
|
19782
|
+
}
|
|
19783
|
+
this.scheduleStateSave();
|
|
19784
|
+
if (payload.final) {
|
|
19785
|
+
return;
|
|
19786
|
+
}
|
|
19787
|
+
if (deliveredSeq <= cursor) {
|
|
19788
|
+
this.log.warn?.("GET_UPDATES user catch-up made no progress; aborting", { cursor, deliveredSeq });
|
|
19789
|
+
return;
|
|
19790
|
+
}
|
|
19791
|
+
cursor = deliveredSeq;
|
|
19792
|
+
}
|
|
19793
|
+
}
|
|
19554
19794
|
requestCatchUpChat(params) {
|
|
19555
19795
|
const previous = this.catchUpRequestedByChatId.get(params.chatId);
|
|
19556
19796
|
this.catchUpRequestedByChatId.set(params.chatId, {
|
|
@@ -19715,7 +19955,8 @@ class InlineSdkClient {
|
|
|
19715
19955
|
const snapshot = {
|
|
19716
19956
|
version: 1,
|
|
19717
19957
|
...this.state.dateCursor != null ? { dateCursor: this.state.dateCursor } : {},
|
|
19718
|
-
...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {}
|
|
19958
|
+
...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {},
|
|
19959
|
+
...this.state.lastUserSeq != null ? { lastUserSeq: this.state.lastUserSeq } : {}
|
|
19719
19960
|
};
|
|
19720
19961
|
this.saveInFlight = store.save(snapshot).catch((error) => {
|
|
19721
19962
|
this.log.warn?.("Failed to persist SDK state", error);
|
|
@@ -34029,9 +34270,17 @@ function looksLikeInlineTargetId(raw, normalizedInput) {
|
|
|
34029
34270
|
// src/inline/monitor.ts
|
|
34030
34271
|
import { mkdir } from "node:fs/promises";
|
|
34031
34272
|
import path2 from "node:path";
|
|
34273
|
+
import {
|
|
34274
|
+
buildCommandTextFromArgs,
|
|
34275
|
+
findCommandByNativeName,
|
|
34276
|
+
parseCommandArgs,
|
|
34277
|
+
resolveCommandArgMenu
|
|
34278
|
+
} from "openclaw/plugin-sdk/native-command-registry";
|
|
34279
|
+
import { resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
34280
|
+
import { applyModelOverrideToSessionEntry, updateSessionStore } from "openclaw/plugin-sdk/config-runtime";
|
|
34281
|
+
import { buildModelsProviderData } from "openclaw/plugin-sdk/models-provider-runtime";
|
|
34032
34282
|
|
|
34033
34283
|
// src/sdk-runtime-compat.ts
|
|
34034
|
-
import { createMessageToolButtonsSchema } from "openclaw/plugin-sdk/channel-actions";
|
|
34035
34284
|
var HISTORY_CONTEXT_MARKER = "[Chat messages since your last reply - for context]";
|
|
34036
34285
|
var CURRENT_MESSAGE_MARKER = "[Current message - respond to this]";
|
|
34037
34286
|
var MAX_HISTORY_KEYS = 1000;
|
|
@@ -34122,14 +34371,6 @@ function recordPendingHistoryEntryIfEnabled(params) {
|
|
|
34122
34371
|
limit: params.limit
|
|
34123
34372
|
});
|
|
34124
34373
|
}
|
|
34125
|
-
var TYPEBOX_OPTIONAL_SYMBOL = Symbol.for("TypeBox.Optional");
|
|
34126
|
-
function markTypeBoxOptional(schema) {
|
|
34127
|
-
schema[TYPEBOX_OPTIONAL_SYMBOL] = "Optional";
|
|
34128
|
-
return schema;
|
|
34129
|
-
}
|
|
34130
|
-
function createMessageToolButtonsSchemaCompat() {
|
|
34131
|
-
return markTypeBoxOptional(createMessageToolButtonsSchema());
|
|
34132
|
-
}
|
|
34133
34374
|
function extensionForMimeCompat(mime) {
|
|
34134
34375
|
const normalized = mime?.trim().toLowerCase();
|
|
34135
34376
|
if (!normalized)
|
|
@@ -34230,44 +34471,6 @@ async function createChannelReplyPipelineCompat(params) {
|
|
|
34230
34471
|
};
|
|
34231
34472
|
}
|
|
34232
34473
|
}
|
|
34233
|
-
async function loadNativeCommandHelpersCompat() {
|
|
34234
|
-
try {
|
|
34235
|
-
const sdk = await import("openclaw/plugin-sdk/command-auth");
|
|
34236
|
-
const listNativeCommandSpecsForConfig = typeof sdk.listNativeCommandSpecsForConfig === "function" ? sdk.listNativeCommandSpecsForConfig : null;
|
|
34237
|
-
const listSkillCommandsForAgents = typeof sdk.listSkillCommandsForAgents === "function" ? sdk.listSkillCommandsForAgents : null;
|
|
34238
|
-
if (!listNativeCommandSpecsForConfig || !listSkillCommandsForAgents) {
|
|
34239
|
-
throw new Error("command-auth helpers unavailable");
|
|
34240
|
-
}
|
|
34241
|
-
return {
|
|
34242
|
-
available: true,
|
|
34243
|
-
listNativeCommandSpecsForConfig,
|
|
34244
|
-
listSkillCommandsForAgents
|
|
34245
|
-
};
|
|
34246
|
-
} catch {
|
|
34247
|
-
return {
|
|
34248
|
-
available: false,
|
|
34249
|
-
listNativeCommandSpecsForConfig: () => [],
|
|
34250
|
-
listSkillCommandsForAgents: () => []
|
|
34251
|
-
};
|
|
34252
|
-
}
|
|
34253
|
-
}
|
|
34254
|
-
async function loadPluginCommandSpecsCompat(provider) {
|
|
34255
|
-
try {
|
|
34256
|
-
const sdk = await import("openclaw/plugin-sdk/plugin-runtime");
|
|
34257
|
-
if (typeof sdk.getPluginCommandSpecs !== "function") {
|
|
34258
|
-
throw new Error("plugin runtime command helper unavailable");
|
|
34259
|
-
}
|
|
34260
|
-
return {
|
|
34261
|
-
available: true,
|
|
34262
|
-
specs: sdk.getPluginCommandSpecs(provider)
|
|
34263
|
-
};
|
|
34264
|
-
} catch {
|
|
34265
|
-
return {
|
|
34266
|
-
available: false,
|
|
34267
|
-
specs: []
|
|
34268
|
-
};
|
|
34269
|
-
}
|
|
34270
|
-
}
|
|
34271
34474
|
|
|
34272
34475
|
// src/inline/message-formatting.ts
|
|
34273
34476
|
var INLINE_FORMATTING_NOTE = "Inline formatting note: prefer bullet lists over markdown tables. If a table is necessary, render it inside a fenced code block. Do not wrap bare URLs in inline code or backticks. Use plain URLs or markdown links. Use inline code only for actual code, commands, file paths, env vars, or identifiers.";
|
|
@@ -34926,246 +35129,28 @@ function summarizeInlineMessageContent(message) {
|
|
|
34926
35129
|
};
|
|
34927
35130
|
}
|
|
34928
35131
|
|
|
34929
|
-
// src/inline/
|
|
34930
|
-
var
|
|
34931
|
-
|
|
34932
|
-
|
|
34933
|
-
|
|
34934
|
-
|
|
34935
|
-
|
|
34936
|
-
|
|
34937
|
-
|
|
34938
|
-
|
|
34939
|
-
|
|
34940
|
-
|
|
34941
|
-
|
|
34942
|
-
|
|
34943
|
-
{ value: "provider", label: "Provider" },
|
|
34944
|
-
{ value: "limit", label: "Limit" },
|
|
34945
|
-
{ value: "summary", label: "Summary" },
|
|
34946
|
-
{ value: "audio", label: "Audio" },
|
|
34947
|
-
{ value: "help", label: "Help" }
|
|
34948
|
-
]
|
|
34949
|
-
},
|
|
34950
|
-
{ name: "value", description: "Provider, limit, or text" }
|
|
34951
|
-
],
|
|
34952
|
-
argsMenu: {
|
|
34953
|
-
arg: "action",
|
|
34954
|
-
title: "Choose TTS action:"
|
|
34955
|
-
}
|
|
34956
|
-
},
|
|
34957
|
-
{
|
|
34958
|
-
key: "session",
|
|
34959
|
-
nativeName: "session",
|
|
34960
|
-
args: [
|
|
34961
|
-
{ name: "action", description: "idle | max-age", choices: ["idle", "max-age"] },
|
|
34962
|
-
{ name: "value", description: "Duration or off" }
|
|
34963
|
-
],
|
|
34964
|
-
argsMenu: "auto"
|
|
34965
|
-
},
|
|
34966
|
-
{
|
|
34967
|
-
key: "subagents",
|
|
34968
|
-
nativeName: "subagents",
|
|
34969
|
-
args: [
|
|
34970
|
-
{
|
|
34971
|
-
name: "action",
|
|
34972
|
-
description: "list | kill | log | info | send | steer | spawn",
|
|
34973
|
-
choices: ["list", "kill", "log", "info", "send", "steer", "spawn"]
|
|
34974
|
-
},
|
|
34975
|
-
{ name: "target", description: "Run id, index, or session key" },
|
|
34976
|
-
{ name: "value", description: "Additional input" }
|
|
34977
|
-
],
|
|
34978
|
-
argsMenu: "auto"
|
|
34979
|
-
},
|
|
34980
|
-
{
|
|
34981
|
-
key: "acp",
|
|
34982
|
-
nativeName: "acp",
|
|
34983
|
-
args: [
|
|
34984
|
-
{
|
|
34985
|
-
name: "action",
|
|
34986
|
-
description: "Action to run",
|
|
34987
|
-
choices: [
|
|
34988
|
-
"spawn",
|
|
34989
|
-
"cancel",
|
|
34990
|
-
"steer",
|
|
34991
|
-
"close",
|
|
34992
|
-
"sessions",
|
|
34993
|
-
"status",
|
|
34994
|
-
"set-mode",
|
|
34995
|
-
"set",
|
|
34996
|
-
"cwd",
|
|
34997
|
-
"permissions",
|
|
34998
|
-
"timeout",
|
|
34999
|
-
"model",
|
|
35000
|
-
"reset-options",
|
|
35001
|
-
"doctor",
|
|
35002
|
-
"install",
|
|
35003
|
-
"help"
|
|
35004
|
-
]
|
|
35005
|
-
},
|
|
35006
|
-
{ name: "value", description: "Action arguments" }
|
|
35007
|
-
],
|
|
35008
|
-
argsMenu: "auto"
|
|
35009
|
-
},
|
|
35010
|
-
{
|
|
35011
|
-
key: "usage",
|
|
35012
|
-
nativeName: "usage",
|
|
35013
|
-
args: [{ name: "mode", description: "off, tokens, full, or cost", choices: ["off", "tokens", "full", "cost"] }],
|
|
35014
|
-
argsMenu: "auto"
|
|
35015
|
-
},
|
|
35016
|
-
{
|
|
35017
|
-
key: "activation",
|
|
35018
|
-
nativeName: "activation",
|
|
35019
|
-
args: [{ name: "mode", description: "mention or always", choices: ["mention", "always"] }],
|
|
35020
|
-
argsMenu: "auto"
|
|
35021
|
-
},
|
|
35022
|
-
{
|
|
35023
|
-
key: "send",
|
|
35024
|
-
nativeName: "send",
|
|
35025
|
-
args: [{ name: "mode", description: "on, off, or inherit", choices: ["on", "off", "inherit"] }],
|
|
35026
|
-
argsMenu: "auto"
|
|
35027
|
-
},
|
|
35028
|
-
{
|
|
35029
|
-
key: "think",
|
|
35030
|
-
nativeName: "think",
|
|
35031
|
-
args: [{ name: "level", description: "thinking level", choices: [...THINKING_LEVEL_CHOICES] }],
|
|
35032
|
-
argsMenu: "auto"
|
|
35033
|
-
},
|
|
35034
|
-
{
|
|
35035
|
-
key: "verbose",
|
|
35036
|
-
nativeName: "verbose",
|
|
35037
|
-
args: [{ name: "mode", description: "on or off", choices: ["on", "off"] }],
|
|
35038
|
-
argsMenu: "auto"
|
|
35039
|
-
},
|
|
35040
|
-
{
|
|
35041
|
-
key: "fast",
|
|
35042
|
-
nativeName: "fast",
|
|
35043
|
-
args: [{ name: "mode", description: "status, on, or off", choices: ["status", "on", "off"] }],
|
|
35044
|
-
argsMenu: "auto"
|
|
35045
|
-
},
|
|
35046
|
-
{
|
|
35047
|
-
key: "reasoning",
|
|
35048
|
-
nativeName: "reasoning",
|
|
35049
|
-
args: [{ name: "mode", description: "on, off, or stream", choices: ["on", "off", "stream"] }],
|
|
35050
|
-
argsMenu: "auto"
|
|
35051
|
-
},
|
|
35052
|
-
{
|
|
35053
|
-
key: "elevated",
|
|
35054
|
-
nativeName: "elevated",
|
|
35055
|
-
args: [{ name: "mode", description: "on, off, ask, or full", choices: ["on", "off", "ask", "full"] }],
|
|
35056
|
-
argsMenu: "auto"
|
|
35057
|
-
}
|
|
35058
|
-
];
|
|
35059
|
-
function parsePositionalArgs(definitions, raw) {
|
|
35060
|
-
const values = {};
|
|
35061
|
-
const trimmed = raw.trim();
|
|
35062
|
-
if (!trimmed)
|
|
35063
|
-
return values;
|
|
35064
|
-
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
35065
|
-
let index = 0;
|
|
35066
|
-
for (const definition of definitions) {
|
|
35067
|
-
if (index >= tokens.length)
|
|
35068
|
-
break;
|
|
35069
|
-
const token = tokens[index];
|
|
35070
|
-
if (!token)
|
|
35071
|
-
break;
|
|
35072
|
-
values[definition.name] = token;
|
|
35073
|
-
index += 1;
|
|
35074
|
-
}
|
|
35075
|
-
return values;
|
|
35076
|
-
}
|
|
35077
|
-
function parseCommandArgs(command, raw) {
|
|
35078
|
-
const trimmed = raw?.trim();
|
|
35079
|
-
if (!trimmed)
|
|
35080
|
-
return;
|
|
35081
|
-
if (!command.args || command.argsParsing === "none") {
|
|
35082
|
-
return { raw: trimmed };
|
|
35083
|
-
}
|
|
35084
|
-
return {
|
|
35085
|
-
raw: trimmed,
|
|
35086
|
-
values: parsePositionalArgs(command.args, trimmed)
|
|
35087
|
-
};
|
|
35088
|
-
}
|
|
35089
|
-
function findCommandByNativeName(name) {
|
|
35090
|
-
const normalized = name.trim().toLowerCase();
|
|
35091
|
-
return COMPAT_COMMANDS.find((command) => command.nativeName.toLowerCase() === normalized);
|
|
35092
|
-
}
|
|
35093
|
-
function resolveCommandArgChoices(arg) {
|
|
35094
|
-
const raw = arg.choices ?? [];
|
|
35095
|
-
return raw.map((choice) => typeof choice === "string" ? { value: choice, label: choice } : choice);
|
|
35096
|
-
}
|
|
35097
|
-
function resolveCommandArgMenu(params) {
|
|
35098
|
-
const { command, args } = params;
|
|
35099
|
-
if (!command.args || !command.argsMenu)
|
|
35100
|
-
return null;
|
|
35101
|
-
if (command.argsParsing === "none")
|
|
35102
|
-
return null;
|
|
35103
|
-
const argName = command.argsMenu === "auto" ? command.args.find((arg2) => resolveCommandArgChoices(arg2).length > 0)?.name : command.argsMenu.arg;
|
|
35104
|
-
if (!argName)
|
|
35105
|
-
return null;
|
|
35106
|
-
if (args?.values && args.values[argName] != null)
|
|
35107
|
-
return null;
|
|
35108
|
-
if (args?.raw && !args.values)
|
|
35109
|
-
return null;
|
|
35110
|
-
const arg = command.args.find((entry) => entry.name === argName);
|
|
35111
|
-
if (!arg)
|
|
35112
|
-
return null;
|
|
35113
|
-
const choices = resolveCommandArgChoices(arg);
|
|
35114
|
-
if (choices.length === 0)
|
|
35115
|
-
return null;
|
|
35116
|
-
const title = command.argsMenu !== "auto" ? command.argsMenu.title : undefined;
|
|
35117
|
-
return {
|
|
35118
|
-
arg,
|
|
35119
|
-
choices,
|
|
35120
|
-
...title ? { title } : {}
|
|
35121
|
-
};
|
|
35122
|
-
}
|
|
35123
|
-
function buildCommandTextFromArgs(command, args) {
|
|
35124
|
-
const values = args?.values ?? {};
|
|
35125
|
-
const argDefs = command.args ?? [];
|
|
35126
|
-
const renderedArgs = [];
|
|
35127
|
-
for (const argDef of argDefs) {
|
|
35128
|
-
const value = values[argDef.name];
|
|
35129
|
-
if (value == null)
|
|
35130
|
-
continue;
|
|
35131
|
-
const normalized = typeof value === "string" ? value.trim() : String(value);
|
|
35132
|
-
if (!normalized)
|
|
35133
|
-
continue;
|
|
35134
|
-
renderedArgs.push(normalized);
|
|
35132
|
+
// src/inline/monitor.ts
|
|
35133
|
+
var CHANNEL_ID = "inline";
|
|
35134
|
+
function summarizeSdkMeta(meta3) {
|
|
35135
|
+
if (meta3 == null)
|
|
35136
|
+
return "";
|
|
35137
|
+
if (meta3 instanceof Error)
|
|
35138
|
+
return `${meta3.name}: ${meta3.message}`;
|
|
35139
|
+
if (typeof meta3 === "string")
|
|
35140
|
+
return meta3;
|
|
35141
|
+
try {
|
|
35142
|
+
const json2 = JSON.stringify(meta3);
|
|
35143
|
+
return json2 === undefined ? String(meta3) : json2;
|
|
35144
|
+
} catch {
|
|
35145
|
+
return String(meta3);
|
|
35135
35146
|
}
|
|
35136
|
-
return renderedArgs.length > 0 ? `/${command.nativeName} ${renderedArgs.join(" ")}` : `/${command.nativeName}`;
|
|
35137
35147
|
}
|
|
35138
|
-
function
|
|
35139
|
-
const
|
|
35140
|
-
|
|
35141
|
-
|
|
35142
|
-
|
|
35143
|
-
const command = findCommandByNativeName(match[1]);
|
|
35144
|
-
if (!command)
|
|
35145
|
-
return null;
|
|
35146
|
-
const args = parseCommandArgs(command, match[2]);
|
|
35147
|
-
const menu = resolveCommandArgMenu({
|
|
35148
|
-
command,
|
|
35149
|
-
...args ? { args } : {}
|
|
35150
|
-
});
|
|
35151
|
-
if (!menu)
|
|
35152
|
-
return null;
|
|
35153
|
-
const title = menu.title ?? `Choose ${menu.arg.description || menu.arg.name} for /${command.nativeName}.`;
|
|
35154
|
-
const rows = [];
|
|
35155
|
-
for (let index = 0;index < menu.choices.length; index += 2) {
|
|
35156
|
-
const slice = menu.choices.slice(index, index + 2);
|
|
35157
|
-
rows.push(slice.map((choice) => ({
|
|
35158
|
-
text: choice.label,
|
|
35159
|
-
callback_data: buildCommandTextFromArgs(command, {
|
|
35160
|
-
values: { [menu.arg.name]: choice.value }
|
|
35161
|
-
})
|
|
35162
|
-
})));
|
|
35163
|
-
}
|
|
35164
|
-
return { title, buttons: rows };
|
|
35148
|
+
function formatSdkLogLine(message, meta3) {
|
|
35149
|
+
const detail = summarizeSdkMeta(meta3);
|
|
35150
|
+
if (!detail)
|
|
35151
|
+
return message;
|
|
35152
|
+
return `${message} ${detail}`;
|
|
35165
35153
|
}
|
|
35166
|
-
|
|
35167
|
-
// src/inline/monitor.ts
|
|
35168
|
-
var CHANNEL_ID = "inline";
|
|
35169
35154
|
var DEFAULT_DM_HISTORY_LIMIT = 6;
|
|
35170
35155
|
var HISTORY_LINE_MAX_CHARS = 280;
|
|
35171
35156
|
var URL_LIKE_PATTERN = /https?:\/\/\S+/i;
|
|
@@ -35228,35 +35213,125 @@ function callbackDataToUtf8(data) {
|
|
|
35228
35213
|
return;
|
|
35229
35214
|
}
|
|
35230
35215
|
}
|
|
35216
|
+
function buildInlineInboundMessageSid(params) {
|
|
35217
|
+
if (params.callbackActionEvent) {
|
|
35218
|
+
return `callback:${String(params.callbackActionEvent.targetMessageId)}:${String(params.callbackActionEvent.interactionId)}`;
|
|
35219
|
+
}
|
|
35220
|
+
return String(params.msgId);
|
|
35221
|
+
}
|
|
35231
35222
|
var INLINE_ACTION_MAX_ROWS = 8;
|
|
35232
35223
|
var INLINE_ACTION_MAX_PER_ROW = 8;
|
|
35233
35224
|
function isRecord3(value) {
|
|
35234
35225
|
return typeof value === "object" && value !== null;
|
|
35235
35226
|
}
|
|
35227
|
+
function resolveInlineNativeCommandMenu(params) {
|
|
35228
|
+
const normalized = params.commandBody.trim();
|
|
35229
|
+
const match = normalized.match(/^\/([^\s]+)(?:\s+([\s\S]+))?$/);
|
|
35230
|
+
if (!match?.[1])
|
|
35231
|
+
return null;
|
|
35232
|
+
const command = findCommandByNativeName(match[1], "telegram");
|
|
35233
|
+
if (!command)
|
|
35234
|
+
return null;
|
|
35235
|
+
const args = parseCommandArgs(command, match[2]);
|
|
35236
|
+
const menu = resolveCommandArgMenu({
|
|
35237
|
+
command,
|
|
35238
|
+
...args ? { args } : {},
|
|
35239
|
+
cfg: params.cfg
|
|
35240
|
+
});
|
|
35241
|
+
if (!menu)
|
|
35242
|
+
return null;
|
|
35243
|
+
const title = menu.title ?? `Choose ${menu.arg.description || menu.arg.name} for /${command.nativeName}.`;
|
|
35244
|
+
const rows = [];
|
|
35245
|
+
for (let index = 0;index < menu.choices.length; index += 2) {
|
|
35246
|
+
const slice = menu.choices.slice(index, index + 2);
|
|
35247
|
+
rows.push(slice.map((choice) => ({
|
|
35248
|
+
text: choice.label,
|
|
35249
|
+
callback_data: buildCommandTextFromArgs(command, {
|
|
35250
|
+
values: { [menu.arg.name]: choice.value }
|
|
35251
|
+
})
|
|
35252
|
+
})));
|
|
35253
|
+
}
|
|
35254
|
+
return { title, buttons: rows };
|
|
35255
|
+
}
|
|
35236
35256
|
function mapInlineModelPickerCallbackToCommand(raw) {
|
|
35237
|
-
const
|
|
35238
|
-
if (!
|
|
35257
|
+
const callback = parseInlineModelPickerCallback(raw);
|
|
35258
|
+
if (!callback)
|
|
35239
35259
|
return;
|
|
35240
|
-
|
|
35241
|
-
|
|
35260
|
+
switch (callback.type) {
|
|
35261
|
+
case "providers":
|
|
35262
|
+
case "back":
|
|
35263
|
+
return "/models";
|
|
35264
|
+
case "list":
|
|
35265
|
+
return `/models ${callback.provider} ${String(callback.page)}`;
|
|
35266
|
+
case "select":
|
|
35267
|
+
return callback.provider ? `/model ${callback.provider}/${callback.model}` : `/model ${callback.model}`;
|
|
35242
35268
|
}
|
|
35269
|
+
}
|
|
35270
|
+
function parseInlineModelPickerCallback(raw) {
|
|
35271
|
+
const trimmed = raw.trim();
|
|
35272
|
+
if (!trimmed)
|
|
35273
|
+
return null;
|
|
35274
|
+
if (trimmed === "mdl_prov")
|
|
35275
|
+
return { type: "providers" };
|
|
35276
|
+
if (trimmed === "mdl_back")
|
|
35277
|
+
return { type: "back" };
|
|
35243
35278
|
const listMatch = trimmed.match(/^mdl_list_([a-z0-9_-]+)_(\d+)$/i);
|
|
35244
35279
|
if (listMatch?.[1] && listMatch[2]) {
|
|
35245
35280
|
const provider = listMatch[1].trim();
|
|
35246
35281
|
const page = Number.parseInt(listMatch[2], 10);
|
|
35247
35282
|
if (provider && Number.isFinite(page) && page > 0) {
|
|
35248
|
-
return
|
|
35283
|
+
return { type: "list", provider, page };
|
|
35249
35284
|
}
|
|
35250
35285
|
}
|
|
35251
35286
|
const standardSelectionMatch = trimmed.match(/^mdl_sel_(.+)$/);
|
|
35252
35287
|
if (standardSelectionMatch?.[1]?.trim()) {
|
|
35253
|
-
|
|
35288
|
+
const modelRef = standardSelectionMatch[1].trim();
|
|
35289
|
+
const slashIndex = modelRef.indexOf("/");
|
|
35290
|
+
if (slashIndex > 0 && slashIndex < modelRef.length - 1) {
|
|
35291
|
+
return {
|
|
35292
|
+
type: "select",
|
|
35293
|
+
provider: modelRef.slice(0, slashIndex),
|
|
35294
|
+
model: modelRef.slice(slashIndex + 1)
|
|
35295
|
+
};
|
|
35296
|
+
}
|
|
35254
35297
|
}
|
|
35255
35298
|
const compactSelectionMatch = trimmed.match(/^mdl_sel\/(.+)$/);
|
|
35256
35299
|
if (compactSelectionMatch?.[1]?.trim()) {
|
|
35257
|
-
return
|
|
35300
|
+
return { type: "select", model: compactSelectionMatch[1].trim() };
|
|
35258
35301
|
}
|
|
35259
|
-
return;
|
|
35302
|
+
return null;
|
|
35303
|
+
}
|
|
35304
|
+
function resolveInlineModelPickerSelection(params) {
|
|
35305
|
+
if (params.callback.provider) {
|
|
35306
|
+
return {
|
|
35307
|
+
kind: "resolved",
|
|
35308
|
+
provider: params.callback.provider,
|
|
35309
|
+
model: params.callback.model
|
|
35310
|
+
};
|
|
35311
|
+
}
|
|
35312
|
+
const matchingProviders = params.providers.filter((id) => params.byProvider.get(id)?.has(params.callback.model));
|
|
35313
|
+
if (matchingProviders.length === 1 && matchingProviders[0]) {
|
|
35314
|
+
return {
|
|
35315
|
+
kind: "resolved",
|
|
35316
|
+
provider: matchingProviders[0],
|
|
35317
|
+
model: params.callback.model
|
|
35318
|
+
};
|
|
35319
|
+
}
|
|
35320
|
+
return {
|
|
35321
|
+
kind: "ambiguous",
|
|
35322
|
+
model: params.callback.model
|
|
35323
|
+
};
|
|
35324
|
+
}
|
|
35325
|
+
function buildInlineModelProviderButtons(providers) {
|
|
35326
|
+
const rows = [];
|
|
35327
|
+
for (let index = 0;index < providers.length; index += 2) {
|
|
35328
|
+
const slice = providers.slice(index, index + 2);
|
|
35329
|
+
rows.push(slice.map((provider) => ({
|
|
35330
|
+
text: `${provider.id} (${provider.count})`,
|
|
35331
|
+
callback_data: `mdl_list_${provider.id}_1`
|
|
35332
|
+
})));
|
|
35333
|
+
}
|
|
35334
|
+
return rows;
|
|
35260
35335
|
}
|
|
35261
35336
|
function normalizeInlineActionCallbackData(raw) {
|
|
35262
35337
|
const trimmed = raw.trim();
|
|
@@ -35264,6 +35339,14 @@ function normalizeInlineActionCallbackData(raw) {
|
|
|
35264
35339
|
return "";
|
|
35265
35340
|
return mapInlineModelPickerCallbackToCommand(trimmed) ?? trimmed;
|
|
35266
35341
|
}
|
|
35342
|
+
function normalizeInlineTelegramButtonCallbackData(raw) {
|
|
35343
|
+
const trimmed = raw.trim();
|
|
35344
|
+
if (!trimmed)
|
|
35345
|
+
return "";
|
|
35346
|
+
if (parseInlineModelPickerCallback(trimmed))
|
|
35347
|
+
return trimmed;
|
|
35348
|
+
return normalizeInlineActionCallbackData(trimmed);
|
|
35349
|
+
}
|
|
35267
35350
|
function normalizeReplyMarkupButtonsWith(raw, options) {
|
|
35268
35351
|
if (!Array.isArray(raw))
|
|
35269
35352
|
return [];
|
|
@@ -35305,7 +35388,7 @@ function resolveInlineReplyActions(payload) {
|
|
|
35305
35388
|
} else if (telegramData && Object.prototype.hasOwnProperty.call(telegramData, "buttons")) {
|
|
35306
35389
|
rawButtons = telegramData.buttons;
|
|
35307
35390
|
hasExplicitButtons = true;
|
|
35308
|
-
mapCallbackData =
|
|
35391
|
+
mapCallbackData = normalizeInlineTelegramButtonCallbackData;
|
|
35309
35392
|
} else if (Object.prototype.hasOwnProperty.call(payload, "buttons")) {
|
|
35310
35393
|
rawButtons = payload.buttons;
|
|
35311
35394
|
hasExplicitButtons = true;
|
|
@@ -35870,19 +35953,35 @@ async function monitorInlineProvider(params) {
|
|
|
35870
35953
|
const stateDir = core3.state.resolveStateDir();
|
|
35871
35954
|
const statePath = path2.join(stateDir, "channels", "inline", `${account.accountId}.json`);
|
|
35872
35955
|
await mkdir(path2.dirname(statePath), { recursive: true });
|
|
35956
|
+
let client = null;
|
|
35957
|
+
const pushDiagnostics = (patch) => {
|
|
35958
|
+
statusSink?.({
|
|
35959
|
+
...patch ?? {},
|
|
35960
|
+
...client ? { diagnostics: client.getDiagnostics() } : {}
|
|
35961
|
+
});
|
|
35962
|
+
};
|
|
35873
35963
|
const sdkLog = {
|
|
35874
|
-
debug: (msg) => log?.debug?.(msg),
|
|
35875
|
-
info: (msg) => log?.info(msg),
|
|
35876
|
-
warn: (msg) =>
|
|
35877
|
-
|
|
35964
|
+
debug: (msg, meta3) => log?.debug?.(formatSdkLogLine(msg, meta3)),
|
|
35965
|
+
info: (msg, meta3) => log?.info(formatSdkLogLine(msg, meta3)),
|
|
35966
|
+
warn: (msg, meta3) => {
|
|
35967
|
+
const line = formatSdkLogLine(msg, meta3);
|
|
35968
|
+
log?.warn(line);
|
|
35969
|
+
pushDiagnostics({ lastError: line });
|
|
35970
|
+
},
|
|
35971
|
+
error: (msg, meta3) => {
|
|
35972
|
+
const line = formatSdkLogLine(msg, meta3);
|
|
35973
|
+
log?.error(line);
|
|
35974
|
+
pushDiagnostics({ lastError: line });
|
|
35975
|
+
}
|
|
35878
35976
|
};
|
|
35879
|
-
|
|
35977
|
+
client = new InlineSdkClient({
|
|
35880
35978
|
baseUrl: account.baseUrl,
|
|
35881
35979
|
token,
|
|
35882
35980
|
logger: sdkLog,
|
|
35883
35981
|
state: new JsonFileStateStore(statePath)
|
|
35884
35982
|
});
|
|
35885
35983
|
await client.connect(abortSignal);
|
|
35984
|
+
pushDiagnostics();
|
|
35886
35985
|
const meResult = await client.invokeRaw(Method.GET_ME, {
|
|
35887
35986
|
oneofKind: "getMe",
|
|
35888
35987
|
getMe: {}
|
|
@@ -35893,6 +35992,7 @@ async function monitorInlineProvider(params) {
|
|
|
35893
35992
|
const meId = meResult.getMe.user.id;
|
|
35894
35993
|
const botUsername = normalizeInlineUsername(meResult.getMe.user.username)?.toLowerCase();
|
|
35895
35994
|
log?.info(`[${account.accountId}] inline connected (me=${String(meId)})`);
|
|
35995
|
+
pushDiagnostics();
|
|
35896
35996
|
const chatCache = new Map;
|
|
35897
35997
|
const senderProfilesById = new Map;
|
|
35898
35998
|
const botMessageIdsByChat = new Map;
|
|
@@ -36140,7 +36240,12 @@ ${JSON.stringify(payload)}`;
|
|
|
36140
36240
|
await answerInlineMessageAction(client, callbackActionEvent.interactionId);
|
|
36141
36241
|
callbackActionAnswered = true;
|
|
36142
36242
|
};
|
|
36143
|
-
|
|
36243
|
+
if (callbackActionEvent) {
|
|
36244
|
+
await answerCallbackIfNeeded().catch((error48) => {
|
|
36245
|
+
runtime2.error?.(`inline callback answer failed: ${String(error48)}`);
|
|
36246
|
+
});
|
|
36247
|
+
}
|
|
36248
|
+
const shouldEditCallbackTargetInPlace = callbackActionEvent != null;
|
|
36144
36249
|
const normalizedCommandBody = callbackCommandBody ?? normalizeInlineCommandBody(rawBody, botUsername);
|
|
36145
36250
|
const allowTextCommands = core3.channel.commands.shouldHandleTextCommands({
|
|
36146
36251
|
cfg,
|
|
@@ -36316,7 +36421,10 @@ ${JSON.stringify(payload)}`;
|
|
|
36316
36421
|
continue;
|
|
36317
36422
|
}
|
|
36318
36423
|
const parseMarkdown = account.config.parseMarkdown ?? true;
|
|
36319
|
-
const nativeCommandMenu =
|
|
36424
|
+
const nativeCommandMenu = resolveInlineNativeCommandMenu({
|
|
36425
|
+
commandBody: normalizedCommandBody,
|
|
36426
|
+
cfg
|
|
36427
|
+
});
|
|
36320
36428
|
if (nativeCommandMenu) {
|
|
36321
36429
|
const menuActions = resolveInlineReplyActions({
|
|
36322
36430
|
channelData: {
|
|
@@ -36325,13 +36433,132 @@ ${JSON.stringify(payload)}`;
|
|
|
36325
36433
|
}
|
|
36326
36434
|
}
|
|
36327
36435
|
});
|
|
36328
|
-
|
|
36329
|
-
|
|
36330
|
-
|
|
36331
|
-
|
|
36436
|
+
let deliveredNativeMenu = false;
|
|
36437
|
+
if (shouldEditCallbackTargetInPlace && callbackActionEvent) {
|
|
36438
|
+
try {
|
|
36439
|
+
const result = await client.invokeRaw(Method.EDIT_MESSAGE, {
|
|
36440
|
+
oneofKind: "editMessage",
|
|
36441
|
+
editMessage: {
|
|
36442
|
+
messageId: callbackActionEvent.targetMessageId,
|
|
36443
|
+
peerId: buildChatPeer2(chatId),
|
|
36444
|
+
text: nativeCommandMenu.title,
|
|
36445
|
+
...menuActions ? { actions: menuActions } : {},
|
|
36446
|
+
parseMarkdown
|
|
36447
|
+
}
|
|
36448
|
+
});
|
|
36449
|
+
if (result.oneofKind !== "editMessage") {
|
|
36450
|
+
throw new Error(`inline native command menu: expected editMessage result, got ${String(result.oneofKind)}`);
|
|
36451
|
+
}
|
|
36452
|
+
deliveredNativeMenu = true;
|
|
36453
|
+
} catch (error48) {
|
|
36454
|
+
runtime2.error?.(`inline native command menu edit failed; falling back to send (${String(error48)})`);
|
|
36455
|
+
}
|
|
36456
|
+
}
|
|
36457
|
+
if (!deliveredNativeMenu) {
|
|
36458
|
+
const sent = await client.sendMessage({
|
|
36459
|
+
chatId,
|
|
36460
|
+
text: nativeCommandMenu.title,
|
|
36461
|
+
...menuActions ? { actions: menuActions } : {}
|
|
36462
|
+
});
|
|
36463
|
+
if (sent.messageId != null) {
|
|
36464
|
+
rememberBotMessageId(botMessageIdsByChat, chatId, sent.messageId);
|
|
36465
|
+
}
|
|
36466
|
+
}
|
|
36467
|
+
statusSink?.({ lastOutboundAt: Date.now() });
|
|
36468
|
+
await answerCallbackIfNeeded().catch((error48) => {
|
|
36469
|
+
runtime2.error?.(`inline callback answer failed: ${String(error48)}`);
|
|
36470
|
+
});
|
|
36471
|
+
continue;
|
|
36472
|
+
}
|
|
36473
|
+
const modelPickerCallbackData = callbackActionEvent ? callbackDataToUtf8(callbackActionEvent.data) : undefined;
|
|
36474
|
+
const modelPickerCallback = modelPickerCallbackData ? parseInlineModelPickerCallback(modelPickerCallbackData) : null;
|
|
36475
|
+
if (shouldEditCallbackTargetInPlace && callbackActionEvent && modelPickerCallback?.type === "select") {
|
|
36476
|
+
const deliverModelPickerEdit = async (text, buttons) => {
|
|
36477
|
+
const actions = resolveInlineReplyActions({
|
|
36478
|
+
channelData: {
|
|
36479
|
+
inline: {
|
|
36480
|
+
buttons
|
|
36481
|
+
}
|
|
36482
|
+
}
|
|
36483
|
+
}) ?? { rows: [] };
|
|
36484
|
+
try {
|
|
36485
|
+
const result = await client.invokeRaw(Method.EDIT_MESSAGE, {
|
|
36486
|
+
oneofKind: "editMessage",
|
|
36487
|
+
editMessage: {
|
|
36488
|
+
messageId: callbackActionEvent.targetMessageId,
|
|
36489
|
+
peerId: buildChatPeer2(chatId),
|
|
36490
|
+
text,
|
|
36491
|
+
actions,
|
|
36492
|
+
parseMarkdown
|
|
36493
|
+
}
|
|
36494
|
+
});
|
|
36495
|
+
if (result.oneofKind !== "editMessage") {
|
|
36496
|
+
throw new Error(`inline model picker edit: expected editMessage result, got ${String(result.oneofKind)}`);
|
|
36497
|
+
}
|
|
36498
|
+
} catch (error48) {
|
|
36499
|
+
runtime2.error?.(`inline model picker edit failed; falling back to send (${String(error48)})`);
|
|
36500
|
+
const sent = await client.sendMessage({
|
|
36501
|
+
chatId,
|
|
36502
|
+
text,
|
|
36503
|
+
actions,
|
|
36504
|
+
parseMarkdown
|
|
36505
|
+
});
|
|
36506
|
+
if (sent.messageId != null) {
|
|
36507
|
+
rememberBotMessageId(botMessageIdsByChat, chatId, sent.messageId);
|
|
36508
|
+
}
|
|
36509
|
+
}
|
|
36510
|
+
};
|
|
36511
|
+
const { byProvider, providers } = await buildModelsProviderData(cfg, route.agentId);
|
|
36512
|
+
const providerButtons = buildInlineModelProviderButtons(providers.map((provider) => ({
|
|
36513
|
+
id: provider,
|
|
36514
|
+
count: byProvider.get(provider)?.size ?? 0
|
|
36515
|
+
})));
|
|
36516
|
+
const selection = resolveInlineModelPickerSelection({
|
|
36517
|
+
callback: modelPickerCallback,
|
|
36518
|
+
providers,
|
|
36519
|
+
byProvider
|
|
36332
36520
|
});
|
|
36333
|
-
if (
|
|
36334
|
-
|
|
36521
|
+
if (selection.kind !== "resolved") {
|
|
36522
|
+
await deliverModelPickerEdit(`Could not resolve model "${selection.model}".
|
|
36523
|
+
|
|
36524
|
+
Select a provider:`, providerButtons);
|
|
36525
|
+
} else {
|
|
36526
|
+
const modelSet = byProvider.get(selection.provider);
|
|
36527
|
+
if (!modelSet?.has(selection.model)) {
|
|
36528
|
+
await deliverModelPickerEdit(`❌ Model "${selection.provider}/${selection.model}" is not allowed.`, []);
|
|
36529
|
+
} else {
|
|
36530
|
+
try {
|
|
36531
|
+
const storePath2 = core3.channel.session.resolveStorePath(cfg.session?.store, {
|
|
36532
|
+
agentId: route.agentId
|
|
36533
|
+
});
|
|
36534
|
+
const resolvedDefault = resolveDefaultModelForAgent({
|
|
36535
|
+
cfg,
|
|
36536
|
+
agentId: route.agentId
|
|
36537
|
+
});
|
|
36538
|
+
const isDefaultSelection = selection.provider === resolvedDefault.provider && selection.model === resolvedDefault.model;
|
|
36539
|
+
await updateSessionStore(storePath2, (store) => {
|
|
36540
|
+
const entry = store[route.sessionKey] ?? {
|
|
36541
|
+
sessionId: route.sessionKey,
|
|
36542
|
+
updatedAt: Date.now()
|
|
36543
|
+
};
|
|
36544
|
+
store[route.sessionKey] = entry;
|
|
36545
|
+
applyModelOverrideToSessionEntry({
|
|
36546
|
+
entry,
|
|
36547
|
+
selection: {
|
|
36548
|
+
provider: selection.provider,
|
|
36549
|
+
model: selection.model,
|
|
36550
|
+
isDefault: isDefaultSelection
|
|
36551
|
+
}
|
|
36552
|
+
});
|
|
36553
|
+
});
|
|
36554
|
+
const actionText = isDefaultSelection ? "reset to default" : `changed to **${selection.provider}/${selection.model}**`;
|
|
36555
|
+
await deliverModelPickerEdit(`✅ Model ${actionText}
|
|
36556
|
+
|
|
36557
|
+
This model will be used for your next message.`, []);
|
|
36558
|
+
} catch (error48) {
|
|
36559
|
+
await deliverModelPickerEdit(`❌ Failed to change model: ${String(error48)}`, []);
|
|
36560
|
+
}
|
|
36561
|
+
}
|
|
36335
36562
|
}
|
|
36336
36563
|
statusSink?.({ lastOutboundAt: Date.now() });
|
|
36337
36564
|
await answerCallbackIfNeeded().catch((error48) => {
|
|
@@ -36421,7 +36648,10 @@ ${currentEntityText}` : null
|
|
|
36421
36648
|
...senderUsername ? { SenderUsername: senderUsername } : {},
|
|
36422
36649
|
Provider: CHANNEL_ID,
|
|
36423
36650
|
Surface: effectiveSurface,
|
|
36424
|
-
MessageSid:
|
|
36651
|
+
MessageSid: buildInlineInboundMessageSid({
|
|
36652
|
+
msgId: msg.id,
|
|
36653
|
+
...callbackActionEvent ? { callbackActionEvent } : {}
|
|
36654
|
+
}),
|
|
36425
36655
|
...replyThreadContext ? { MessageThreadId: String(replyThreadContext.childChatId) } : {},
|
|
36426
36656
|
...replyThreadContext?.threadLabel ? { ThreadLabel: replyThreadContext.threadLabel } : {},
|
|
36427
36657
|
...msg.replyToMsgId != null ? { ReplyToId: String(msg.replyToMsgId) } : {},
|
|
@@ -36476,12 +36706,20 @@ ${currentEntityText}` : null
|
|
|
36476
36706
|
responsePrefixContextProvider: replyPipeline.responsePrefixContextProvider
|
|
36477
36707
|
} : {}
|
|
36478
36708
|
};
|
|
36709
|
+
const callbackTargetMessage = shouldEditCallbackTargetInPlace && callbackActionEvent ? await findChatMessageById({
|
|
36710
|
+
client,
|
|
36711
|
+
chatId,
|
|
36712
|
+
messageId: callbackActionEvent.targetMessageId,
|
|
36713
|
+
limit: REPLY_TARGET_LOOKUP_LIMIT,
|
|
36714
|
+
meId,
|
|
36715
|
+
botMessageIdsByChat
|
|
36716
|
+
}).catch(() => null) : null;
|
|
36479
36717
|
const streamViaEditMessage = account.config.streamViaEditMessage === true && !shouldEditCallbackTargetInPlace;
|
|
36480
36718
|
const defaultReplyToMsgId = isGroup && msg.replyToMsgId != null ? msg.id : undefined;
|
|
36481
36719
|
const disableBlockStreaming = streamViaEditMessage ? true : typeof account.config.blockStreaming === "boolean" ? !account.config.blockStreaming : undefined;
|
|
36482
36720
|
const editStreamState = {
|
|
36483
|
-
messageId: null,
|
|
36484
|
-
accumulatedText: "",
|
|
36721
|
+
messageId: shouldEditCallbackTargetInPlace ? callbackActionEvent?.targetMessageId ?? null : null,
|
|
36722
|
+
accumulatedText: callbackTargetMessage?.message ?? "",
|
|
36485
36723
|
lastPartialText: "",
|
|
36486
36724
|
finalTextAccumulator: "",
|
|
36487
36725
|
failed: false,
|
|
@@ -36649,7 +36887,7 @@ ${currentEntityText}` : null
|
|
|
36649
36887
|
return false;
|
|
36650
36888
|
const nextText = text.trim();
|
|
36651
36889
|
const textForEdit = nextText || editStreamState.accumulatedText;
|
|
36652
|
-
if (!textForEdit)
|
|
36890
|
+
if (!textForEdit && actions === undefined)
|
|
36653
36891
|
return true;
|
|
36654
36892
|
const shouldSkipTextUpdate = !editStreamState.failed && textForEdit === editStreamState.accumulatedText;
|
|
36655
36893
|
if (shouldSkipTextUpdate && actions === undefined)
|
|
@@ -36675,6 +36913,16 @@ ${currentEntityText}` : null
|
|
|
36675
36913
|
return true;
|
|
36676
36914
|
};
|
|
36677
36915
|
if (mediaList.length === 0) {
|
|
36916
|
+
if (shouldEditCallbackTargetInPlace && editStreamState.messageId != null) {
|
|
36917
|
+
const callbackEditActions = outboundActions ?? { rows: [] };
|
|
36918
|
+
if (!outboundText.trim() && outboundActions === undefined) {
|
|
36919
|
+
return;
|
|
36920
|
+
}
|
|
36921
|
+
await updateStreamedMessage(outboundText, callbackEditActions);
|
|
36922
|
+
delivered = true;
|
|
36923
|
+
statusSink?.({ lastOutboundAt: Date.now() });
|
|
36924
|
+
return;
|
|
36925
|
+
}
|
|
36678
36926
|
if (streamViaEditMessage && infoKind === "final" && finalDeliveredForCurrentAssistantMessage && editStreamState.messageId != null) {
|
|
36679
36927
|
await resetEditStreamForAssistantMessage();
|
|
36680
36928
|
}
|
|
@@ -36790,6 +37038,10 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
|
|
|
36790
37038
|
runtime2.error?.(`inline monitor loop crashed: ${String(err)}`);
|
|
36791
37039
|
}
|
|
36792
37040
|
})();
|
|
37041
|
+
const diagnosticsTimer = setInterval(() => {
|
|
37042
|
+
pushDiagnostics();
|
|
37043
|
+
}, 15000);
|
|
37044
|
+
diagnosticsTimer.unref?.();
|
|
36793
37045
|
let stopPromise = null;
|
|
36794
37046
|
const stop = async () => {
|
|
36795
37047
|
if (stopPromise) {
|
|
@@ -36797,6 +37049,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
|
|
|
36797
37049
|
return;
|
|
36798
37050
|
}
|
|
36799
37051
|
stopPromise = (async () => {
|
|
37052
|
+
clearInterval(diagnosticsTimer);
|
|
36800
37053
|
await client.close().catch(() => {});
|
|
36801
37054
|
await loop.catch(() => {});
|
|
36802
37055
|
})();
|
|
@@ -36809,6 +37062,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
|
|
|
36809
37062
|
}
|
|
36810
37063
|
|
|
36811
37064
|
// src/inline/actions.ts
|
|
37065
|
+
import { createMessageToolButtonsSchema } from "openclaw/plugin-sdk/channel-actions";
|
|
36812
37066
|
import {
|
|
36813
37067
|
normalizeInteractiveReply,
|
|
36814
37068
|
reduceInteractiveReply
|
|
@@ -37597,7 +37851,7 @@ function describeInlineMessageTool({
|
|
|
37597
37851
|
const schema = buttonsEnabled ? [
|
|
37598
37852
|
{
|
|
37599
37853
|
properties: {
|
|
37600
|
-
buttons:
|
|
37854
|
+
buttons: createMessageToolButtonsSchema()
|
|
37601
37855
|
}
|
|
37602
37856
|
}
|
|
37603
37857
|
] : [];
|
|
@@ -38649,6 +38903,7 @@ async function probeInlineAccount(account, timeoutMs) {
|
|
|
38649
38903
|
|
|
38650
38904
|
// src/inline/status-issues.ts
|
|
38651
38905
|
import { asString, isRecord as isRecord5 } from "openclaw/plugin-sdk/status-helpers";
|
|
38906
|
+
var RECENT_RUNTIME_ISSUE_MS = 30 * 60 * 1000;
|
|
38652
38907
|
function readInlineProbeSummary(value) {
|
|
38653
38908
|
if (!isRecord5(value)) {
|
|
38654
38909
|
return {};
|
|
@@ -38666,6 +38921,38 @@ function readInlineProbeSummary(value) {
|
|
|
38666
38921
|
function looksLikeAuthError(text) {
|
|
38667
38922
|
return /(401|403|unauth|forbidden|invalid token|token invalid|unauthorized)/i.test(text);
|
|
38668
38923
|
}
|
|
38924
|
+
function readInlineDiagnosticsSummary(value) {
|
|
38925
|
+
if (!isRecord5(value)) {
|
|
38926
|
+
return {};
|
|
38927
|
+
}
|
|
38928
|
+
const protocolValue = isRecord5(value.protocol) ? value.protocol : undefined;
|
|
38929
|
+
const transportValue = (protocolValue && isRecord5(protocolValue.transport) ? protocolValue.transport : undefined) ?? (isRecord5(value.transport) ? value.transport : undefined);
|
|
38930
|
+
const pingValue = protocolValue && isRecord5(protocolValue.ping) ? protocolValue.ping : undefined;
|
|
38931
|
+
return {
|
|
38932
|
+
...protocolValue ? {
|
|
38933
|
+
protocol: {
|
|
38934
|
+
...typeof protocolValue.lastFailureAt === "number" ? { lastFailureAt: protocolValue.lastFailureAt } : {},
|
|
38935
|
+
...asString(protocolValue.lastFailureReason) ? { lastFailureReason: asString(protocolValue.lastFailureReason) } : {},
|
|
38936
|
+
...pingValue && typeof pingValue.lastTimeoutAt === "number" ? {
|
|
38937
|
+
ping: {
|
|
38938
|
+
lastTimeoutAt: pingValue.lastTimeoutAt
|
|
38939
|
+
}
|
|
38940
|
+
} : {}
|
|
38941
|
+
}
|
|
38942
|
+
} : {},
|
|
38943
|
+
...transportValue ? {
|
|
38944
|
+
transport: {
|
|
38945
|
+
...typeof transportValue.reconnectCount === "number" ? { reconnectCount: transportValue.reconnectCount } : {},
|
|
38946
|
+
...asString(transportValue.lastReconnectCause) ? { lastReconnectCause: asString(transportValue.lastReconnectCause) } : {}
|
|
38947
|
+
}
|
|
38948
|
+
} : {}
|
|
38949
|
+
};
|
|
38950
|
+
}
|
|
38951
|
+
function isRecentTimestamp(timestamp) {
|
|
38952
|
+
if (typeof timestamp !== "number" || !Number.isFinite(timestamp) || timestamp <= 0)
|
|
38953
|
+
return false;
|
|
38954
|
+
return Date.now() - timestamp <= RECENT_RUNTIME_ISSUE_MS;
|
|
38955
|
+
}
|
|
38669
38956
|
function collectInlineStatusIssues(accounts) {
|
|
38670
38957
|
const issues = [];
|
|
38671
38958
|
for (const entry of accounts) {
|
|
@@ -38721,6 +39008,25 @@ function collectInlineStatusIssues(accounts) {
|
|
|
38721
39008
|
fix: "Verify token/baseUrl connectivity, then re-run channel status."
|
|
38722
39009
|
});
|
|
38723
39010
|
}
|
|
39011
|
+
const diagnostics = readInlineDiagnosticsSummary(entry.diagnostics);
|
|
39012
|
+
if (isRecentTimestamp(diagnostics.protocol?.lastFailureAt) && (diagnostics.transport?.reconnectCount ?? 0) >= 3) {
|
|
39013
|
+
issues.push({
|
|
39014
|
+
channel: "inline",
|
|
39015
|
+
accountId,
|
|
39016
|
+
kind: "runtime",
|
|
39017
|
+
message: `Inline connection is flapping (${diagnostics.transport?.reconnectCount ?? 0} reconnects). ` + `${diagnostics.protocol?.lastFailureReason ?? diagnostics.transport?.lastReconnectCause ?? "Recent reconnect failures detected."}`,
|
|
39018
|
+
fix: "Inspect gateway logs for websocket close/error details and verify Inline API/network stability."
|
|
39019
|
+
});
|
|
39020
|
+
}
|
|
39021
|
+
if (isRecentTimestamp(diagnostics.protocol?.ping?.lastTimeoutAt)) {
|
|
39022
|
+
issues.push({
|
|
39023
|
+
channel: "inline",
|
|
39024
|
+
accountId,
|
|
39025
|
+
kind: "runtime",
|
|
39026
|
+
message: "Inline ping watchdog triggered a reconnect recently.",
|
|
39027
|
+
fix: "Check websocket latency/packet loss and compare last pong timing in the Inline diagnostics snapshot."
|
|
39028
|
+
});
|
|
39029
|
+
}
|
|
38724
39030
|
}
|
|
38725
39031
|
return issues;
|
|
38726
39032
|
}
|
|
@@ -39735,22 +40041,29 @@ var inlineChannelPlugin = {
|
|
|
39735
40041
|
buildChannelSummary: ({ snapshot }) => buildTokenChannelStatusSummary(snapshot),
|
|
39736
40042
|
probeAccount: async ({ account, timeoutMs }) => await probeInlineAccount(account, timeoutMs),
|
|
39737
40043
|
formatCapabilitiesProbe: ({ probe }) => formatInlineCapabilitiesProbeLines(probe),
|
|
39738
|
-
buildAccountSnapshot: ({ account, runtime: runtime2, probe }) =>
|
|
39739
|
-
|
|
39740
|
-
|
|
39741
|
-
|
|
39742
|
-
|
|
39743
|
-
|
|
39744
|
-
|
|
39745
|
-
|
|
39746
|
-
|
|
39747
|
-
|
|
39748
|
-
|
|
39749
|
-
|
|
39750
|
-
|
|
39751
|
-
|
|
39752
|
-
|
|
39753
|
-
|
|
40044
|
+
buildAccountSnapshot: ({ account, runtime: runtime2, probe }) => {
|
|
40045
|
+
const snapshot = {
|
|
40046
|
+
accountId: account.accountId,
|
|
40047
|
+
name: account.name,
|
|
40048
|
+
enabled: account.enabled,
|
|
40049
|
+
configured: account.configured,
|
|
40050
|
+
baseUrl: account.baseUrl ? "[set]" : "[missing]",
|
|
40051
|
+
tokenSource: account.token ? "config" : account.tokenFile ? "file" : "missing",
|
|
40052
|
+
running: runtime2?.running ?? false,
|
|
40053
|
+
lastStartAt: runtime2?.lastStartAt ?? null,
|
|
40054
|
+
lastStopAt: runtime2?.lastStopAt ?? null,
|
|
40055
|
+
lastError: runtime2?.lastError ?? null,
|
|
40056
|
+
lastInboundAt: runtime2?.lastInboundAt ?? null,
|
|
40057
|
+
lastOutboundAt: runtime2?.lastOutboundAt ?? null,
|
|
40058
|
+
lastProbeAt: runtime2?.lastProbeAt ?? null,
|
|
40059
|
+
...probe !== undefined ? { probe } : {}
|
|
40060
|
+
};
|
|
40061
|
+
const diagnostics = runtime2?.diagnostics;
|
|
40062
|
+
if (diagnostics !== undefined) {
|
|
40063
|
+
snapshot.diagnostics = diagnostics;
|
|
40064
|
+
}
|
|
40065
|
+
return snapshot;
|
|
40066
|
+
}
|
|
39754
40067
|
},
|
|
39755
40068
|
gateway: {
|
|
39756
40069
|
startAccount: async (ctx) => {
|
|
@@ -40516,7 +40829,12 @@ async function callInlineBotApi(params) {
|
|
|
40516
40829
|
if (params.body !== undefined) {
|
|
40517
40830
|
request.body = JSON.stringify(params.body);
|
|
40518
40831
|
}
|
|
40519
|
-
|
|
40832
|
+
let response;
|
|
40833
|
+
try {
|
|
40834
|
+
response = await fetch(url2, request);
|
|
40835
|
+
} catch (error48) {
|
|
40836
|
+
throw new Error(`inline_bot_commands: ${params.method} ${redactInlineBotApiUrl(url2)} fetch failed: ${summarizeInlineBotApiError(error48)}`);
|
|
40837
|
+
}
|
|
40520
40838
|
const payload = await response.json().catch(() => null);
|
|
40521
40839
|
return { response, payload };
|
|
40522
40840
|
};
|
|
@@ -40546,6 +40864,20 @@ async function callInlineBotApi(params) {
|
|
|
40546
40864
|
}
|
|
40547
40865
|
return resolve(headerResult);
|
|
40548
40866
|
}
|
|
40867
|
+
function summarizeInlineBotApiError(error48) {
|
|
40868
|
+
if (error48 instanceof Error) {
|
|
40869
|
+
return `${error48.name}: ${error48.message}`;
|
|
40870
|
+
}
|
|
40871
|
+
return String(error48);
|
|
40872
|
+
}
|
|
40873
|
+
function redactInlineBotApiUrl(raw) {
|
|
40874
|
+
try {
|
|
40875
|
+
const url2 = new URL(raw);
|
|
40876
|
+
return `${url2.protocol}//${url2.host}${url2.pathname.replace(/\/bot[^/]*\//, "/bot<redacted>/")}`;
|
|
40877
|
+
} catch {
|
|
40878
|
+
return raw.replace(/\/bot[^/]*\//, "/bot<redacted>/");
|
|
40879
|
+
}
|
|
40880
|
+
}
|
|
40549
40881
|
|
|
40550
40882
|
// src/inline/bot-commands-tool.ts
|
|
40551
40883
|
var BOT_COMMAND_LIMIT = 100;
|
|
@@ -40706,6 +41038,9 @@ function createInlineBotCommandsTool(ctx) {
|
|
|
40706
41038
|
}
|
|
40707
41039
|
|
|
40708
41040
|
// src/inline/bot-commands-sync.ts
|
|
41041
|
+
import { listNativeCommandSpecsForConfig } from "openclaw/plugin-sdk/native-command-registry";
|
|
41042
|
+
import { getPluginCommandSpecs } from "openclaw/plugin-sdk/plugin-runtime";
|
|
41043
|
+
import { listSkillCommandsForAgents } from "openclaw/plugin-sdk/skill-commands-runtime";
|
|
40709
41044
|
var INLINE_BASE_NATIVE_COMMANDS = [
|
|
40710
41045
|
{ command: "help", description: "Show available commands." },
|
|
40711
41046
|
{ command: "commands", description: "List all slash commands." },
|
|
@@ -40735,15 +41070,6 @@ var INLINE_BASE_NATIVE_COMMANDS = [
|
|
|
40735
41070
|
];
|
|
40736
41071
|
var INLINE_COMMAND_NAME_RE = /^[a-z0-9_]{1,32}$/;
|
|
40737
41072
|
var INLINE_COMMAND_LIMIT = 100;
|
|
40738
|
-
var FALLBACK_NATIVE_COMMAND_HELPERS = {
|
|
40739
|
-
available: false,
|
|
40740
|
-
listNativeCommandSpecsForConfig: () => [],
|
|
40741
|
-
listSkillCommandsForAgents: () => []
|
|
40742
|
-
};
|
|
40743
|
-
var FALLBACK_PLUGIN_COMMAND_SPECS = {
|
|
40744
|
-
available: false,
|
|
40745
|
-
specs: []
|
|
40746
|
-
};
|
|
40747
41073
|
function normalizeDynamicCommandName(raw) {
|
|
40748
41074
|
const trimmed = raw.trim().toLowerCase();
|
|
40749
41075
|
const withoutSlash = trimmed.startsWith("/") ? trimmed.slice(1) : trimmed;
|
|
@@ -40777,10 +41103,12 @@ async function buildInlineNativeCommandsForConfig(params) {
|
|
|
40777
41103
|
if (params.cfg.commands?.debug === true) {
|
|
40778
41104
|
commands.push({ command: "debug", description: "Set runtime debug overrides." });
|
|
40779
41105
|
}
|
|
40780
|
-
const { listNativeCommandSpecsForConfig, listSkillCommandsForAgents } = params.nativeHelpers;
|
|
40781
41106
|
const skillCommands = shouldSyncInlineNativeSkills(params.cfg) ? listSkillCommandsForAgents({ cfg: params.cfg }) : [];
|
|
40782
|
-
const nativeSpecs = listNativeCommandSpecsForConfig(params.cfg, {
|
|
40783
|
-
|
|
41107
|
+
const nativeSpecs = listNativeCommandSpecsForConfig(params.cfg, {
|
|
41108
|
+
skillCommands,
|
|
41109
|
+
provider: "telegram"
|
|
41110
|
+
});
|
|
41111
|
+
const pluginSpecs = getPluginCommandSpecs("inline");
|
|
40784
41112
|
const seen = new Set;
|
|
40785
41113
|
const resolved = [];
|
|
40786
41114
|
for (const base of commands) {
|
|
@@ -40797,19 +41125,13 @@ async function buildInlineNativeCommandsForConfig(params) {
|
|
|
40797
41125
|
async function syncInlineNativeCommands(params) {
|
|
40798
41126
|
const accountIds = listInlineAccountIds(params.cfg);
|
|
40799
41127
|
const nativeEnabled = shouldSyncInlineNativeCommands(params.cfg);
|
|
40800
|
-
const nativeHelpers = nativeEnabled ? await loadNativeCommandHelpersCompat() : FALLBACK_NATIVE_COMMAND_HELPERS;
|
|
40801
|
-
const pluginSpecs = nativeEnabled ? await loadPluginCommandSpecsCompat("inline") : FALLBACK_PLUGIN_COMMAND_SPECS;
|
|
40802
|
-
const usingSdkSource = nativeHelpers.available || pluginSpecs.available;
|
|
40803
41128
|
const allCommands = nativeEnabled ? await buildInlineNativeCommandsForConfig({
|
|
40804
|
-
cfg: params.cfg
|
|
40805
|
-
nativeHelpers,
|
|
40806
|
-
pluginSpecs
|
|
41129
|
+
cfg: params.cfg
|
|
40807
41130
|
}) : [];
|
|
40808
41131
|
const commands = allCommands.slice(0, INLINE_COMMAND_LIMIT);
|
|
40809
41132
|
if (allCommands.length > INLINE_COMMAND_LIMIT) {
|
|
40810
41133
|
params.logger?.warn?.(`[inline] native command sync truncating ${allCommands.length} commands to ${INLINE_COMMAND_LIMIT}`);
|
|
40811
41134
|
}
|
|
40812
|
-
params.logger?.info?.(`[inline] native command source: ${usingSdkSource ? "plugin-sdk" : "fallback"}`);
|
|
40813
41135
|
let synced = 0;
|
|
40814
41136
|
let failed = 0;
|
|
40815
41137
|
for (const accountId of accountIds) {
|
|
@@ -40895,5 +41217,5 @@ export {
|
|
|
40895
41217
|
src_default as default
|
|
40896
41218
|
};
|
|
40897
41219
|
|
|
40898
|
-
//# debugId=
|
|
41220
|
+
//# debugId=3B7100874DF4D61664756E2164756E21
|
|
40899
41221
|
//# sourceMappingURL=index.js.map
|