@kafca/agentdock 0.1.42 → 0.1.44
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 +10 -0
- package/dist/renderer/assets/{Badge-D-WU4kUV.js → Badge-Qk9qHovH.js} +1 -1
- package/dist/renderer/assets/{Chat-BGkC5tAe.js → Chat-BK-fm0Xr.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-CfbC1jRd.js → ChatMarkdown-BKdW8OON.js} +1 -1
- package/dist/renderer/assets/{Config-qQb4bX5D.js → Config-B93CQGvY.js} +2 -2
- package/dist/renderer/assets/CronList-Z3TvSRKP.js +1 -0
- package/dist/renderer/assets/{Dashboard-xn6cUy_n.js → Dashboard-Ch3QkWwf.js} +2 -2
- package/dist/renderer/assets/{EmptyState-BdKBBUpr.js → EmptyState-kD9yAwtw.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Duk8IQP3.js → KnowledgeDetail-BAMCLrjz.js} +2 -2
- package/dist/renderer/assets/{KnowledgeHome-BfjX_4Sv.js → KnowledgeHome-ChvjOfrc.js} +2 -2
- package/dist/renderer/assets/{Logs-Bfq61QMn.js → Logs-Cv0nth3j.js} +1 -1
- package/dist/renderer/assets/{Modal-B3vlBmBr.js → Modal-DwY4lecS.js} +1 -1
- package/dist/renderer/assets/MonitorList-JEvMoWUm.js +1 -0
- package/dist/renderer/assets/{Page-CPsLOP3z.js → Page-CnB9ePsb.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-D-g46wyF.js → ProjectDetail-DJa3sMmU.js} +2 -2
- package/dist/renderer/assets/{ProjectList-BrQEKDQ8.js → ProjectList-D6CXumR_.js} +1 -1
- package/dist/renderer/assets/{Select-C4CFMQmF.js → Select-zfoksLGB.js} +1 -1
- package/dist/renderer/assets/SessionChat-DUTh4WoM.js +1 -0
- package/dist/renderer/assets/{SessionList-DPWIUbOg.js → SessionList-D9o-lUst.js} +1 -1
- package/dist/renderer/assets/{ThreadChat-BjtU-j9q.js → ThreadChat-BYXlT-Kc.js} +7 -7
- package/dist/renderer/assets/{Workspace-BcNmHuJx.js → Workspace-BrhSwRQ-.js} +1 -1
- package/dist/renderer/assets/{arrow-left-DPzSmidS.js → arrow-left-CNEAuElg.js} +1 -1
- package/dist/renderer/assets/{book-open-B0xhoRqZ.js → book-open-BNJMhNI-.js} +1 -1
- package/dist/renderer/assets/{check-BTJTyd0C.js → check-BnclClRU.js} +1 -1
- package/dist/renderer/assets/{chevron-down-B6jJXlhi.js → chevron-down-Bh53e0O-.js} +1 -1
- package/dist/renderer/assets/{circle-qRhJR9qR.js → circle-ClZTWCWO.js} +1 -1
- package/dist/renderer/assets/desktop-C5vBT0yM.js +1 -0
- package/dist/renderer/assets/desktop-C6q6wBae.js +5 -0
- package/dist/renderer/assets/en-D2SkCrhG.js +1 -0
- package/dist/renderer/assets/{funnel-CbYKGTn8.js → funnel-_5hsz0xI.js} +1 -1
- package/dist/renderer/assets/{heart-DjwWJfkz.js → heart-u4Q1aOqj.js} +1 -1
- package/dist/renderer/assets/{index-BWmHJRhe.js → index-B36eowj-.js} +39 -34
- package/dist/renderer/assets/{index-CyZs_2NJ.js → index-BNFx4uYv.js} +3 -3
- package/dist/renderer/assets/{pencil-1dfAivmj.js → pencil-DLh9QNmT.js} +1 -1
- package/dist/renderer/assets/{play-CB3w1G6S.js → play-BDTk9Scm.js} +1 -1
- package/dist/renderer/assets/{plug-Bvep5o3r.js → plug-BG0JHW6B.js} +1 -1
- package/dist/renderer/assets/{plus-DJVg9m09.js → plus-BSc8POsz.js} +1 -1
- package/dist/renderer/assets/projects-DwfZwxDW.js +1 -0
- package/dist/renderer/assets/{save-xjJn3qf2.js → save-D5AO_G6a.js} +1 -1
- package/dist/renderer/assets/{search-BK3UrQxM.js → search-CniPk7Ey.js} +1 -1
- package/dist/renderer/assets/{server-Dyd2eXJu.js → server-GsXyQAZm.js} +1 -1
- package/dist/renderer/assets/{session-utils-eXC0020s.js → session-utils-BDxzgTBC.js} +1 -1
- package/dist/renderer/assets/{sessions-WLYpkyUt.js → sessions-CLcKA1Tt.js} +1 -1
- package/dist/renderer/assets/{shield-check-C0N6aWzF.js → shield-check-4i0E3hmf.js} +1 -1
- package/dist/renderer/assets/{trash-2-BGMTNJA6.js → trash-2-DhtOCsO5.js} +1 -1
- package/dist/renderer/assets/{user-BcGMLyhu.js → user-BtC_pVXV.js} +1 -1
- package/dist/renderer/assets/{wifi-off-FhcQx0HK.js → wifi-off-BHPzPY_B.js} +1 -1
- package/dist/renderer/assets/zh-DIcdHycM.js +1 -0
- package/dist/renderer/index.html +1 -1
- package/dist-electron/packages/contracts/src/local-core.js +28 -0
- package/dist-electron/packages/core-sdk/src/index.js +32 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +51 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +4 -1364
- package/dist-electron/services/local-ai-core/src/acp/store/agent-task-store.js +166 -0
- package/dist-electron/services/local-ai-core/src/acp/store/automation-monitor-store.js +231 -0
- package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +263 -0
- package/dist-electron/services/local-ai-core/src/acp/store/platform-store.js +186 -0
- package/dist-electron/services/local-ai-core/src/acp/store/scheduler-store.js +201 -0
- package/dist-electron/services/local-ai-core/src/acp/store/schema.js +275 -0
- package/dist-electron/services/local-ai-core/src/acp/store/security-store.js +266 -0
- package/dist-electron/services/local-ai-core/src/acp/store/thread-store.js +232 -0
- package/dist-electron/services/local-ai-core/src/acp/store/utils.js +47 -0
- package/dist-electron/services/local-ai-core/src/acp/store/workspace-registry-store.js +109 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-conversation-executor.js +136 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-monitor-repository.js +56 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-monitor-service.js +359 -0
- package/dist-electron/services/local-ai-core/src/automation/condition-evaluator.js +77 -0
- package/dist-electron/services/local-ai-core/src/automation/mock-stock-provider.js +40 -0
- package/dist-electron/services/local-ai-core/src/automation/monitor-id.js +10 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/cards.js +55 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/inbound.js +114 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +153 -94
- package/dist-electron/services/local-ai-core/src/channel/shared/session-command-runtime.js +53 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/thread-routing.js +34 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +63 -51
- package/dist-electron/services/local-ai-core/src/cli/lac.js +196 -0
- package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +37 -0
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +43 -0
- package/dist-electron/services/local-ai-core/src/kernel/capability-registry.js +12 -0
- package/dist-electron/services/local-ai-core/src/plugins/builtin/monitor-stock-plugin.js +30 -0
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +41 -0
- package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +31 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +36 -0
- package/dist-electron/services/local-ai-core/src/scheduler/scheduled-bridge-session.js +25 -11
- package/dist-electron/services/local-ai-core/src/thread/session-command-service.js +275 -0
- package/dist-electron/services/local-ai-core/src/thread/slash-command-registry.js +27 -0
- package/dist-electron/services/local-ai-core/src/thread/thread-command-service.js +15 -15
- package/dist-electron/shared/desktop.js +21 -1
- package/dist-electron/tests/contracts/local-core-contracts.test.js +9 -0
- package/dist-electron/tests/electron/automation-monitor.test.js +38 -0
- package/dist-electron/tests/electron/lac-cli.test.js +146 -0
- package/dist-electron/tests/integration/channel-gateways.test.js +32 -0
- package/dist-electron/tests/integration/lark-gateway.test.js +1918 -0
- package/dist-electron/tests/integration/local-core-acp-progress.test.js +1772 -0
- package/dist-electron/tests/integration/local-core-refactor.test.js +216 -4566
- package/dist-electron/tests/integration/local-core-routes.test.js +204 -0
- package/dist-electron/tests/integration/weixin-gateway.test.js +927 -0
- package/package.json +1 -1
- package/dist/renderer/assets/CronList-CKhggzYk.js +0 -1
- package/dist/renderer/assets/SessionChat-06Jny5_G.js +0 -1
- package/dist/renderer/assets/desktop-DXmXjjUR.js +0 -1
- package/dist/renderer/assets/desktop-O8_6ZCVZ.js +0 -4
- package/dist/renderer/assets/en-CKhCF6St.js +0 -1
- package/dist/renderer/assets/projects-xnW0fTtq.js +0 -1
- package/dist/renderer/assets/zh-Dz5FLTBV.js +0 -1
|
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildInteractiveCard = buildInteractiveCard;
|
|
4
4
|
exports.renderPermissionCard = renderPermissionCard;
|
|
5
5
|
exports.renderPendingPairingCard = renderPendingPairingCard;
|
|
6
|
+
exports.buildSessionCommandCard = buildSessionCommandCard;
|
|
6
7
|
exports.extractCardActionMessageId = extractCardActionMessageId;
|
|
7
8
|
exports.extractCardActionValue = extractCardActionValue;
|
|
9
|
+
exports.extractSessionCommandActionValue = extractSessionCommandActionValue;
|
|
8
10
|
exports.formatPermissionButtonLabel = formatPermissionButtonLabel;
|
|
9
11
|
exports.formatPermissionResponseLabel = formatPermissionResponseLabel;
|
|
10
12
|
const desktop_js_1 = require("../../../../../shared/desktop.js");
|
|
@@ -80,6 +82,37 @@ function renderPendingPairingCard(code) {
|
|
|
80
82
|
}
|
|
81
83
|
return lines.join('\n\n');
|
|
82
84
|
}
|
|
85
|
+
function buildSessionCommandCard(text, actionRows = [], sessionKey, threadId) {
|
|
86
|
+
const elements = [];
|
|
87
|
+
if (text) {
|
|
88
|
+
elements.push({ tag: 'markdown', content: text });
|
|
89
|
+
}
|
|
90
|
+
for (const row of actionRows) {
|
|
91
|
+
const actions = row
|
|
92
|
+
.filter((button) => button.label && button.command)
|
|
93
|
+
.map((button) => ({
|
|
94
|
+
tag: 'button',
|
|
95
|
+
text: {
|
|
96
|
+
tag: 'plain_text',
|
|
97
|
+
content: button.label,
|
|
98
|
+
},
|
|
99
|
+
type: button.type || 'default',
|
|
100
|
+
value: {
|
|
101
|
+
action: 'session_command',
|
|
102
|
+
command: button.command,
|
|
103
|
+
session_key: sessionKey || '',
|
|
104
|
+
thread_id: threadId || '',
|
|
105
|
+
},
|
|
106
|
+
}));
|
|
107
|
+
if (actions.length) {
|
|
108
|
+
elements.push({ tag: 'action', actions });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
config: { wide_screen_mode: true },
|
|
113
|
+
elements,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
83
116
|
function extractCardActionMessageId(...payloads) {
|
|
84
117
|
for (const payload of payloads) {
|
|
85
118
|
const messageId = extractKnownCardActionMessageId(payload);
|
|
@@ -117,6 +150,28 @@ function extractCardActionValue(payload) {
|
|
|
117
150
|
sessionKey,
|
|
118
151
|
};
|
|
119
152
|
}
|
|
153
|
+
function extractSessionCommandActionValue(payload) {
|
|
154
|
+
const event = (payload?.event && typeof payload.event === 'object')
|
|
155
|
+
? payload.event
|
|
156
|
+
: payload;
|
|
157
|
+
const value = event?.action?.value;
|
|
158
|
+
if (!value || value.action !== 'session_command') {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
const command = String(value.command || '').trim();
|
|
162
|
+
const threadId = String(value.thread_id || '').trim();
|
|
163
|
+
const sessionKey = String(value.session_key || '').trim();
|
|
164
|
+
if (!command || !threadId) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
event,
|
|
169
|
+
value: value,
|
|
170
|
+
command,
|
|
171
|
+
threadId,
|
|
172
|
+
sessionKey,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
120
175
|
function formatPermissionButtonLabel(button) {
|
|
121
176
|
return formatPermissionResponseLabel(button.data || button.text);
|
|
122
177
|
}
|
|
@@ -45,6 +45,8 @@ function collectLarkWorkspaceBindings(config, options) {
|
|
|
45
45
|
|| platform.options.card_actions === true
|
|
46
46
|
|| platform.options.enable_card_actions === true
|
|
47
47
|
|| options.defaultCardActionsEnabled,
|
|
48
|
+
groupReplyAll: String(platform.options.group_reply_all || '').trim().toLowerCase() === 'true'
|
|
49
|
+
|| platform.options.group_reply_all === true,
|
|
48
50
|
brand: String(platform.options.brand || platform.options.lark_brand || '').trim().toLowerCase() === 'lark' ? 'lark' : 'feishu',
|
|
49
51
|
enabled: Boolean(String(platform.options.app_id || '').trim() && String(platform.options.app_secret || '').trim()),
|
|
50
52
|
project,
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeLarkInboundMessageEvent = normalizeLarkInboundMessageEvent;
|
|
4
|
+
exports.isLarkBotMentioned = isLarkBotMentioned;
|
|
5
|
+
exports.stripLarkMentions = stripLarkMentions;
|
|
6
|
+
exports.summarizeLarkInboundPayload = summarizeLarkInboundPayload;
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
function normalizeLarkInboundMessageEvent(data, options = {}) {
|
|
9
|
+
const payload = (data?.event && typeof data.event === 'object')
|
|
10
|
+
? data.event
|
|
11
|
+
: data;
|
|
12
|
+
const message = payload?.message;
|
|
13
|
+
const sender = payload?.sender;
|
|
14
|
+
if (!message || !sender) {
|
|
15
|
+
return { ok: false, reason: 'missing-message-or-sender', detail: JSON.stringify(Object.keys(data || {})) };
|
|
16
|
+
}
|
|
17
|
+
let parsedContent = {};
|
|
18
|
+
try {
|
|
19
|
+
parsedContent = JSON.parse(String(message.content || '{}'));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
parsedContent = {};
|
|
23
|
+
}
|
|
24
|
+
const messageType = String(message.message_type || '').trim().toLowerCase();
|
|
25
|
+
const chatType = String(message.chat_type || '').trim().toLowerCase();
|
|
26
|
+
const mentions = Array.isArray(message.mentions) ? message.mentions : [];
|
|
27
|
+
const botOpenId = String(options.botOpenId || '').trim();
|
|
28
|
+
if (chatType === 'group' && !options.groupReplyAll && botOpenId && !isLarkBotMentioned(mentions, botOpenId)) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
reason: 'group-message-without-bot-mention',
|
|
32
|
+
detail: `chat=${String(message.chat_id || '')} message=${String(message.message_id || '')}`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const text = stripLarkMentions(String(parsedContent.text || '').trim(), mentions, botOpenId);
|
|
36
|
+
const platformUserId = String(sender.sender_id?.user_id || sender.sender_id?.open_id || '').trim();
|
|
37
|
+
const chatId = String(message.chat_id || platformUserId).trim();
|
|
38
|
+
if (!platformUserId || !chatId) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
reason: 'missing-sender-or-chat',
|
|
42
|
+
detail: `senderKeys=${JSON.stringify(Object.keys(sender?.sender_id || {}))} chat=${String(message.chat_id || '')}`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
ok: true,
|
|
47
|
+
message: {
|
|
48
|
+
payload,
|
|
49
|
+
message,
|
|
50
|
+
sender,
|
|
51
|
+
parsedContent,
|
|
52
|
+
messageType,
|
|
53
|
+
chatType,
|
|
54
|
+
mentions,
|
|
55
|
+
text,
|
|
56
|
+
platformUserId,
|
|
57
|
+
chatId,
|
|
58
|
+
displayName: String(sender.sender_id?.user_id ||
|
|
59
|
+
sender.sender_id?.open_id ||
|
|
60
|
+
`Lark ${platformUserId.slice(-6)}`),
|
|
61
|
+
messageId: String(message.message_id || (0, node_crypto_1.randomUUID)()),
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function isLarkBotMentioned(mentions, botOpenId) {
|
|
66
|
+
if (!botOpenId) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return mentions.some((mention) => {
|
|
70
|
+
const item = mention && typeof mention === 'object' ? mention : {};
|
|
71
|
+
return getMentionOpenId(item) === botOpenId;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function stripLarkMentions(text, mentions, botOpenId) {
|
|
75
|
+
let next = String(text || '');
|
|
76
|
+
for (const mention of mentions) {
|
|
77
|
+
const item = mention && typeof mention === 'object' ? mention : {};
|
|
78
|
+
const key = String(item.key || '').trim();
|
|
79
|
+
if (!key) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const openId = getMentionOpenId(item);
|
|
83
|
+
const name = String(item.name || item.display_name || item.displayName || '').trim();
|
|
84
|
+
if (botOpenId && openId === botOpenId) {
|
|
85
|
+
next = next.split(key).join('');
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
next = next.split(key).join(name ? `@${name}` : '');
|
|
89
|
+
}
|
|
90
|
+
return next.trim();
|
|
91
|
+
}
|
|
92
|
+
function summarizeLarkInboundPayload(payload) {
|
|
93
|
+
const eventPayload = (payload?.event && typeof payload.event === 'object')
|
|
94
|
+
? payload.event
|
|
95
|
+
: payload;
|
|
96
|
+
const message = eventPayload?.message || {};
|
|
97
|
+
const sender = eventPayload?.sender || {};
|
|
98
|
+
const senderId = sender?.sender_id || {};
|
|
99
|
+
const content = typeof message.content === 'string' ? message.content : '';
|
|
100
|
+
return [
|
|
101
|
+
`message=${String(message.message_id || '') || 'missing'}`,
|
|
102
|
+
`type=${String(message.message_type || '') || 'missing'}`,
|
|
103
|
+
`chat=${String(message.chat_id || '') || 'missing'}`,
|
|
104
|
+
`chatType=${String(message.chat_type || '') || 'missing'}`,
|
|
105
|
+
`sender=${String(senderId.user_id || senderId.open_id || '') || 'missing'}`,
|
|
106
|
+
`mentions=${Array.isArray(message.mentions) ? message.mentions.length : 0}`,
|
|
107
|
+
`contentBytes=${Buffer.byteLength(content, 'utf8')}`,
|
|
108
|
+
`keys=${JSON.stringify(Object.keys(eventPayload || {}))}`,
|
|
109
|
+
].join(' ');
|
|
110
|
+
}
|
|
111
|
+
function getMentionOpenId(item) {
|
|
112
|
+
const id = item.id || item.user_id || item.userId || {};
|
|
113
|
+
return String(id.open_id || id.openId || item.open_id || item.openId || '').trim();
|
|
114
|
+
}
|
|
@@ -41,11 +41,15 @@ const node_path_1 = require("node:path");
|
|
|
41
41
|
const desktop_js_1 = require("../../../../../shared/desktop.js");
|
|
42
42
|
const content_js_1 = require("../shared/content.js");
|
|
43
43
|
const file_utils_js_1 = require("../shared/file-utils.js");
|
|
44
|
+
const session_command_runtime_js_1 = require("../shared/session-command-runtime.js");
|
|
45
|
+
const thread_routing_js_1 = require("../shared/thread-routing.js");
|
|
44
46
|
const cards_js_1 = require("./cards.js");
|
|
45
47
|
const config_js_1 = require("./config.js");
|
|
46
48
|
const registration_js_1 = require("./registration.js");
|
|
47
49
|
const messages_js_1 = require("./rendering/messages.js");
|
|
50
|
+
const inbound_js_1 = require("./inbound.js");
|
|
48
51
|
const runtime_state_js_1 = require("./runtime-state.js");
|
|
52
|
+
const session_command_service_js_1 = require("../../thread/session-command-service.js");
|
|
49
53
|
const PAIRING_EXPIRY_MS = 10 * 60 * 1000;
|
|
50
54
|
const LARK_MAX_UPLOAD_FILE_SIZE = 30 * 1024 * 1024;
|
|
51
55
|
const LARK_FINAL_PATCH_INTERVAL_MS = 900;
|
|
@@ -62,12 +66,37 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
62
66
|
outboundEventChains = new Map();
|
|
63
67
|
outboundTurns = new Map();
|
|
64
68
|
mutedThreadBridgeCounts = new Map();
|
|
69
|
+
sessionCommandRuntime;
|
|
65
70
|
larkModulePromise = null;
|
|
66
71
|
platform = 'lark';
|
|
67
72
|
routeType = 'channel.chat';
|
|
68
73
|
constructor(options) {
|
|
69
74
|
super();
|
|
70
75
|
this.options = options;
|
|
76
|
+
const sessionCommandService = new session_command_service_js_1.SessionCommandService({
|
|
77
|
+
listThreads: (workspaceId) => this.options.getWorkspaceRouter().listThreads(workspaceId),
|
|
78
|
+
getThread: (threadId) => this.options.getWorkspaceRouter().getThread(threadId),
|
|
79
|
+
createThread: (workspaceId, title) => this.options.getWorkspaceRouter().createThread(workspaceId, title),
|
|
80
|
+
renameThread: (threadId, title) => this.options.getWorkspaceRouter().renameThread(threadId, title),
|
|
81
|
+
deleteThread: (threadId) => this.options.getWorkspaceRouter().deleteThread(threadId),
|
|
82
|
+
});
|
|
83
|
+
this.sessionCommandRuntime = new session_command_runtime_js_1.ChannelSessionCommandRuntime({
|
|
84
|
+
service: sessionCommandService,
|
|
85
|
+
store: this.options.store,
|
|
86
|
+
getThreadSessionKey: (threadId) => this.options.getWorkspaceRouter().getThreadSessionKey(threadId),
|
|
87
|
+
setThreadRoute: (sessionKey, route) => {
|
|
88
|
+
this.threadRouting.set(sessionKey, route);
|
|
89
|
+
},
|
|
90
|
+
createRoute: (input, threadId) => ({
|
|
91
|
+
workspaceId: input.workspaceId,
|
|
92
|
+
instanceId: input.instanceId,
|
|
93
|
+
platformKey: input.platformKey,
|
|
94
|
+
platformUserId: input.platformUserId,
|
|
95
|
+
chatId: input.chatId,
|
|
96
|
+
threadId,
|
|
97
|
+
}),
|
|
98
|
+
sendResult: (input, result) => this.sendSessionCommandResult(input, result),
|
|
99
|
+
});
|
|
71
100
|
}
|
|
72
101
|
async refreshBindings() {
|
|
73
102
|
const config = await this.options.readConfig();
|
|
@@ -97,6 +126,8 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
97
126
|
appId: binding.appId,
|
|
98
127
|
autoApprove: binding.autoApprove,
|
|
99
128
|
cardActionsEnabled: binding.cardActionsEnabled,
|
|
129
|
+
groupReplyAll: binding.groupReplyAll,
|
|
130
|
+
botOpenId: binding.botOpenId,
|
|
100
131
|
});
|
|
101
132
|
}
|
|
102
133
|
continue;
|
|
@@ -204,6 +235,17 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
204
235
|
}
|
|
205
236
|
};
|
|
206
237
|
}
|
|
238
|
+
async executeSessionCommand(input) {
|
|
239
|
+
return this.sessionCommandRuntime.execute(input);
|
|
240
|
+
}
|
|
241
|
+
async sendSessionCommandResult(input, result) {
|
|
242
|
+
const state = this.resolveRuntimeState(input.workspaceId, input.instanceId).state;
|
|
243
|
+
if (state?.client && state.connected && result.card?.actions?.length && state.cardActionsEnabled) {
|
|
244
|
+
await this.sendSessionCommandCard(state, input.chatId, result.displayText, result.card.actions, this.options.getWorkspaceRouter().getThreadSessionKey(input.currentThreadId), input.currentThreadId);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
await this.sendImmediateCard(input.workspaceId, input.chatId, result.displayText, input.instanceId);
|
|
248
|
+
}
|
|
207
249
|
async sendOutboundMessage(workspaceId, input) {
|
|
208
250
|
const state = this.resolveRuntimeState(workspaceId, input.route?.instanceId).state;
|
|
209
251
|
if (!state?.client || !state.connected) {
|
|
@@ -621,25 +663,17 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
621
663
|
return { paired: false };
|
|
622
664
|
}
|
|
623
665
|
const router = this.options.getWorkspaceRouter();
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
platform_user_id: input.platformUserId,
|
|
636
|
-
thread_id: threadId,
|
|
637
|
-
last_platform_message_id: null,
|
|
638
|
-
created_at: now,
|
|
639
|
-
updated_at: now,
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
const sessionKey = this.options.getWorkspaceRouter().getThreadSessionKey(threadId);
|
|
666
|
+
let { threadId } = await (0, thread_routing_js_1.resolveChannelThreadRoute)({
|
|
667
|
+
store: this.options.store,
|
|
668
|
+
router,
|
|
669
|
+
workspaceId: input.workspaceId,
|
|
670
|
+
platformKey,
|
|
671
|
+
chatId: input.chatId,
|
|
672
|
+
platformUserId: input.platformUserId,
|
|
673
|
+
displayName: input.displayName,
|
|
674
|
+
fallbackTitlePrefix: 'Lark',
|
|
675
|
+
authorized,
|
|
676
|
+
});
|
|
643
677
|
const normalizedText = String(input.text || '').trim().toLowerCase();
|
|
644
678
|
const permissionThreadId = (normalizedText === 'allow' || normalizedText === 'allow all' || normalizedText === 'deny')
|
|
645
679
|
? this.findAwaitingPermissionThreadId(input.workspaceId, input.chatId, input.platformUserId)
|
|
@@ -659,35 +693,18 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
659
693
|
const acknowledgement = this.createTurnState(effectiveSessionKey, input.messageId);
|
|
660
694
|
await this.addAcknowledgementReaction(input.workspaceId, input.messageId, acknowledgement, instanceId);
|
|
661
695
|
const slashCommand = this.parseSlashCommand(input.text);
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
chat_id: input.chatId,
|
|
675
|
-
platform_user_id: input.platformUserId,
|
|
676
|
-
thread_id: nextThread.id,
|
|
677
|
-
last_platform_message_id: null,
|
|
678
|
-
created_at: now,
|
|
679
|
-
updated_at: now,
|
|
680
|
-
});
|
|
681
|
-
this.threadRouting.set(this.options.getWorkspaceRouter().getThreadSessionKey(nextThread.id), {
|
|
682
|
-
workspaceId: input.workspaceId,
|
|
683
|
-
instanceId,
|
|
684
|
-
platformKey,
|
|
685
|
-
platformUserId: input.platformUserId,
|
|
686
|
-
chatId: input.chatId,
|
|
687
|
-
threadId: nextThread.id,
|
|
688
|
-
});
|
|
689
|
-
await this.sendImmediateCard(input.workspaceId, input.chatId, '**已开始新会话**', instanceId);
|
|
690
|
-
return { paired: true, threadId: nextThread.id };
|
|
696
|
+
const sessionCommand = await this.executeSessionCommand({
|
|
697
|
+
workspaceId: input.workspaceId,
|
|
698
|
+
currentThreadId: threadId,
|
|
699
|
+
text: input.text,
|
|
700
|
+
defaultTitle: `${input.displayName || 'Lark'} ${new Date().toLocaleTimeString()}`,
|
|
701
|
+
chatId: input.chatId,
|
|
702
|
+
platformUserId: input.platformUserId,
|
|
703
|
+
platformKey,
|
|
704
|
+
instanceId,
|
|
705
|
+
});
|
|
706
|
+
if (sessionCommand.handled) {
|
|
707
|
+
return { paired: true, threadId: sessionCommand.threadId || threadId };
|
|
691
708
|
}
|
|
692
709
|
const latestRun = this.options.store.getLatestRunForThread(threadId);
|
|
693
710
|
if ((normalizedText === 'allow' || normalizedText === 'allow all' || normalizedText === 'deny')
|
|
@@ -768,6 +785,8 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
768
785
|
appId: binding.appId,
|
|
769
786
|
autoApprove: binding.autoApprove,
|
|
770
787
|
cardActionsEnabled: binding.cardActionsEnabled,
|
|
788
|
+
groupReplyAll: binding.groupReplyAll,
|
|
789
|
+
botOpenId: binding.botOpenId,
|
|
771
790
|
};
|
|
772
791
|
this.runtime.set(key, status);
|
|
773
792
|
this.notifyRuntimeStateChanged();
|
|
@@ -780,6 +799,14 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
780
799
|
appType: mod.AppType.SelfBuild,
|
|
781
800
|
domain: mod.Domain.Feishu,
|
|
782
801
|
});
|
|
802
|
+
try {
|
|
803
|
+
status.botOpenId = await this.fetchBotOpenId(status);
|
|
804
|
+
binding.botOpenId = status.botOpenId;
|
|
805
|
+
this.options.log?.(`localcore-lark bot identified for ${binding.workspaceId}/${binding.instanceId}: ${status.botOpenId}`);
|
|
806
|
+
}
|
|
807
|
+
catch (error) {
|
|
808
|
+
this.options.log?.(`localcore-lark bot identity lookup failed for ${binding.workspaceId}/${binding.instanceId}; group mention filtering may be limited: ${error instanceof Error ? error.message : String(error)}`);
|
|
809
|
+
}
|
|
783
810
|
status.eventDispatcher = new mod.EventDispatcher({
|
|
784
811
|
encryptKey: binding.encryptKey || '',
|
|
785
812
|
verificationToken: binding.verificationToken || '',
|
|
@@ -854,6 +881,8 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
854
881
|
appId: state.appId,
|
|
855
882
|
autoApprove: state.autoApprove,
|
|
856
883
|
cardActionsEnabled: state.cardActionsEnabled,
|
|
884
|
+
groupReplyAll: state.groupReplyAll,
|
|
885
|
+
botOpenId: state.botOpenId,
|
|
857
886
|
});
|
|
858
887
|
this.notifyRuntimeStateChanged();
|
|
859
888
|
}
|
|
@@ -870,25 +899,17 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
870
899
|
const instanceId = legacyCall ? 'default' : instanceIdOrData;
|
|
871
900
|
const platformKey = legacyCall ? 'lark' : String(platformKeyOrData || (0, config_js_1.channelPlatformKey)('lark', instanceId));
|
|
872
901
|
const data = (legacyCall ? instanceIdOrData : maybeData) || {};
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
:
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
this.options.log?.(`localcore-lark handling message event for ${workspaceId}: ${
|
|
879
|
-
if (!
|
|
880
|
-
this.options.log?.(`localcore-lark ignored event
|
|
902
|
+
const runtimeState = this.resolveRuntimeState(workspaceId, instanceId).state;
|
|
903
|
+
const normalized = (0, inbound_js_1.normalizeLarkInboundMessageEvent)(data, {
|
|
904
|
+
botOpenId: runtimeState?.botOpenId,
|
|
905
|
+
groupReplyAll: runtimeState?.groupReplyAll,
|
|
906
|
+
});
|
|
907
|
+
this.options.log?.(`localcore-lark handling message event for ${workspaceId}: ${(0, inbound_js_1.summarizeLarkInboundPayload)(data)}`);
|
|
908
|
+
if (!normalized.ok) {
|
|
909
|
+
this.options.log?.(`localcore-lark ignored message event for ${workspaceId}: reason=${normalized.reason}${normalized.detail ? ` ${normalized.detail}` : ''}`);
|
|
881
910
|
return;
|
|
882
911
|
}
|
|
883
|
-
|
|
884
|
-
try {
|
|
885
|
-
parsedContent = JSON.parse(String(message.content || '{}'));
|
|
886
|
-
}
|
|
887
|
-
catch {
|
|
888
|
-
parsedContent = {};
|
|
889
|
-
}
|
|
890
|
-
const messageType = String(message.message_type || '').trim().toLowerCase();
|
|
891
|
-
const text = String(parsedContent.text || '').trim();
|
|
912
|
+
const { message, parsedContent, messageType, chatType, mentions, text, platformUserId, chatId, displayName, messageId, } = normalized.message;
|
|
892
913
|
const contentParts = [];
|
|
893
914
|
if (text) {
|
|
894
915
|
contentParts.push({ type: 'text', text });
|
|
@@ -924,24 +945,16 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
924
945
|
return;
|
|
925
946
|
}
|
|
926
947
|
const displayText = text || this.summarizeInboundContentParts(contentParts);
|
|
927
|
-
|
|
928
|
-
const chatId = String(message.chat_id || platformUserId).trim();
|
|
929
|
-
if (!platformUserId || !chatId) {
|
|
930
|
-
this.options.log?.(`localcore-lark ignored message without sender/chat for ${workspaceId}: senderKeys=${JSON.stringify(Object.keys(sender?.sender_id || {}))} chat=${String(message.chat_id || '')}`);
|
|
931
|
-
return;
|
|
932
|
-
}
|
|
933
|
-
this.options.log?.(`localcore-lark inbound message for ${workspaceId}: chat=${chatId} user=${platformUserId} type=${messageType || 'unknown'} text=${JSON.stringify(displayText.slice(0, 120))}`);
|
|
948
|
+
this.options.log?.(`localcore-lark inbound message for ${workspaceId}: chat=${chatId} user=${platformUserId} chatType=${chatType || 'unknown'} mentions=${mentions.length} type=${messageType || 'unknown'} text=${JSON.stringify(displayText.slice(0, 120))}`);
|
|
934
949
|
await this.handleInboundMessage({
|
|
935
950
|
workspaceId,
|
|
936
951
|
instanceId,
|
|
937
952
|
platformKey,
|
|
938
953
|
platformUserId,
|
|
939
954
|
chatId,
|
|
940
|
-
displayName
|
|
941
|
-
payload?.sender?.sender_id?.open_id ||
|
|
942
|
-
`Lark ${platformUserId.slice(-6)}`),
|
|
955
|
+
displayName,
|
|
943
956
|
text: displayText,
|
|
944
|
-
messageId
|
|
957
|
+
messageId,
|
|
945
958
|
contentParts,
|
|
946
959
|
});
|
|
947
960
|
}
|
|
@@ -1088,24 +1101,19 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1088
1101
|
}
|
|
1089
1102
|
}
|
|
1090
1103
|
summarizeLarkEvent(data) {
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
const
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
`chat=${String(message.chat_id || '') || 'missing'}`,
|
|
1105
|
-
`sender=${String(senderId.user_id || senderId.open_id || '') || 'missing'}`,
|
|
1106
|
-
`contentBytes=${Buffer.byteLength(content, 'utf8')}`,
|
|
1107
|
-
`keys=${JSON.stringify(Object.keys(payload || {}))}`,
|
|
1108
|
-
].join(' ');
|
|
1104
|
+
return (0, inbound_js_1.summarizeLarkInboundPayload)(data);
|
|
1105
|
+
}
|
|
1106
|
+
async fetchBotOpenId(state) {
|
|
1107
|
+
const response = await state.client.request({
|
|
1108
|
+
url: '/open-apis/bot/v3/info',
|
|
1109
|
+
method: 'GET',
|
|
1110
|
+
});
|
|
1111
|
+
const bot = response?.bot || response?.data?.bot;
|
|
1112
|
+
const openId = String(bot?.open_id || bot?.openId || '').trim();
|
|
1113
|
+
if (!openId) {
|
|
1114
|
+
throw new Error('Lark bot info response did not include bot.open_id');
|
|
1115
|
+
}
|
|
1116
|
+
return openId;
|
|
1109
1117
|
}
|
|
1110
1118
|
summarizeWsArgs(args) {
|
|
1111
1119
|
if (args.length === 0) {
|
|
@@ -1157,6 +1165,21 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1157
1165
|
this.options.log?.(`localcore-lark card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1158
1166
|
return String(response?.data?.message_id || '').trim();
|
|
1159
1167
|
}
|
|
1168
|
+
async sendSessionCommandCard(state, chatId, text, actionRows, sessionKey, threadId) {
|
|
1169
|
+
const startedAt = Date.now();
|
|
1170
|
+
const response = await state.client.im.message.create({
|
|
1171
|
+
params: {
|
|
1172
|
+
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1173
|
+
},
|
|
1174
|
+
data: {
|
|
1175
|
+
receive_id: chatId,
|
|
1176
|
+
msg_type: 'interactive',
|
|
1177
|
+
content: JSON.stringify((0, cards_js_1.buildSessionCommandCard)(text, actionRows, sessionKey, threadId)),
|
|
1178
|
+
},
|
|
1179
|
+
});
|
|
1180
|
+
this.options.log?.(`localcore-lark session card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1181
|
+
return String(response?.data?.message_id || '').trim();
|
|
1182
|
+
}
|
|
1160
1183
|
async sendTextAsMessage(state, chatId, text) {
|
|
1161
1184
|
const startedAt = Date.now();
|
|
1162
1185
|
const rendered = (0, messages_js_1.renderLarkTextMessage)(text);
|
|
@@ -1272,6 +1295,27 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1272
1295
|
const instanceId = legacyCall ? 'default' : instanceIdOrData;
|
|
1273
1296
|
const data = (legacyCall ? instanceIdOrData : maybeData) || {};
|
|
1274
1297
|
try {
|
|
1298
|
+
const sessionAction = (0, cards_js_1.extractSessionCommandActionValue)(data);
|
|
1299
|
+
if (sessionAction) {
|
|
1300
|
+
const route = this.threadRouting.get(sessionAction.sessionKey)
|
|
1301
|
+
|| this.routeFromThreadBinding(sessionAction.threadId, instanceId);
|
|
1302
|
+
if (!route) {
|
|
1303
|
+
this.options.log?.(`localcore-lark session card action ignored without route for thread=${sessionAction.threadId}`);
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
await this.executeSessionCommand({
|
|
1307
|
+
workspaceId,
|
|
1308
|
+
currentThreadId: sessionAction.threadId,
|
|
1309
|
+
text: sessionAction.command,
|
|
1310
|
+
defaultTitle: `Lark ${new Date().toLocaleTimeString()}`,
|
|
1311
|
+
chatId: route.chatId,
|
|
1312
|
+
platformUserId: route.platformUserId,
|
|
1313
|
+
platformKey: route.platformKey,
|
|
1314
|
+
instanceId: route.instanceId,
|
|
1315
|
+
});
|
|
1316
|
+
this.options.log?.(`localcore-lark processed session card action for ${workspaceId}/${instanceId}: ${sessionAction.command}`);
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1275
1319
|
const action = (0, cards_js_1.extractCardActionValue)(data);
|
|
1276
1320
|
if (!action) {
|
|
1277
1321
|
return;
|
|
@@ -1285,6 +1329,21 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1285
1329
|
this.options.log?.(`localcore-lark card action failed for ${workspaceId}/${instanceId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1286
1330
|
}
|
|
1287
1331
|
}
|
|
1332
|
+
routeFromThreadBinding(threadId, instanceId) {
|
|
1333
|
+
const binding = this.options.store.getPlatformThreadBindingByThreadId(threadId);
|
|
1334
|
+
if (!binding || (binding.platform !== 'lark' && !binding.platform.startsWith('lark:'))) {
|
|
1335
|
+
return undefined;
|
|
1336
|
+
}
|
|
1337
|
+
const bindingInstanceId = getLarkInstanceId(binding.platform) || instanceId || 'default';
|
|
1338
|
+
return {
|
|
1339
|
+
workspaceId: binding.workspace_id,
|
|
1340
|
+
instanceId: bindingInstanceId,
|
|
1341
|
+
platformKey: binding.platform,
|
|
1342
|
+
platformUserId: binding.platform_user_id,
|
|
1343
|
+
chatId: binding.chat_id,
|
|
1344
|
+
threadId: binding.thread_id,
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1288
1347
|
async markPermissionCardActionHandled(workspaceId, instanceId, rootPayload, payload, value, response, threadId) {
|
|
1289
1348
|
const state = this.resolveRuntimeState(workspaceId, instanceId).state;
|
|
1290
1349
|
if (!state?.client) {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChannelSessionCommandRuntime = void 0;
|
|
4
|
+
class ChannelSessionCommandRuntime {
|
|
5
|
+
options;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = options;
|
|
8
|
+
}
|
|
9
|
+
async execute(input) {
|
|
10
|
+
const result = await this.options.service.execute(input.text, {
|
|
11
|
+
workspaceId: input.workspaceId,
|
|
12
|
+
currentThreadId: input.currentThreadId,
|
|
13
|
+
defaultTitle: input.defaultTitle,
|
|
14
|
+
});
|
|
15
|
+
if (!result.handled) {
|
|
16
|
+
return { handled: false, threadId: input.currentThreadId };
|
|
17
|
+
}
|
|
18
|
+
let activeThreadId = input.currentThreadId;
|
|
19
|
+
for (const effect of result.effects || []) {
|
|
20
|
+
if (effect.type === 'created_thread') {
|
|
21
|
+
this.inheritAgentMode(input.currentThreadId, effect.threadId);
|
|
22
|
+
}
|
|
23
|
+
if (effect.type === 'activate_thread') {
|
|
24
|
+
activeThreadId = effect.threadId;
|
|
25
|
+
this.activateThread(input, effect.threadId);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
await this.options.sendResult(input, result);
|
|
29
|
+
return { handled: true, threadId: activeThreadId, result };
|
|
30
|
+
}
|
|
31
|
+
inheritAgentMode(sourceThreadId, targetThreadId) {
|
|
32
|
+
const inheritedMode = this.options.store.getThreadRow?.(sourceThreadId)?.agent_mode || '';
|
|
33
|
+
if (inheritedMode && inheritedMode !== 'default') {
|
|
34
|
+
this.options.store.updateThreadAgentMode?.(targetThreadId, inheritedMode);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
activateThread(input, threadId) {
|
|
38
|
+
const now = new Date().toISOString();
|
|
39
|
+
this.options.store.updateAuthorizedUserThread(input.workspaceId, input.platformUserId, threadId, input.platformKey);
|
|
40
|
+
this.options.store.upsertPlatformThreadBinding({
|
|
41
|
+
workspace_id: input.workspaceId,
|
|
42
|
+
platform: input.platformKey,
|
|
43
|
+
chat_id: input.chatId,
|
|
44
|
+
platform_user_id: input.platformUserId,
|
|
45
|
+
thread_id: threadId,
|
|
46
|
+
last_platform_message_id: null,
|
|
47
|
+
created_at: now,
|
|
48
|
+
updated_at: now,
|
|
49
|
+
});
|
|
50
|
+
this.options.setThreadRoute(this.options.getThreadSessionKey(threadId), this.options.createRoute(input, threadId));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.ChannelSessionCommandRuntime = ChannelSessionCommandRuntime;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveChannelThreadRoute = resolveChannelThreadRoute;
|
|
4
|
+
async function resolveChannelThreadRoute(input) {
|
|
5
|
+
const threadBinding = input.store.getPlatformThreadBinding(input.workspaceId, input.chatId, input.platformUserId, input.platformKey);
|
|
6
|
+
let threadId = threadBinding?.thread_id || (input.authorized.chat_id === input.chatId ? input.authorized.thread_id : '') || '';
|
|
7
|
+
let createdThread = false;
|
|
8
|
+
if (!threadId) {
|
|
9
|
+
const thread = await input.router.createThread(input.workspaceId, input.displayName || `${input.fallbackTitlePrefix} ${input.chatId}`);
|
|
10
|
+
threadId = thread.id;
|
|
11
|
+
createdThread = true;
|
|
12
|
+
input.store.updateAuthorizedUserThread(input.workspaceId, input.platformUserId, threadId, input.platformKey);
|
|
13
|
+
}
|
|
14
|
+
let createdBinding = false;
|
|
15
|
+
if (!threadBinding) {
|
|
16
|
+
const now = new Date().toISOString();
|
|
17
|
+
input.store.upsertPlatformThreadBinding({
|
|
18
|
+
workspace_id: input.workspaceId,
|
|
19
|
+
platform: input.platformKey,
|
|
20
|
+
chat_id: input.chatId,
|
|
21
|
+
platform_user_id: input.platformUserId,
|
|
22
|
+
thread_id: threadId,
|
|
23
|
+
last_platform_message_id: null,
|
|
24
|
+
created_at: now,
|
|
25
|
+
updated_at: now,
|
|
26
|
+
});
|
|
27
|
+
createdBinding = true;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
threadId,
|
|
31
|
+
createdThread,
|
|
32
|
+
createdBinding,
|
|
33
|
+
};
|
|
34
|
+
}
|