@inline-openclaw/inline 0.0.40 → 0.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/approval-handler.runtime.js +189 -30
- package/dist/approval-handler.runtime.js.map +5 -5
- package/dist/channel-plugin-api.js +192 -32
- package/dist/channel-plugin-api.js.map +6 -6
- package/dist/index.d.ts +1 -1
- package/dist/inline/actions.d.ts +1 -1
- package/dist/inline/approval-native.d.ts.map +1 -1
- package/dist/inline/channel.d.ts.map +1 -1
- package/dist/inline/exec-approvals.d.ts.map +1 -1
- package/dist/inline/shared.d.ts +1 -1
- package/dist/inline/thread-routes.d.ts.map +1 -1
- package/dist/inline/threadreply-command.d.ts +17 -0
- package/dist/inline/threadreply-command.d.ts.map +1 -0
- package/dist/runtime-register-api.d.ts.map +1 -1
- package/dist/runtime-register-api.js +577 -30
- package/dist/runtime-register-api.js.map +8 -6
- package/dist/setup-entry.d.ts +1 -1
- package/openclaw.plugin.json +2 -2
- package/package.json +6 -6
|
@@ -20562,6 +20562,8 @@ class InlineSdkClient {
|
|
|
20562
20562
|
saveInFlight = null;
|
|
20563
20563
|
catchUpInFlightByChatId = new Map;
|
|
20564
20564
|
catchUpRequestedByChatId = new Map;
|
|
20565
|
+
catchUpInFlightBySpaceId = new Map;
|
|
20566
|
+
catchUpRequestedBySpaceId = new Map;
|
|
20565
20567
|
userCatchUpInFlight = null;
|
|
20566
20568
|
constructor(options) {
|
|
20567
20569
|
this.options = options;
|
|
@@ -20626,7 +20628,11 @@ class InlineSdkClient {
|
|
|
20626
20628
|
this.started = false;
|
|
20627
20629
|
this.rejectOpen(new Error("closed"));
|
|
20628
20630
|
this.eventStream.close();
|
|
20629
|
-
await Promise.allSettled(
|
|
20631
|
+
await Promise.allSettled([
|
|
20632
|
+
...this.catchUpInFlightByChatId.values(),
|
|
20633
|
+
...this.catchUpInFlightBySpaceId.values(),
|
|
20634
|
+
...this.userCatchUpInFlight ? [this.userCatchUpInFlight] : []
|
|
20635
|
+
]);
|
|
20630
20636
|
await this.flushStateSave();
|
|
20631
20637
|
await this.protocol.stopTransport();
|
|
20632
20638
|
}
|
|
@@ -20650,6 +20656,7 @@ class InlineSdkClient {
|
|
|
20650
20656
|
version: 1,
|
|
20651
20657
|
...this.state.dateCursor != null ? { dateCursor: this.state.dateCursor } : {},
|
|
20652
20658
|
...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {},
|
|
20659
|
+
...this.state.lastSeqBySpaceId != null ? { lastSeqBySpaceId: { ...this.state.lastSeqBySpaceId } } : {},
|
|
20653
20660
|
...this.state.lastUserSeq != null ? { lastUserSeq: this.state.lastUserSeq } : {}
|
|
20654
20661
|
};
|
|
20655
20662
|
}
|
|
@@ -20670,12 +20677,7 @@ class InlineSdkClient {
|
|
|
20670
20677
|
const chat = result.getChat.chat;
|
|
20671
20678
|
if (!chat)
|
|
20672
20679
|
throw new Error("getChat: missing chat");
|
|
20673
|
-
return {
|
|
20674
|
-
chatId: chat.id,
|
|
20675
|
-
peer: chat.peerId,
|
|
20676
|
-
title: chat.title,
|
|
20677
|
-
...chat.lastMsgId != null ? { lastMsgId: chat.lastMsgId } : {}
|
|
20678
|
-
};
|
|
20680
|
+
return { chatId: chat.id, peer: chat.peerId, title: chat.title };
|
|
20679
20681
|
}
|
|
20680
20682
|
async getMessages(params) {
|
|
20681
20683
|
const peerId = this.inputPeerFromTarget(params, "getMessages");
|
|
@@ -21004,32 +21006,57 @@ class InlineSdkClient {
|
|
|
21004
21006
|
}
|
|
21005
21007
|
case "clearChatHistory": {
|
|
21006
21008
|
const payload = update.update.clearChatHistory;
|
|
21009
|
+
if (!payload.target) {
|
|
21010
|
+
this.log.warn?.("Skipping clearChatHistory update without target");
|
|
21011
|
+
return;
|
|
21012
|
+
}
|
|
21007
21013
|
if (payload.target.oneofKind === "spaceId") {
|
|
21014
|
+
this.bumpSpaceSeq(payload.target.spaceId, seq);
|
|
21008
21015
|
await this.eventStream.send({
|
|
21009
21016
|
kind: "space.history.clear",
|
|
21010
21017
|
spaceId: payload.target.spaceId,
|
|
21011
21018
|
...payload.beforeDate != null ? { beforeDate: payload.beforeDate } : {},
|
|
21012
21019
|
deleteReplyThreads: payload.deleteReplyThreads,
|
|
21020
|
+
deletedChatIds: payload.deletedChatIds,
|
|
21021
|
+
orphanedChatIds: payload.orphanedChatIds,
|
|
21022
|
+
detachedChatIds: payload.detachedChatIds,
|
|
21013
21023
|
seq,
|
|
21014
21024
|
date
|
|
21015
21025
|
});
|
|
21016
21026
|
return;
|
|
21017
21027
|
}
|
|
21018
21028
|
const peerId = payload.target.oneofKind === "peerId" ? payload.target.peerId : undefined;
|
|
21019
|
-
|
|
21020
|
-
|
|
21021
|
-
this.
|
|
21029
|
+
if (peerId?.type.oneofKind === "chat") {
|
|
21030
|
+
const chatId = peerId.type.chat.chatId;
|
|
21031
|
+
this.bumpChatSeq(chatId, seq);
|
|
21032
|
+
await this.eventStream.send({
|
|
21033
|
+
kind: "message.history.clear",
|
|
21034
|
+
chatId,
|
|
21035
|
+
...payload.beforeDate != null ? { beforeDate: payload.beforeDate } : {},
|
|
21036
|
+
deleteReplyThreads: payload.deleteReplyThreads,
|
|
21037
|
+
deletedChatIds: payload.deletedChatIds,
|
|
21038
|
+
orphanedChatIds: payload.orphanedChatIds,
|
|
21039
|
+
detachedChatIds: payload.detachedChatIds,
|
|
21040
|
+
seq,
|
|
21041
|
+
date
|
|
21042
|
+
});
|
|
21022
21043
|
return;
|
|
21023
21044
|
}
|
|
21024
|
-
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
|
|
21028
|
-
|
|
21029
|
-
|
|
21030
|
-
|
|
21031
|
-
|
|
21032
|
-
|
|
21045
|
+
if (peerId?.type.oneofKind === "user") {
|
|
21046
|
+
await this.eventStream.send({
|
|
21047
|
+
kind: "message.history.clear",
|
|
21048
|
+
userId: peerId.type.user.userId,
|
|
21049
|
+
...payload.beforeDate != null ? { beforeDate: payload.beforeDate } : {},
|
|
21050
|
+
deleteReplyThreads: payload.deleteReplyThreads,
|
|
21051
|
+
deletedChatIds: payload.deletedChatIds,
|
|
21052
|
+
orphanedChatIds: payload.orphanedChatIds,
|
|
21053
|
+
detachedChatIds: payload.detachedChatIds,
|
|
21054
|
+
seq,
|
|
21055
|
+
date
|
|
21056
|
+
});
|
|
21057
|
+
return;
|
|
21058
|
+
}
|
|
21059
|
+
this.log.warn?.("Skipping clearChatHistory update without peer target", peerId);
|
|
21033
21060
|
return;
|
|
21034
21061
|
}
|
|
21035
21062
|
case "updateReaction": {
|
|
@@ -21113,6 +21140,7 @@ class InlineSdkClient {
|
|
|
21113
21140
|
seq,
|
|
21114
21141
|
date
|
|
21115
21142
|
});
|
|
21143
|
+
this.requestCatchUpSpace({ spaceId: payload.spaceId, updateSeq: payload.updateSeq });
|
|
21116
21144
|
return;
|
|
21117
21145
|
}
|
|
21118
21146
|
default:
|
|
@@ -21131,6 +21159,18 @@ class InlineSdkClient {
|
|
|
21131
21159
|
this.scheduleStateSave();
|
|
21132
21160
|
}
|
|
21133
21161
|
}
|
|
21162
|
+
bumpSpaceSeq(spaceId, seq) {
|
|
21163
|
+
if (!Number.isFinite(seq))
|
|
21164
|
+
return;
|
|
21165
|
+
if (!this.state.lastSeqBySpaceId)
|
|
21166
|
+
this.state.lastSeqBySpaceId = {};
|
|
21167
|
+
const key = spaceId.toString();
|
|
21168
|
+
const prev = this.state.lastSeqBySpaceId[key] ?? 0;
|
|
21169
|
+
if (seq > prev) {
|
|
21170
|
+
this.state.lastSeqBySpaceId[key] = seq;
|
|
21171
|
+
this.scheduleStateSave();
|
|
21172
|
+
}
|
|
21173
|
+
}
|
|
21134
21174
|
shouldSkipUserSeq(seq) {
|
|
21135
21175
|
if (!Number.isFinite(seq))
|
|
21136
21176
|
return false;
|
|
@@ -21310,6 +21350,112 @@ class InlineSdkClient {
|
|
|
21310
21350
|
}
|
|
21311
21351
|
return false;
|
|
21312
21352
|
}
|
|
21353
|
+
requestCatchUpSpace(params) {
|
|
21354
|
+
const previous = this.catchUpRequestedBySpaceId.get(params.spaceId);
|
|
21355
|
+
this.catchUpRequestedBySpaceId.set(params.spaceId, {
|
|
21356
|
+
endSeq: Math.max(previous?.endSeq ?? 0, params.updateSeq)
|
|
21357
|
+
});
|
|
21358
|
+
if (this.catchUpInFlightBySpaceId.has(params.spaceId)) {
|
|
21359
|
+
return;
|
|
21360
|
+
}
|
|
21361
|
+
const task = this.drainCatchUpSpace(params.spaceId).catch((error) => {
|
|
21362
|
+
this.catchUpRequestedBySpaceId.delete(params.spaceId);
|
|
21363
|
+
this.log.warn?.("GET_UPDATES space catch-up failed; continuing live delivery", {
|
|
21364
|
+
spaceId: params.spaceId.toString(),
|
|
21365
|
+
error: extractErrorMessage(error)
|
|
21366
|
+
});
|
|
21367
|
+
}).finally(() => {
|
|
21368
|
+
this.catchUpInFlightBySpaceId.delete(params.spaceId);
|
|
21369
|
+
});
|
|
21370
|
+
this.catchUpInFlightBySpaceId.set(params.spaceId, task);
|
|
21371
|
+
}
|
|
21372
|
+
async drainCatchUpSpace(spaceId) {
|
|
21373
|
+
const key = spaceId.toString();
|
|
21374
|
+
while (true) {
|
|
21375
|
+
const request = this.catchUpRequestedBySpaceId.get(spaceId);
|
|
21376
|
+
if (!request)
|
|
21377
|
+
return;
|
|
21378
|
+
const lastSeq = this.state.lastSeqBySpaceId?.[key];
|
|
21379
|
+
const startSeq = lastSeq ?? Math.max(0, request.endSeq - defaultColdStartCatchUpWindow);
|
|
21380
|
+
if (request.endSeq <= startSeq) {
|
|
21381
|
+
this.catchUpRequestedBySpaceId.delete(spaceId);
|
|
21382
|
+
return;
|
|
21383
|
+
}
|
|
21384
|
+
const stop = await this.doCatchUpSpace(spaceId, startSeq, request.endSeq);
|
|
21385
|
+
if (stop) {
|
|
21386
|
+
this.catchUpRequestedBySpaceId.delete(spaceId);
|
|
21387
|
+
return;
|
|
21388
|
+
}
|
|
21389
|
+
const latest = this.catchUpRequestedBySpaceId.get(spaceId);
|
|
21390
|
+
const syncedSeq = this.state.lastSeqBySpaceId?.[key] ?? 0;
|
|
21391
|
+
if (!latest || latest.endSeq <= syncedSeq) {
|
|
21392
|
+
this.catchUpRequestedBySpaceId.delete(spaceId);
|
|
21393
|
+
return;
|
|
21394
|
+
}
|
|
21395
|
+
}
|
|
21396
|
+
}
|
|
21397
|
+
async doCatchUpSpace(spaceId, startSeq, endSeq) {
|
|
21398
|
+
let cursor = startSeq;
|
|
21399
|
+
while (cursor < endSeq) {
|
|
21400
|
+
const result = await this.invoke(Method.GET_UPDATES, {
|
|
21401
|
+
oneofKind: "getUpdates",
|
|
21402
|
+
getUpdates: GetUpdatesInput.create({
|
|
21403
|
+
bucket: UpdateBucket.create({
|
|
21404
|
+
type: {
|
|
21405
|
+
oneofKind: "space",
|
|
21406
|
+
space: {
|
|
21407
|
+
spaceId
|
|
21408
|
+
}
|
|
21409
|
+
}
|
|
21410
|
+
}),
|
|
21411
|
+
startSeq: BigInt(cursor),
|
|
21412
|
+
seqEnd: BigInt(endSeq),
|
|
21413
|
+
totalLimit: defaultCatchUpTotalLimit,
|
|
21414
|
+
limit: defaultCatchUpPageLimit
|
|
21415
|
+
})
|
|
21416
|
+
});
|
|
21417
|
+
const payload = result.getUpdates;
|
|
21418
|
+
if (payload.resultType === GetUpdatesResult_ResultType.TOO_LONG) {
|
|
21419
|
+
this.log.warn?.("GET_UPDATES space too long; fast-forwarding cursor", {
|
|
21420
|
+
spaceId: spaceId.toString(),
|
|
21421
|
+
seq: payload.seq
|
|
21422
|
+
});
|
|
21423
|
+
this.bumpSpaceSeq(spaceId, endSeq);
|
|
21424
|
+
if (payload.date !== 0n) {
|
|
21425
|
+
this.state.dateCursor = payload.date;
|
|
21426
|
+
}
|
|
21427
|
+
this.scheduleStateSave();
|
|
21428
|
+
return true;
|
|
21429
|
+
}
|
|
21430
|
+
const deliveredSeq = Number(payload.seq ?? 0n);
|
|
21431
|
+
if (!Number.isSafeInteger(deliveredSeq)) {
|
|
21432
|
+
this.log.warn?.("GET_UPDATES space returned non-integer seq; aborting catch-up", {
|
|
21433
|
+
spaceId: spaceId.toString()
|
|
21434
|
+
});
|
|
21435
|
+
return true;
|
|
21436
|
+
}
|
|
21437
|
+
this.bumpSpaceSeq(spaceId, deliveredSeq);
|
|
21438
|
+
for (const update of payload.updates) {
|
|
21439
|
+
await this.handleUpdate(update);
|
|
21440
|
+
}
|
|
21441
|
+
if (payload.date !== 0n) {
|
|
21442
|
+
this.state.dateCursor = payload.date;
|
|
21443
|
+
}
|
|
21444
|
+
this.scheduleStateSave();
|
|
21445
|
+
if (payload.final)
|
|
21446
|
+
return true;
|
|
21447
|
+
if (deliveredSeq <= cursor) {
|
|
21448
|
+
this.log.warn?.("GET_UPDATES space made no progress; aborting catch-up", {
|
|
21449
|
+
spaceId: spaceId.toString(),
|
|
21450
|
+
cursor,
|
|
21451
|
+
deliveredSeq
|
|
21452
|
+
});
|
|
21453
|
+
return true;
|
|
21454
|
+
}
|
|
21455
|
+
cursor = deliveredSeq;
|
|
21456
|
+
}
|
|
21457
|
+
return false;
|
|
21458
|
+
}
|
|
21313
21459
|
peerToInputPeer(peer, chatId) {
|
|
21314
21460
|
if (!peer) {
|
|
21315
21461
|
return InputPeer.create({ type: { oneofKind: "chat", chat: { chatId } } });
|
|
@@ -21390,6 +21536,7 @@ class InlineSdkClient {
|
|
|
21390
21536
|
version: 1,
|
|
21391
21537
|
...this.state.dateCursor != null ? { dateCursor: this.state.dateCursor } : {},
|
|
21392
21538
|
...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {},
|
|
21539
|
+
...this.state.lastSeqBySpaceId != null ? { lastSeqBySpaceId: { ...this.state.lastSeqBySpaceId } } : {},
|
|
21393
21540
|
...this.state.lastUserSeq != null ? { lastUserSeq: this.state.lastUserSeq } : {}
|
|
21394
21541
|
};
|
|
21395
21542
|
this.saveInFlight = store.save(snapshot).catch((error) => {
|
|
@@ -21607,7 +21754,9 @@ var serializeStateV1 = (state) => {
|
|
|
21607
21754
|
const json = {
|
|
21608
21755
|
version: 1,
|
|
21609
21756
|
...state.dateCursor != null ? { dateCursor: state.dateCursor.toString() } : {},
|
|
21610
|
-
...state.lastSeqByChatId != null ? { lastSeqByChatId: state.lastSeqByChatId } : {}
|
|
21757
|
+
...state.lastSeqByChatId != null ? { lastSeqByChatId: state.lastSeqByChatId } : {},
|
|
21758
|
+
...state.lastSeqBySpaceId != null ? { lastSeqBySpaceId: state.lastSeqBySpaceId } : {},
|
|
21759
|
+
...state.lastUserSeq != null ? { lastUserSeq: state.lastUserSeq } : {}
|
|
21611
21760
|
};
|
|
21612
21761
|
return JSON.stringify(json, null, 2);
|
|
21613
21762
|
};
|
|
@@ -21619,10 +21768,21 @@ var deserializeStateV1 = (raw) => {
|
|
|
21619
21768
|
return {
|
|
21620
21769
|
version: 1,
|
|
21621
21770
|
...parsed.dateCursor != null ? { dateCursor: BigInt(parsed.dateCursor) } : {},
|
|
21622
|
-
...parsed.lastSeqByChatId != null ? { lastSeqByChatId: parsed.lastSeqByChatId } : {}
|
|
21771
|
+
...parsed.lastSeqByChatId != null ? { lastSeqByChatId: parsed.lastSeqByChatId } : {},
|
|
21772
|
+
...parsed.lastSeqBySpaceId != null ? { lastSeqBySpaceId: parsed.lastSeqBySpaceId } : {},
|
|
21773
|
+
...parsed.lastUserSeq != null ? { lastUserSeq: parsed.lastUserSeq } : {}
|
|
21623
21774
|
};
|
|
21624
21775
|
};
|
|
21625
21776
|
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21777
|
+
var isSeqRecord = (value) => {
|
|
21778
|
+
if (!isRecord2(value))
|
|
21779
|
+
return false;
|
|
21780
|
+
for (const v of Object.values(value)) {
|
|
21781
|
+
if (typeof v !== "number" || !Number.isFinite(v))
|
|
21782
|
+
return false;
|
|
21783
|
+
}
|
|
21784
|
+
return true;
|
|
21785
|
+
};
|
|
21626
21786
|
var isStateJsonV1 = (value) => {
|
|
21627
21787
|
if (!isRecord2(value))
|
|
21628
21788
|
return false;
|
|
@@ -21630,14 +21790,12 @@ var isStateJsonV1 = (value) => {
|
|
|
21630
21790
|
return false;
|
|
21631
21791
|
if (value.dateCursor != null && typeof value.dateCursor !== "string")
|
|
21632
21792
|
return false;
|
|
21633
|
-
if (value.lastSeqByChatId != null)
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
}
|
|
21640
|
-
}
|
|
21793
|
+
if (value.lastSeqByChatId != null && !isSeqRecord(value.lastSeqByChatId))
|
|
21794
|
+
return false;
|
|
21795
|
+
if (value.lastSeqBySpaceId != null && !isSeqRecord(value.lastSeqBySpaceId))
|
|
21796
|
+
return false;
|
|
21797
|
+
if (value.lastUserSeq != null && (typeof value.lastUserSeq !== "number" || !Number.isFinite(value.lastUserSeq)))
|
|
21798
|
+
return false;
|
|
21641
21799
|
return true;
|
|
21642
21800
|
};
|
|
21643
21801
|
|
|
@@ -38777,6 +38935,391 @@ async function syncInlineNativeCommands(params) {
|
|
|
38777
38935
|
};
|
|
38778
38936
|
}
|
|
38779
38937
|
|
|
38938
|
+
// src/inline/policy.ts
|
|
38939
|
+
function normalizeAccountId2(raw) {
|
|
38940
|
+
return normalizeAccountId(raw);
|
|
38941
|
+
}
|
|
38942
|
+
function resolveInlineGroups(cfg, accountId) {
|
|
38943
|
+
const inline = cfg.channels?.inline;
|
|
38944
|
+
if (!inline)
|
|
38945
|
+
return;
|
|
38946
|
+
const normalized = normalizeAccountId2(accountId);
|
|
38947
|
+
const accounts = inline.accounts ?? {};
|
|
38948
|
+
const accountEntry = accounts[normalized] ?? accounts[Object.keys(accounts).find((key) => key.toLowerCase() === normalized) ?? ""];
|
|
38949
|
+
return accountEntry?.groups ?? inline.groups;
|
|
38950
|
+
}
|
|
38951
|
+
function normalizeGroupId(raw) {
|
|
38952
|
+
const trimmed = raw.trim();
|
|
38953
|
+
if (!trimmed || trimmed === "*")
|
|
38954
|
+
return trimmed;
|
|
38955
|
+
const normalized = normalizeInlineTarget(trimmed);
|
|
38956
|
+
return normalized && /^[0-9]+$/.test(normalized) ? normalized : trimmed;
|
|
38957
|
+
}
|
|
38958
|
+
function resolveGroupConfig(groups, groupId) {
|
|
38959
|
+
if (!groups)
|
|
38960
|
+
return;
|
|
38961
|
+
const normalizedGroupId = normalizeGroupId(groupId ?? "");
|
|
38962
|
+
if (!normalizedGroupId)
|
|
38963
|
+
return;
|
|
38964
|
+
const direct = groups[normalizedGroupId];
|
|
38965
|
+
if (direct)
|
|
38966
|
+
return direct;
|
|
38967
|
+
const lowered = normalizedGroupId.toLowerCase();
|
|
38968
|
+
const matchedKey = Object.keys(groups).find((key) => key !== "*" && normalizeGroupId(key).toLowerCase() === lowered);
|
|
38969
|
+
return matchedKey ? groups[matchedKey] : undefined;
|
|
38970
|
+
}
|
|
38971
|
+
function normalizeSenderKey(raw) {
|
|
38972
|
+
const trimmed = raw.trim();
|
|
38973
|
+
if (!trimmed)
|
|
38974
|
+
return "";
|
|
38975
|
+
const withoutAt = trimmed.startsWith("@") ? trimmed.slice(1) : trimmed;
|
|
38976
|
+
return withoutAt.toLowerCase();
|
|
38977
|
+
}
|
|
38978
|
+
function resolveToolsBySender(params) {
|
|
38979
|
+
const entries = Object.entries(params.toolsBySender ?? {});
|
|
38980
|
+
if (!entries.length)
|
|
38981
|
+
return;
|
|
38982
|
+
const normalizedMap = new Map;
|
|
38983
|
+
let wildcard;
|
|
38984
|
+
for (const [rawKey, policy] of entries) {
|
|
38985
|
+
if (!policy)
|
|
38986
|
+
continue;
|
|
38987
|
+
const key = normalizeSenderKey(rawKey);
|
|
38988
|
+
if (!key)
|
|
38989
|
+
continue;
|
|
38990
|
+
if (key === "*") {
|
|
38991
|
+
wildcard = policy;
|
|
38992
|
+
continue;
|
|
38993
|
+
}
|
|
38994
|
+
if (!normalizedMap.has(key)) {
|
|
38995
|
+
normalizedMap.set(key, policy);
|
|
38996
|
+
}
|
|
38997
|
+
}
|
|
38998
|
+
const candidates = [
|
|
38999
|
+
params.senderId,
|
|
39000
|
+
params.senderE164,
|
|
39001
|
+
params.senderUsername,
|
|
39002
|
+
params.senderName
|
|
39003
|
+
];
|
|
39004
|
+
for (const candidate of candidates) {
|
|
39005
|
+
const key = normalizeSenderKey(candidate ?? "");
|
|
39006
|
+
if (!key)
|
|
39007
|
+
continue;
|
|
39008
|
+
const matched = normalizedMap.get(key);
|
|
39009
|
+
if (matched)
|
|
39010
|
+
return matched;
|
|
39011
|
+
}
|
|
39012
|
+
return wildcard;
|
|
39013
|
+
}
|
|
39014
|
+
function resolveInlineGroupRequireMention(params) {
|
|
39015
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39016
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39017
|
+
const defaultConfig = groups?.["*"];
|
|
39018
|
+
if (typeof groupConfig?.requireMention === "boolean")
|
|
39019
|
+
return groupConfig.requireMention;
|
|
39020
|
+
if (typeof defaultConfig?.requireMention === "boolean")
|
|
39021
|
+
return defaultConfig.requireMention;
|
|
39022
|
+
return params.requireMentionDefault;
|
|
39023
|
+
}
|
|
39024
|
+
function resolveInlineGroupReplyThreadMode(params) {
|
|
39025
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39026
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39027
|
+
const defaultConfig = groups?.["*"];
|
|
39028
|
+
return groupConfig?.replyThreadMode ?? defaultConfig?.replyThreadMode ?? params.defaultMode;
|
|
39029
|
+
}
|
|
39030
|
+
function resolveInlineGroupReplyThreadAutoCreateMinMessages(params) {
|
|
39031
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39032
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39033
|
+
const defaultConfig = groups?.["*"];
|
|
39034
|
+
return groupConfig?.replyThreadAutoCreateMinMessages ?? defaultConfig?.replyThreadAutoCreateMinMessages ?? params.defaultMinMessages;
|
|
39035
|
+
}
|
|
39036
|
+
function resolveInlineGroupReplyThreadRequireExplicitMention(params) {
|
|
39037
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39038
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39039
|
+
const defaultConfig = groups?.["*"];
|
|
39040
|
+
if (typeof groupConfig?.replyThreadRequireExplicitMention === "boolean") {
|
|
39041
|
+
return groupConfig.replyThreadRequireExplicitMention;
|
|
39042
|
+
}
|
|
39043
|
+
if (typeof defaultConfig?.replyThreadRequireExplicitMention === "boolean") {
|
|
39044
|
+
return defaultConfig.replyThreadRequireExplicitMention;
|
|
39045
|
+
}
|
|
39046
|
+
return params.defaultRequireExplicitMention;
|
|
39047
|
+
}
|
|
39048
|
+
function resolveInlineGroupReplyThreadParentHistoryLimit(params) {
|
|
39049
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39050
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39051
|
+
const defaultConfig = groups?.["*"];
|
|
39052
|
+
return groupConfig?.replyThreadParentHistoryLimit ?? defaultConfig?.replyThreadParentHistoryLimit ?? params.defaultLimit;
|
|
39053
|
+
}
|
|
39054
|
+
function resolveInlineGroupSystemPrompt(params) {
|
|
39055
|
+
return resolveGroupConfig(params.groups, params.groupId)?.systemPrompt?.trim() || undefined;
|
|
39056
|
+
}
|
|
39057
|
+
function resolveInlineGroupAccessPolicy(params) {
|
|
39058
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39059
|
+
const hasGroups = Boolean(groups && Object.keys(groups).length > 0);
|
|
39060
|
+
const allowlistEnabled = params.groupPolicy === "allowlist" || hasGroups;
|
|
39061
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39062
|
+
const defaultConfig = groups?.["*"];
|
|
39063
|
+
const allowAll = allowlistEnabled && Boolean(groups && Object.hasOwn(groups, "*"));
|
|
39064
|
+
const senderFilterBypass = params.groupPolicy === "allowlist" && !hasGroups && params.hasGroupAllowFrom;
|
|
39065
|
+
return {
|
|
39066
|
+
allowlistEnabled,
|
|
39067
|
+
allowed: params.groupPolicy === "disabled" ? false : !allowlistEnabled || allowAll || Boolean(groupConfig) || senderFilterBypass,
|
|
39068
|
+
groupConfig,
|
|
39069
|
+
defaultConfig
|
|
39070
|
+
};
|
|
39071
|
+
}
|
|
39072
|
+
function resolveInlineGroupToolPolicy(params) {
|
|
39073
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39074
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39075
|
+
const defaultConfig = groups?.["*"];
|
|
39076
|
+
const groupSenderPolicy = resolveToolsBySender({
|
|
39077
|
+
toolsBySender: groupConfig?.toolsBySender,
|
|
39078
|
+
senderId: params.senderId,
|
|
39079
|
+
senderName: params.senderName,
|
|
39080
|
+
senderUsername: params.senderUsername,
|
|
39081
|
+
senderE164: params.senderE164
|
|
39082
|
+
});
|
|
39083
|
+
if (groupSenderPolicy)
|
|
39084
|
+
return groupSenderPolicy;
|
|
39085
|
+
if (groupConfig?.tools)
|
|
39086
|
+
return groupConfig.tools;
|
|
39087
|
+
const defaultSenderPolicy = resolveToolsBySender({
|
|
39088
|
+
toolsBySender: defaultConfig?.toolsBySender,
|
|
39089
|
+
senderId: params.senderId,
|
|
39090
|
+
senderName: params.senderName,
|
|
39091
|
+
senderUsername: params.senderUsername,
|
|
39092
|
+
senderE164: params.senderE164
|
|
39093
|
+
});
|
|
39094
|
+
if (defaultSenderPolicy)
|
|
39095
|
+
return defaultSenderPolicy;
|
|
39096
|
+
return defaultConfig?.tools;
|
|
39097
|
+
}
|
|
39098
|
+
function resolveInlineGroupAllowFrom(params) {
|
|
39099
|
+
const groups = resolveInlineGroups(params.cfg, params.accountId);
|
|
39100
|
+
const groupConfig = resolveGroupConfig(groups, params.groupId);
|
|
39101
|
+
const defaultConfig = groups?.["*"];
|
|
39102
|
+
if (groupConfig?.allowFrom && groupConfig.allowFrom.length > 0)
|
|
39103
|
+
return groupConfig.allowFrom;
|
|
39104
|
+
if (defaultConfig?.allowFrom && defaultConfig.allowFrom.length > 0)
|
|
39105
|
+
return defaultConfig.allowFrom;
|
|
39106
|
+
return params.accountAllowFrom;
|
|
39107
|
+
}
|
|
39108
|
+
|
|
39109
|
+
// src/inline/threadreply-command.ts
|
|
39110
|
+
var MODE_LABELS = {
|
|
39111
|
+
auto: "auto",
|
|
39112
|
+
thread: "thread",
|
|
39113
|
+
main: "main"
|
|
39114
|
+
};
|
|
39115
|
+
function isRecord3(value) {
|
|
39116
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
39117
|
+
}
|
|
39118
|
+
function asInlineConfig(value) {
|
|
39119
|
+
return isRecord3(value) ? value : undefined;
|
|
39120
|
+
}
|
|
39121
|
+
function normalizeMode(raw) {
|
|
39122
|
+
if (typeof raw !== "string")
|
|
39123
|
+
return null;
|
|
39124
|
+
const normalized = raw.trim().toLowerCase();
|
|
39125
|
+
if (normalized === "on" || normalized === "threads")
|
|
39126
|
+
return "thread";
|
|
39127
|
+
if (normalized === "off" || normalized === "parent" || normalized === "parentchat")
|
|
39128
|
+
return "main";
|
|
39129
|
+
if (normalized === "auto" || normalized === "thread" || normalized === "main")
|
|
39130
|
+
return normalized;
|
|
39131
|
+
return null;
|
|
39132
|
+
}
|
|
39133
|
+
function resolveInlineGroupId(ctx) {
|
|
39134
|
+
const raw = ctx.from?.trim() ?? "";
|
|
39135
|
+
if (!/(^|:)chat:/i.test(raw))
|
|
39136
|
+
return null;
|
|
39137
|
+
const normalized = normalizeInlineTarget(raw);
|
|
39138
|
+
return normalized && /^[0-9]+$/.test(normalized) ? normalized : null;
|
|
39139
|
+
}
|
|
39140
|
+
function resolveInlineConfigForAccount(inline, accountId) {
|
|
39141
|
+
const normalized = normalizeAccountId(accountId);
|
|
39142
|
+
const accounts = isRecord3(inline.accounts) ? inline.accounts : undefined;
|
|
39143
|
+
const accountKey = accounts ? Object.keys(accounts).find((key) => normalizeAccountId(key) === normalized) : undefined;
|
|
39144
|
+
if (accountKey && accounts?.[accountKey]) {
|
|
39145
|
+
return accounts[accountKey];
|
|
39146
|
+
}
|
|
39147
|
+
if (normalized !== DEFAULT_ACCOUNT_ID) {
|
|
39148
|
+
return {};
|
|
39149
|
+
}
|
|
39150
|
+
return inline;
|
|
39151
|
+
}
|
|
39152
|
+
function resolveCurrentMode(params) {
|
|
39153
|
+
const inline = asInlineConfig(params.cfg.channels?.inline) ?? {};
|
|
39154
|
+
const accountConfig = resolveInlineConfigForAccount(inline, params.accountId);
|
|
39155
|
+
return resolveInlineGroupReplyThreadMode({
|
|
39156
|
+
cfg: params.cfg,
|
|
39157
|
+
accountId: params.accountId ?? null,
|
|
39158
|
+
groupId: params.groupId,
|
|
39159
|
+
defaultMode: normalizeMode(accountConfig.replyThreadMode) ?? "auto"
|
|
39160
|
+
});
|
|
39161
|
+
}
|
|
39162
|
+
function readExplicitMode(params) {
|
|
39163
|
+
const inline = asInlineConfig(params.cfg.channels?.inline);
|
|
39164
|
+
if (!inline)
|
|
39165
|
+
return null;
|
|
39166
|
+
const accountConfig = resolveInlineConfigForAccount(inline, params.accountId);
|
|
39167
|
+
const group = accountConfig.groups?.[params.groupId];
|
|
39168
|
+
return normalizeMode(group?.replyThreadMode);
|
|
39169
|
+
}
|
|
39170
|
+
function ensureRecordField(parent, key) {
|
|
39171
|
+
const current = parent[key];
|
|
39172
|
+
if (isRecord3(current))
|
|
39173
|
+
return current;
|
|
39174
|
+
const next = {};
|
|
39175
|
+
parent[key] = next;
|
|
39176
|
+
return next;
|
|
39177
|
+
}
|
|
39178
|
+
function resolveMutableInlineConfigForAccount(inline, accountId) {
|
|
39179
|
+
const normalized = normalizeAccountId(accountId);
|
|
39180
|
+
if (normalized === DEFAULT_ACCOUNT_ID) {
|
|
39181
|
+
const accounts2 = isRecord3(inline.accounts) ? inline.accounts : undefined;
|
|
39182
|
+
const defaultKey = accounts2 ? Object.keys(accounts2).find((key) => normalizeAccountId(key) === DEFAULT_ACCOUNT_ID) : undefined;
|
|
39183
|
+
const defaultAccount = defaultKey ? accounts2?.[defaultKey] : undefined;
|
|
39184
|
+
return defaultAccount ?? inline;
|
|
39185
|
+
}
|
|
39186
|
+
const accounts = ensureRecordField(inline, "accounts");
|
|
39187
|
+
const accountKey = Object.keys(accounts).find((key) => normalizeAccountId(key) === normalized) ?? normalized;
|
|
39188
|
+
const account = asInlineConfig(accounts[accountKey]) ?? {};
|
|
39189
|
+
accounts[accountKey] = account;
|
|
39190
|
+
return account;
|
|
39191
|
+
}
|
|
39192
|
+
function setGroupMode(params) {
|
|
39193
|
+
const root = params.draft;
|
|
39194
|
+
const channels = root.channels ?? {};
|
|
39195
|
+
root.channels = channels;
|
|
39196
|
+
const inline = asInlineConfig(channels.inline) ?? {};
|
|
39197
|
+
channels.inline = inline;
|
|
39198
|
+
const accountConfig = resolveMutableInlineConfigForAccount(inline, params.accountId);
|
|
39199
|
+
const groups = ensureRecordField(accountConfig, "groups");
|
|
39200
|
+
const group = isRecord3(groups[params.groupId]) ? groups[params.groupId] : {};
|
|
39201
|
+
groups[params.groupId] = group;
|
|
39202
|
+
if (params.mode === "inherit") {
|
|
39203
|
+
delete group.replyThreadMode;
|
|
39204
|
+
return;
|
|
39205
|
+
}
|
|
39206
|
+
group.replyThreadMode = params.mode;
|
|
39207
|
+
}
|
|
39208
|
+
function buildStatusText(params) {
|
|
39209
|
+
const explicit = readExplicitMode(params);
|
|
39210
|
+
const current = resolveCurrentMode(params);
|
|
39211
|
+
return [
|
|
39212
|
+
`Thread reply mode for chat ${params.groupId}: ${MODE_LABELS[current]}.`,
|
|
39213
|
+
explicit ? `Explicit chat override: ${MODE_LABELS[explicit]}.` : "Explicit chat override: inherit."
|
|
39214
|
+
].join(`
|
|
39215
|
+
`);
|
|
39216
|
+
}
|
|
39217
|
+
function buildMenuText(params) {
|
|
39218
|
+
return [
|
|
39219
|
+
buildStatusText(params),
|
|
39220
|
+
"",
|
|
39221
|
+
"Choose where automatic replies for this group should go."
|
|
39222
|
+
].join(`
|
|
39223
|
+
`);
|
|
39224
|
+
}
|
|
39225
|
+
function buildModeButtons() {
|
|
39226
|
+
return {
|
|
39227
|
+
inline: {
|
|
39228
|
+
buttons: [
|
|
39229
|
+
[
|
|
39230
|
+
{ text: "Thread", callback_data: "/threadreply thread" },
|
|
39231
|
+
{ text: "Main", callback_data: "/threadreply main" },
|
|
39232
|
+
{ text: "Auto", callback_data: "/threadreply auto" }
|
|
39233
|
+
],
|
|
39234
|
+
[{ text: "Inherit", callback_data: "/threadreply inherit" }]
|
|
39235
|
+
]
|
|
39236
|
+
}
|
|
39237
|
+
};
|
|
39238
|
+
}
|
|
39239
|
+
function normalizeAction(args) {
|
|
39240
|
+
const [first = ""] = args.split(/\s+/).filter(Boolean);
|
|
39241
|
+
const normalized = first.trim().toLowerCase();
|
|
39242
|
+
if (!normalized || normalized === "help" || normalized === "options")
|
|
39243
|
+
return "help";
|
|
39244
|
+
if (normalized === "status" || normalized === "show")
|
|
39245
|
+
return "status";
|
|
39246
|
+
if (normalized === "inherit" || normalized === "default" || normalized === "unset")
|
|
39247
|
+
return "inherit";
|
|
39248
|
+
return normalizeMode(normalized);
|
|
39249
|
+
}
|
|
39250
|
+
async function handleInlineThreadReplyCommand(api2, ctx) {
|
|
39251
|
+
if (!ctx.isAuthorizedSender) {
|
|
39252
|
+
return { text: "This command requires authorization." };
|
|
39253
|
+
}
|
|
39254
|
+
const groupId = resolveInlineGroupId(ctx);
|
|
39255
|
+
if (!groupId) {
|
|
39256
|
+
return { text: "/threadreply is only available in Inline group chats." };
|
|
39257
|
+
}
|
|
39258
|
+
const currentConfig = api2.runtime.config.current();
|
|
39259
|
+
const action = normalizeAction(ctx.args?.trim() ?? "");
|
|
39260
|
+
if (action === "help") {
|
|
39261
|
+
return {
|
|
39262
|
+
text: buildMenuText({
|
|
39263
|
+
cfg: currentConfig,
|
|
39264
|
+
accountId: ctx.accountId,
|
|
39265
|
+
groupId
|
|
39266
|
+
}),
|
|
39267
|
+
channelData: buildModeButtons()
|
|
39268
|
+
};
|
|
39269
|
+
}
|
|
39270
|
+
if (action === "status") {
|
|
39271
|
+
return {
|
|
39272
|
+
text: buildStatusText({
|
|
39273
|
+
cfg: currentConfig,
|
|
39274
|
+
accountId: ctx.accountId,
|
|
39275
|
+
groupId
|
|
39276
|
+
})
|
|
39277
|
+
};
|
|
39278
|
+
}
|
|
39279
|
+
if (!action) {
|
|
39280
|
+
return {
|
|
39281
|
+
text: [
|
|
39282
|
+
"Usage: /threadreply thread|main|auto|inherit|status",
|
|
39283
|
+
"",
|
|
39284
|
+
"- thread: auto-route long parent-chat replies into an Inline reply thread.",
|
|
39285
|
+
"- main: keep automatic replies in the parent chat.",
|
|
39286
|
+
"- auto: use Inline's automatic default behavior for this chat.",
|
|
39287
|
+
"- inherit: remove this chat override and use account/default config."
|
|
39288
|
+
].join(`
|
|
39289
|
+
`)
|
|
39290
|
+
};
|
|
39291
|
+
}
|
|
39292
|
+
const committed = await api2.runtime.config.mutateConfigFile({
|
|
39293
|
+
afterWrite: { mode: "auto" },
|
|
39294
|
+
mutate: (draft) => {
|
|
39295
|
+
setGroupMode({
|
|
39296
|
+
draft,
|
|
39297
|
+
accountId: ctx.accountId,
|
|
39298
|
+
groupId,
|
|
39299
|
+
mode: action
|
|
39300
|
+
});
|
|
39301
|
+
}
|
|
39302
|
+
});
|
|
39303
|
+
const nextConfig = committed.nextConfig;
|
|
39304
|
+
return {
|
|
39305
|
+
text: buildStatusText({
|
|
39306
|
+
cfg: nextConfig,
|
|
39307
|
+
accountId: ctx.accountId,
|
|
39308
|
+
groupId
|
|
39309
|
+
})
|
|
39310
|
+
};
|
|
39311
|
+
}
|
|
39312
|
+
function createInlineThreadReplyCommand(api2) {
|
|
39313
|
+
return {
|
|
39314
|
+
name: "threadreply",
|
|
39315
|
+
nativeNames: { inline: "threadreply" },
|
|
39316
|
+
description: "Set Inline reply-thread mode for this chat.",
|
|
39317
|
+
channels: ["inline"],
|
|
39318
|
+
acceptsArgs: true,
|
|
39319
|
+
handler: async (ctx) => await handleInlineThreadReplyCommand(api2, ctx)
|
|
39320
|
+
};
|
|
39321
|
+
}
|
|
39322
|
+
|
|
38780
39323
|
// src/runtime-register-api.ts
|
|
38781
39324
|
function registerInlinePluginFull(api2) {
|
|
38782
39325
|
api2.registerTool((ctx) => createInlineMembersTool(ctx), {
|
|
@@ -38794,6 +39337,10 @@ function registerInlinePluginFull(api2) {
|
|
|
38794
39337
|
api2.registerTool((ctx) => createInlineParentContextTool(ctx), {
|
|
38795
39338
|
names: ["inline_parent_context"]
|
|
38796
39339
|
});
|
|
39340
|
+
const registerCommand = api2.registerCommand;
|
|
39341
|
+
if (typeof registerCommand === "function") {
|
|
39342
|
+
registerCommand(createInlineThreadReplyCommand(api2));
|
|
39343
|
+
}
|
|
38797
39344
|
api2.on("message_sending", (event, ctx) => {
|
|
38798
39345
|
if (ctx.channelId !== "inline")
|
|
38799
39346
|
return;
|
|
@@ -38821,5 +39368,5 @@ export {
|
|
|
38821
39368
|
registerInlinePluginFull
|
|
38822
39369
|
};
|
|
38823
39370
|
|
|
38824
|
-
//# debugId=
|
|
39371
|
+
//# debugId=D4578A65DC3F320064756E2164756E21
|
|
38825
39372
|
//# sourceMappingURL=runtime-register-api.js.map
|