@inline-openclaw/inline 0.0.39 → 0.0.40
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 +19 -25
- package/dist/approval-handler.runtime.js +573 -168
- package/dist/approval-handler.runtime.js.map +8 -7
- package/dist/channel-plugin-api.js +612 -108
- package/dist/channel-plugin-api.js.map +9 -8
- package/dist/inline/channel.d.ts.map +1 -1
- package/dist/inline/monitor.d.ts.map +1 -1
- package/dist/inline/reply-threads.d.ts.map +1 -1
- package/dist/inline/thread-routes.d.ts +28 -0
- package/dist/inline/thread-routes.d.ts.map +1 -0
- package/dist/runtime-register-api.js +118 -33
- package/dist/runtime-register-api.js.map +4 -4
- package/openclaw.plugin.json +4 -4
- package/package.json +1 -1
|
@@ -5589,7 +5589,7 @@ function hasInlineConfiguredState(params) {
|
|
|
5589
5589
|
|
|
5590
5590
|
// src/inline/channel.ts
|
|
5591
5591
|
import { unlink } from "node:fs/promises";
|
|
5592
|
-
import
|
|
5592
|
+
import path5 from "node:path";
|
|
5593
5593
|
import {
|
|
5594
5594
|
buildChannelOutboundSessionRoute,
|
|
5595
5595
|
buildThreadAwareOutboundSessionRoute
|
|
@@ -5630,6 +5630,8 @@ var MessageEntity_Type;
|
|
|
5630
5630
|
MessageEntity_Type2[MessageEntity_Type2["CODE"] = 8] = "CODE";
|
|
5631
5631
|
MessageEntity_Type2[MessageEntity_Type2["PRE"] = 9] = "PRE";
|
|
5632
5632
|
MessageEntity_Type2[MessageEntity_Type2["PHONE_NUMBER"] = 10] = "PHONE_NUMBER";
|
|
5633
|
+
MessageEntity_Type2[MessageEntity_Type2["THREAD"] = 11] = "THREAD";
|
|
5634
|
+
MessageEntity_Type2[MessageEntity_Type2["THREAD_TITLE"] = 12] = "THREAD_TITLE";
|
|
5633
5635
|
})(MessageEntity_Type || (MessageEntity_Type = {}));
|
|
5634
5636
|
var Member_Role;
|
|
5635
5637
|
(function(Member_Role2) {
|
|
@@ -7760,7 +7762,9 @@ class MessageEntity$Type extends import_runtime4.MessageType {
|
|
|
7760
7762
|
{ no: 3, name: "length", kind: "scalar", T: 3, L: 0 },
|
|
7761
7763
|
{ no: 4, name: "mention", kind: "message", oneof: "entity", T: () => MessageEntity_MessageEntityMention },
|
|
7762
7764
|
{ no: 5, name: "text_url", kind: "message", oneof: "entity", T: () => MessageEntity_MessageEntityTextUrl },
|
|
7763
|
-
{ no: 6, name: "pre", kind: "message", oneof: "entity", T: () => MessageEntity_MessageEntityPre }
|
|
7765
|
+
{ no: 6, name: "pre", kind: "message", oneof: "entity", T: () => MessageEntity_MessageEntityPre },
|
|
7766
|
+
{ no: 7, name: "thread", kind: "message", oneof: "entity", T: () => MessageEntity_MessageEntityThread },
|
|
7767
|
+
{ no: 8, name: "thread_title", kind: "message", oneof: "entity", T: () => MessageEntity_MessageEntityThreadTitle }
|
|
7764
7768
|
]);
|
|
7765
7769
|
}
|
|
7766
7770
|
create(value) {
|
|
@@ -7805,6 +7809,18 @@ class MessageEntity$Type extends import_runtime4.MessageType {
|
|
|
7805
7809
|
pre: MessageEntity_MessageEntityPre.internalBinaryRead(reader, reader.uint32(), options, message.entity.pre)
|
|
7806
7810
|
};
|
|
7807
7811
|
break;
|
|
7812
|
+
case 7:
|
|
7813
|
+
message.entity = {
|
|
7814
|
+
oneofKind: "thread",
|
|
7815
|
+
thread: MessageEntity_MessageEntityThread.internalBinaryRead(reader, reader.uint32(), options, message.entity.thread)
|
|
7816
|
+
};
|
|
7817
|
+
break;
|
|
7818
|
+
case 8:
|
|
7819
|
+
message.entity = {
|
|
7820
|
+
oneofKind: "threadTitle",
|
|
7821
|
+
threadTitle: MessageEntity_MessageEntityThreadTitle.internalBinaryRead(reader, reader.uint32(), options, message.entity.threadTitle)
|
|
7822
|
+
};
|
|
7823
|
+
break;
|
|
7808
7824
|
default:
|
|
7809
7825
|
let u = options.readUnknownField;
|
|
7810
7826
|
if (u === "throw")
|
|
@@ -7829,6 +7845,10 @@ class MessageEntity$Type extends import_runtime4.MessageType {
|
|
|
7829
7845
|
MessageEntity_MessageEntityTextUrl.internalBinaryWrite(message.entity.textUrl, writer.tag(5, import_runtime.WireType.LengthDelimited).fork(), options).join();
|
|
7830
7846
|
if (message.entity.oneofKind === "pre")
|
|
7831
7847
|
MessageEntity_MessageEntityPre.internalBinaryWrite(message.entity.pre, writer.tag(6, import_runtime.WireType.LengthDelimited).fork(), options).join();
|
|
7848
|
+
if (message.entity.oneofKind === "thread")
|
|
7849
|
+
MessageEntity_MessageEntityThread.internalBinaryWrite(message.entity.thread, writer.tag(7, import_runtime.WireType.LengthDelimited).fork(), options).join();
|
|
7850
|
+
if (message.entity.oneofKind === "threadTitle")
|
|
7851
|
+
MessageEntity_MessageEntityThreadTitle.internalBinaryWrite(message.entity.threadTitle, writer.tag(8, import_runtime.WireType.LengthDelimited).fork(), options).join();
|
|
7832
7852
|
let u = options.writeUnknownFields;
|
|
7833
7853
|
if (u !== false)
|
|
7834
7854
|
(u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -7966,6 +7986,99 @@ class MessageEntity_MessageEntityPre$Type extends import_runtime4.MessageType {
|
|
|
7966
7986
|
}
|
|
7967
7987
|
var MessageEntity_MessageEntityPre = new MessageEntity_MessageEntityPre$Type;
|
|
7968
7988
|
|
|
7989
|
+
class MessageEntity_MessageEntityThread$Type extends import_runtime4.MessageType {
|
|
7990
|
+
constructor() {
|
|
7991
|
+
super("MessageEntity.MessageEntityThread", [
|
|
7992
|
+
{ no: 1, name: "chat_id", kind: "scalar", T: 3, L: 0 }
|
|
7993
|
+
]);
|
|
7994
|
+
}
|
|
7995
|
+
create(value) {
|
|
7996
|
+
const message = globalThis.Object.create(this.messagePrototype);
|
|
7997
|
+
message.chatId = 0n;
|
|
7998
|
+
if (value !== undefined)
|
|
7999
|
+
import_runtime3.reflectionMergePartial(this, message, value);
|
|
8000
|
+
return message;
|
|
8001
|
+
}
|
|
8002
|
+
internalBinaryRead(reader, length, options, target) {
|
|
8003
|
+
let message = target ?? this.create(), end = reader.pos + length;
|
|
8004
|
+
while (reader.pos < end) {
|
|
8005
|
+
let [fieldNo, wireType] = reader.tag();
|
|
8006
|
+
switch (fieldNo) {
|
|
8007
|
+
case 1:
|
|
8008
|
+
message.chatId = reader.int64().toBigInt();
|
|
8009
|
+
break;
|
|
8010
|
+
default:
|
|
8011
|
+
let u = options.readUnknownField;
|
|
8012
|
+
if (u === "throw")
|
|
8013
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
8014
|
+
let d = reader.skip(wireType);
|
|
8015
|
+
if (u !== false)
|
|
8016
|
+
(u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
8017
|
+
}
|
|
8018
|
+
}
|
|
8019
|
+
return message;
|
|
8020
|
+
}
|
|
8021
|
+
internalBinaryWrite(message, writer, options) {
|
|
8022
|
+
if (message.chatId !== 0n)
|
|
8023
|
+
writer.tag(1, import_runtime.WireType.Varint).int64(message.chatId);
|
|
8024
|
+
let u = options.writeUnknownFields;
|
|
8025
|
+
if (u !== false)
|
|
8026
|
+
(u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
8027
|
+
return writer;
|
|
8028
|
+
}
|
|
8029
|
+
}
|
|
8030
|
+
var MessageEntity_MessageEntityThread = new MessageEntity_MessageEntityThread$Type;
|
|
8031
|
+
|
|
8032
|
+
class MessageEntity_MessageEntityThreadTitle$Type extends import_runtime4.MessageType {
|
|
8033
|
+
constructor() {
|
|
8034
|
+
super("MessageEntity.MessageEntityThreadTitle", [
|
|
8035
|
+
{ no: 1, name: "space_id", kind: "scalar", T: 3, L: 0 },
|
|
8036
|
+
{ no: 2, name: "title", kind: "scalar", T: 9 }
|
|
8037
|
+
]);
|
|
8038
|
+
}
|
|
8039
|
+
create(value) {
|
|
8040
|
+
const message = globalThis.Object.create(this.messagePrototype);
|
|
8041
|
+
message.spaceId = 0n;
|
|
8042
|
+
message.title = "";
|
|
8043
|
+
if (value !== undefined)
|
|
8044
|
+
import_runtime3.reflectionMergePartial(this, message, value);
|
|
8045
|
+
return message;
|
|
8046
|
+
}
|
|
8047
|
+
internalBinaryRead(reader, length, options, target) {
|
|
8048
|
+
let message = target ?? this.create(), end = reader.pos + length;
|
|
8049
|
+
while (reader.pos < end) {
|
|
8050
|
+
let [fieldNo, wireType] = reader.tag();
|
|
8051
|
+
switch (fieldNo) {
|
|
8052
|
+
case 1:
|
|
8053
|
+
message.spaceId = reader.int64().toBigInt();
|
|
8054
|
+
break;
|
|
8055
|
+
case 2:
|
|
8056
|
+
message.title = reader.string();
|
|
8057
|
+
break;
|
|
8058
|
+
default:
|
|
8059
|
+
let u = options.readUnknownField;
|
|
8060
|
+
if (u === "throw")
|
|
8061
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
8062
|
+
let d = reader.skip(wireType);
|
|
8063
|
+
if (u !== false)
|
|
8064
|
+
(u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
8065
|
+
}
|
|
8066
|
+
}
|
|
8067
|
+
return message;
|
|
8068
|
+
}
|
|
8069
|
+
internalBinaryWrite(message, writer, options) {
|
|
8070
|
+
if (message.spaceId !== 0n)
|
|
8071
|
+
writer.tag(1, import_runtime.WireType.Varint).int64(message.spaceId);
|
|
8072
|
+
if (message.title !== "")
|
|
8073
|
+
writer.tag(2, import_runtime.WireType.LengthDelimited).string(message.title);
|
|
8074
|
+
let u = options.writeUnknownFields;
|
|
8075
|
+
if (u !== false)
|
|
8076
|
+
(u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
8077
|
+
return writer;
|
|
8078
|
+
}
|
|
8079
|
+
}
|
|
8080
|
+
var MessageEntity_MessageEntityThreadTitle = new MessageEntity_MessageEntityThreadTitle$Type;
|
|
8081
|
+
|
|
7969
8082
|
class MessageReactions$Type extends import_runtime4.MessageType {
|
|
7970
8083
|
constructor() {
|
|
7971
8084
|
super("MessageReactions", [
|
|
@@ -36567,27 +36680,6 @@ var GET_CHAT_METHOD = typeof Method.GET_CHAT === "number" && Number.isInteger(Me
|
|
|
36567
36680
|
var GET_CHAT_HISTORY_METHOD = typeof Method.GET_CHAT_HISTORY === "number" && Number.isInteger(Method.GET_CHAT_HISTORY) && Method.GET_CHAT_HISTORY > 0 ? Method.GET_CHAT_HISTORY : 5;
|
|
36568
36681
|
var GET_MESSAGES_METHOD = typeof Method.GET_MESSAGES === "number" && Number.isInteger(Method.GET_MESSAGES) && Method.GET_MESSAGES > 0 ? Method.GET_MESSAGES : 38;
|
|
36569
36682
|
var CREATE_SUBTHREAD_METHOD = typeof Method.CREATE_SUBTHREAD === "number" && Number.isInteger(Method.CREATE_SUBTHREAD) && Method.CREATE_SUBTHREAD > 0 ? Method.CREATE_SUBTHREAD : 42;
|
|
36570
|
-
function isPlacementMode(raw) {
|
|
36571
|
-
return raw === "thread" || raw === "main";
|
|
36572
|
-
}
|
|
36573
|
-
function hasReplyThreadConfig(config2) {
|
|
36574
|
-
if (isPlacementMode(config2.replyThreadMode))
|
|
36575
|
-
return true;
|
|
36576
|
-
if (typeof config2.replyThreadAutoCreateMinMessages === "number")
|
|
36577
|
-
return true;
|
|
36578
|
-
if (typeof config2.replyThreadRequireExplicitMention === "boolean")
|
|
36579
|
-
return true;
|
|
36580
|
-
if (typeof config2.replyThreadParentHistoryLimit === "number")
|
|
36581
|
-
return true;
|
|
36582
|
-
if (!config2.groups || typeof config2.groups !== "object" || Array.isArray(config2.groups))
|
|
36583
|
-
return false;
|
|
36584
|
-
return Object.values(config2.groups).some((group) => {
|
|
36585
|
-
if (!group || typeof group !== "object" || Array.isArray(group))
|
|
36586
|
-
return false;
|
|
36587
|
-
const groupConfig = group;
|
|
36588
|
-
return isPlacementMode(groupConfig.replyThreadMode) || typeof groupConfig.replyThreadAutoCreateMinMessages === "number" || typeof groupConfig.replyThreadRequireExplicitMention === "boolean" || typeof groupConfig.replyThreadParentHistoryLimit === "number";
|
|
36589
|
-
});
|
|
36590
|
-
}
|
|
36591
36683
|
function buildChatPeer(chatId) {
|
|
36592
36684
|
return {
|
|
36593
36685
|
type: {
|
|
@@ -36597,21 +36689,14 @@ function buildChatPeer(chatId) {
|
|
|
36597
36689
|
};
|
|
36598
36690
|
}
|
|
36599
36691
|
function getInlineReplyThreadsCapabilityConfig(params) {
|
|
36600
|
-
|
|
36601
|
-
cfg: params.cfg,
|
|
36602
|
-
accountId: params.accountId ?? null
|
|
36603
|
-
});
|
|
36604
|
-
return {
|
|
36605
|
-
replyThreads: account.config.capabilities?.replyThreads === true || hasReplyThreadConfig(account.config)
|
|
36606
|
-
};
|
|
36692
|
+
return { replyThreads: true };
|
|
36607
36693
|
}
|
|
36608
36694
|
function isInlineReplyThreadsEnabled(params) {
|
|
36609
36695
|
return getInlineReplyThreadsCapabilityConfig(params).replyThreads;
|
|
36610
36696
|
}
|
|
36611
36697
|
function resolveInlineReplyThreadChatId(params) {
|
|
36612
|
-
|
|
36613
|
-
|
|
36614
|
-
}
|
|
36698
|
+
params.cfg;
|
|
36699
|
+
params.accountId;
|
|
36615
36700
|
if (params.parentChatId == null) {
|
|
36616
36701
|
return null;
|
|
36617
36702
|
}
|
|
@@ -36726,7 +36811,7 @@ function looksLikeInlineTargetId(raw, normalizedInput) {
|
|
|
36726
36811
|
|
|
36727
36812
|
// src/inline/monitor.ts
|
|
36728
36813
|
import { mkdir } from "node:fs/promises";
|
|
36729
|
-
import
|
|
36814
|
+
import path4 from "node:path";
|
|
36730
36815
|
import {
|
|
36731
36816
|
buildCommandTextFromArgs,
|
|
36732
36817
|
findCommandByNativeName,
|
|
@@ -37529,6 +37614,315 @@ function sanitizeInlineOutgoingText(text) {
|
|
|
37529
37614
|
});
|
|
37530
37615
|
}
|
|
37531
37616
|
|
|
37617
|
+
// src/inline/thread-routes.ts
|
|
37618
|
+
import path2 from "node:path";
|
|
37619
|
+
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
37620
|
+
import { readJsonFileWithFallback, writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store";
|
|
37621
|
+
var TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
37622
|
+
var MAX_ENTRIES = 5000;
|
|
37623
|
+
var PERSISTENT_MAX_ENTRIES = 2000;
|
|
37624
|
+
var STORE_VERSION = 1;
|
|
37625
|
+
var PERSISTENT_NAMESPACE = "inline.reply-thread-routes";
|
|
37626
|
+
var INLINE_REPLY_THREAD_ROUTE_KEY = Symbol.for("openclaw.inlineReplyThreadRoutes");
|
|
37627
|
+
var DEFAULT_AGENT_KEY = "__any__";
|
|
37628
|
+
var DEFAULT_STORE_KEY = "__default__";
|
|
37629
|
+
var routeState;
|
|
37630
|
+
var persistentStore;
|
|
37631
|
+
var persistentStoreDisabled = false;
|
|
37632
|
+
function getRouteState() {
|
|
37633
|
+
if (routeState)
|
|
37634
|
+
return routeState;
|
|
37635
|
+
const globalStore = globalThis;
|
|
37636
|
+
const existing = globalStore[INLINE_REPLY_THREAD_ROUTE_KEY];
|
|
37637
|
+
routeState = existing ?? {
|
|
37638
|
+
memory: new Map,
|
|
37639
|
+
fileWrites: new Map
|
|
37640
|
+
};
|
|
37641
|
+
globalStore[INLINE_REPLY_THREAD_ROUTE_KEY] = routeState;
|
|
37642
|
+
return routeState;
|
|
37643
|
+
}
|
|
37644
|
+
function normalizePositiveId(raw) {
|
|
37645
|
+
if (raw == null)
|
|
37646
|
+
return;
|
|
37647
|
+
if (typeof raw === "bigint")
|
|
37648
|
+
return raw >= 0n ? String(raw) : undefined;
|
|
37649
|
+
if (typeof raw === "number") {
|
|
37650
|
+
return Number.isInteger(raw) && raw >= 0 ? String(raw) : undefined;
|
|
37651
|
+
}
|
|
37652
|
+
const trimmed = raw.trim();
|
|
37653
|
+
if (!/^\d+$/.test(trimmed))
|
|
37654
|
+
return;
|
|
37655
|
+
return trimmed;
|
|
37656
|
+
}
|
|
37657
|
+
function normalizeOptionalText(raw) {
|
|
37658
|
+
const trimmed = raw?.trim();
|
|
37659
|
+
return trimmed || undefined;
|
|
37660
|
+
}
|
|
37661
|
+
function safePathSegment(value) {
|
|
37662
|
+
return value.trim().replace(/[^a-z0-9._-]+/gi, "_").slice(0, 80) || "global";
|
|
37663
|
+
}
|
|
37664
|
+
function isRecord3(value) {
|
|
37665
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37666
|
+
}
|
|
37667
|
+
function readString(record2, key) {
|
|
37668
|
+
const value = record2[key];
|
|
37669
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
37670
|
+
}
|
|
37671
|
+
function readTimestamp(record2, key, fallback) {
|
|
37672
|
+
const value = record2[key];
|
|
37673
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : fallback;
|
|
37674
|
+
}
|
|
37675
|
+
function normalizeRecord(value) {
|
|
37676
|
+
if (!isRecord3(value))
|
|
37677
|
+
return null;
|
|
37678
|
+
const accountId = readString(value, "accountId");
|
|
37679
|
+
const parentChatId = normalizePositiveId(readString(value, "parentChatId"));
|
|
37680
|
+
const threadId = normalizePositiveId(readString(value, "threadId"));
|
|
37681
|
+
if (!accountId || !parentChatId || !threadId)
|
|
37682
|
+
return null;
|
|
37683
|
+
const now = Date.now();
|
|
37684
|
+
const parentMessageId = normalizePositiveId(readString(value, "parentMessageId"));
|
|
37685
|
+
const title = normalizeOptionalText(readString(value, "title"));
|
|
37686
|
+
const threadLabel = normalizeOptionalText(readString(value, "threadLabel"));
|
|
37687
|
+
const agentId = normalizeOptionalText(readString(value, "agentId"));
|
|
37688
|
+
return {
|
|
37689
|
+
accountId,
|
|
37690
|
+
parentChatId,
|
|
37691
|
+
threadId,
|
|
37692
|
+
createdAt: readTimestamp(value, "createdAt", now),
|
|
37693
|
+
updatedAt: readTimestamp(value, "updatedAt", now),
|
|
37694
|
+
...parentMessageId ? { parentMessageId } : {},
|
|
37695
|
+
...title ? { title } : {},
|
|
37696
|
+
...threadLabel ? { threadLabel } : {},
|
|
37697
|
+
...agentId ? { agentId } : {}
|
|
37698
|
+
};
|
|
37699
|
+
}
|
|
37700
|
+
function isExpired(record2, now) {
|
|
37701
|
+
return now - record2.updatedAt > TTL_MS;
|
|
37702
|
+
}
|
|
37703
|
+
function reportRouteStateError(error51) {
|
|
37704
|
+
try {
|
|
37705
|
+
getOptionalInlineRuntime()?.logging.getChildLogger({ plugin: "inline", feature: "reply-thread-route-state" }).warn("Inline reply-thread route state failed", { error: String(error51) });
|
|
37706
|
+
} catch {}
|
|
37707
|
+
}
|
|
37708
|
+
function disablePersistentStore(error51) {
|
|
37709
|
+
persistentStoreDisabled = true;
|
|
37710
|
+
persistentStore = undefined;
|
|
37711
|
+
if (!String(error51).includes("openKeyedStore is only available")) {
|
|
37712
|
+
reportRouteStateError(error51);
|
|
37713
|
+
}
|
|
37714
|
+
}
|
|
37715
|
+
function getPersistentStore() {
|
|
37716
|
+
if (persistentStoreDisabled)
|
|
37717
|
+
return;
|
|
37718
|
+
if (persistentStore)
|
|
37719
|
+
return persistentStore;
|
|
37720
|
+
const openKeyedStore = getOptionalInlineRuntime()?.state?.openKeyedStore;
|
|
37721
|
+
if (typeof openKeyedStore !== "function")
|
|
37722
|
+
return;
|
|
37723
|
+
try {
|
|
37724
|
+
persistentStore = openKeyedStore({
|
|
37725
|
+
namespace: PERSISTENT_NAMESPACE,
|
|
37726
|
+
maxEntries: PERSISTENT_MAX_ENTRIES,
|
|
37727
|
+
defaultTtlMs: TTL_MS
|
|
37728
|
+
});
|
|
37729
|
+
return persistentStore;
|
|
37730
|
+
} catch (error51) {
|
|
37731
|
+
disablePersistentStore(error51);
|
|
37732
|
+
return;
|
|
37733
|
+
}
|
|
37734
|
+
}
|
|
37735
|
+
function resolveRoutesPath(accountId) {
|
|
37736
|
+
const resolveStateDir = getOptionalInlineRuntime()?.state?.resolveStateDir;
|
|
37737
|
+
if (typeof resolveStateDir !== "function")
|
|
37738
|
+
return;
|
|
37739
|
+
return path2.join(resolveStateDir(), "inline", "reply-thread-routes", `${safePathSegment(accountId)}.json`);
|
|
37740
|
+
}
|
|
37741
|
+
function activeKey(accountId, parentChatId, agentId) {
|
|
37742
|
+
return `${accountId}:parent:${parentChatId}:agent:${agentId || DEFAULT_AGENT_KEY}`;
|
|
37743
|
+
}
|
|
37744
|
+
function messageKey(accountId, parentChatId, parentMessageId) {
|
|
37745
|
+
return `${accountId}:parent:${parentChatId}:message:${parentMessageId}`;
|
|
37746
|
+
}
|
|
37747
|
+
function keysForRecord(record2) {
|
|
37748
|
+
const keys = new Set;
|
|
37749
|
+
if (record2.parentMessageId) {
|
|
37750
|
+
keys.add(messageKey(record2.accountId, record2.parentChatId, record2.parentMessageId));
|
|
37751
|
+
}
|
|
37752
|
+
if (record2.agentId) {
|
|
37753
|
+
keys.add(activeKey(record2.accountId, record2.parentChatId, record2.agentId));
|
|
37754
|
+
}
|
|
37755
|
+
keys.add(activeKey(record2.accountId, record2.parentChatId));
|
|
37756
|
+
return [...keys];
|
|
37757
|
+
}
|
|
37758
|
+
function keysForLookup(params) {
|
|
37759
|
+
const keys = new Set;
|
|
37760
|
+
if (params.parentMessageId) {
|
|
37761
|
+
keys.add(messageKey(params.accountId, params.parentChatId, params.parentMessageId));
|
|
37762
|
+
}
|
|
37763
|
+
if (params.agentId) {
|
|
37764
|
+
keys.add(activeKey(params.accountId, params.parentChatId, params.agentId));
|
|
37765
|
+
}
|
|
37766
|
+
keys.add(activeKey(params.accountId, params.parentChatId));
|
|
37767
|
+
return [...keys];
|
|
37768
|
+
}
|
|
37769
|
+
function setMemory(key, value, now) {
|
|
37770
|
+
const memory = getRouteState().memory;
|
|
37771
|
+
memory.delete(key);
|
|
37772
|
+
memory.set(key, { value, updatedAt: now });
|
|
37773
|
+
pruneMapToMaxSize(memory, MAX_ENTRIES);
|
|
37774
|
+
}
|
|
37775
|
+
function getMemory(key, now) {
|
|
37776
|
+
const memory = getRouteState().memory;
|
|
37777
|
+
const entry = memory.get(key);
|
|
37778
|
+
if (!entry)
|
|
37779
|
+
return;
|
|
37780
|
+
if (now - entry.updatedAt > TTL_MS) {
|
|
37781
|
+
memory.delete(key);
|
|
37782
|
+
return;
|
|
37783
|
+
}
|
|
37784
|
+
memory.delete(key);
|
|
37785
|
+
memory.set(key, { ...entry, updatedAt: now });
|
|
37786
|
+
return entry.value;
|
|
37787
|
+
}
|
|
37788
|
+
async function readFileRoutes(accountId) {
|
|
37789
|
+
const filePath = resolveRoutesPath(accountId);
|
|
37790
|
+
if (!filePath)
|
|
37791
|
+
return new Map;
|
|
37792
|
+
const fallback = { version: STORE_VERSION, routes: {} };
|
|
37793
|
+
const now = Date.now();
|
|
37794
|
+
try {
|
|
37795
|
+
const { value } = await readJsonFileWithFallback(filePath, fallback);
|
|
37796
|
+
if (value.version !== STORE_VERSION || !isRecord3(value.routes)) {
|
|
37797
|
+
return new Map;
|
|
37798
|
+
}
|
|
37799
|
+
const routes = new Map;
|
|
37800
|
+
for (const [key, raw] of Object.entries(value.routes)) {
|
|
37801
|
+
const route = normalizeRecord(raw);
|
|
37802
|
+
if (route && !isExpired(route, now))
|
|
37803
|
+
routes.set(key, route);
|
|
37804
|
+
}
|
|
37805
|
+
return routes;
|
|
37806
|
+
} catch (error51) {
|
|
37807
|
+
reportRouteStateError(error51);
|
|
37808
|
+
return new Map;
|
|
37809
|
+
}
|
|
37810
|
+
}
|
|
37811
|
+
async function writeFileRoutes(accountId, routes) {
|
|
37812
|
+
const filePath = resolveRoutesPath(accountId);
|
|
37813
|
+
if (!filePath)
|
|
37814
|
+
return;
|
|
37815
|
+
const pruned = [...routes.entries()].sort((left, right) => right[1].updatedAt - left[1].updatedAt).slice(0, PERSISTENT_MAX_ENTRIES);
|
|
37816
|
+
await writeJsonFileAtomically(filePath, {
|
|
37817
|
+
version: STORE_VERSION,
|
|
37818
|
+
routes: Object.fromEntries(pruned)
|
|
37819
|
+
});
|
|
37820
|
+
}
|
|
37821
|
+
function rememberFileRoutes(params) {
|
|
37822
|
+
const state = getRouteState();
|
|
37823
|
+
const queueKey = params.accountId || DEFAULT_STORE_KEY;
|
|
37824
|
+
const previous = state.fileWrites.get(queueKey) ?? Promise.resolve();
|
|
37825
|
+
const next = previous.catch(() => {
|
|
37826
|
+
return;
|
|
37827
|
+
}).then(async () => {
|
|
37828
|
+
const routes = await readFileRoutes(params.accountId);
|
|
37829
|
+
for (const key of params.keys) {
|
|
37830
|
+
routes.set(key, params.record);
|
|
37831
|
+
}
|
|
37832
|
+
await writeFileRoutes(params.accountId, routes);
|
|
37833
|
+
});
|
|
37834
|
+
state.fileWrites.set(queueKey, next);
|
|
37835
|
+
const cleanup = () => {
|
|
37836
|
+
if (state.fileWrites.get(queueKey) === next) {
|
|
37837
|
+
state.fileWrites.delete(queueKey);
|
|
37838
|
+
}
|
|
37839
|
+
};
|
|
37840
|
+
next.then(cleanup, cleanup);
|
|
37841
|
+
next.catch(reportRouteStateError);
|
|
37842
|
+
}
|
|
37843
|
+
function rememberInlineReplyThreadRoute(params) {
|
|
37844
|
+
const accountId = params.accountId.trim();
|
|
37845
|
+
const parentChatId = normalizePositiveId(params.parentChatId);
|
|
37846
|
+
const threadId = normalizePositiveId(params.threadId);
|
|
37847
|
+
if (!accountId || !parentChatId || !threadId)
|
|
37848
|
+
return null;
|
|
37849
|
+
const now = Date.now();
|
|
37850
|
+
const parentMessageId = normalizePositiveId(params.parentMessageId);
|
|
37851
|
+
const title = normalizeOptionalText(params.title);
|
|
37852
|
+
const threadLabel = normalizeOptionalText(params.threadLabel);
|
|
37853
|
+
const agentId = normalizeOptionalText(params.agentId);
|
|
37854
|
+
const record2 = {
|
|
37855
|
+
accountId,
|
|
37856
|
+
parentChatId,
|
|
37857
|
+
threadId,
|
|
37858
|
+
createdAt: now,
|
|
37859
|
+
updatedAt: now,
|
|
37860
|
+
...parentMessageId ? { parentMessageId } : {},
|
|
37861
|
+
...title ? { title } : {},
|
|
37862
|
+
...threadLabel ? { threadLabel } : {},
|
|
37863
|
+
...agentId ? { agentId } : {}
|
|
37864
|
+
};
|
|
37865
|
+
const keys = keysForRecord(record2);
|
|
37866
|
+
for (const key of keys) {
|
|
37867
|
+
setMemory(key, record2, now);
|
|
37868
|
+
}
|
|
37869
|
+
const store = getPersistentStore();
|
|
37870
|
+
if (store) {
|
|
37871
|
+
for (const key of keys) {
|
|
37872
|
+
store.register(key, record2, { ttlMs: TTL_MS }).catch(disablePersistentStore);
|
|
37873
|
+
}
|
|
37874
|
+
return record2;
|
|
37875
|
+
}
|
|
37876
|
+
rememberFileRoutes({ accountId, keys, record: record2 });
|
|
37877
|
+
return record2;
|
|
37878
|
+
}
|
|
37879
|
+
async function lookupInlineReplyThreadRoute(params) {
|
|
37880
|
+
const accountId = params.accountId.trim();
|
|
37881
|
+
const parentChatId = normalizePositiveId(params.parentChatId);
|
|
37882
|
+
if (!accountId || !parentChatId)
|
|
37883
|
+
return null;
|
|
37884
|
+
const parentMessageId = normalizePositiveId(params.parentMessageId);
|
|
37885
|
+
const agentId = normalizeOptionalText(params.agentId);
|
|
37886
|
+
const keys = keysForLookup({
|
|
37887
|
+
accountId,
|
|
37888
|
+
parentChatId,
|
|
37889
|
+
...parentMessageId ? { parentMessageId } : {},
|
|
37890
|
+
...agentId ? { agentId } : {}
|
|
37891
|
+
});
|
|
37892
|
+
const now = Date.now();
|
|
37893
|
+
for (const key of keys) {
|
|
37894
|
+
const cached3 = getMemory(key, now);
|
|
37895
|
+
if (cached3)
|
|
37896
|
+
return cached3;
|
|
37897
|
+
}
|
|
37898
|
+
const store = getPersistentStore();
|
|
37899
|
+
if (store) {
|
|
37900
|
+
for (const key of keys) {
|
|
37901
|
+
try {
|
|
37902
|
+
const found = await store.lookup(key);
|
|
37903
|
+
const normalized = normalizeRecord(found);
|
|
37904
|
+
if (normalized && !isExpired(normalized, now)) {
|
|
37905
|
+
setMemory(key, normalized, now);
|
|
37906
|
+
return normalized;
|
|
37907
|
+
}
|
|
37908
|
+
} catch (error51) {
|
|
37909
|
+
disablePersistentStore(error51);
|
|
37910
|
+
break;
|
|
37911
|
+
}
|
|
37912
|
+
}
|
|
37913
|
+
}
|
|
37914
|
+
const fileRoutes = await readFileRoutes(accountId);
|
|
37915
|
+
for (const key of keys) {
|
|
37916
|
+
const found = fileRoutes.get(key);
|
|
37917
|
+
const normalized = normalizeRecord(found);
|
|
37918
|
+
if (normalized) {
|
|
37919
|
+
setMemory(key, normalized, now);
|
|
37920
|
+
return normalized;
|
|
37921
|
+
}
|
|
37922
|
+
}
|
|
37923
|
+
return null;
|
|
37924
|
+
}
|
|
37925
|
+
|
|
37532
37926
|
// src/inline/outbound-sanitize.ts
|
|
37533
37927
|
var HEARTBEAT_TOKEN = "HEARTBEAT_OK";
|
|
37534
37928
|
var OPENCLAW_RUNTIME_CONTEXT_NOTICE = "This context is runtime-generated, not user-authored. Keep internal details private.";
|
|
@@ -37942,7 +38336,7 @@ function optionalVisibleActionText(raw, label) {
|
|
|
37942
38336
|
}
|
|
37943
38337
|
return visible.text.trim() || undefined;
|
|
37944
38338
|
}
|
|
37945
|
-
function
|
|
38339
|
+
function isRecord4(value) {
|
|
37946
38340
|
return typeof value === "object" && value !== null;
|
|
37947
38341
|
}
|
|
37948
38342
|
function normalizeReplyMarkupButtons(raw) {
|
|
@@ -37954,7 +38348,7 @@ function normalizeReplyMarkupButtons(raw) {
|
|
|
37954
38348
|
continue;
|
|
37955
38349
|
const row = [];
|
|
37956
38350
|
for (const candidateButton of candidateRow) {
|
|
37957
|
-
if (!
|
|
38351
|
+
if (!isRecord4(candidateButton))
|
|
37958
38352
|
continue;
|
|
37959
38353
|
const text = sanitizeInlineActionLabel(typeof candidateButton.text === "string" ? candidateButton.text : "");
|
|
37960
38354
|
const callbackData = sanitizeInlineActionCallbackData(typeof candidateButton.callback_data === "string" ? candidateButton.callback_data : "");
|
|
@@ -38536,7 +38930,7 @@ async function withInlineClient(params) {
|
|
|
38536
38930
|
});
|
|
38537
38931
|
await client.connect();
|
|
38538
38932
|
try {
|
|
38539
|
-
return await params.fn(client);
|
|
38933
|
+
return await params.fn(client, account);
|
|
38540
38934
|
} finally {
|
|
38541
38935
|
await client.close().catch(() => {});
|
|
38542
38936
|
}
|
|
@@ -38805,16 +39199,16 @@ var inlineMessageActions = {
|
|
|
38805
39199
|
}
|
|
38806
39200
|
if (normalizedAction === "reply" || normalizedAction === "thread-reply") {
|
|
38807
39201
|
const parseMarkdown = resolveInlineAccount({ cfg, accountId: accountId ?? null }).config.parseMarkdown ?? true;
|
|
38808
|
-
const
|
|
39202
|
+
const isThreadReply = normalizedAction === "thread-reply";
|
|
38809
39203
|
return await withInlineClient({
|
|
38810
39204
|
cfg,
|
|
38811
39205
|
accountId,
|
|
38812
39206
|
fn: async (client) => {
|
|
38813
39207
|
const actions = resolveInlineMessageActionsParam(params);
|
|
38814
|
-
if (
|
|
39208
|
+
if (isThreadReply) {
|
|
38815
39209
|
const rawThreadId = readFlexibleId(params, "threadId") ?? readStringParam(params, "threadId");
|
|
38816
39210
|
if (!rawThreadId) {
|
|
38817
|
-
throw new Error("inline thread-reply: threadId is required
|
|
39211
|
+
throw new Error("inline thread-reply: threadId is required. Call thread-create first or use reply for the parent chat.");
|
|
38818
39212
|
}
|
|
38819
39213
|
const chatId2 = parseInlineId(rawThreadId, "threadId");
|
|
38820
39214
|
const replyToMsgId2 = parseOptionalInlineId(readFlexibleId(params, "messageId") ?? readFlexibleId(params, "replyTo") ?? readFlexibleId(params, "replyToId") ?? readStringParam(params, "messageId") ?? readStringParam(params, "replyTo") ?? readStringParam(params, "replyToId"), "messageId");
|
|
@@ -38838,7 +39232,7 @@ var inlineMessageActions = {
|
|
|
38838
39232
|
replyToId: replyToMsgId2 != null ? String(replyToMsgId2) : null
|
|
38839
39233
|
});
|
|
38840
39234
|
}
|
|
38841
|
-
const replyParams =
|
|
39235
|
+
const replyParams = params;
|
|
38842
39236
|
const chatId = resolveChatIdFromParams(replyParams);
|
|
38843
39237
|
const replyToMsgId = parseInlineId(readFlexibleId(replyParams, "messageId") ?? readFlexibleId(replyParams, "replyTo") ?? readFlexibleId(replyParams, "replyToId") ?? readStringParam(replyParams, "messageId") ?? readStringParam(replyParams, "replyTo") ?? readStringParam(replyParams, "replyToId", { required: true }), "messageId");
|
|
38844
39238
|
const text = resolveInlineActionText(replyParams, { required: true });
|
|
@@ -39177,11 +39571,11 @@ var inlineMessageActions = {
|
|
|
39177
39571
|
});
|
|
39178
39572
|
}
|
|
39179
39573
|
if (normalizedAction === "channel-create" || normalizedAction === "thread-create") {
|
|
39180
|
-
const
|
|
39574
|
+
const isThreadCreate = normalizedAction === "thread-create";
|
|
39181
39575
|
return await withInlineClient({
|
|
39182
39576
|
cfg,
|
|
39183
39577
|
accountId,
|
|
39184
|
-
fn: async (client) => {
|
|
39578
|
+
fn: async (client, account) => {
|
|
39185
39579
|
const title = requireVisibleActionText(readStringParam(params, "title") ?? readStringParam(params, "name") ?? readStringParam(params, "threadName") ?? readStringParam(params, "message", { required: true }), "title");
|
|
39186
39580
|
const description = optionalVisibleActionText(readStringParam(params, "description"), "description");
|
|
39187
39581
|
const emoji3 = readStringParam(params, "emoji");
|
|
@@ -39200,7 +39594,7 @@ var inlineMessageActions = {
|
|
|
39200
39594
|
values: participantRefs,
|
|
39201
39595
|
label: "participant"
|
|
39202
39596
|
});
|
|
39203
|
-
if (
|
|
39597
|
+
if (isThreadCreate) {
|
|
39204
39598
|
const parentChatId = resolveChatIdFromParams(params);
|
|
39205
39599
|
const parentMessageId = parseOptionalInlineId(resolveThreadParentMessageId({
|
|
39206
39600
|
args: params,
|
|
@@ -39220,12 +39614,23 @@ var inlineMessageActions = {
|
|
|
39220
39614
|
if (result2.oneofKind !== "createSubthread") {
|
|
39221
39615
|
throw new Error(`inline action: expected createSubthread result, got ${String(result2.oneofKind)}`);
|
|
39222
39616
|
}
|
|
39617
|
+
const createdChat = result2.createSubthread.chat ?? null;
|
|
39618
|
+
if (createdChat?.id != null) {
|
|
39619
|
+
const routeParentMessageId = createdChat.parentMessageId ?? parentMessageId;
|
|
39620
|
+
rememberInlineReplyThreadRoute({
|
|
39621
|
+
accountId: account.accountId,
|
|
39622
|
+
parentChatId: createdChat.parentChatId ?? parentChatId,
|
|
39623
|
+
threadId: createdChat.id,
|
|
39624
|
+
title: createdChat.title ?? title,
|
|
39625
|
+
...routeParentMessageId != null ? { parentMessageId: routeParentMessageId } : {}
|
|
39626
|
+
});
|
|
39627
|
+
}
|
|
39223
39628
|
return jsonResult(toJsonSafe({
|
|
39224
39629
|
ok: true,
|
|
39225
39630
|
title,
|
|
39226
39631
|
parentChatId: String(parentChatId),
|
|
39227
39632
|
parentMessageId: parentMessageId != null ? String(parentMessageId) : null,
|
|
39228
|
-
chat:
|
|
39633
|
+
chat: createdChat,
|
|
39229
39634
|
dialog: result2.createSubthread.dialog ?? null,
|
|
39230
39635
|
anchorMessage: result2.createSubthread.anchorMessage ?? null
|
|
39231
39636
|
}));
|
|
@@ -40054,26 +40459,26 @@ function buildInlineModelBrowseChannelData() {
|
|
|
40054
40459
|
}
|
|
40055
40460
|
|
|
40056
40461
|
// src/inline/thread-participation.ts
|
|
40057
|
-
import
|
|
40462
|
+
import path3 from "node:path";
|
|
40058
40463
|
import { resolveGlobalDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
|
|
40059
40464
|
import { createPersistentDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
40060
|
-
var
|
|
40061
|
-
var
|
|
40062
|
-
var
|
|
40063
|
-
var
|
|
40465
|
+
var TTL_MS2 = 24 * 60 * 60 * 1000;
|
|
40466
|
+
var MAX_ENTRIES2 = 5000;
|
|
40467
|
+
var PERSISTENT_MAX_ENTRIES2 = 1000;
|
|
40468
|
+
var PERSISTENT_NAMESPACE2 = "inline.thread-participation";
|
|
40064
40469
|
var PERSISTENT_DEDUPE_NAMESPACE = "participation";
|
|
40065
40470
|
var INLINE_THREAD_PARTICIPATION_KEY = Symbol.for("openclaw.inlineThreadParticipation");
|
|
40066
40471
|
var threadParticipation = resolveGlobalDedupeCache(INLINE_THREAD_PARTICIPATION_KEY, {
|
|
40067
|
-
ttlMs:
|
|
40068
|
-
maxSize:
|
|
40472
|
+
ttlMs: TTL_MS2,
|
|
40473
|
+
maxSize: MAX_ENTRIES2
|
|
40069
40474
|
});
|
|
40070
|
-
var
|
|
40071
|
-
var
|
|
40475
|
+
var persistentStore2;
|
|
40476
|
+
var persistentStoreDisabled2 = false;
|
|
40072
40477
|
var persistentDedupe;
|
|
40073
40478
|
function makeKey(accountId, parentChatId, threadId) {
|
|
40074
40479
|
return `${accountId}:${String(parentChatId)}:${String(threadId)}`;
|
|
40075
40480
|
}
|
|
40076
|
-
function
|
|
40481
|
+
function safePathSegment2(value) {
|
|
40077
40482
|
return value.trim().replace(/[^a-z0-9._-]+/gi, "_").slice(0, 80) || "global";
|
|
40078
40483
|
}
|
|
40079
40484
|
function isExpectedOpenKeyedStoreUnavailable(error51) {
|
|
@@ -40085,28 +40490,28 @@ function reportPersistentThreadParticipationError(error51) {
|
|
|
40085
40490
|
} catch {}
|
|
40086
40491
|
}
|
|
40087
40492
|
function disablePersistentThreadParticipation(error51) {
|
|
40088
|
-
|
|
40089
|
-
|
|
40493
|
+
persistentStoreDisabled2 = true;
|
|
40494
|
+
persistentStore2 = undefined;
|
|
40090
40495
|
if (!isExpectedOpenKeyedStoreUnavailable(error51)) {
|
|
40091
40496
|
reportPersistentThreadParticipationError(error51);
|
|
40092
40497
|
}
|
|
40093
40498
|
}
|
|
40094
40499
|
function getPersistentThreadParticipationStore() {
|
|
40095
|
-
if (
|
|
40500
|
+
if (persistentStoreDisabled2)
|
|
40096
40501
|
return;
|
|
40097
|
-
if (
|
|
40098
|
-
return
|
|
40502
|
+
if (persistentStore2)
|
|
40503
|
+
return persistentStore2;
|
|
40099
40504
|
const runtime = getOptionalInlineRuntime();
|
|
40100
40505
|
const openKeyedStore = runtime?.state?.openKeyedStore;
|
|
40101
40506
|
if (typeof openKeyedStore !== "function")
|
|
40102
40507
|
return;
|
|
40103
40508
|
try {
|
|
40104
|
-
|
|
40105
|
-
namespace:
|
|
40106
|
-
maxEntries:
|
|
40107
|
-
defaultTtlMs:
|
|
40509
|
+
persistentStore2 = openKeyedStore({
|
|
40510
|
+
namespace: PERSISTENT_NAMESPACE2,
|
|
40511
|
+
maxEntries: PERSISTENT_MAX_ENTRIES2,
|
|
40512
|
+
defaultTtlMs: TTL_MS2
|
|
40108
40513
|
});
|
|
40109
|
-
return
|
|
40514
|
+
return persistentStore2;
|
|
40110
40515
|
} catch (error51) {
|
|
40111
40516
|
disablePersistentThreadParticipation(error51);
|
|
40112
40517
|
return;
|
|
@@ -40121,10 +40526,10 @@ function getPersistentThreadParticipationDedupe() {
|
|
|
40121
40526
|
try {
|
|
40122
40527
|
const stateDir = resolveStateDir();
|
|
40123
40528
|
persistentDedupe = createPersistentDedupe({
|
|
40124
|
-
ttlMs:
|
|
40125
|
-
memoryMaxSize:
|
|
40126
|
-
fileMaxEntries:
|
|
40127
|
-
resolveFilePath: (namespace) =>
|
|
40529
|
+
ttlMs: TTL_MS2,
|
|
40530
|
+
memoryMaxSize: MAX_ENTRIES2,
|
|
40531
|
+
fileMaxEntries: PERSISTENT_MAX_ENTRIES2,
|
|
40532
|
+
resolveFilePath: (namespace) => path3.join(stateDir, "inline", "thread-participation", `${safePathSegment2(namespace)}.json`),
|
|
40128
40533
|
onDiskError: reportPersistentThreadParticipationError
|
|
40129
40534
|
});
|
|
40130
40535
|
return persistentDedupe;
|
|
@@ -40139,7 +40544,7 @@ function rememberPersistentThreadParticipation(params) {
|
|
|
40139
40544
|
store.register(params.key, {
|
|
40140
40545
|
...params.agentId ? { agentId: params.agentId } : {},
|
|
40141
40546
|
repliedAt: Date.now()
|
|
40142
|
-
}, { ttlMs:
|
|
40547
|
+
}, { ttlMs: TTL_MS2 }).catch(disablePersistentThreadParticipation);
|
|
40143
40548
|
return;
|
|
40144
40549
|
}
|
|
40145
40550
|
getPersistentThreadParticipationDedupe()?.checkAndRecord(params.key, { namespace: PERSISTENT_DEDUPE_NAMESPACE }).catch(reportPersistentThreadParticipationError);
|
|
@@ -40832,7 +41237,7 @@ function buildSyntheticInlineTextMessage(params) {
|
|
|
40832
41237
|
}
|
|
40833
41238
|
var INLINE_ACTION_MAX_ROWS2 = 8;
|
|
40834
41239
|
var INLINE_ACTION_MAX_PER_ROW2 = 8;
|
|
40835
|
-
function
|
|
41240
|
+
function isRecord5(value) {
|
|
40836
41241
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40837
41242
|
}
|
|
40838
41243
|
function normalizeOptionalString2(value) {
|
|
@@ -40853,7 +41258,7 @@ function normalizeInlineStreamingMode(value) {
|
|
|
40853
41258
|
}
|
|
40854
41259
|
}
|
|
40855
41260
|
function resolveExplicitInlineStreamingMode(config2) {
|
|
40856
|
-
const streaming =
|
|
41261
|
+
const streaming = isRecord5(config2.streaming) ? config2.streaming : null;
|
|
40857
41262
|
return normalizeInlineStreamingMode(streaming?.mode) ?? normalizeInlineStreamingMode(config2.streaming) ?? normalizeInlineStreamingMode(config2.streamMode);
|
|
40858
41263
|
}
|
|
40859
41264
|
function resolveInlineStreamingMode(config2) {
|
|
@@ -40873,14 +41278,14 @@ function resolveInlineProgressPlaceholderEnabled(config2) {
|
|
|
40873
41278
|
return true;
|
|
40874
41279
|
if (config2.streaming === false)
|
|
40875
41280
|
return false;
|
|
40876
|
-
if (
|
|
41281
|
+
if (isRecord5(config2.streaming) && isRecord5(config2.streaming.progress))
|
|
40877
41282
|
return true;
|
|
40878
41283
|
return config2.streaming === undefined && config2.streamMode === undefined && config2.streamViaEditMessage !== true;
|
|
40879
41284
|
}
|
|
40880
41285
|
function resolveInlineBlockStreamingEnabled(config2) {
|
|
40881
41286
|
const mode = resolveInlineStreamingMode(config2);
|
|
40882
|
-
const streaming =
|
|
40883
|
-
const block = streaming &&
|
|
41287
|
+
const streaming = isRecord5(config2.streaming) ? config2.streaming : null;
|
|
41288
|
+
const block = streaming && isRecord5(streaming.block) ? streaming.block : null;
|
|
40884
41289
|
if (typeof block?.enabled === "boolean")
|
|
40885
41290
|
return block.enabled;
|
|
40886
41291
|
if (typeof config2.blockStreaming === "boolean")
|
|
@@ -41104,7 +41509,7 @@ function normalizeReplyMarkupButtonsWith(raw, options) {
|
|
|
41104
41509
|
continue;
|
|
41105
41510
|
const row = [];
|
|
41106
41511
|
for (const candidateButton of candidateRow) {
|
|
41107
|
-
if (!
|
|
41512
|
+
if (!isRecord5(candidateButton))
|
|
41108
41513
|
continue;
|
|
41109
41514
|
const text = sanitizeInlineActionLabel(typeof candidateButton.text === "string" ? candidateButton.text : "");
|
|
41110
41515
|
const callbackDataRaw = typeof candidateButton.callback_data === "string" ? candidateButton.callback_data.trim() : "";
|
|
@@ -41125,9 +41530,9 @@ function normalizeReplyMarkupButtonsWith(raw, options) {
|
|
|
41125
41530
|
return rows;
|
|
41126
41531
|
}
|
|
41127
41532
|
function resolveInlineReplyActions(payload) {
|
|
41128
|
-
const channelData =
|
|
41129
|
-
const inlineData = channelData &&
|
|
41130
|
-
const telegramData = channelData &&
|
|
41533
|
+
const channelData = isRecord5(payload.channelData) ? payload.channelData : undefined;
|
|
41534
|
+
const inlineData = channelData && isRecord5(channelData.inline) ? channelData.inline : undefined;
|
|
41535
|
+
const telegramData = channelData && isRecord5(channelData.telegram) ? channelData.telegram : undefined;
|
|
41131
41536
|
let rawButtons = undefined;
|
|
41132
41537
|
let hasExplicitButtons = false;
|
|
41133
41538
|
let mapCallbackData;
|
|
@@ -41223,6 +41628,14 @@ function rememberInlineBotDelivery(params) {
|
|
|
41223
41628
|
if (!params.replyThreadContext || params.chatId !== params.replyThreadContext.childChatId)
|
|
41224
41629
|
return;
|
|
41225
41630
|
recordInlineThreadParticipation(params.accountId, params.replyThreadContext.parentChatId, params.replyThreadContext.childChatId, { agentId: params.agentId });
|
|
41631
|
+
rememberInlineReplyThreadRoute({
|
|
41632
|
+
accountId: params.accountId,
|
|
41633
|
+
parentChatId: params.replyThreadContext.parentChatId,
|
|
41634
|
+
threadId: params.replyThreadContext.childChatId,
|
|
41635
|
+
parentMessageId: params.replyThreadContext.parentMessageId,
|
|
41636
|
+
threadLabel: params.replyThreadContext.threadLabel,
|
|
41637
|
+
agentId: params.agentId
|
|
41638
|
+
});
|
|
41226
41639
|
}
|
|
41227
41640
|
function hasBotMessageId(cache, chatId, messageId) {
|
|
41228
41641
|
const key = String(chatId);
|
|
@@ -41637,7 +42050,7 @@ function resolveFilePathHint(params) {
|
|
|
41637
42050
|
return preferred;
|
|
41638
42051
|
try {
|
|
41639
42052
|
const pathname = new URL(params.sourceUrl).pathname;
|
|
41640
|
-
const base =
|
|
42053
|
+
const base = path4.basename(pathname).trim();
|
|
41641
42054
|
if (base)
|
|
41642
42055
|
return base;
|
|
41643
42056
|
} catch {}
|
|
@@ -41712,6 +42125,44 @@ async function resolveInlineInboundReplyThreadContext(params) {
|
|
|
41712
42125
|
anchorMessage
|
|
41713
42126
|
};
|
|
41714
42127
|
}
|
|
42128
|
+
function parseCachedInlineId(raw) {
|
|
42129
|
+
if (!raw || !/^\d+$/.test(raw))
|
|
42130
|
+
return null;
|
|
42131
|
+
try {
|
|
42132
|
+
return BigInt(raw);
|
|
42133
|
+
} catch {
|
|
42134
|
+
return null;
|
|
42135
|
+
}
|
|
42136
|
+
}
|
|
42137
|
+
async function resolveInlineReplyThreadContextFromRoute(params) {
|
|
42138
|
+
const parentChatId = parseCachedInlineId(params.route.parentChatId);
|
|
42139
|
+
const childChatId = parseCachedInlineId(params.route.threadId);
|
|
42140
|
+
if (parentChatId == null || childChatId == null) {
|
|
42141
|
+
return null;
|
|
42142
|
+
}
|
|
42143
|
+
const parentMessageId = parseCachedInlineId(params.route.parentMessageId);
|
|
42144
|
+
const parentChatInfo = await resolveChatInfo(params.client, params.chatCache, parentChatId).catch(() => ({
|
|
42145
|
+
kind: "group",
|
|
42146
|
+
title: params.fallbackParentChatTitle
|
|
42147
|
+
}));
|
|
42148
|
+
const anchorMessage = parentMessageId != null ? await loadInlineReplyThreadAnchorMessage({
|
|
42149
|
+
client: params.client,
|
|
42150
|
+
parentChatId,
|
|
42151
|
+
parentMessageId
|
|
42152
|
+
}).catch(() => null) : null;
|
|
42153
|
+
const labelSource = params.route.threadLabel ?? params.route.title ?? null;
|
|
42154
|
+
return {
|
|
42155
|
+
childChatId,
|
|
42156
|
+
parentChatId,
|
|
42157
|
+
parentChatTitle: parentChatInfo.title ?? params.fallbackParentChatTitle,
|
|
42158
|
+
parentMessageId,
|
|
42159
|
+
threadLabel: buildInlineReplyThreadLabel({
|
|
42160
|
+
title: labelSource,
|
|
42161
|
+
anchorMessage
|
|
42162
|
+
}),
|
|
42163
|
+
anchorMessage
|
|
42164
|
+
};
|
|
42165
|
+
}
|
|
41715
42166
|
function normalizeInlineReplyThreadMode(raw) {
|
|
41716
42167
|
return raw === "thread" || raw === "main" ? raw : "auto";
|
|
41717
42168
|
}
|
|
@@ -41840,8 +42291,8 @@ async function monitorInlineProvider(params) {
|
|
|
41840
42291
|
}
|
|
41841
42292
|
const token = await resolveInlineToken(account);
|
|
41842
42293
|
const stateDir = core3.state.resolveStateDir();
|
|
41843
|
-
const statePath =
|
|
41844
|
-
await mkdir(
|
|
42294
|
+
const statePath = path4.join(stateDir, "channels", "inline", `${account.accountId}.json`);
|
|
42295
|
+
await mkdir(path4.dirname(statePath), { recursive: true });
|
|
41845
42296
|
let client = null;
|
|
41846
42297
|
const pushDiagnostics = (patch) => {
|
|
41847
42298
|
statusSink?.({
|
|
@@ -41953,7 +42404,7 @@ async function monitorInlineProvider(params) {
|
|
|
41953
42404
|
statusSink?.({ lastError: `getChat failed: ${String(err)}` });
|
|
41954
42405
|
}
|
|
41955
42406
|
const isGroup = chatInfo.kind !== "direct";
|
|
41956
|
-
const replyThreadsEnabled =
|
|
42407
|
+
const replyThreadsEnabled = isInlineReplyThreadsEnabled({ cfg, accountId: account.accountId });
|
|
41957
42408
|
const replyThreadContext = await resolveInlineInboundReplyThreadContext({
|
|
41958
42409
|
replyThreadsEnabled,
|
|
41959
42410
|
client,
|
|
@@ -42193,7 +42644,7 @@ async function monitorInlineProvider(params) {
|
|
|
42193
42644
|
statusSink?.({ lastError: `getChat failed: ${String(err)}` });
|
|
42194
42645
|
}
|
|
42195
42646
|
const isGroup = chatInfo.kind !== "direct";
|
|
42196
|
-
const replyThreadsEnabled =
|
|
42647
|
+
const replyThreadsEnabled = isInlineReplyThreadsEnabled({ cfg, accountId: account.accountId });
|
|
42197
42648
|
const replyThreadContext = await resolveInlineInboundReplyThreadContext({
|
|
42198
42649
|
replyThreadsEnabled,
|
|
42199
42650
|
client,
|
|
@@ -42290,6 +42741,16 @@ async function monitorInlineProvider(params) {
|
|
|
42290
42741
|
}
|
|
42291
42742
|
});
|
|
42292
42743
|
const inboundSessionKey = replyThreadContext && isGroup ? buildInlineReplyThreadSessionKey(route.sessionKey, replyThreadContext.childChatId) : route.sessionKey;
|
|
42744
|
+
if (replyThreadContext && isGroup) {
|
|
42745
|
+
rememberInlineReplyThreadRoute({
|
|
42746
|
+
accountId: account.accountId,
|
|
42747
|
+
parentChatId: replyThreadContext.parentChatId,
|
|
42748
|
+
threadId: replyThreadContext.childChatId,
|
|
42749
|
+
parentMessageId: replyThreadContext.parentMessageId,
|
|
42750
|
+
threadLabel: replyThreadContext.threadLabel,
|
|
42751
|
+
agentId: route.agentId
|
|
42752
|
+
});
|
|
42753
|
+
}
|
|
42293
42754
|
const rememberSentBotMessage = (params2) => {
|
|
42294
42755
|
if (params2.messageId == null)
|
|
42295
42756
|
return;
|
|
@@ -42723,6 +43184,30 @@ This model will be used for your next message.`, []);
|
|
|
42723
43184
|
minMessages: replyThreadAutoCreateMinMessages
|
|
42724
43185
|
}) && !shouldEditCallbackTargetInPlace;
|
|
42725
43186
|
if (shouldCreateDeliveryThread) {
|
|
43187
|
+
const cachedRoute = await lookupInlineReplyThreadRoute({
|
|
43188
|
+
accountId: account.accountId,
|
|
43189
|
+
parentChatId: effectiveChatId,
|
|
43190
|
+
parentMessageId: msg.id,
|
|
43191
|
+
agentId: route.agentId
|
|
43192
|
+
}).catch((error51) => {
|
|
43193
|
+
statusSink?.({ lastError: `reply-thread route lookup failed: ${String(error51)}` });
|
|
43194
|
+
runtime.error?.(`inline reply-thread route lookup failed: ${String(error51)}`);
|
|
43195
|
+
return null;
|
|
43196
|
+
});
|
|
43197
|
+
if (cachedRoute) {
|
|
43198
|
+
deliveryReplyThreadContext = await resolveInlineReplyThreadContextFromRoute({
|
|
43199
|
+
route: cachedRoute,
|
|
43200
|
+
client,
|
|
43201
|
+
chatCache,
|
|
43202
|
+
fallbackParentChatTitle: effectiveGroupTitle
|
|
43203
|
+
}).catch((error51) => {
|
|
43204
|
+
statusSink?.({ lastError: `reply-thread route restore failed: ${String(error51)}` });
|
|
43205
|
+
runtime.error?.(`inline reply-thread route restore failed: ${String(error51)}`);
|
|
43206
|
+
return null;
|
|
43207
|
+
});
|
|
43208
|
+
}
|
|
43209
|
+
}
|
|
43210
|
+
if (shouldCreateDeliveryThread && !deliveryReplyThreadContext) {
|
|
42726
43211
|
const createdThread = await createInlineReplyThreadForMessage({
|
|
42727
43212
|
client,
|
|
42728
43213
|
parentChatId: effectiveChatId,
|
|
@@ -42744,13 +43229,35 @@ This model will be used for your next message.`, []);
|
|
|
42744
43229
|
}),
|
|
42745
43230
|
anchorMessage: createdThread.anchorMessage
|
|
42746
43231
|
};
|
|
43232
|
+
rememberInlineReplyThreadRoute({
|
|
43233
|
+
accountId: account.accountId,
|
|
43234
|
+
parentChatId: deliveryReplyThreadContext.parentChatId,
|
|
43235
|
+
threadId: deliveryReplyThreadContext.childChatId,
|
|
43236
|
+
parentMessageId: deliveryReplyThreadContext.parentMessageId,
|
|
43237
|
+
title: createdThread.title,
|
|
43238
|
+
threadLabel: deliveryReplyThreadContext.threadLabel,
|
|
43239
|
+
agentId: route.agentId
|
|
43240
|
+
});
|
|
42747
43241
|
}
|
|
42748
43242
|
}
|
|
42749
43243
|
if (shouldCreateDeliveryThread && !deliveryReplyThreadContext) {
|
|
42750
|
-
await
|
|
42751
|
-
|
|
42752
|
-
|
|
42753
|
-
|
|
43244
|
+
const cachedRoute = await lookupInlineReplyThreadRoute({
|
|
43245
|
+
accountId: account.accountId,
|
|
43246
|
+
parentChatId: effectiveChatId,
|
|
43247
|
+
parentMessageId: msg.id,
|
|
43248
|
+
agentId: route.agentId
|
|
43249
|
+
}).catch(() => null);
|
|
43250
|
+
if (cachedRoute) {
|
|
43251
|
+
deliveryReplyThreadContext = await resolveInlineReplyThreadContextFromRoute({
|
|
43252
|
+
route: cachedRoute,
|
|
43253
|
+
client,
|
|
43254
|
+
chatCache,
|
|
43255
|
+
fallbackParentChatTitle: effectiveGroupTitle
|
|
43256
|
+
}).catch(() => null);
|
|
43257
|
+
}
|
|
43258
|
+
}
|
|
43259
|
+
if (shouldCreateDeliveryThread && !deliveryReplyThreadContext) {
|
|
43260
|
+
runtime.error?.("inline create reply thread failed; falling back to parent chat delivery");
|
|
42754
43261
|
}
|
|
42755
43262
|
if (!replyThreadContext && deliveryReplyThreadContext?.anchorMessage != null) {
|
|
42756
43263
|
effectiveHistoryContext = prependInlineReplyThreadAnchor({
|
|
@@ -43688,7 +44195,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
|
|
|
43688
44195
|
}
|
|
43689
44196
|
|
|
43690
44197
|
// src/inline/doctor.ts
|
|
43691
|
-
function
|
|
44198
|
+
function isRecord6(value) {
|
|
43692
44199
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
43693
44200
|
}
|
|
43694
44201
|
function readInherited(account, parent, key) {
|
|
@@ -43699,12 +44206,12 @@ function hasEntries(value) {
|
|
|
43699
44206
|
}
|
|
43700
44207
|
function hasConfiguredGroups(account, parent) {
|
|
43701
44208
|
const groups = readInherited(account, parent, "groups");
|
|
43702
|
-
return
|
|
44209
|
+
return isRecord6(groups) && Object.keys(groups).length > 0;
|
|
43703
44210
|
}
|
|
43704
44211
|
function hasGroupScopedSenders(groups) {
|
|
43705
|
-
if (!
|
|
44212
|
+
if (!isRecord6(groups))
|
|
43706
44213
|
return false;
|
|
43707
|
-
return Object.values(groups).some((group) =>
|
|
44214
|
+
return Object.values(groups).some((group) => isRecord6(group) && hasEntries(group.allowFrom));
|
|
43708
44215
|
}
|
|
43709
44216
|
function hasGroupSenders(account, parent) {
|
|
43710
44217
|
return hasEntries(readInherited(account, parent, "groupAllowFrom")) || hasGroupScopedSenders(readInherited(account, parent, "groups"));
|
|
@@ -44291,11 +44798,11 @@ async function probeInlineAccount(account, timeoutMs) {
|
|
|
44291
44798
|
}
|
|
44292
44799
|
|
|
44293
44800
|
// src/inline/status-issues.ts
|
|
44294
|
-
import { asString, isRecord as
|
|
44801
|
+
import { asString, isRecord as isRecord7 } from "openclaw/plugin-sdk/status-helpers";
|
|
44295
44802
|
var RECENT_RUNTIME_ISSUE_MS = 30 * 60 * 1000;
|
|
44296
44803
|
var INLINE_CONNECT_GRACE_MS = 120 * 1000;
|
|
44297
44804
|
function readInlineProbeSummary(value) {
|
|
44298
|
-
if (!
|
|
44805
|
+
if (!isRecord7(value)) {
|
|
44299
44806
|
return {};
|
|
44300
44807
|
}
|
|
44301
44808
|
const summary = {};
|
|
@@ -44312,12 +44819,12 @@ function looksLikeAuthError(text) {
|
|
|
44312
44819
|
return /(401|403|unauth|forbidden|invalid token|token invalid|unauthorized)/i.test(text);
|
|
44313
44820
|
}
|
|
44314
44821
|
function readInlineDiagnosticsSummary(value) {
|
|
44315
|
-
if (!
|
|
44822
|
+
if (!isRecord7(value)) {
|
|
44316
44823
|
return {};
|
|
44317
44824
|
}
|
|
44318
|
-
const protocolValue =
|
|
44319
|
-
const transportValue = (protocolValue &&
|
|
44320
|
-
const pingValue = protocolValue &&
|
|
44825
|
+
const protocolValue = isRecord7(value.protocol) ? value.protocol : undefined;
|
|
44826
|
+
const transportValue = (protocolValue && isRecord7(protocolValue.transport) ? protocolValue.transport : undefined) ?? (isRecord7(value.transport) ? value.transport : undefined);
|
|
44827
|
+
const pingValue = protocolValue && isRecord7(protocolValue.ping) ? protocolValue.ping : undefined;
|
|
44321
44828
|
return {
|
|
44322
44829
|
...protocolValue ? {
|
|
44323
44830
|
protocol: {
|
|
@@ -44349,7 +44856,7 @@ function asFiniteNumber(value) {
|
|
|
44349
44856
|
function collectInlineStatusIssues(accounts) {
|
|
44350
44857
|
const issues = [];
|
|
44351
44858
|
for (const entry of accounts) {
|
|
44352
|
-
if (!
|
|
44859
|
+
if (!isRecord7(entry)) {
|
|
44353
44860
|
continue;
|
|
44354
44861
|
}
|
|
44355
44862
|
const accountId = asString(entry.accountId);
|
|
@@ -44848,7 +45355,7 @@ var inlineNativeApprovalAdapter = splitChannelApprovalCapability(inlineApprovalC
|
|
|
44848
45355
|
// src/inline/channel.ts
|
|
44849
45356
|
var activeMonitors = new Map;
|
|
44850
45357
|
function resolveInlineStatePath(accountId) {
|
|
44851
|
-
return
|
|
45358
|
+
return path5.join(getInlineRuntime().state.resolveStateDir(), "channels", "inline", `${accountId}.json`);
|
|
44852
45359
|
}
|
|
44853
45360
|
async function deleteInlineAccountState(accountId) {
|
|
44854
45361
|
try {
|
|
@@ -45974,13 +46481,10 @@ var inlineChannelPlugin = {
|
|
|
45974
46481
|
] : [],
|
|
45975
46482
|
"- Inline history tools: `read` and `search` return media-aware message payloads (`media`, `attachments`, `attachmentUrls`) so image-only history remains discoverable. `search` is chat-scoped; run it per chat.",
|
|
45976
46483
|
"- Inline special tools: use `inline_nudge` to send a nudge, and `inline_forward` to forward message ids between chats or users.",
|
|
45977
|
-
|
|
45978
|
-
|
|
45979
|
-
|
|
45980
|
-
|
|
45981
|
-
] : [
|
|
45982
|
-
"- Inline reply threads are disabled: `thread-reply` uses the legacy reply path and `thread-create` creates a normal chat, not a dedicated Inline reply-thread chat."
|
|
45983
|
-
]
|
|
46484
|
+
"- Inline reply threads: use normal `reply` for short or newly started parent-chat conversations unless the user asks for a thread.",
|
|
46485
|
+
"- Inline reply threads: use `thread-create` to create or reuse a real reply thread under the current/target chat. On inbound turns, omit `messageId` to anchor it to the current message, or pass `messageId`/`parentMessageId` explicitly.",
|
|
46486
|
+
"- Inline reply threads: use `thread-reply` to send into a real reply thread, with `threadId` set to the reply-thread chat id returned by `thread-create`. Reuse that `threadId`; do not create one thread per message.",
|
|
46487
|
+
"- Inline reply-thread turns include nearby parent-chat context by default. If that context is incomplete, call `inline_parent_context` before answering."
|
|
45984
46488
|
]
|
|
45985
46489
|
},
|
|
45986
46490
|
messaging: {
|
|
@@ -46343,5 +46847,5 @@ export {
|
|
|
46343
46847
|
inlineChannelPlugin
|
|
46344
46848
|
};
|
|
46345
46849
|
|
|
46346
|
-
//# debugId=
|
|
46850
|
+
//# debugId=A439BD5C99EA226864756E2164756E21
|
|
46347
46851
|
//# sourceMappingURL=channel-plugin-api.js.map
|