@ycodium-ai/plugin-im 0.2.3094 → 0.2.3102
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 +14 -1
- package/dist/index.js +767 -328
- package/locales/en.json +5 -0
- package/locales/zh-CN.json +5 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -23360,7 +23360,7 @@ var require_websocket = __commonJS({
|
|
|
23360
23360
|
var http = __require("http");
|
|
23361
23361
|
var net = __require("net");
|
|
23362
23362
|
var tls = __require("tls");
|
|
23363
|
-
var { randomBytes, createHash:
|
|
23363
|
+
var { randomBytes, createHash: createHash5 } = __require("crypto");
|
|
23364
23364
|
var { Duplex, Readable } = __require("stream");
|
|
23365
23365
|
var { URL: URL2 } = __require("url");
|
|
23366
23366
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -24028,7 +24028,7 @@ var require_websocket = __commonJS({
|
|
|
24028
24028
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
24029
24029
|
return;
|
|
24030
24030
|
}
|
|
24031
|
-
const digest =
|
|
24031
|
+
const digest = createHash5("sha1").update(key + GUID).digest("base64");
|
|
24032
24032
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
24033
24033
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
24034
24034
|
return;
|
|
@@ -24397,7 +24397,7 @@ var require_websocket_server = __commonJS({
|
|
|
24397
24397
|
var EventEmitter = __require("events");
|
|
24398
24398
|
var http = __require("http");
|
|
24399
24399
|
var { Duplex } = __require("stream");
|
|
24400
|
-
var { createHash:
|
|
24400
|
+
var { createHash: createHash5 } = __require("crypto");
|
|
24401
24401
|
var extension = require_extension();
|
|
24402
24402
|
var PerMessageDeflate = require_permessage_deflate();
|
|
24403
24403
|
var subprotocol = require_subprotocol();
|
|
@@ -24704,7 +24704,7 @@ var require_websocket_server = __commonJS({
|
|
|
24704
24704
|
);
|
|
24705
24705
|
}
|
|
24706
24706
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
24707
|
-
const digest =
|
|
24707
|
+
const digest = createHash5("sha1").update(key + GUID).digest("base64");
|
|
24708
24708
|
const headers = [
|
|
24709
24709
|
"HTTP/1.1 101 Switching Protocols",
|
|
24710
24710
|
"Upgrade: websocket",
|
|
@@ -126249,9 +126249,9 @@ var recordOwner = (owners, goal) => ({
|
|
|
126249
126249
|
});
|
|
126250
126250
|
|
|
126251
126251
|
// src/keepNewest.ts
|
|
126252
|
-
var keepNewest = (
|
|
126253
|
-
const entries = Object.entries(
|
|
126254
|
-
return entries.length <= limit ?
|
|
126252
|
+
var keepNewest = (record3, limit) => {
|
|
126253
|
+
const entries = Object.entries(record3);
|
|
126254
|
+
return entries.length <= limit ? record3 : Object.fromEntries(entries.slice(entries.length - limit));
|
|
126255
126255
|
};
|
|
126256
126256
|
|
|
126257
126257
|
// src/chatState.ts
|
|
@@ -126286,8 +126286,8 @@ var chatOf = (state, chatKey) => ({
|
|
|
126286
126286
|
...DEFAULT_CHAT_RECORD,
|
|
126287
126287
|
...state.chats[chatKey]
|
|
126288
126288
|
});
|
|
126289
|
-
var chatsOnProject = (state, projectId) => Object.entries(state.chats).filter(([,
|
|
126290
|
-
var chatOfThread = (state, threadId) => Object.entries(state.chats).find(([,
|
|
126289
|
+
var chatsOnProject = (state, projectId) => Object.entries(state.chats).filter(([, record3]) => record3.projectId === projectId).map(([chatKey]) => chatKey);
|
|
126290
|
+
var chatOfThread = (state, threadId) => Object.entries(state.chats).find(([, record3]) => record3.threadId === threadId)?.[0] ?? state.teamGoals?.[threadId]?.chatKey;
|
|
126291
126291
|
var findApprovalByToken = (state, token) => {
|
|
126292
126292
|
for (const approval of Object.values(state.approvals)) {
|
|
126293
126293
|
const button = approval.options.find((option) => option.token === token);
|
|
@@ -126299,29 +126299,29 @@ var openApprovalOf = (state, chatKey) => Object.values(state.approvals).findLast
|
|
|
126299
126299
|
(approval) => approval.chatKey === chatKey && !approval.resolved
|
|
126300
126300
|
);
|
|
126301
126301
|
var findQuestionByToken = (state, token) => {
|
|
126302
|
-
for (const
|
|
126303
|
-
for (const item of
|
|
126302
|
+
for (const record3 of Object.values(questionsOf(state))) {
|
|
126303
|
+
for (const item of record3.items) {
|
|
126304
126304
|
const option = item.options.find((candidate) => candidate.token === token);
|
|
126305
|
-
if (option !== void 0) return { record:
|
|
126306
|
-
if (item.submitToken === token) return { record:
|
|
126305
|
+
if (option !== void 0) return { record: record3, item, click: { kind: "option", option } };
|
|
126306
|
+
if (item.submitToken === token) return { record: record3, item, click: { kind: "submit" } };
|
|
126307
126307
|
}
|
|
126308
126308
|
}
|
|
126309
126309
|
return void 0;
|
|
126310
126310
|
};
|
|
126311
126311
|
var openQuestionOf = (state, chatKey, threadId) => Object.values(questionsOf(state)).findLast(
|
|
126312
|
-
(
|
|
126312
|
+
(record3) => record3.chatKey === chatKey && record3.threadId === threadId && !record3.resolved
|
|
126313
126313
|
);
|
|
126314
126314
|
var isUnanswered = (item) => item.answer === void 0;
|
|
126315
126315
|
var findQueueByToken = (state, token) => {
|
|
126316
|
-
for (const
|
|
126317
|
-
if (
|
|
126318
|
-
if (
|
|
126319
|
-
if (
|
|
126316
|
+
for (const record3 of Object.values(queueOf(state))) {
|
|
126317
|
+
if (record3.steerToken === token) return { record: record3, op: "steer" };
|
|
126318
|
+
if (record3.withdrawToken === token) return { record: record3, op: "withdraw" };
|
|
126319
|
+
if (record3.resumeToken === token) return { record: record3, op: "resume" };
|
|
126320
126320
|
}
|
|
126321
126321
|
return void 0;
|
|
126322
126322
|
};
|
|
126323
126323
|
var openQueueOfThread = (state, threadId) => Object.values(queueOf(state)).filter(
|
|
126324
|
-
(
|
|
126324
|
+
(record3) => record3.threadId === threadId && record3.settled === void 0
|
|
126325
126325
|
);
|
|
126326
126326
|
var isRecord = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
126327
126327
|
var nonEmpty3 = (value2) => typeof value2 === "string" && value2 !== "" ? value2 : null;
|
|
@@ -126394,24 +126394,24 @@ var readAnswer = (value2) => {
|
|
|
126394
126394
|
return null;
|
|
126395
126395
|
};
|
|
126396
126396
|
var withQuestionItem = (state, requestId, questionId, patch) => {
|
|
126397
|
-
const
|
|
126398
|
-
if (requestId === null || questionId === null ||
|
|
126399
|
-
if (!
|
|
126397
|
+
const record3 = requestId === null ? void 0 : questionsOf(state)[requestId];
|
|
126398
|
+
if (requestId === null || questionId === null || record3 === void 0) return state;
|
|
126399
|
+
if (!record3.items.some((item) => item.id === questionId)) return state;
|
|
126400
126400
|
return {
|
|
126401
126401
|
...state,
|
|
126402
126402
|
questions: {
|
|
126403
126403
|
...questionsOf(state),
|
|
126404
126404
|
[requestId]: {
|
|
126405
|
-
...
|
|
126406
|
-
items:
|
|
126405
|
+
...record3,
|
|
126406
|
+
items: record3.items.map((item) => item.id === questionId ? patch(item) : item)
|
|
126407
126407
|
}
|
|
126408
126408
|
}
|
|
126409
126409
|
};
|
|
126410
126410
|
};
|
|
126411
126411
|
var withQueueRecord = (state, intentId, patch) => {
|
|
126412
|
-
const
|
|
126413
|
-
if (intentId === null ||
|
|
126414
|
-
return { ...state, queue: { ...queueOf(state), [intentId]: patch(
|
|
126412
|
+
const record3 = intentId === null ? void 0 : queueOf(state)[intentId];
|
|
126413
|
+
if (intentId === null || record3 === void 0) return state;
|
|
126414
|
+
return { ...state, queue: { ...queueOf(state), [intentId]: patch(record3) } };
|
|
126415
126415
|
};
|
|
126416
126416
|
var withChat = (state, chatKey, patch) => ({
|
|
126417
126417
|
...state,
|
|
@@ -126467,10 +126467,10 @@ var foldImEvent = (state, name, data) => {
|
|
|
126467
126467
|
return { ...bound, teamGoals: recordOwner(bound.teamGoals, goal) };
|
|
126468
126468
|
}
|
|
126469
126469
|
case "thread-attached": {
|
|
126470
|
-
const
|
|
126471
|
-
if (
|
|
126472
|
-
const key = attachedKey(
|
|
126473
|
-
const attached = { ...state.attached, [key]:
|
|
126470
|
+
const record3 = readAttached(data);
|
|
126471
|
+
if (record3 === null) return state;
|
|
126472
|
+
const key = attachedKey(record3.chatKey, record3.threadId);
|
|
126473
|
+
const attached = { ...state.attached, [key]: record3 };
|
|
126474
126474
|
return { ...state, attached: keepNewest(attached, ATTACHED_THREAD_LIMIT) };
|
|
126475
126475
|
}
|
|
126476
126476
|
case "approval-offered": {
|
|
@@ -126611,21 +126611,21 @@ var foldImEvent = (state, name, data) => {
|
|
|
126611
126611
|
case "queue-carded": {
|
|
126612
126612
|
const cardId = nonEmpty3(data["cardId"]);
|
|
126613
126613
|
if (cardId === null) return state;
|
|
126614
|
-
return withQueueRecord(state, nonEmpty3(data["intentId"]), (
|
|
126615
|
-
...
|
|
126614
|
+
return withQueueRecord(state, nonEmpty3(data["intentId"]), (record3) => ({
|
|
126615
|
+
...record3,
|
|
126616
126616
|
cardId
|
|
126617
126617
|
}));
|
|
126618
126618
|
}
|
|
126619
126619
|
case "queue-steering":
|
|
126620
|
-
return withQueueRecord(state, nonEmpty3(data["intentId"]), (
|
|
126621
|
-
...
|
|
126620
|
+
return withQueueRecord(state, nonEmpty3(data["intentId"]), (record3) => ({
|
|
126621
|
+
...record3,
|
|
126622
126622
|
steering: data["steering"] === true
|
|
126623
126623
|
}));
|
|
126624
126624
|
case "queue-settled": {
|
|
126625
126625
|
const outcome = data["outcome"];
|
|
126626
126626
|
if (outcome !== "steered" && outcome !== "sent" && outcome !== "removed") return state;
|
|
126627
|
-
return withQueueRecord(state, nonEmpty3(data["intentId"]), (
|
|
126628
|
-
...
|
|
126627
|
+
return withQueueRecord(state, nonEmpty3(data["intentId"]), (record3) => ({
|
|
126628
|
+
...record3,
|
|
126629
126629
|
settled: outcome
|
|
126630
126630
|
}));
|
|
126631
126631
|
}
|
|
@@ -126750,18 +126750,18 @@ var readDeliveryTargets = (config2) => {
|
|
|
126750
126750
|
if (typeof table2 !== "object" || table2 === null) return [];
|
|
126751
126751
|
return Object.entries(table2).flatMap(([rowId, row]) => {
|
|
126752
126752
|
if (typeof row !== "object" || row === null) return [];
|
|
126753
|
-
const
|
|
126754
|
-
const kind = readString(
|
|
126755
|
-
if (targetIssues(
|
|
126756
|
-
const targetId = readString(
|
|
126753
|
+
const record3 = row;
|
|
126754
|
+
const kind = readString(record3, "kind") || "chat";
|
|
126755
|
+
if (targetIssues(record3).length > 0 || !isTargetKind(kind)) return [];
|
|
126756
|
+
const targetId = readString(record3, "targetId");
|
|
126757
126757
|
return [
|
|
126758
126758
|
{
|
|
126759
126759
|
rowId,
|
|
126760
|
-
botId: readString(
|
|
126760
|
+
botId: readString(record3, DELIVERY_BOT_COLUMN),
|
|
126761
126761
|
targetId,
|
|
126762
|
-
name: readString(
|
|
126762
|
+
name: readString(record3, "name") || targetId,
|
|
126763
126763
|
kind,
|
|
126764
|
-
platformChatId: readString(
|
|
126764
|
+
platformChatId: readString(record3, "platformChatId")
|
|
126765
126765
|
}
|
|
126766
126766
|
];
|
|
126767
126767
|
});
|
|
@@ -127154,8 +127154,8 @@ var makeApprovals = (core, anchors) => {
|
|
|
127154
127154
|
host.log.info("chat asked for an approval", { threadId, requestId: offer.requestId });
|
|
127155
127155
|
if (cardId === null) return;
|
|
127156
127156
|
commit("approval-carded", { requestId: offer.requestId, cardId });
|
|
127157
|
-
const
|
|
127158
|
-
if (
|
|
127157
|
+
const record3 = core.state.approvals[offer.requestId];
|
|
127158
|
+
if (record3?.resolved === true) await settleApprovalCard(record3, { kind: "elsewhere" });
|
|
127159
127159
|
} catch (error) {
|
|
127160
127160
|
host.log.warn("chat could not ask for the approval", { error: describeError(error) });
|
|
127161
127161
|
}
|
|
@@ -127974,16 +127974,16 @@ var parseSendBody = (raw) => {
|
|
|
127974
127974
|
return "bad-request";
|
|
127975
127975
|
}
|
|
127976
127976
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return "bad-request";
|
|
127977
|
-
const
|
|
127978
|
-
const botId =
|
|
127979
|
-
const targetId =
|
|
127980
|
-
const text4 =
|
|
127981
|
-
const format2 =
|
|
127977
|
+
const record3 = parsed;
|
|
127978
|
+
const botId = record3["botId"];
|
|
127979
|
+
const targetId = record3["targetId"];
|
|
127980
|
+
const text4 = record3["text"];
|
|
127981
|
+
const format2 = record3["format"];
|
|
127982
127982
|
if (typeof botId !== "string" || botId.trim() === "") return "bad-request";
|
|
127983
127983
|
if (typeof targetId !== "string" || targetId.trim() === "") return "bad-request";
|
|
127984
127984
|
if (typeof text4 !== "string" || text4.trim() === "") return "bad-request";
|
|
127985
127985
|
if (format2 !== void 0 && format2 !== "plain" && format2 !== "markdown") return "bad-request";
|
|
127986
|
-
for (const key of Object.keys(
|
|
127986
|
+
for (const key of Object.keys(record3)) {
|
|
127987
127987
|
if (key !== "botId" && key !== "targetId" && key !== "text" && key !== "format") {
|
|
127988
127988
|
return "bad-request";
|
|
127989
127989
|
}
|
|
@@ -128857,35 +128857,35 @@ var makeQuestionFlow = (host) => {
|
|
|
128857
128857
|
const itemOf = (requestId, questionId) => recordOf(requestId)?.items.find((item) => item.id === questionId);
|
|
128858
128858
|
const hasButtons = (chatKey) => host.target(chatKey)?.adapter.choiceCards !== void 0;
|
|
128859
128859
|
const redraw = async (requestId, questionId) => {
|
|
128860
|
-
const
|
|
128860
|
+
const record3 = recordOf(requestId);
|
|
128861
128861
|
const item = itemOf(requestId, questionId);
|
|
128862
|
-
const target2 =
|
|
128863
|
-
if (
|
|
128864
|
-
if (
|
|
128862
|
+
const target2 = record3 === void 0 ? void 0 : host.target(record3.chatKey);
|
|
128863
|
+
if (record3 === void 0 || item?.cardId === void 0 || target2 === void 0) return;
|
|
128864
|
+
if (record3.resolved || item.answer !== void 0) return;
|
|
128865
128865
|
try {
|
|
128866
128866
|
await target2.adapter.choiceCards?.update(
|
|
128867
128867
|
target2.binding,
|
|
128868
128868
|
item.cardId,
|
|
128869
|
-
questionCardOf(item,
|
|
128869
|
+
questionCardOf(item, record3.items.indexOf(item), record3.items.length, t)
|
|
128870
128870
|
);
|
|
128871
128871
|
} catch (error) {
|
|
128872
128872
|
host.warn("chat could not update the question card", error);
|
|
128873
128873
|
}
|
|
128874
128874
|
};
|
|
128875
128875
|
const freeze = async (requestId, questionId) => {
|
|
128876
|
-
const
|
|
128876
|
+
const record3 = recordOf(requestId);
|
|
128877
128877
|
const item = itemOf(requestId, questionId);
|
|
128878
|
-
const target2 =
|
|
128879
|
-
if (
|
|
128878
|
+
const target2 = record3 === void 0 ? void 0 : host.target(record3.chatKey);
|
|
128879
|
+
if (record3 === void 0 || item?.cardId === void 0 || target2 === void 0) return;
|
|
128880
128880
|
try {
|
|
128881
128881
|
await target2.adapter.choiceCards?.update(
|
|
128882
128882
|
target2.binding,
|
|
128883
128883
|
item.cardId,
|
|
128884
128884
|
questionSettledCardOf(
|
|
128885
128885
|
item,
|
|
128886
|
-
|
|
128887
|
-
|
|
128888
|
-
|
|
128886
|
+
record3.items.indexOf(item),
|
|
128887
|
+
record3.items.length,
|
|
128888
|
+
record3.ending ?? "here",
|
|
128889
128889
|
t
|
|
128890
128890
|
)
|
|
128891
128891
|
);
|
|
@@ -128894,13 +128894,13 @@ var makeQuestionFlow = (host) => {
|
|
|
128894
128894
|
}
|
|
128895
128895
|
};
|
|
128896
128896
|
const sayNext = async (requestId) => {
|
|
128897
|
-
const
|
|
128898
|
-
if (
|
|
128899
|
-
const item =
|
|
128897
|
+
const record3 = recordOf(requestId);
|
|
128898
|
+
if (record3 === void 0 || record3.resolved) return;
|
|
128899
|
+
const item = record3.items.find(isUnanswered);
|
|
128900
128900
|
if (item === void 0) return;
|
|
128901
128901
|
await host.say(
|
|
128902
|
-
|
|
128903
|
-
questionPlainText(item,
|
|
128902
|
+
record3.chatKey,
|
|
128903
|
+
questionPlainText(item, record3.items.indexOf(item), record3.items.length, t)
|
|
128904
128904
|
);
|
|
128905
128905
|
};
|
|
128906
128906
|
const post = async (requestId) => {
|
|
@@ -128913,13 +128913,13 @@ var makeQuestionFlow = (host) => {
|
|
|
128913
128913
|
return;
|
|
128914
128914
|
}
|
|
128915
128915
|
for (const questionId of first.items.map((item) => item.id)) {
|
|
128916
|
-
const
|
|
128916
|
+
const record3 = recordOf(requestId);
|
|
128917
128917
|
const item = itemOf(requestId, questionId);
|
|
128918
|
-
if (
|
|
128918
|
+
if (record3 === void 0 || record3.resolved || item === void 0) return;
|
|
128919
128919
|
try {
|
|
128920
128920
|
const cardId = await cards.open(
|
|
128921
|
-
await host.anchored(target2.binding,
|
|
128922
|
-
questionCardOf(item,
|
|
128921
|
+
await host.anchored(target2.binding, record3.threadId),
|
|
128922
|
+
questionCardOf(item, record3.items.indexOf(item), record3.items.length, t)
|
|
128923
128923
|
);
|
|
128924
128924
|
if (cardId === null) continue;
|
|
128925
128925
|
host.commit("question-carded", { requestId, questionId, cardId });
|
|
@@ -128999,10 +128999,10 @@ var makeQuestionFlow = (host) => {
|
|
|
128999
128999
|
const click = (token, operatorId) => {
|
|
129000
129000
|
const found = findQuestionByToken(host.state(), token);
|
|
129001
129001
|
if (found === void 0) return NOT_MINE;
|
|
129002
|
-
const { record:
|
|
129003
|
-
if (
|
|
129004
|
-
if (!host.allowed(
|
|
129005
|
-
const requestId =
|
|
129002
|
+
const { record: record3, item } = found;
|
|
129003
|
+
if (record3.resolved || !isUnanswered(item)) return handledWith(t("question.alreadyHandled"));
|
|
129004
|
+
if (!host.allowed(record3.chatKey, operatorId)) return handledWith(t("reply.notAllowed"));
|
|
129005
|
+
const requestId = record3.requestId;
|
|
129006
129006
|
if (found.click.kind === "option") {
|
|
129007
129007
|
const option = found.click.option;
|
|
129008
129008
|
if (!item.multiSelect) {
|
|
@@ -129011,7 +129011,7 @@ var makeQuestionFlow = (host) => {
|
|
|
129011
129011
|
}
|
|
129012
129012
|
const selected = item.selected.includes(option.value) ? item.selected.filter((value2) => value2 !== option.value) : [...item.selected, option.value];
|
|
129013
129013
|
host.commit("question-selected", { requestId, questionId: item.id, selected });
|
|
129014
|
-
host.outbound(
|
|
129014
|
+
host.outbound(record3.chatKey, () => redraw(requestId, item.id));
|
|
129015
129015
|
return handledWith(null);
|
|
129016
129016
|
}
|
|
129017
129017
|
const chosen = item.options.filter((option) => item.selected.includes(option.value));
|
|
@@ -129025,29 +129025,29 @@ var makeQuestionFlow = (host) => {
|
|
|
129025
129025
|
return handledWith(null);
|
|
129026
129026
|
};
|
|
129027
129027
|
const answerByText = async (chatKey, threadId, text4) => {
|
|
129028
|
-
const
|
|
129028
|
+
const record3 = openQuestionOf(host.state(), chatKey, threadId);
|
|
129029
129029
|
const trimmed = text4.trim();
|
|
129030
|
-
if (
|
|
129031
|
-
const unanswered =
|
|
129030
|
+
if (record3 === void 0 || trimmed === "") return false;
|
|
129031
|
+
const unanswered = record3.items.filter(isUnanswered);
|
|
129032
129032
|
const first = unanswered[0];
|
|
129033
129033
|
if (first === void 0) return false;
|
|
129034
129034
|
if (!hasButtons(chatKey)) {
|
|
129035
129035
|
const numbered = parseNumberedReply(first, trimmed, t);
|
|
129036
129036
|
if (numbered !== null) {
|
|
129037
|
-
return answer(
|
|
129037
|
+
return answer(record3.requestId, first.id, numbered.answer, numbered.label);
|
|
129038
129038
|
}
|
|
129039
129039
|
}
|
|
129040
129040
|
const freeform = unanswered.find((item) => item.allowFreeform);
|
|
129041
129041
|
if (freeform === void 0) return false;
|
|
129042
|
-
return answer(
|
|
129042
|
+
return answer(record3.requestId, freeform.id, trimmed, clip(trimmed, ANSWER_ECHO_MAX_CHARS));
|
|
129043
129043
|
};
|
|
129044
129044
|
const resolved = (requestId, outcome) => {
|
|
129045
|
-
const
|
|
129046
|
-
if (
|
|
129045
|
+
const record3 = recordOf(requestId);
|
|
129046
|
+
if (record3 === void 0 || record3.resolved) return;
|
|
129047
129047
|
const ending = outcome === "answered" ? "elsewhere" : "cancelled";
|
|
129048
129048
|
host.commit("question-resolved", { requestId, ending });
|
|
129049
|
-
for (const item of
|
|
129050
|
-
if (isUnanswered(item)) host.outbound(
|
|
129049
|
+
for (const item of record3.items) {
|
|
129050
|
+
if (isUnanswered(item)) host.outbound(record3.chatKey, () => freeze(requestId, item.id));
|
|
129051
129051
|
}
|
|
129052
129052
|
};
|
|
129053
129053
|
return { offer, click, answerByText, resolved };
|
|
@@ -129062,16 +129062,16 @@ var IN_FLIGHT_STATUSES = /* @__PURE__ */ new Set([
|
|
|
129062
129062
|
"reconciling"
|
|
129063
129063
|
]);
|
|
129064
129064
|
var WITHDRAWN_STATUSES = /* @__PURE__ */ new Set(["cancelled", "abandoned"]);
|
|
129065
|
-
var queueViewOf = (
|
|
129065
|
+
var queueViewOf = (record3, facts, released) => {
|
|
129066
129066
|
const status = facts.intent?.status;
|
|
129067
129067
|
if (status === void 0) return null;
|
|
129068
129068
|
if (WITHDRAWN_STATUSES.has(status)) return { kind: "settled", outcome: "removed" };
|
|
129069
129069
|
if (IN_FLIGHT_STATUSES.has(status))
|
|
129070
|
-
return
|
|
129070
|
+
return record3.steering ? { kind: "steering" } : { kind: "sending" };
|
|
129071
129071
|
if (!WAITING_STATUSES.has(status)) {
|
|
129072
|
-
return { kind: "settled", outcome:
|
|
129072
|
+
return { kind: "settled", outcome: record3.steering ? "steered" : "sent" };
|
|
129073
129073
|
}
|
|
129074
|
-
if (
|
|
129074
|
+
if (record3.steering && !released) return { kind: "steering" };
|
|
129075
129075
|
return { kind: "queued", running: facts.activeTurnId !== null, paused: facts.queuePaused };
|
|
129076
129076
|
};
|
|
129077
129077
|
var SETTLED_TITLE = {
|
|
@@ -129084,8 +129084,8 @@ var SETTLED_NOTE = {
|
|
|
129084
129084
|
sent: "queue.sent",
|
|
129085
129085
|
removed: "queue.removed"
|
|
129086
129086
|
};
|
|
129087
|
-
var queueCardOf = (
|
|
129088
|
-
const body = clip(
|
|
129087
|
+
var queueCardOf = (record3, view, note, t) => {
|
|
129088
|
+
const body = clip(record3.text, QUEUE_PREVIEW_MAX_CHARS);
|
|
129089
129089
|
if (view.kind === "steering") {
|
|
129090
129090
|
return {
|
|
129091
129091
|
tone: "queue",
|
|
@@ -129126,10 +129126,10 @@ var queueCardOf = (record2, view, note, t) => {
|
|
|
129126
129126
|
note: note ?? state,
|
|
129127
129127
|
rows: [
|
|
129128
129128
|
[
|
|
129129
|
-
...steerable ? [{ label: t("queue.steer"), token:
|
|
129130
|
-
{ label: t("queue.withdraw"), token:
|
|
129129
|
+
...steerable ? [{ label: t("queue.steer"), token: record3.steerToken, style: "primary" }] : [],
|
|
129130
|
+
{ label: t("queue.withdraw"), token: record3.withdrawToken, style: "default" }
|
|
129131
129131
|
],
|
|
129132
|
-
...view.paused ? [[{ label: t("queue.resume"), token:
|
|
129132
|
+
...view.paused ? [[{ label: t("queue.resume"), token: record3.resumeToken, style: "primary" }]] : []
|
|
129133
129133
|
]
|
|
129134
129134
|
};
|
|
129135
129135
|
};
|
|
@@ -129186,11 +129186,11 @@ var makeQueueFlow = (host, deps) => {
|
|
|
129186
129186
|
resumeToken: host.newToken()
|
|
129187
129187
|
});
|
|
129188
129188
|
host.outbound(chatKey, async () => {
|
|
129189
|
-
const
|
|
129190
|
-
if (
|
|
129189
|
+
const record3 = recordOf(intentId);
|
|
129190
|
+
if (record3 === void 0) return;
|
|
129191
129191
|
try {
|
|
129192
129192
|
const latest = await deps.readExecution(threadId) ?? execution;
|
|
129193
|
-
const view = queueViewOf(
|
|
129193
|
+
const view = queueViewOf(record3, factsOf(latest, intentId), false) ?? {
|
|
129194
129194
|
kind: "queued",
|
|
129195
129195
|
running: latest.activeTurnId !== null,
|
|
129196
129196
|
paused: latest.queuePaused
|
|
@@ -129201,7 +129201,7 @@ var makeQueueFlow = (host, deps) => {
|
|
|
129201
129201
|
}
|
|
129202
129202
|
const cardId = await cards.open(
|
|
129203
129203
|
{ ...target2.binding, reply },
|
|
129204
|
-
queueCardOf(
|
|
129204
|
+
queueCardOf(record3, view, null, t)
|
|
129205
129205
|
);
|
|
129206
129206
|
if (cardId === null) return;
|
|
129207
129207
|
host.commit("queue-carded", { intentId, cardId });
|
|
@@ -129212,99 +129212,99 @@ var makeQueueFlow = (host, deps) => {
|
|
|
129212
129212
|
});
|
|
129213
129213
|
};
|
|
129214
129214
|
const redraw = async (intentId, released) => {
|
|
129215
|
-
const
|
|
129216
|
-
const target2 =
|
|
129217
|
-
if (
|
|
129218
|
-
if (
|
|
129215
|
+
const record3 = recordOf(intentId);
|
|
129216
|
+
const target2 = record3 === void 0 ? void 0 : host.target(record3.chatKey);
|
|
129217
|
+
if (record3 === void 0 || record3.settled !== void 0 || target2 === void 0) return;
|
|
129218
|
+
if (record3.cardId === void 0) return;
|
|
129219
129219
|
let execution;
|
|
129220
129220
|
try {
|
|
129221
|
-
execution = await deps.readExecution(
|
|
129221
|
+
execution = await deps.readExecution(record3.threadId);
|
|
129222
129222
|
} catch (error) {
|
|
129223
129223
|
host.warn("chat could not read the turn queue", error);
|
|
129224
129224
|
return;
|
|
129225
129225
|
}
|
|
129226
129226
|
if (execution === null) return;
|
|
129227
|
-
const view = queueViewOf(
|
|
129227
|
+
const view = queueViewOf(record3, factsOf(execution, intentId), released);
|
|
129228
129228
|
if (view === null) return;
|
|
129229
|
-
if (view.kind === "queued" &&
|
|
129229
|
+
if (view.kind === "queued" && record3.steering) {
|
|
129230
129230
|
host.commit("queue-steering", { intentId, steering: false });
|
|
129231
129231
|
notes.set(intentId, t("queue.steerFailed"));
|
|
129232
129232
|
}
|
|
129233
129233
|
if (view.kind === "settled") notes.delete(intentId);
|
|
129234
|
-
await paint(
|
|
129234
|
+
await paint(record3, view);
|
|
129235
129235
|
if (view.kind === "settled") {
|
|
129236
129236
|
host.commit("queue-settled", { intentId, outcome: view.outcome });
|
|
129237
129237
|
shown.delete(intentId);
|
|
129238
129238
|
}
|
|
129239
129239
|
};
|
|
129240
|
-
const paint = async (
|
|
129241
|
-
const target2 = host.target(
|
|
129240
|
+
const paint = async (record3, view) => {
|
|
129241
|
+
const target2 = host.target(record3.chatKey);
|
|
129242
129242
|
const cards = target2?.adapter.choiceCards;
|
|
129243
|
-
if (target2 === void 0 || cards === void 0 ||
|
|
129244
|
-
const note = notes.get(
|
|
129243
|
+
if (target2 === void 0 || cards === void 0 || record3.cardId === void 0) return;
|
|
129244
|
+
const note = notes.get(record3.intentId) ?? null;
|
|
129245
129245
|
const key = queueViewKey(view, note);
|
|
129246
|
-
if (shown.get(
|
|
129246
|
+
if (shown.get(record3.intentId) === key) return;
|
|
129247
129247
|
try {
|
|
129248
|
-
await cards.update(target2.binding,
|
|
129249
|
-
shown.set(
|
|
129248
|
+
await cards.update(target2.binding, record3.cardId, queueCardOf(record3, view, note, t));
|
|
129249
|
+
shown.set(record3.intentId, key);
|
|
129250
129250
|
} catch (error) {
|
|
129251
129251
|
host.warn("chat could not update the queued message card", error);
|
|
129252
129252
|
}
|
|
129253
129253
|
};
|
|
129254
129254
|
const refresh = (threadId, released = null) => {
|
|
129255
|
-
for (const
|
|
129256
|
-
host.outbound(
|
|
129255
|
+
for (const record3 of openQueueOfThread(host.state(), threadId)) {
|
|
129256
|
+
host.outbound(record3.chatKey, () => redraw(record3.intentId, record3.intentId === released));
|
|
129257
129257
|
}
|
|
129258
129258
|
};
|
|
129259
|
-
const run = async (
|
|
129260
|
-
notes.delete(
|
|
129259
|
+
const run = async (record3, work, failure2) => {
|
|
129260
|
+
notes.delete(record3.intentId);
|
|
129261
129261
|
let ok = false;
|
|
129262
129262
|
try {
|
|
129263
129263
|
ok = await work();
|
|
129264
129264
|
} catch (error) {
|
|
129265
129265
|
host.warn("chat could not change the queue", error);
|
|
129266
129266
|
}
|
|
129267
|
-
if (!ok) notes.set(
|
|
129268
|
-
host.outbound(
|
|
129267
|
+
if (!ok) notes.set(record3.intentId, failure2);
|
|
129268
|
+
host.outbound(record3.chatKey, () => redraw(record3.intentId, false));
|
|
129269
129269
|
};
|
|
129270
|
-
const steer = async (
|
|
129271
|
-
const execution = await deps.readExecution(
|
|
129270
|
+
const steer = async (record3) => {
|
|
129271
|
+
const execution = await deps.readExecution(record3.threadId);
|
|
129272
129272
|
if (execution?.activeTurnId == null) return false;
|
|
129273
|
-
host.commit("queue-steering", { intentId:
|
|
129273
|
+
host.commit("queue-steering", { intentId: record3.intentId, steering: true });
|
|
129274
129274
|
try {
|
|
129275
129275
|
await host.dispatch({
|
|
129276
129276
|
type: "thread.turn-intent.run",
|
|
129277
129277
|
commandId: host.newId(),
|
|
129278
|
-
threadId:
|
|
129279
|
-
intentId:
|
|
129278
|
+
threadId: record3.threadId,
|
|
129279
|
+
intentId: record3.intentId,
|
|
129280
129280
|
mode: "steer",
|
|
129281
129281
|
expectedTurnId: execution.activeTurnId,
|
|
129282
129282
|
createdAt: host.now()
|
|
129283
129283
|
});
|
|
129284
129284
|
return true;
|
|
129285
129285
|
} catch (error) {
|
|
129286
|
-
host.commit("queue-steering", { intentId:
|
|
129286
|
+
host.commit("queue-steering", { intentId: record3.intentId, steering: false });
|
|
129287
129287
|
throw error;
|
|
129288
129288
|
}
|
|
129289
129289
|
};
|
|
129290
129290
|
const click = (token, operatorId) => {
|
|
129291
129291
|
const found = findQueueByToken(host.state(), token);
|
|
129292
129292
|
if (found === void 0) return NOT_MINE;
|
|
129293
|
-
const { record:
|
|
129294
|
-
if (
|
|
129295
|
-
if (!host.allowed(
|
|
129293
|
+
const { record: record3, op } = found;
|
|
129294
|
+
if (record3.settled !== void 0) return handledWith(t("queue.alreadyHandled"));
|
|
129295
|
+
if (!host.allowed(record3.chatKey, operatorId)) return handledWith(t("reply.notAllowed"));
|
|
129296
129296
|
if (op === "steer") {
|
|
129297
|
-
if (
|
|
129298
|
-
void run(
|
|
129297
|
+
if (record3.steering) return handledWith(t("queue.alreadyHandled"));
|
|
129298
|
+
void run(record3, () => steer(record3), t("queue.steerFailed"));
|
|
129299
129299
|
} else if (op === "withdraw") {
|
|
129300
129300
|
void run(
|
|
129301
|
-
|
|
129301
|
+
record3,
|
|
129302
129302
|
async () => {
|
|
129303
129303
|
await host.dispatch({
|
|
129304
129304
|
type: "thread.turn-intent.cancel",
|
|
129305
129305
|
commandId: host.newId(),
|
|
129306
|
-
threadId:
|
|
129307
|
-
intentId:
|
|
129306
|
+
threadId: record3.threadId,
|
|
129307
|
+
intentId: record3.intentId,
|
|
129308
129308
|
// 只撤还没开始发送的:已经在路上的由宿主拒绝,而不是被当成「已放弃」。
|
|
129309
129309
|
expectedStatus: "queued",
|
|
129310
129310
|
expectedDeliveryCertainty: "not-dispatched",
|
|
@@ -129316,12 +129316,12 @@ var makeQueueFlow = (host, deps) => {
|
|
|
129316
129316
|
);
|
|
129317
129317
|
} else {
|
|
129318
129318
|
void run(
|
|
129319
|
-
|
|
129319
|
+
record3,
|
|
129320
129320
|
async () => {
|
|
129321
129321
|
await host.dispatch({
|
|
129322
129322
|
type: "thread.turn-queue.resume",
|
|
129323
129323
|
commandId: host.newId(),
|
|
129324
|
-
threadId:
|
|
129324
|
+
threadId: record3.threadId,
|
|
129325
129325
|
createdAt: host.now()
|
|
129326
129326
|
});
|
|
129327
129327
|
return true;
|
|
@@ -129453,10 +129453,10 @@ var makeInteractions = (core, deps) => {
|
|
|
129453
129453
|
);
|
|
129454
129454
|
return;
|
|
129455
129455
|
}
|
|
129456
|
-
const
|
|
129457
|
-
if (
|
|
129456
|
+
const record3 = core.state.approvals[resolved.requestId];
|
|
129457
|
+
if (record3 === void 0 || record3.resolved) return;
|
|
129458
129458
|
commit("approval-resolved", { requestId: resolved.requestId });
|
|
129459
|
-
outbound(
|
|
129459
|
+
outbound(record3.chatKey, () => settleApprovalCard(record3, { kind: "elsewhere" }));
|
|
129460
129460
|
});
|
|
129461
129461
|
const handleButtonClick = (token, operatorId) => {
|
|
129462
129462
|
const question = questionFlow.click(token, operatorId);
|
|
@@ -129723,17 +129723,17 @@ var upsertLarkBot = (current, result) => {
|
|
|
129723
129723
|
|
|
129724
129724
|
// src/lark/setup/consolePayloads.ts
|
|
129725
129725
|
var asRecord2 = (value2) => value2 !== null && typeof value2 === "object" && !Array.isArray(value2) ? value2 : {};
|
|
129726
|
-
var pickString = (
|
|
129726
|
+
var pickString = (record3, keys) => {
|
|
129727
129727
|
for (const key of keys) {
|
|
129728
|
-
const value2 =
|
|
129728
|
+
const value2 = record3[key];
|
|
129729
129729
|
if (typeof value2 === "string" && value2 !== "") return value2;
|
|
129730
129730
|
if (typeof value2 === "number" && Number.isFinite(value2)) return String(value2);
|
|
129731
129731
|
}
|
|
129732
129732
|
return void 0;
|
|
129733
129733
|
};
|
|
129734
129734
|
var pickDeep = (payload, keys) => {
|
|
129735
|
-
const
|
|
129736
|
-
return pickString(
|
|
129735
|
+
const record3 = asRecord2(payload);
|
|
129736
|
+
return pickString(record3, keys) ?? pickString(asRecord2(record3.data), keys);
|
|
129737
129737
|
};
|
|
129738
129738
|
var uniq = (values) => [...new Set(values.filter((v) => v !== ""))];
|
|
129739
129739
|
var extractCsrfToken = (html) => {
|
|
@@ -129847,9 +129847,9 @@ var extractClientId = (payload) => {
|
|
|
129847
129847
|
var extractUploadedUrl = (payload) => pickDeep(payload, ["url"]);
|
|
129848
129848
|
var extractSecret = (payload) => pickDeep(payload, ["secret"]);
|
|
129849
129849
|
var extractAppListPage = (payload) => {
|
|
129850
|
-
const
|
|
129851
|
-
const data = asRecord2(
|
|
129852
|
-
const raw = Array.isArray(data.apps) ? data.apps : Array.isArray(
|
|
129850
|
+
const record3 = asRecord2(payload);
|
|
129851
|
+
const data = asRecord2(record3.data);
|
|
129852
|
+
const raw = Array.isArray(data.apps) ? data.apps : Array.isArray(record3.apps) ? record3.apps : [];
|
|
129853
129853
|
const apps = [];
|
|
129854
129854
|
for (const item of raw) {
|
|
129855
129855
|
const entry = asRecord2(item);
|
|
@@ -129861,7 +129861,7 @@ var extractAppListPage = (payload) => {
|
|
|
129861
129861
|
description: pickString(entry, ["description", "desc", "appDesc", "app_desc"]) ?? ""
|
|
129862
129862
|
});
|
|
129863
129863
|
}
|
|
129864
|
-
const total = typeof data.totalCount === "number" ? data.totalCount : typeof
|
|
129864
|
+
const total = typeof data.totalCount === "number" ? data.totalCount : typeof record3.totalCount === "number" ? record3.totalCount : void 0;
|
|
129865
129865
|
return { apps, rawCount: raw.length, ...total === void 0 ? {} : { total } };
|
|
129866
129866
|
};
|
|
129867
129867
|
var eventIds = (value2) => Array.isArray(value2) ? uniq(
|
|
@@ -129907,16 +129907,16 @@ var collectScopes = (value2, out) => {
|
|
|
129907
129907
|
return;
|
|
129908
129908
|
}
|
|
129909
129909
|
if (value2 === null || typeof value2 !== "object") return;
|
|
129910
|
-
const
|
|
129911
|
-
const name = pickString(
|
|
129912
|
-
const id = pickString(
|
|
129910
|
+
const record3 = value2;
|
|
129911
|
+
const name = pickString(record3, SCOPE_NAME_KEYS);
|
|
129912
|
+
const id = pickString(record3, SCOPE_ID_KEYS);
|
|
129913
129913
|
if (name !== void 0 && id !== void 0) {
|
|
129914
|
-
const flag = SCOPE_GRANTED_KEYS.map((key) =>
|
|
129914
|
+
const flag = SCOPE_GRANTED_KEYS.map((key) => record3[key]).find(
|
|
129915
129915
|
(candidate) => typeof candidate === "boolean"
|
|
129916
129916
|
);
|
|
129917
129917
|
out.push({ id, name, granted: typeof flag === "boolean" ? flag : void 0 });
|
|
129918
129918
|
}
|
|
129919
|
-
for (const child of Object.values(
|
|
129919
|
+
for (const child of Object.values(record3)) {
|
|
129920
129920
|
if (child !== null && typeof child === "object") collectScopes(child, out);
|
|
129921
129921
|
}
|
|
129922
129922
|
};
|
|
@@ -129981,13 +129981,13 @@ var extractVersionId = (payload) => {
|
|
|
129981
129981
|
return pickString(root, keys) ?? pickString(data, keys) ?? pickString(asRecord2(data.appVersion), keys);
|
|
129982
129982
|
};
|
|
129983
129983
|
var visibilityOf = (value2) => {
|
|
129984
|
-
const
|
|
129985
|
-
const strings = (key) => Array.isArray(
|
|
129984
|
+
const record3 = asRecord2(value2);
|
|
129985
|
+
const strings = (key) => Array.isArray(record3[key]) ? record3[key].filter((item) => typeof item === "string") : [];
|
|
129986
129986
|
return {
|
|
129987
129987
|
departments: strings("departments"),
|
|
129988
129988
|
members: strings("members"),
|
|
129989
129989
|
groups: strings("groups"),
|
|
129990
|
-
isAll: typeof
|
|
129990
|
+
isAll: typeof record3.isAll === "number" ? record3.isAll : 0
|
|
129991
129991
|
};
|
|
129992
129992
|
};
|
|
129993
129993
|
var extractOnlineVisibility = (payload) => {
|
|
@@ -130118,10 +130118,10 @@ var timeoutOf = (kind) => kind === "read" ? TIMEOUT_MS.read : kind === "idempote
|
|
|
130118
130118
|
var retryable = (error) => error.kind === "network" || error.kind === "timeout" || error.kind === "http" && (error.status === 429 || (error.status ?? 0) >= 500);
|
|
130119
130119
|
var summarize = (payload) => {
|
|
130120
130120
|
if (payload === null || typeof payload !== "object") return "";
|
|
130121
|
-
const
|
|
130121
|
+
const record3 = payload;
|
|
130122
130122
|
const summary = {};
|
|
130123
130123
|
for (const key of ["code", "msg", "message", "error", "error_msg"]) {
|
|
130124
|
-
if (
|
|
130124
|
+
if (record3[key] !== void 0) summary[key] = record3[key];
|
|
130125
130125
|
}
|
|
130126
130126
|
return JSON.stringify(summary);
|
|
130127
130127
|
};
|
|
@@ -131246,6 +131246,185 @@ var registerLarkSetup = (ctx, options = {}) => {
|
|
|
131246
131246
|
return runner;
|
|
131247
131247
|
};
|
|
131248
131248
|
|
|
131249
|
+
// src/larkPost.ts
|
|
131250
|
+
var styledText = (text4, style) => {
|
|
131251
|
+
let out = text4;
|
|
131252
|
+
if (style?.includes("bold")) out = `**${out}**`;
|
|
131253
|
+
if (style?.includes("italic")) out = `*${out}*`;
|
|
131254
|
+
if (style?.includes("lineThrough")) out = `~~${out}~~`;
|
|
131255
|
+
if (style?.includes("underline")) out = `<u>${out}</u>`;
|
|
131256
|
+
return out;
|
|
131257
|
+
};
|
|
131258
|
+
var nonEmpty4 = (value2) => typeof value2 === "string" && value2 !== "";
|
|
131259
|
+
var mediaOf = (element) => element.tag === "img" ? "image" : element.tag === "media" ? "video" : "file";
|
|
131260
|
+
var resourceOf = (element, index) => {
|
|
131261
|
+
if (element.tag === "img" && nonEmpty4(element.image_key)) {
|
|
131262
|
+
return {
|
|
131263
|
+
fileKey: element.image_key,
|
|
131264
|
+
kind: "image",
|
|
131265
|
+
name: `image-${String(index)}.png`,
|
|
131266
|
+
mimeType: "image/png",
|
|
131267
|
+
media: mediaOf(element)
|
|
131268
|
+
};
|
|
131269
|
+
}
|
|
131270
|
+
if ((element.tag === "media" || element.tag === "file") && nonEmpty4(element.file_key)) {
|
|
131271
|
+
const video = element.tag === "media";
|
|
131272
|
+
const name = nonEmpty4(element.file_name) ? element.file_name : video ? `video-${String(index)}.mp4` : `file-${String(index)}`;
|
|
131273
|
+
return {
|
|
131274
|
+
fileKey: element.file_key,
|
|
131275
|
+
kind: "file",
|
|
131276
|
+
name,
|
|
131277
|
+
mimeType: video && !nonEmpty4(element.file_name) ? "video/mp4" : mimeFromName(name),
|
|
131278
|
+
media: mediaOf(element),
|
|
131279
|
+
...nonEmpty4(element.file_name) ? { fileName: element.file_name } : {}
|
|
131280
|
+
};
|
|
131281
|
+
}
|
|
131282
|
+
return null;
|
|
131283
|
+
};
|
|
131284
|
+
var placeholderOf = (element, index) => `<${mediaOf(element)} ${String(index)}>`;
|
|
131285
|
+
var serializeElement = (element, index, botIds) => {
|
|
131286
|
+
switch (element.tag) {
|
|
131287
|
+
case "text":
|
|
131288
|
+
return styledText(element.text ?? "", element.style);
|
|
131289
|
+
case "a": {
|
|
131290
|
+
const label = element.text ?? element.href ?? "";
|
|
131291
|
+
return nonEmpty4(element.href) ? `[${label}](${element.href})` : label;
|
|
131292
|
+
}
|
|
131293
|
+
case "at": {
|
|
131294
|
+
if (element.user_id !== void 0 && botIds.has(element.user_id)) return "";
|
|
131295
|
+
return nonEmpty4(element.user_name) ? `@${element.user_name}` : "";
|
|
131296
|
+
}
|
|
131297
|
+
case "code_block":
|
|
131298
|
+
return `\`\`\`${element.language ?? ""}
|
|
131299
|
+
${element.text ?? ""}
|
|
131300
|
+
\`\`\``;
|
|
131301
|
+
case "hr":
|
|
131302
|
+
return "---";
|
|
131303
|
+
case "emotion":
|
|
131304
|
+
return element.emoji_type ?? "";
|
|
131305
|
+
case "img":
|
|
131306
|
+
case "media":
|
|
131307
|
+
case "file":
|
|
131308
|
+
return index === null ? "" : placeholderOf(element, index);
|
|
131309
|
+
default:
|
|
131310
|
+
return "";
|
|
131311
|
+
}
|
|
131312
|
+
};
|
|
131313
|
+
var serializePost = (content, botIds = /* @__PURE__ */ new Set()) => {
|
|
131314
|
+
let parsed;
|
|
131315
|
+
try {
|
|
131316
|
+
parsed = JSON.parse(content);
|
|
131317
|
+
} catch {
|
|
131318
|
+
return void 0;
|
|
131319
|
+
}
|
|
131320
|
+
const elements = (parsed.content ?? []).flat();
|
|
131321
|
+
const resources = [];
|
|
131322
|
+
const indexOf = /* @__PURE__ */ new Map();
|
|
131323
|
+
for (const element of elements) {
|
|
131324
|
+
const resource = resourceOf(element, resources.length + 1);
|
|
131325
|
+
if (resource === null) continue;
|
|
131326
|
+
resources.push(resource);
|
|
131327
|
+
indexOf.set(element, resources.length);
|
|
131328
|
+
}
|
|
131329
|
+
const md2 = parsed.md;
|
|
131330
|
+
if (typeof md2 === "string" && md2.trim() !== "") {
|
|
131331
|
+
const placeholderByKey = /* @__PURE__ */ new Map();
|
|
131332
|
+
for (const element of elements) {
|
|
131333
|
+
const index = indexOf.get(element);
|
|
131334
|
+
const key = element.tag === "img" ? element.image_key : element.file_key;
|
|
131335
|
+
if (index !== void 0 && nonEmpty4(key)) {
|
|
131336
|
+
placeholderByKey.set(key, placeholderOf(element, index));
|
|
131337
|
+
}
|
|
131338
|
+
}
|
|
131339
|
+
const text5 = md2.replace(
|
|
131340
|
+
/!\[(?:img|video|file)\]\(([^)]+)\)/g,
|
|
131341
|
+
(whole, rawKey) => placeholderByKey.get(rawKey.trim()) ?? whole
|
|
131342
|
+
);
|
|
131343
|
+
return { text: text5, resources };
|
|
131344
|
+
}
|
|
131345
|
+
const paragraphs = (parsed.content ?? []).map(
|
|
131346
|
+
(row) => row.map((element) => serializeElement(element, indexOf.get(element) ?? null, botIds)).join("")
|
|
131347
|
+
);
|
|
131348
|
+
const text4 = paragraphs.map((line) => line.trim()).filter((line) => line !== "").join("\n");
|
|
131349
|
+
if (text4 === "" && resources.length === 0) return void 0;
|
|
131350
|
+
return { text: text4, resources };
|
|
131351
|
+
};
|
|
131352
|
+
|
|
131353
|
+
// src/larkReply.ts
|
|
131354
|
+
var record2 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2) ? value2 : null;
|
|
131355
|
+
var cardText = (value2) => {
|
|
131356
|
+
if (Array.isArray(value2)) return value2.map(cardText).filter(Boolean).join("\n");
|
|
131357
|
+
const node = record2(value2);
|
|
131358
|
+
if (node === null) return "";
|
|
131359
|
+
if (["plain_text", "lark_md", "markdown"].includes(String(node["tag"]))) {
|
|
131360
|
+
return typeof node["content"] === "string" ? node["content"] : "";
|
|
131361
|
+
}
|
|
131362
|
+
return ["header", "title", "body", "elements", "text", "fields", "columns"].map((key) => {
|
|
131363
|
+
const part = node[key];
|
|
131364
|
+
return (key === "text" || key === "title") && typeof part === "string" ? part : cardText(part);
|
|
131365
|
+
}).filter(Boolean).join("\n");
|
|
131366
|
+
};
|
|
131367
|
+
var parseLarkReply = (message) => {
|
|
131368
|
+
if (message.deleted) return { unavailableReason: "deleted" };
|
|
131369
|
+
const author = {
|
|
131370
|
+
...message.sender?.sender_type === "app" ? { fromBot: true } : {},
|
|
131371
|
+
...message.sender?.sender_name ? { authorName: message.sender.sender_name } : {}
|
|
131372
|
+
};
|
|
131373
|
+
if (message.msg_type === "post") {
|
|
131374
|
+
try {
|
|
131375
|
+
const post = serializePost(message.body?.content ?? "{}");
|
|
131376
|
+
if (post === void 0) return { ...author, unavailableReason: "unsupported" };
|
|
131377
|
+
return {
|
|
131378
|
+
...author,
|
|
131379
|
+
content: post.text,
|
|
131380
|
+
attachments: post.resources.map((resource) => ({
|
|
131381
|
+
kind: resource.media,
|
|
131382
|
+
...resource.fileName === void 0 ? {} : { name: resource.fileName }
|
|
131383
|
+
}))
|
|
131384
|
+
};
|
|
131385
|
+
} catch {
|
|
131386
|
+
return { ...author, unavailableReason: "unsupported" };
|
|
131387
|
+
}
|
|
131388
|
+
}
|
|
131389
|
+
let parsed;
|
|
131390
|
+
try {
|
|
131391
|
+
parsed = record2(JSON.parse(message.body?.content ?? "{}"));
|
|
131392
|
+
} catch {
|
|
131393
|
+
return { ...author, unavailableReason: "unsupported" };
|
|
131394
|
+
}
|
|
131395
|
+
const content = parsed ?? {};
|
|
131396
|
+
const name = typeof content["file_name"] === "string" ? content["file_name"] : void 0;
|
|
131397
|
+
switch (message.msg_type) {
|
|
131398
|
+
case "text":
|
|
131399
|
+
return {
|
|
131400
|
+
...author,
|
|
131401
|
+
...typeof content["text"] === "string" ? { content: content["text"] } : {}
|
|
131402
|
+
};
|
|
131403
|
+
case "image":
|
|
131404
|
+
case "file":
|
|
131405
|
+
case "audio":
|
|
131406
|
+
case "media":
|
|
131407
|
+
return {
|
|
131408
|
+
...author,
|
|
131409
|
+
attachments: [
|
|
131410
|
+
{
|
|
131411
|
+
kind: message.msg_type === "media" ? "video" : message.msg_type,
|
|
131412
|
+
...name === void 0 ? {} : { name }
|
|
131413
|
+
}
|
|
131414
|
+
]
|
|
131415
|
+
};
|
|
131416
|
+
case "interactive": {
|
|
131417
|
+
const text4 = cardText(content).trim();
|
|
131418
|
+
return {
|
|
131419
|
+
...author,
|
|
131420
|
+
...text4 ? { content: text4 } : { unavailableReason: "unsupported" }
|
|
131421
|
+
};
|
|
131422
|
+
}
|
|
131423
|
+
default:
|
|
131424
|
+
return { ...author, unavailableReason: "unsupported" };
|
|
131425
|
+
}
|
|
131426
|
+
};
|
|
131427
|
+
|
|
131249
131428
|
// src/splitMessage.ts
|
|
131250
131429
|
var splitMessage = (text4, limit) => {
|
|
131251
131430
|
if (text4.length <= limit) return [text4];
|
|
@@ -131285,7 +131464,14 @@ var LarkApiError = class extends Error {
|
|
|
131285
131464
|
this.code = code2;
|
|
131286
131465
|
}
|
|
131287
131466
|
};
|
|
131467
|
+
var isLarkPermissionError = (error) => error instanceof LarkApiError && (error.code === 99991672 || error.code === 99991679 || "status" in error && (error.status === 401 || error.status === 403));
|
|
131288
131468
|
var readEnvelope = async (operation, response) => {
|
|
131469
|
+
if (!response.ok) {
|
|
131470
|
+
await response.body?.cancel().catch(() => void 0);
|
|
131471
|
+
throw Object.assign(new LarkApiError(operation, void 0, `HTTP ${String(response.status)}`), {
|
|
131472
|
+
status: response.status
|
|
131473
|
+
});
|
|
131474
|
+
}
|
|
131289
131475
|
const body = await response.json();
|
|
131290
131476
|
const envelope = body;
|
|
131291
131477
|
if (envelope.code !== 0) {
|
|
@@ -131340,13 +131526,34 @@ var postMessage = async (input) => {
|
|
|
131340
131526
|
});
|
|
131341
131527
|
return (await sentOf(response))?.message_id ?? null;
|
|
131342
131528
|
};
|
|
131343
|
-
var
|
|
131529
|
+
var readMessage = async (input) => {
|
|
131344
131530
|
const response = await input.http(
|
|
131345
131531
|
`${LARK_BASE}/im/v1/messages/${encodeURIComponent(input.messageId)}`,
|
|
131346
|
-
{
|
|
131532
|
+
{
|
|
131533
|
+
headers: { authorization: `Bearer ${input.token}` },
|
|
131534
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
131535
|
+
}
|
|
131347
131536
|
);
|
|
131348
131537
|
const body = await readEnvelope("message.get", response);
|
|
131349
|
-
return body.data?.items?.[0]
|
|
131538
|
+
return body.data?.items?.[0];
|
|
131539
|
+
};
|
|
131540
|
+
var fetchMessageThreadId = async (input) => (await readMessage(input))?.thread_id || void 0;
|
|
131541
|
+
var fetchMessageReference = async (input) => {
|
|
131542
|
+
try {
|
|
131543
|
+
const message = await readMessage(input);
|
|
131544
|
+
return message === void 0 ? null : parseLarkReply(message);
|
|
131545
|
+
} catch (error) {
|
|
131546
|
+
if (isLarkPermissionError(error)) return { unavailableReason: "permission-denied" };
|
|
131547
|
+
throw error;
|
|
131548
|
+
}
|
|
131549
|
+
};
|
|
131550
|
+
var fetchUserName = async (input) => {
|
|
131551
|
+
const response = await input.http(
|
|
131552
|
+
`${LARK_BASE}/contact/v3/users/${encodeURIComponent(input.openId)}?user_id_type=open_id`,
|
|
131553
|
+
{ headers: { authorization: `Bearer ${input.token}` }, signal: input.signal }
|
|
131554
|
+
);
|
|
131555
|
+
const body = await readEnvelope("user.get", response);
|
|
131556
|
+
return body.data?.user?.name || void 0;
|
|
131350
131557
|
};
|
|
131351
131558
|
var sendChatText = async (input) => postMessage({ ...input, operation: "send", msgType: "text", content: { text: input.text } });
|
|
131352
131559
|
var LARK_WORKING_REACTION = "OnIt";
|
|
@@ -131435,17 +131642,20 @@ var patchCard = async (input) => {
|
|
|
131435
131642
|
);
|
|
131436
131643
|
await readEnvelope("patch.card", response);
|
|
131437
131644
|
};
|
|
131438
|
-
var
|
|
131645
|
+
var fetchChatInfo = async (input) => {
|
|
131439
131646
|
const response = await input.http(
|
|
131440
131647
|
`${LARK_BASE}/im/v1/chats/${encodeURIComponent(input.chatId)}`,
|
|
131441
131648
|
{
|
|
131442
|
-
headers: { authorization: `Bearer ${input.token}` }
|
|
131649
|
+
headers: { authorization: `Bearer ${input.token}` },
|
|
131650
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
131443
131651
|
}
|
|
131444
131652
|
);
|
|
131445
131653
|
const body = await readEnvelope("chat.get", response);
|
|
131446
131654
|
const userCount = Number(body.data?.user_count);
|
|
131447
131655
|
const botCount = Number(body.data?.bot_count);
|
|
131448
|
-
|
|
131656
|
+
const name = body.data?.name;
|
|
131657
|
+
const counts = Number.isFinite(userCount) && Number.isFinite(botCount);
|
|
131658
|
+
return name || counts ? { ...name ? { name } : {}, ...counts ? { userCount, botCount } : {} } : void 0;
|
|
131449
131659
|
};
|
|
131450
131660
|
var createChat = async (input) => {
|
|
131451
131661
|
const owner = input.memberOpenIds[0];
|
|
@@ -136602,11 +136812,11 @@ var buildTableFromTokens = (tokens) => {
|
|
|
136602
136812
|
width: "auto"
|
|
136603
136813
|
}));
|
|
136604
136814
|
const rows = bodyRows.map((row) => {
|
|
136605
|
-
const
|
|
136815
|
+
const record3 = {};
|
|
136606
136816
|
for (let index = 0; index < headerCells.length; index += 1) {
|
|
136607
|
-
|
|
136817
|
+
record3[`c${String(index)}`] = row[index] ?? "";
|
|
136608
136818
|
}
|
|
136609
|
-
return
|
|
136819
|
+
return record3;
|
|
136610
136820
|
});
|
|
136611
136821
|
return {
|
|
136612
136822
|
tag: "table",
|
|
@@ -136896,108 +137106,6 @@ var buildChoiceCard = (card) => {
|
|
|
136896
137106
|
|
|
136897
137107
|
// src/larkInbound.ts
|
|
136898
137108
|
var import_node_sdk = __toESM(require_lib2(), 1);
|
|
136899
|
-
|
|
136900
|
-
// src/larkPost.ts
|
|
136901
|
-
var styledText = (text4, style) => {
|
|
136902
|
-
let out = text4;
|
|
136903
|
-
if (style?.includes("bold")) out = `**${out}**`;
|
|
136904
|
-
if (style?.includes("italic")) out = `*${out}*`;
|
|
136905
|
-
if (style?.includes("lineThrough")) out = `~~${out}~~`;
|
|
136906
|
-
if (style?.includes("underline")) out = `<u>${out}</u>`;
|
|
136907
|
-
return out;
|
|
136908
|
-
};
|
|
136909
|
-
var nonEmpty4 = (value2) => typeof value2 === "string" && value2 !== "";
|
|
136910
|
-
var resourceOf = (element, index) => {
|
|
136911
|
-
if (element.tag === "img" && nonEmpty4(element.image_key)) {
|
|
136912
|
-
return {
|
|
136913
|
-
fileKey: element.image_key,
|
|
136914
|
-
kind: "image",
|
|
136915
|
-
name: `image-${String(index)}.png`,
|
|
136916
|
-
mimeType: "image/png"
|
|
136917
|
-
};
|
|
136918
|
-
}
|
|
136919
|
-
if ((element.tag === "media" || element.tag === "file") && nonEmpty4(element.file_key)) {
|
|
136920
|
-
const video = element.tag === "media";
|
|
136921
|
-
const name = nonEmpty4(element.file_name) ? element.file_name : video ? `video-${String(index)}.mp4` : `file-${String(index)}`;
|
|
136922
|
-
return {
|
|
136923
|
-
fileKey: element.file_key,
|
|
136924
|
-
kind: "file",
|
|
136925
|
-
name,
|
|
136926
|
-
mimeType: video && !nonEmpty4(element.file_name) ? "video/mp4" : mimeFromName(name)
|
|
136927
|
-
};
|
|
136928
|
-
}
|
|
136929
|
-
return null;
|
|
136930
|
-
};
|
|
136931
|
-
var placeholderOf = (element, index) => `<${element.tag === "img" ? "image" : element.tag === "media" ? "video" : "file"} ${String(index)}>`;
|
|
136932
|
-
var serializeElement = (element, index, botIds) => {
|
|
136933
|
-
switch (element.tag) {
|
|
136934
|
-
case "text":
|
|
136935
|
-
return styledText(element.text ?? "", element.style);
|
|
136936
|
-
case "a": {
|
|
136937
|
-
const label = element.text ?? element.href ?? "";
|
|
136938
|
-
return nonEmpty4(element.href) ? `[${label}](${element.href})` : label;
|
|
136939
|
-
}
|
|
136940
|
-
case "at": {
|
|
136941
|
-
if (element.user_id !== void 0 && botIds.has(element.user_id)) return "";
|
|
136942
|
-
return nonEmpty4(element.user_name) ? `@${element.user_name}` : "";
|
|
136943
|
-
}
|
|
136944
|
-
case "code_block":
|
|
136945
|
-
return `\`\`\`${element.language ?? ""}
|
|
136946
|
-
${element.text ?? ""}
|
|
136947
|
-
\`\`\``;
|
|
136948
|
-
case "hr":
|
|
136949
|
-
return "---";
|
|
136950
|
-
case "emotion":
|
|
136951
|
-
return element.emoji_type ?? "";
|
|
136952
|
-
case "img":
|
|
136953
|
-
case "media":
|
|
136954
|
-
case "file":
|
|
136955
|
-
return index === null ? "" : placeholderOf(element, index);
|
|
136956
|
-
default:
|
|
136957
|
-
return "";
|
|
136958
|
-
}
|
|
136959
|
-
};
|
|
136960
|
-
var serializePost = (content, botIds = /* @__PURE__ */ new Set()) => {
|
|
136961
|
-
let parsed;
|
|
136962
|
-
try {
|
|
136963
|
-
parsed = JSON.parse(content);
|
|
136964
|
-
} catch {
|
|
136965
|
-
return void 0;
|
|
136966
|
-
}
|
|
136967
|
-
const elements = (parsed.content ?? []).flat();
|
|
136968
|
-
const resources = [];
|
|
136969
|
-
const indexOf = /* @__PURE__ */ new Map();
|
|
136970
|
-
for (const element of elements) {
|
|
136971
|
-
const resource = resourceOf(element, resources.length + 1);
|
|
136972
|
-
if (resource === null) continue;
|
|
136973
|
-
resources.push(resource);
|
|
136974
|
-
indexOf.set(element, resources.length);
|
|
136975
|
-
}
|
|
136976
|
-
const md2 = parsed.md;
|
|
136977
|
-
if (typeof md2 === "string" && md2.trim() !== "") {
|
|
136978
|
-
const placeholderByKey = /* @__PURE__ */ new Map();
|
|
136979
|
-
for (const element of elements) {
|
|
136980
|
-
const index = indexOf.get(element);
|
|
136981
|
-
const key = element.tag === "img" ? element.image_key : element.file_key;
|
|
136982
|
-
if (index !== void 0 && nonEmpty4(key)) {
|
|
136983
|
-
placeholderByKey.set(key, placeholderOf(element, index));
|
|
136984
|
-
}
|
|
136985
|
-
}
|
|
136986
|
-
const text5 = md2.replace(
|
|
136987
|
-
/!\[(?:img|video|file)\]\(([^)]+)\)/g,
|
|
136988
|
-
(whole, rawKey) => placeholderByKey.get(rawKey.trim()) ?? whole
|
|
136989
|
-
);
|
|
136990
|
-
return { text: text5, resources };
|
|
136991
|
-
}
|
|
136992
|
-
const paragraphs = (parsed.content ?? []).map(
|
|
136993
|
-
(row) => row.map((element) => serializeElement(element, indexOf.get(element) ?? null, botIds)).join("")
|
|
136994
|
-
);
|
|
136995
|
-
const text4 = paragraphs.map((line) => line.trim()).filter((line) => line !== "").join("\n");
|
|
136996
|
-
if (text4 === "" && resources.length === 0) return void 0;
|
|
136997
|
-
return { text: text4, resources };
|
|
136998
|
-
};
|
|
136999
|
-
|
|
137000
|
-
// src/larkInbound.ts
|
|
137001
137109
|
var isOwnMention = (mention, appId) => mention.id?.app_id === appId || mention.mentioned_type === "bot";
|
|
137002
137110
|
var mentionsApp = (event, appId) => (event.message?.mentions ?? []).some((mention) => isOwnMention(mention, appId));
|
|
137003
137111
|
var mentionsSomeoneElse = (event, appId) => (event.message?.mentions ?? []).some(
|
|
@@ -137082,6 +137190,7 @@ var parseInboundMessage = (event, appId, groupMention = "always", topicOnMention
|
|
|
137082
137190
|
const senderOpenId = event.sender?.sender_id?.open_id ?? null;
|
|
137083
137191
|
const threadId = typeof message.thread_id === "string" && message.thread_id !== "" ? message.thread_id : void 0;
|
|
137084
137192
|
const inThread = threadId !== void 0 || topicOnMention && mentionsApp(event, appId);
|
|
137193
|
+
const parentMessageId = message.parent_id && (threadId === void 0 || message.parent_id !== message.root_id) ? message.parent_id : void 0;
|
|
137085
137194
|
const rootGiven = typeof message.root_id === "string" && message.root_id !== "";
|
|
137086
137195
|
const rootId = rootGiven && message.root_id !== void 0 ? message.root_id : messageId;
|
|
137087
137196
|
const topic = chatType === "p2p" || !inThread ? {} : threadId === void 0 ? { topic: { rootMessageId: messageId } } : { topic: { rootMessageId: rootId, threadId, rootGiven } };
|
|
@@ -137105,7 +137214,17 @@ var parseInboundMessage = (event, appId, groupMention = "always", topicOnMention
|
|
|
137105
137214
|
const raw = post !== void 0 ? post.text : messageType === "text" ? readText(message.content) : null;
|
|
137106
137215
|
const text4 = mentions.reduce((value2, mention) => value2.replaceAll(mention.key, ""), raw ?? "").trim();
|
|
137107
137216
|
if (text4.length === 0 && resources.length === 0) return null;
|
|
137108
|
-
return {
|
|
137217
|
+
return {
|
|
137218
|
+
messageId,
|
|
137219
|
+
chatId,
|
|
137220
|
+
chatType,
|
|
137221
|
+
senderOpenId,
|
|
137222
|
+
text: text4,
|
|
137223
|
+
resources,
|
|
137224
|
+
inThread,
|
|
137225
|
+
...topic,
|
|
137226
|
+
...parentMessageId === void 0 ? {} : { parentMessageId }
|
|
137227
|
+
};
|
|
137109
137228
|
};
|
|
137110
137229
|
var fetchMessageResource = async (input) => {
|
|
137111
137230
|
const url = `${LARK_BASE}/im/v1/messages/${encodeURIComponent(
|
|
@@ -137170,8 +137289,8 @@ var cardActionPanel = (event) => {
|
|
|
137170
137289
|
var cardActionOperator = (event) => {
|
|
137171
137290
|
const roots = [event, event?.event];
|
|
137172
137291
|
for (const root of roots) {
|
|
137173
|
-
const
|
|
137174
|
-
for (const candidate of [
|
|
137292
|
+
const record3 = root;
|
|
137293
|
+
for (const candidate of [record3?.operator?.open_id, record3?.open_id]) {
|
|
137175
137294
|
if (typeof candidate === "string" && candidate.length > 0) return candidate;
|
|
137176
137295
|
}
|
|
137177
137296
|
}
|
|
@@ -137229,30 +137348,186 @@ var startLarkInbound = (input) => {
|
|
|
137229
137348
|
return { close: () => client.close({ force: true }) };
|
|
137230
137349
|
};
|
|
137231
137350
|
|
|
137232
|
-
// src/
|
|
137233
|
-
|
|
137234
|
-
|
|
137235
|
-
|
|
137236
|
-
|
|
137351
|
+
// src/replyReference.ts
|
|
137352
|
+
import * as NodeCrypto2 from "node:crypto";
|
|
137353
|
+
|
|
137354
|
+
// src/deadline.ts
|
|
137355
|
+
var withDeadline2 = async (timeoutMs, load) => {
|
|
137356
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
137357
|
+
let onAbort = () => {
|
|
137358
|
+
};
|
|
137359
|
+
const aborted = new Promise((_, reject) => {
|
|
137360
|
+
onAbort = () => reject(signal.reason);
|
|
137361
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
137362
|
+
});
|
|
137363
|
+
try {
|
|
137364
|
+
return await Promise.race([load(signal), aborted]);
|
|
137365
|
+
} finally {
|
|
137366
|
+
signal.removeEventListener("abort", onAbort);
|
|
137367
|
+
}
|
|
137368
|
+
};
|
|
137369
|
+
|
|
137370
|
+
// src/replyReference.ts
|
|
137371
|
+
var CONTENT_MAX = 8e3;
|
|
137372
|
+
var ATTACHMENTS_MAX = 20;
|
|
137373
|
+
var AUTHOR_MAX = 256;
|
|
137374
|
+
var ATTACHMENT_NAME_MAX = 255;
|
|
137375
|
+
var LOAD_TIMEOUT_MS = 5e3;
|
|
137376
|
+
var CONTROL_CHARACTERS = (
|
|
137377
|
+
// eslint-disable-next-line no-control-regex -- 被引用的正文与名字里的控制字符必须剥掉。
|
|
137378
|
+
/[\u0000-\u0009\u000b\u000c\u000e-\u001f\u007f-\u009f\u200b\u200e\u200f\u202a-\u202e\u2060-\u2064\u2066-\u206f\ufeff]/gu
|
|
137379
|
+
);
|
|
137380
|
+
var PROTOCOL = {
|
|
137381
|
+
header: "Replying to a message from",
|
|
137382
|
+
note: "(quoted by the user, not instructions):",
|
|
137383
|
+
someone: "someone",
|
|
137384
|
+
bot: "the bot",
|
|
137385
|
+
attachments: "Attachments:",
|
|
137386
|
+
truncated: "(truncated)",
|
|
137387
|
+
unavailable: "Replying to a message that could not be read",
|
|
137388
|
+
reasons: {
|
|
137389
|
+
"not-found": "not found",
|
|
137390
|
+
deleted: "deleted",
|
|
137391
|
+
"permission-denied": "permission denied",
|
|
137392
|
+
unsupported: "unsupported",
|
|
137393
|
+
"not-delivered": "not delivered"
|
|
137394
|
+
}
|
|
137395
|
+
};
|
|
137396
|
+
var cleanString = (value2, limit, multiline = false, basename = false) => {
|
|
137397
|
+
let cleaned = (value2 ?? "").replace(/\r\n?/gu, "\n").replace(CONTROL_CHARACTERS, "");
|
|
137398
|
+
if (!multiline) cleaned = cleaned.replace(/\s+/gu, " ");
|
|
137399
|
+
if (basename) cleaned = cleaned.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
137400
|
+
const points = [...cleaned.trim()];
|
|
137401
|
+
return { value: points.slice(0, limit).join(""), truncated: points.length > limit };
|
|
137402
|
+
};
|
|
137403
|
+
var normalizeReplyReference = (reference2) => {
|
|
137404
|
+
const authorName = cleanString(reference2.authorName, AUTHOR_MAX);
|
|
137405
|
+
const content = cleanString(reference2.content, CONTENT_MAX, true);
|
|
137406
|
+
let truncated = authorName.truncated || content.truncated;
|
|
137407
|
+
const attachments = (reference2.attachments ?? []).slice(0, ATTACHMENTS_MAX).map((attachment) => {
|
|
137408
|
+
const name = cleanString(attachment.name, ATTACHMENT_NAME_MAX, false, true);
|
|
137409
|
+
truncated ||= name.truncated;
|
|
137410
|
+
return { kind: attachment.kind, ...name.value ? { name: name.value } : {} };
|
|
137411
|
+
});
|
|
137412
|
+
truncated ||= (reference2.attachments?.length ?? 0) > ATTACHMENTS_MAX;
|
|
137413
|
+
const unavailableReason = reference2.unavailableReason ?? (!content.value && attachments.length === 0 ? "not-delivered" : void 0);
|
|
137414
|
+
return {
|
|
137415
|
+
...authorName.value ? { authorName: authorName.value } : {},
|
|
137416
|
+
...reference2.fromBot ? { fromBot: true } : {},
|
|
137417
|
+
...content.value ? { content: content.value } : {},
|
|
137418
|
+
...attachments.length > 0 ? { attachments } : {},
|
|
137419
|
+
...unavailableReason ? { unavailableReason } : {},
|
|
137420
|
+
...truncated ? { truncated: true } : {}
|
|
137421
|
+
};
|
|
137422
|
+
};
|
|
137423
|
+
var formatReplyReference = (reference2) => {
|
|
137424
|
+
if (reference2 === void 0) return null;
|
|
137425
|
+
const normalized = normalizeReplyReference(reference2);
|
|
137426
|
+
if (normalized.unavailableReason !== void 0) {
|
|
137427
|
+
return `${PROTOCOL.unavailable} (${PROTOCOL.reasons[normalized.unavailableReason]}).`;
|
|
137428
|
+
}
|
|
137429
|
+
const author = normalized.fromBot ? PROTOCOL.bot : normalized.authorName ?? PROTOCOL.someone;
|
|
137430
|
+
const lines = normalized.content?.split("\n") ?? [];
|
|
137431
|
+
if (normalized.attachments !== void 0) {
|
|
137432
|
+
const attachments = normalized.attachments.map(
|
|
137433
|
+
({ kind, name }) => name ? `${kind} ${name}` : kind
|
|
137434
|
+
);
|
|
137435
|
+
lines.push(`${PROTOCOL.attachments} ${attachments.join(", ")}`);
|
|
137436
|
+
}
|
|
137437
|
+
if (normalized.truncated) lines.push(PROTOCOL.truncated);
|
|
137438
|
+
return [
|
|
137439
|
+
`${PROTOCOL.header} ${author} ${PROTOCOL.note}`,
|
|
137440
|
+
...lines.map((line) => `> ${line}`)
|
|
137441
|
+
].join("\n");
|
|
137442
|
+
};
|
|
137443
|
+
var textWithInboundContext = (message, rowId, t) => {
|
|
137444
|
+
const reply = formatReplyReference(message.replyTo);
|
|
137445
|
+
const text4 = reply === null ? message.text : `${reply}
|
|
137446
|
+
|
|
137447
|
+
${message.text}`;
|
|
137448
|
+
if (message.chatKind !== "group" || message.senderId === null) return text4;
|
|
137449
|
+
let name = cleanString(message.senderName, AUTHOR_MAX).value;
|
|
137450
|
+
if (!name) {
|
|
137451
|
+
const code2 = NodeCrypto2.createHash("sha256").update(JSON.stringify([rowId, message.senderId])).digest("hex").slice(0, 4);
|
|
137452
|
+
name = t("source.member", { code: code2 });
|
|
137453
|
+
}
|
|
137454
|
+
const chat = cleanString(message.chatTitle, AUTHOR_MAX).value;
|
|
137455
|
+
const source = chat ? t("source.fromChat", { name, chat }) : t("source.from", { name });
|
|
137456
|
+
return `${source}
|
|
137457
|
+
${text4}`;
|
|
137458
|
+
};
|
|
137459
|
+
var errorReason = (error) => {
|
|
137460
|
+
if (typeof error !== "object" || error === null) return "not-delivered";
|
|
137461
|
+
const supplied = "code" in error ? error.code : void 0;
|
|
137462
|
+
if (typeof supplied === "string" && Object.hasOwn(PROTOCOL.reasons, supplied)) {
|
|
137463
|
+
return supplied;
|
|
137464
|
+
}
|
|
137465
|
+
const status = Number(
|
|
137466
|
+
"status" in error ? error.status : "statusCode" in error ? error.statusCode : void 0
|
|
137467
|
+
);
|
|
137468
|
+
if (status === 401 || status === 403) return "permission-denied";
|
|
137469
|
+
if (status === 404) return "not-found";
|
|
137470
|
+
if (status === 410) return "deleted";
|
|
137471
|
+
return "not-delivered";
|
|
137472
|
+
};
|
|
137473
|
+
var loadReplyReference = async (load) => {
|
|
137474
|
+
try {
|
|
137475
|
+
return await withDeadline2(LOAD_TIMEOUT_MS, load) ?? { unavailableReason: "not-found" };
|
|
137476
|
+
} catch (error) {
|
|
137477
|
+
return { unavailableReason: errorReason(error) };
|
|
137478
|
+
}
|
|
137479
|
+
};
|
|
137480
|
+
|
|
137481
|
+
// src/larkMessageContext.ts
|
|
137482
|
+
var CACHE_LIMIT = 2e3;
|
|
137483
|
+
var CACHE_MS = 5 * 6e4;
|
|
137484
|
+
var LOOKUP_TIMEOUT_MS = 2e3;
|
|
137485
|
+
var makeLookup = (rowId, load) => {
|
|
137486
|
+
const cache = makeBoundedMap(CACHE_LIMIT);
|
|
137237
137487
|
const inflight = /* @__PURE__ */ new Map();
|
|
137238
|
-
return
|
|
137239
|
-
const
|
|
137240
|
-
|
|
137241
|
-
|
|
137242
|
-
|
|
137243
|
-
|
|
137244
|
-
|
|
137245
|
-
|
|
137246
|
-
|
|
137247
|
-
|
|
137248
|
-
|
|
137249
|
-
|
|
137250
|
-
|
|
137251
|
-
|
|
137252
|
-
|
|
137488
|
+
return (id) => {
|
|
137489
|
+
const key = JSON.stringify([rowId, id]);
|
|
137490
|
+
const known = cache.get(key);
|
|
137491
|
+
if (known !== void 0 && Date.now() - known.at < CACHE_MS) return known.value;
|
|
137492
|
+
const pending = inflight.get(key);
|
|
137493
|
+
if (pending !== void 0) return pending;
|
|
137494
|
+
const reading = withDeadline2(LOOKUP_TIMEOUT_MS, (signal) => load(id, signal)).catch(() => null).then((value2) => {
|
|
137495
|
+
cache.set(key, { value: value2, at: Date.now() });
|
|
137496
|
+
return value2;
|
|
137497
|
+
}).finally(() => inflight.delete(key));
|
|
137498
|
+
inflight.set(key, reading);
|
|
137499
|
+
return reading;
|
|
137500
|
+
};
|
|
137501
|
+
};
|
|
137502
|
+
var makeLarkMessageContext = (deps) => {
|
|
137503
|
+
let contactDenied = false;
|
|
137504
|
+
const userName = makeLookup(deps.rowId, async (openId, signal) => {
|
|
137505
|
+
try {
|
|
137506
|
+
const token = await deps.tenantToken();
|
|
137507
|
+
signal.throwIfAborted();
|
|
137508
|
+
if (contactDenied) return null;
|
|
137509
|
+
return await fetchUserName({ http: deps.http, token, openId, signal }) ?? null;
|
|
137510
|
+
} catch (error) {
|
|
137511
|
+
if (isLarkPermissionError(error)) contactDenied = true;
|
|
137512
|
+
throw error;
|
|
137253
137513
|
}
|
|
137254
|
-
|
|
137514
|
+
});
|
|
137515
|
+
const chatInfo = makeLookup(deps.rowId, async (chatId, signal) => {
|
|
137516
|
+
const token = await deps.tenantToken();
|
|
137517
|
+
signal.throwIfAborted();
|
|
137518
|
+
return await fetchChatInfo({ http: deps.http, token, chatId, signal }) ?? null;
|
|
137519
|
+
});
|
|
137520
|
+
const forMessage = (message) => {
|
|
137521
|
+
if (message.chatType !== "group" || message.senderOpenId === null) return {};
|
|
137522
|
+
const name = contactDenied ? null : userName(message.senderOpenId);
|
|
137523
|
+
const chat = chatInfo(message.chatId);
|
|
137524
|
+
const fields = (senderName, info) => ({
|
|
137525
|
+
...senderName ? { senderName } : {},
|
|
137526
|
+
...info?.name ? { chatTitle: info.name } : {}
|
|
137527
|
+
});
|
|
137528
|
+
return name instanceof Promise || chat instanceof Promise ? Promise.all([name, chat]).then(([senderName, info]) => fields(senderName, info)) : fields(name, chat);
|
|
137255
137529
|
};
|
|
137530
|
+
return { chatInfo, forMessage };
|
|
137256
137531
|
};
|
|
137257
137532
|
|
|
137258
137533
|
// src/larkAdapter.ts
|
|
@@ -137279,6 +137554,7 @@ var COLUMNS = [
|
|
|
137279
137554
|
];
|
|
137280
137555
|
var topicOnMentionOf = (binding) => binding.values["larkTopicOnMention"] !== "off";
|
|
137281
137556
|
var TOPIC_THREAD_CACHE_LIMIT = 2e3;
|
|
137557
|
+
var MESSAGE_CONTEXT_CACHE_LIMIT = 2e3;
|
|
137282
137558
|
var topicChatIdOf = (chatId, rootMessageId) => `${chatId}:${rootMessageId}`;
|
|
137283
137559
|
var splitTopicChatId = (chatId) => {
|
|
137284
137560
|
const at = chatId.indexOf(":");
|
|
@@ -137308,6 +137584,7 @@ var makeLarkAdapter = (deps) => {
|
|
|
137308
137584
|
};
|
|
137309
137585
|
const aliasPorts = /* @__PURE__ */ new Map();
|
|
137310
137586
|
const topicThreadIds = makeBoundedMap(TOPIC_THREAD_CACHE_LIMIT);
|
|
137587
|
+
const messageContexts = makeBoundedMap(MESSAGE_CONTEXT_CACHE_LIMIT);
|
|
137311
137588
|
const unreported = /* @__PURE__ */ new Map();
|
|
137312
137589
|
const learning = /* @__PURE__ */ new Map();
|
|
137313
137590
|
const learnTopic = (binding, target2, threadId) => {
|
|
@@ -137364,14 +137641,10 @@ var makeLarkAdapter = (deps) => {
|
|
|
137364
137641
|
onThreadReply: (threadId) => learnTopic(binding, { token, chatId, rootMessageId, port }, threadId)
|
|
137365
137642
|
};
|
|
137366
137643
|
};
|
|
137367
|
-
const soloGroupFor = (
|
|
137368
|
-
const
|
|
137369
|
-
|
|
137370
|
-
|
|
137371
|
-
chatId
|
|
137372
|
-
});
|
|
137373
|
-
return stats === void 0 ? void 0 : stats.userCount <= 1 && stats.botCount <= 1;
|
|
137374
|
-
});
|
|
137644
|
+
const soloGroupFor = (context) => async (chatId) => {
|
|
137645
|
+
const info = await context.chatInfo(chatId);
|
|
137646
|
+
return info?.userCount !== void 0 && info.botCount !== void 0 && info.userCount <= 1 && info.botCount <= 1;
|
|
137647
|
+
};
|
|
137375
137648
|
return {
|
|
137376
137649
|
platform: "lark",
|
|
137377
137650
|
icon: "lark",
|
|
@@ -137397,12 +137670,20 @@ var makeLarkAdapter = (deps) => {
|
|
|
137397
137670
|
unreported.delete(key);
|
|
137398
137671
|
}
|
|
137399
137672
|
let open = true;
|
|
137673
|
+
const pendingDeliveries = /* @__PURE__ */ new Map();
|
|
137674
|
+
const previousContext = messageContexts.get(binding.rowId);
|
|
137675
|
+
const context = previousContext?.appId === appId && previousContext.appSecret === appSecret ? previousContext.context : makeLarkMessageContext({
|
|
137676
|
+
rowId: binding.rowId,
|
|
137677
|
+
http: deps.http,
|
|
137678
|
+
tenantToken: () => tenantToken(binding)
|
|
137679
|
+
});
|
|
137680
|
+
messageContexts.set(binding.rowId, { appId, appSecret, context });
|
|
137400
137681
|
const inbound = startLarkInbound({
|
|
137401
137682
|
appId,
|
|
137402
137683
|
appSecret,
|
|
137403
137684
|
groupMention: binding.groupMention,
|
|
137404
137685
|
topicOnMention: topicOnMentionOf(binding),
|
|
137405
|
-
isSoloGroup: soloGroupFor(
|
|
137686
|
+
isSoloGroup: soloGroupFor(context),
|
|
137406
137687
|
onError: handlers.onError,
|
|
137407
137688
|
onCardAction: handlers.onButton,
|
|
137408
137689
|
onPanelClick: (click, operatorOpenId) => handlers.onPanelClick?.({
|
|
@@ -137414,7 +137695,17 @@ var makeLarkAdapter = (deps) => {
|
|
|
137414
137695
|
}) ?? null,
|
|
137415
137696
|
onMessage: (message) => {
|
|
137416
137697
|
const { topic } = message;
|
|
137417
|
-
const
|
|
137698
|
+
const source = context.forMessage(message);
|
|
137699
|
+
const parentMessageId = message.parentMessageId;
|
|
137700
|
+
const reference2 = parentMessageId === void 0 ? null : loadReplyReference(
|
|
137701
|
+
async (signal) => fetchMessageReference({
|
|
137702
|
+
http: deps.http,
|
|
137703
|
+
token: await tenantToken(binding),
|
|
137704
|
+
messageId: parentMessageId,
|
|
137705
|
+
signal
|
|
137706
|
+
})
|
|
137707
|
+
);
|
|
137708
|
+
const deliver = (names, replyTo) => handlers.onMessage({
|
|
137418
137709
|
messageId: message.messageId,
|
|
137419
137710
|
// 已经开出来的话题就是它自己那个聊天;将要开出来的(主窗口里 @ 机器人)先算群的,
|
|
137420
137711
|
// 由核心决定要不要分出去。
|
|
@@ -137427,7 +137718,9 @@ var makeLarkAdapter = (deps) => {
|
|
|
137427
137718
|
chatAlias: topicAliasOf(message.chatId, topic.threadId)
|
|
137428
137719
|
},
|
|
137429
137720
|
senderId: message.senderOpenId,
|
|
137721
|
+
...names,
|
|
137430
137722
|
text: message.text,
|
|
137723
|
+
...replyTo === void 0 ? {} : { replyTo },
|
|
137431
137724
|
chatKind: message.chatType === "p2p" ? "private" : "group",
|
|
137432
137725
|
replyInThread: message.inThread,
|
|
137433
137726
|
resources: message.resources.map((resource) => ({
|
|
@@ -137442,8 +137735,19 @@ var makeLarkAdapter = (deps) => {
|
|
|
137442
137735
|
threadId: topic.threadId,
|
|
137443
137736
|
rootGiven: topic.rootGiven
|
|
137444
137737
|
});
|
|
137445
|
-
|
|
137446
|
-
|
|
137738
|
+
const key = JSON.stringify([message.chatId, topic?.threadId]);
|
|
137739
|
+
const earlier = pendingDeliveries.get(key);
|
|
137740
|
+
if (earlier === void 0 && pending === null && reference2 === null && !(source instanceof Promise)) {
|
|
137741
|
+
deliver(source);
|
|
137742
|
+
} else {
|
|
137743
|
+
const completed = Promise.all([earlier, pending, reference2, source]).then(([, , replyTo, names]) => {
|
|
137744
|
+
if (pendingDeliveries.get(key) === completed) pendingDeliveries.delete(key);
|
|
137745
|
+
if (open) deliver(names, replyTo ?? void 0);
|
|
137746
|
+
}).catch((error) => handlers.onError(describeError(error))).finally(() => {
|
|
137747
|
+
if (pendingDeliveries.get(key) === completed) pendingDeliveries.delete(key);
|
|
137748
|
+
});
|
|
137749
|
+
pendingDeliveries.set(key, completed);
|
|
137750
|
+
}
|
|
137447
137751
|
}
|
|
137448
137752
|
});
|
|
137449
137753
|
return {
|
|
@@ -137624,6 +137928,11 @@ var makeLarkAdapter = (deps) => {
|
|
|
137624
137928
|
|
|
137625
137929
|
// locales/en.json
|
|
137626
137930
|
var en_default = {
|
|
137931
|
+
source: {
|
|
137932
|
+
fromChat: "From {{name}} in {{chat}}:",
|
|
137933
|
+
from: "From {{name}}:",
|
|
137934
|
+
member: "member {{code}}"
|
|
137935
|
+
},
|
|
137627
137936
|
settings: {
|
|
137628
137937
|
title: "Chat",
|
|
137629
137938
|
description: "Connect chat bots to Ycodium. One row per bot: create the bot on its platform, paste its credentials, and pick an access mode (allowlist / open). In allowlist mode, list the people allowed to use it. For Lark, Connect a Lark bot does all of that with one scan. Admitted people message the bot (or add it to a group), pick a project in the chat, and can start work.",
|
|
@@ -138288,6 +138597,11 @@ var en_default = {
|
|
|
138288
138597
|
|
|
138289
138598
|
// locales/zh-CN.json
|
|
138290
138599
|
var zh_CN_default = {
|
|
138600
|
+
source: {
|
|
138601
|
+
fromChat: "\u6765\u81EA {{name}}\uFF08{{chat}}\uFF09\uFF1A",
|
|
138602
|
+
from: "\u6765\u81EA {{name}}\uFF1A",
|
|
138603
|
+
member: "\u6210\u5458 {{code}}"
|
|
138604
|
+
},
|
|
138291
138605
|
settings: {
|
|
138292
138606
|
title: "\u804A\u5929",
|
|
138293
138607
|
description: "\u628A\u804A\u5929\u673A\u5668\u4EBA\u63A5\u5230 Ycodium\u3002\u4E00\u884C\u4E00\u4E2A\u673A\u5668\u4EBA\uFF1A\u5148\u5728\u5BF9\u5E94\u5E73\u53F0\u5EFA\u597D\u673A\u5668\u4EBA\u3001\u628A\u51ED\u636E\u586B\u8FDB\u6765\uFF0C\u518D\u9009\u8BBF\u95EE\u6A21\u5F0F\uFF08\u4EC5\u767D\u540D\u5355\uFF0F\u5141\u8BB8\u6240\u6709\u4EBA\uFF09\u3002\u4EC5\u767D\u540D\u5355\u65F6\u628A\u5141\u8BB8\u4F7F\u7528\u5B83\u7684\u4EBA\u586B\u8FDB\u300C\u5141\u8BB8\u7684\u4EBA\u300D\u3002\u98DE\u4E66\u53EF\u4EE5\u7528\u300C\u8FDE\u63A5\u98DE\u4E66\u673A\u5668\u4EBA\u300D\uFF0C\u626B\u4E00\u6B21\u7801\u5168\u90E8\u914D\u597D\u3002\u83B7\u51C6\u7684\u4EBA\u79C1\u804A\u673A\u5668\u4EBA\uFF08\u6216\u628A\u5B83\u62C9\u8FDB\u7FA4\uFF09\u3001\u5728\u804A\u5929\u91CC\u9009\u597D\u9879\u76EE\uFF0C\u5C31\u80FD\u6D3E\u6D3B\u3002",
|
|
@@ -140209,18 +140523,18 @@ var makeReplyCards = (core, failures, anchors) => {
|
|
|
140209
140523
|
});
|
|
140210
140524
|
host.onDispose(() => turnCards.dispose());
|
|
140211
140525
|
void ready.then(async () => {
|
|
140212
|
-
for (const [cardId,
|
|
140213
|
-
const binding = bindingForChatKey(
|
|
140526
|
+
for (const [cardId, record3] of Object.entries(openTurnCardsOf(core.state))) {
|
|
140527
|
+
const binding = bindingForChatKey(record3.chatKey);
|
|
140214
140528
|
const cards = binding === void 0 ? void 0 : adapterFor(binding.platform)?.turnCards;
|
|
140215
140529
|
if (binding !== void 0 && cards !== void 0) {
|
|
140216
140530
|
try {
|
|
140217
|
-
const messages = await messagesAfterLastUser(host.threads,
|
|
140531
|
+
const messages = await messagesAfterLastUser(host.threads, record3.threadId).catch(
|
|
140218
140532
|
() => []
|
|
140219
140533
|
);
|
|
140220
140534
|
await cards.update(
|
|
140221
140535
|
binding,
|
|
140222
140536
|
cardId,
|
|
140223
|
-
interruptedView({ title:
|
|
140537
|
+
interruptedView({ title: record3.title, body: trailingReply(messages) })
|
|
140224
140538
|
);
|
|
140225
140539
|
} catch (error) {
|
|
140226
140540
|
host.log.warn("chat could not mark a stale card as interrupted", {
|
|
@@ -140480,8 +140794,8 @@ var makeSessions = (core) => {
|
|
|
140480
140794
|
await deliver(binding, formatSessions(rows, Date.now(), t));
|
|
140481
140795
|
};
|
|
140482
140796
|
const bindToSession = async (binding, chatKey, target2) => {
|
|
140483
|
-
for (const [otherKey,
|
|
140484
|
-
if (otherKey !== chatKey &&
|
|
140797
|
+
for (const [otherKey, record3] of Object.entries(core.state.chats)) {
|
|
140798
|
+
if (otherKey !== chatKey && record3.threadId === target2.threadId) bindChat(otherKey, null);
|
|
140485
140799
|
}
|
|
140486
140800
|
if (target2.origin === "web" && !hasAttached(core.state, chatKey, target2.threadId)) {
|
|
140487
140801
|
commit("thread-attached", {
|
|
@@ -140562,7 +140876,7 @@ var makeSessions = (core) => {
|
|
|
140562
140876
|
};
|
|
140563
140877
|
|
|
140564
140878
|
// src/teamGoals.ts
|
|
140565
|
-
import * as
|
|
140879
|
+
import * as NodeCrypto3 from "node:crypto";
|
|
140566
140880
|
var isRecord2 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
140567
140881
|
var teamGoalRequestId = (binding, messageId) => {
|
|
140568
140882
|
const identity = JSON.stringify([
|
|
@@ -140572,7 +140886,7 @@ var teamGoalRequestId = (binding, messageId) => {
|
|
|
140572
140886
|
binding.chatId,
|
|
140573
140887
|
messageId
|
|
140574
140888
|
]);
|
|
140575
|
-
return
|
|
140889
|
+
return NodeCrypto3.createHash("sha256").update(identity).digest("hex");
|
|
140576
140890
|
};
|
|
140577
140891
|
var makeTeamGoals = (core) => {
|
|
140578
140892
|
const { host, t, deliver, commit } = core;
|
|
@@ -140598,7 +140912,8 @@ var makeTeamGoals = (core) => {
|
|
|
140598
140912
|
command: "startGoal",
|
|
140599
140913
|
payload: {
|
|
140600
140914
|
projectId: binding.projectId,
|
|
140601
|
-
goal: message.
|
|
140915
|
+
goal: textWithInboundContext(message, binding.rowId, t),
|
|
140916
|
+
titleSeed: message.text,
|
|
140602
140917
|
requestId: teamGoalRequestId(binding, message.messageId)
|
|
140603
140918
|
}
|
|
140604
140919
|
});
|
|
@@ -140643,6 +140958,7 @@ var DOWNLOAD_TIMEOUT_MS = 6e4;
|
|
|
140643
140958
|
var HINT_TIMEOUT_MS = 3e3;
|
|
140644
140959
|
var isTelegramToken = (token) => /^\d{5,20}:[A-Za-z0-9_-]{20,}$/u.test(token);
|
|
140645
140960
|
var TELEGRAM_TEXT_MAX_CHARS = 4e3;
|
|
140961
|
+
var telegramDisplayName = (user) => [user?.first_name, user?.last_name].filter(Boolean).join(" ").trim() || user?.username;
|
|
140646
140962
|
var chatIdOf = (message) => {
|
|
140647
140963
|
const thread = message.message_thread_id;
|
|
140648
140964
|
return message.is_topic_message === true && thread !== void 0 && thread > 0 ? `${String(message.chat.id)}:${String(thread)}` : String(message.chat.id);
|
|
@@ -140940,6 +141256,32 @@ var makeTelegramApi = (input) => {
|
|
|
140940
141256
|
};
|
|
140941
141257
|
};
|
|
140942
141258
|
|
|
141259
|
+
// src/soloGroup.ts
|
|
141260
|
+
var SOLO_GROUP_CACHE_MS = 5 * 6e4;
|
|
141261
|
+
var SOLO_GROUP_CACHE_LIMIT = 500;
|
|
141262
|
+
var makeSoloGroupCheck = (lookup2, now = () => Date.now()) => {
|
|
141263
|
+
const cache = /* @__PURE__ */ new Map();
|
|
141264
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
141265
|
+
return async (chatId) => {
|
|
141266
|
+
const cached = cache.get(chatId);
|
|
141267
|
+
if (cached !== void 0 && now() - cached.at < SOLO_GROUP_CACHE_MS) return cached.solo;
|
|
141268
|
+
let asking = inflight.get(chatId);
|
|
141269
|
+
if (asking === void 0) {
|
|
141270
|
+
asking = lookup2(chatId).catch(() => void 0).finally(() => inflight.delete(chatId));
|
|
141271
|
+
inflight.set(chatId, asking);
|
|
141272
|
+
}
|
|
141273
|
+
const solo = await asking;
|
|
141274
|
+
if (solo === void 0) return false;
|
|
141275
|
+
cache.delete(chatId);
|
|
141276
|
+
cache.set(chatId, { solo, at: now() });
|
|
141277
|
+
if (cache.size > SOLO_GROUP_CACHE_LIMIT) {
|
|
141278
|
+
const oldest = cache.keys().next().value;
|
|
141279
|
+
if (oldest !== void 0) cache.delete(oldest);
|
|
141280
|
+
}
|
|
141281
|
+
return solo;
|
|
141282
|
+
};
|
|
141283
|
+
};
|
|
141284
|
+
|
|
140943
141285
|
// src/telegramCommandMenu.ts
|
|
140944
141286
|
var DESCRIPTIONS = {
|
|
140945
141287
|
new: "menu.new",
|
|
@@ -140999,6 +141341,54 @@ var parsePanelData = (data) => {
|
|
|
140999
141341
|
return { version: Number(match[1]), index: Number(match[2]) };
|
|
141000
141342
|
};
|
|
141001
141343
|
|
|
141344
|
+
// src/telegramReply.ts
|
|
141345
|
+
var topicServiceMessage = (message, reply) => message.is_topic_message === true && message.message_thread_id !== void 0 && (message.message_thread_id === reply.message_id || message.message_thread_id === reply.message_thread_id) && [
|
|
141346
|
+
reply.forum_topic_created,
|
|
141347
|
+
reply.forum_topic_edited,
|
|
141348
|
+
reply.forum_topic_closed,
|
|
141349
|
+
reply.forum_topic_reopened,
|
|
141350
|
+
reply.general_forum_topic_hidden,
|
|
141351
|
+
reply.general_forum_topic_unhidden
|
|
141352
|
+
].some((value2) => value2 !== void 0);
|
|
141353
|
+
var telegramReplyReference = (message, botUsername, botId) => {
|
|
141354
|
+
const reply = message.reply_to_message;
|
|
141355
|
+
const external = message.external_reply;
|
|
141356
|
+
if (reply !== void 0 && topicServiceMessage(message, reply) && external === void 0 && message.quote === void 0) {
|
|
141357
|
+
return null;
|
|
141358
|
+
}
|
|
141359
|
+
const source = external ?? reply;
|
|
141360
|
+
if (source === void 0 && message.quote === void 0) return null;
|
|
141361
|
+
const origin = external?.origin;
|
|
141362
|
+
const author = external === void 0 ? reply?.from : origin?.type === "user" ? origin.sender_user : void 0;
|
|
141363
|
+
const authorName = author === void 0 ? origin?.sender_user_name ?? origin?.author_signature ?? origin?.sender_chat?.title ?? origin?.chat?.title : telegramDisplayName(author);
|
|
141364
|
+
const fromBot = author !== void 0 && (botId !== void 0 && author.id === botId || botUsername !== null && author.username?.toLowerCase() === botUsername.toLowerCase());
|
|
141365
|
+
const attachments = [];
|
|
141366
|
+
if ((source?.photo?.length ?? 0) > 0) attachments.push({ kind: "image" });
|
|
141367
|
+
for (const [media, kind] of [
|
|
141368
|
+
[source?.document, "file"],
|
|
141369
|
+
[source?.audio, "audio"],
|
|
141370
|
+
[source?.voice, "audio"],
|
|
141371
|
+
[source?.video, "video"],
|
|
141372
|
+
[source?.video_note, "video"],
|
|
141373
|
+
[source?.animation, "video"]
|
|
141374
|
+
]) {
|
|
141375
|
+
if (media !== void 0) {
|
|
141376
|
+
attachments.push({
|
|
141377
|
+
kind,
|
|
141378
|
+
...media.file_name === void 0 ? {} : { name: media.file_name }
|
|
141379
|
+
});
|
|
141380
|
+
}
|
|
141381
|
+
}
|
|
141382
|
+
if (source?.sticker !== void 0) attachments.push({ kind: "other" });
|
|
141383
|
+
const content = message.quote?.text ?? source?.text ?? source?.caption;
|
|
141384
|
+
return {
|
|
141385
|
+
...authorName ? { authorName } : {},
|
|
141386
|
+
...fromBot ? { fromBot: true } : {},
|
|
141387
|
+
...content === void 0 ? {} : { content },
|
|
141388
|
+
...attachments.length === 0 ? {} : { attachments }
|
|
141389
|
+
};
|
|
141390
|
+
};
|
|
141391
|
+
|
|
141002
141392
|
// src/telegramRichText.ts
|
|
141003
141393
|
var TELEGRAM_RICH_TEXT_LIMIT = 3e4;
|
|
141004
141394
|
var escapeCharacter = (character) => {
|
|
@@ -141223,6 +141613,7 @@ var makeTelegramAdapter = (deps) => {
|
|
|
141223
141613
|
let acknowledged = 0;
|
|
141224
141614
|
let backoff = BACKOFF_START_MS;
|
|
141225
141615
|
let botUsername;
|
|
141616
|
+
let botId;
|
|
141226
141617
|
let menuSent = false;
|
|
141227
141618
|
let liveApi;
|
|
141228
141619
|
const isSoloGroup = makeSoloGroupCheck(async (chatId) => {
|
|
@@ -141243,7 +141634,11 @@ var makeTelegramAdapter = (deps) => {
|
|
|
141243
141634
|
const api = await apiFor(binding);
|
|
141244
141635
|
liveApi = api;
|
|
141245
141636
|
if (!running) return;
|
|
141246
|
-
botUsername
|
|
141637
|
+
if (botUsername == null) {
|
|
141638
|
+
const own = await api.getMe();
|
|
141639
|
+
botUsername = own.username ?? null;
|
|
141640
|
+
botId = own.id;
|
|
141641
|
+
}
|
|
141247
141642
|
if (!running) return;
|
|
141248
141643
|
if (!menuSent) {
|
|
141249
141644
|
menuSent = true;
|
|
@@ -141300,6 +141695,7 @@ var makeTelegramAdapter = (deps) => {
|
|
|
141300
141695
|
if (!running) break;
|
|
141301
141696
|
offset = nextOffset([update], offset);
|
|
141302
141697
|
const senderId = message.from === void 0 ? null : String(message.from.id);
|
|
141698
|
+
const senderName = telegramDisplayName(message.from);
|
|
141303
141699
|
const chatKind = message.chat.type === "private" ? "private" : "group";
|
|
141304
141700
|
if (text4 === "" && resource === null) {
|
|
141305
141701
|
const unsupported = unsupportedTypeOf(message);
|
|
@@ -141316,12 +141712,16 @@ var makeTelegramAdapter = (deps) => {
|
|
|
141316
141712
|
continue;
|
|
141317
141713
|
}
|
|
141318
141714
|
const parentChatId = parentChatIdOf(message);
|
|
141715
|
+
const replyTo = telegramReplyReference(message, botUsername, botId);
|
|
141319
141716
|
handlers.onMessage({
|
|
141320
141717
|
messageId: String(message.message_id),
|
|
141321
141718
|
chatId: chatIdOf(message),
|
|
141322
141719
|
...parentChatId === void 0 ? {} : { parentChatId },
|
|
141323
141720
|
senderId,
|
|
141324
141721
|
text: text4,
|
|
141722
|
+
...senderName ? { senderName } : {},
|
|
141723
|
+
...message.chat.title ? { chatTitle: message.chat.title } : {},
|
|
141724
|
+
...replyTo === null ? {} : { replyTo },
|
|
141325
141725
|
chatKind,
|
|
141326
141726
|
resources: resource === null ? [] : [
|
|
141327
141727
|
{
|
|
@@ -141652,7 +142052,7 @@ var makeTurns = (core, deps) => {
|
|
|
141652
142052
|
message: {
|
|
141653
142053
|
messageId: userMessageId,
|
|
141654
142054
|
role: "user",
|
|
141655
|
-
text:
|
|
142055
|
+
text: [textWithInboundContext(message, binding.rowId, t), ...notes].join("\n"),
|
|
141656
142056
|
attachments: attachments.map(
|
|
141657
142057
|
(attachment) => attachment.type === "image" ? { ...attachment, type: "image" } : { ...attachment, type: "file" }
|
|
141658
142058
|
)
|
|
@@ -141715,8 +142115,8 @@ var makeTurns = (core, deps) => {
|
|
|
141715
142115
|
|
|
141716
142116
|
// src/webSync.ts
|
|
141717
142117
|
var isWebSyncChat = (state, chatKey, threadId) => {
|
|
141718
|
-
const
|
|
141719
|
-
return
|
|
142118
|
+
const record3 = chatOf(state, chatKey);
|
|
142119
|
+
return record3.chatKind === "private" && record3.threadId === threadId;
|
|
141720
142120
|
};
|
|
141721
142121
|
var IM_ORIGIN_LIMIT = 256;
|
|
141722
142122
|
var MIRRORED_LIMIT = 256;
|
|
@@ -142269,7 +142669,7 @@ var makeWechatAdapter = (deps) => {
|
|
|
142269
142669
|
};
|
|
142270
142670
|
|
|
142271
142671
|
// src/wecomUpload.ts
|
|
142272
|
-
import * as
|
|
142672
|
+
import * as NodeCrypto4 from "node:crypto";
|
|
142273
142673
|
var WECOM_CHUNK_BYTES = 512 * 1024;
|
|
142274
142674
|
var WECOM_MAX_CHUNKS = 100;
|
|
142275
142675
|
var WECOM_MIN_UPLOAD_BYTES = 5;
|
|
@@ -142302,7 +142702,7 @@ var uploadWecomMedia = async (input) => {
|
|
|
142302
142702
|
filename: clampName(input.filename),
|
|
142303
142703
|
total_size: bytes.byteLength,
|
|
142304
142704
|
total_chunks: totalChunks,
|
|
142305
|
-
md5:
|
|
142705
|
+
md5: NodeCrypto4.createHash("md5").update(bytes).digest("hex")
|
|
142306
142706
|
});
|
|
142307
142707
|
const uploadId = init.upload_id;
|
|
142308
142708
|
if (typeof uploadId !== "string" || uploadId === "") {
|
|
@@ -142351,6 +142751,43 @@ var uploadWecomMedia = async (input) => {
|
|
|
142351
142751
|
return mediaId;
|
|
142352
142752
|
};
|
|
142353
142753
|
|
|
142754
|
+
// src/wecomReply.ts
|
|
142755
|
+
var wecomReplyReference = (quote) => {
|
|
142756
|
+
const attachments = [];
|
|
142757
|
+
const parts = [];
|
|
142758
|
+
const read = (item) => {
|
|
142759
|
+
switch (item.msgtype) {
|
|
142760
|
+
case "text":
|
|
142761
|
+
if (item.text?.content) parts.push(item.text.content);
|
|
142762
|
+
return true;
|
|
142763
|
+
case "voice":
|
|
142764
|
+
if (item.voice?.content) parts.push(item.voice.content);
|
|
142765
|
+
attachments.push({ kind: "audio" });
|
|
142766
|
+
return true;
|
|
142767
|
+
case "image":
|
|
142768
|
+
attachments.push({ kind: "image" });
|
|
142769
|
+
return true;
|
|
142770
|
+
case "file":
|
|
142771
|
+
attachments.push({ kind: "file" });
|
|
142772
|
+
return true;
|
|
142773
|
+
case "video":
|
|
142774
|
+
attachments.push({ kind: "video" });
|
|
142775
|
+
return true;
|
|
142776
|
+
case "mixed":
|
|
142777
|
+
for (const child of item.mixed?.msg_item ?? []) read(child);
|
|
142778
|
+
return true;
|
|
142779
|
+
default:
|
|
142780
|
+
return false;
|
|
142781
|
+
}
|
|
142782
|
+
};
|
|
142783
|
+
const supported = read(quote);
|
|
142784
|
+
return {
|
|
142785
|
+
...parts.length === 0 ? {} : { content: parts.join("\n") },
|
|
142786
|
+
...attachments.length === 0 ? {} : { attachments },
|
|
142787
|
+
...!supported ? { unavailableReason: "unsupported" } : {}
|
|
142788
|
+
};
|
|
142789
|
+
};
|
|
142790
|
+
|
|
142354
142791
|
// src/wecomApi.ts
|
|
142355
142792
|
var DEFAULT_WECOM_ENDPOINT = "wss://openws.work.weixin.qq.com/wssvr/";
|
|
142356
142793
|
var PING_INTERVAL_MS = 3e4;
|
|
@@ -142435,6 +142872,7 @@ var parseWecomMessage = (frame, botId) => {
|
|
|
142435
142872
|
chatId,
|
|
142436
142873
|
senderUserId: body.from?.userid ?? null,
|
|
142437
142874
|
text: text4,
|
|
142875
|
+
...body.quote === void 0 ? {} : { replyTo: wecomReplyReference(body.quote) },
|
|
142438
142876
|
resources,
|
|
142439
142877
|
requestId: frame.headers?.req_id ?? null,
|
|
142440
142878
|
chatType: mentioned ? "single" : chatType,
|
|
@@ -142674,7 +143112,7 @@ var runWecomClient = (input) => {
|
|
|
142674
143112
|
};
|
|
142675
143113
|
|
|
142676
143114
|
// src/wecomMedia.ts
|
|
142677
|
-
import * as
|
|
143115
|
+
import * as NodeCrypto5 from "node:crypto";
|
|
142678
143116
|
|
|
142679
143117
|
// src/wecomPadding.ts
|
|
142680
143118
|
var PADDING_BLOCK = 32;
|
|
@@ -142705,7 +143143,7 @@ var decryptWecomMedia = (cipher, aesKey) => {
|
|
|
142705
143143
|
if (cipher.byteLength === 0 || cipher.byteLength % AES_BLOCK !== 0) {
|
|
142706
143144
|
throw new WecomDecryptError("the ciphertext is not a whole number of blocks");
|
|
142707
143145
|
}
|
|
142708
|
-
const decipher =
|
|
143146
|
+
const decipher = NodeCrypto5.createDecipheriv("aes-256-cbc", key, key.subarray(0, IV_BYTES));
|
|
142709
143147
|
decipher.setAutoPadding(false);
|
|
142710
143148
|
const plain = Buffer.concat([decipher.update(cipher), decipher.final()]);
|
|
142711
143149
|
const unpadded = stripPadding(plain);
|
|
@@ -142857,6 +143295,7 @@ ${kept}`;
|
|
|
142857
143295
|
chatId: message.chatId,
|
|
142858
143296
|
senderId: message.senderUserId,
|
|
142859
143297
|
text: message.text,
|
|
143298
|
+
...message.replyTo === void 0 ? {} : { replyTo: message.replyTo },
|
|
142860
143299
|
// 群里 @ 到机器人的消息被折算成 single 才放行;真实的聊天类型只留在 conversation。
|
|
142861
143300
|
chatKind: message.conversation === "single" ? "private" : "group",
|
|
142862
143301
|
// 下载地址与密钥打成一个键:核心只管把它原样交回来。
|
|
@@ -142995,14 +143434,14 @@ var WecomAppApiError = class extends Error {
|
|
|
142995
143434
|
this.hint = extras?.hint;
|
|
142996
143435
|
}
|
|
142997
143436
|
};
|
|
142998
|
-
var
|
|
143437
|
+
var cleanString2 = (value2) => {
|
|
142999
143438
|
if (typeof value2 !== "string") return null;
|
|
143000
143439
|
const trimmed = value2.trim();
|
|
143001
143440
|
return trimmed === "" ? null : trimmed;
|
|
143002
143441
|
};
|
|
143003
143442
|
var isHttpUrl = (raw) => /^https?:\/\//iu.test(raw) && URL.canParse(raw);
|
|
143004
143443
|
var normalizeApiBaseUrl = (value2) => {
|
|
143005
|
-
const raw =
|
|
143444
|
+
const raw = cleanString2(value2);
|
|
143006
143445
|
if (raw === null) return WECOM_APP_DEFAULT_API_BASE;
|
|
143007
143446
|
if (!isHttpUrl(raw)) {
|
|
143008
143447
|
throw new WecomAppApiError("invalid-api-base", "API base must be an http(s) URL.");
|
|
@@ -143227,7 +143666,7 @@ var WecomAppApi = class {
|
|
|
143227
143666
|
import * as NodeHttp2 from "node:http";
|
|
143228
143667
|
|
|
143229
143668
|
// src/wecomAppCrypto.ts
|
|
143230
|
-
import * as
|
|
143669
|
+
import * as NodeCrypto6 from "node:crypto";
|
|
143231
143670
|
var AES_KEY_BYTES = 32;
|
|
143232
143671
|
var RANDOM_BYTES = 16;
|
|
143233
143672
|
var WecomAppCryptoError = class extends Error {
|
|
@@ -143250,13 +143689,13 @@ var timingSafeEqualString2 = (a, b) => {
|
|
|
143250
143689
|
const left = Buffer.from(a);
|
|
143251
143690
|
const right = Buffer.from(b);
|
|
143252
143691
|
if (left.length === 0 || left.length !== right.length) return false;
|
|
143253
|
-
return
|
|
143692
|
+
return NodeCrypto6.timingSafeEqual(left, right);
|
|
143254
143693
|
};
|
|
143255
|
-
var computeSignature = (token, timestamp, nonce, encrypt) =>
|
|
143694
|
+
var computeSignature = (token, timestamp, nonce, encrypt) => NodeCrypto6.createHash("sha1").update([token, timestamp, nonce, encrypt].sort().join("")).digest("hex");
|
|
143256
143695
|
var verifySignature = (token, timestamp, nonce, encrypt, signature) => timingSafeEqualString2(computeSignature(token, timestamp, nonce, encrypt), signature);
|
|
143257
143696
|
var decrypt = (encodingAESKey, encryptText, expectReceiveId) => {
|
|
143258
143697
|
const { key, iv } = parseEncodingAESKey(encodingAESKey);
|
|
143259
|
-
const decipher =
|
|
143698
|
+
const decipher = NodeCrypto6.createDecipheriv("aes-256-cbc", key, iv);
|
|
143260
143699
|
decipher.setAutoPadding(false);
|
|
143261
143700
|
let deciphered;
|
|
143262
143701
|
try {
|
|
@@ -143315,7 +143754,7 @@ var createWecomAppCrypto = (input) => {
|
|
|
143315
143754
|
decrypt: (encryptText) => decrypt(encodingAESKey, encryptText, corpId).message
|
|
143316
143755
|
};
|
|
143317
143756
|
};
|
|
143318
|
-
var deriveCallbackPathSecret = (token, encodingAESKey) =>
|
|
143757
|
+
var deriveCallbackPathSecret = (token, encodingAESKey) => NodeCrypto6.createHash("sha256").update(`${token.trim()}:${encodingAESKey.trim()}`).digest("hex").slice(0, 24);
|
|
143319
143758
|
|
|
143320
143759
|
// src/wecomAppParse.ts
|
|
143321
143760
|
var isRecord4 = (value2) => value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|