@kafca/agentdock 0.1.55 → 0.1.57
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 -0
- package/dist/renderer/assets/{Badge-Bg_nNvBL.js → Badge-CDTbmw1h.js} +1 -1
- package/dist/renderer/assets/Card-DayUo35w.js +1 -0
- package/dist/renderer/assets/Config-ByGMQuzR.js +21 -0
- package/dist/renderer/assets/CronList-XqHdVlgu.js +1 -0
- package/dist/renderer/assets/Dashboard-CZj-oANw.js +41 -0
- package/dist/renderer/assets/{EmptyState-C60g3RMj.js → EmptyState-EFMkOjZO.js} +1 -1
- package/dist/renderer/assets/HighlightedMarkdown-DyvF3DHK.js +12 -0
- package/dist/renderer/assets/Input-DxoWVc9d.js +1 -0
- package/dist/renderer/assets/{KnowledgeDetail-CC5C7JYe.js → KnowledgeDetail-CbUb2tG7.js} +2 -2
- package/dist/renderer/assets/{KnowledgeHome-3rlvxgWf.js → KnowledgeHome-BWV1gz4f.js} +3 -3
- package/dist/renderer/assets/Logs-DqnanQTc.js +6 -0
- package/dist/renderer/assets/{Modal-BQUW9LSf.js → Modal-yY7TzR0x.js} +3 -3
- package/dist/renderer/assets/MonitorList-CIjGQkFs.js +1 -0
- package/dist/renderer/assets/Page-vwHNUdoj.js +1 -0
- package/dist/renderer/assets/{Select-CfRkos3z.js → Select-CmbK36pN.js} +2 -2
- package/dist/renderer/assets/ThreadChat-4OceMgM4.js +86 -0
- package/dist/renderer/assets/Workspace-DplPJOjJ.js +19 -0
- package/dist/renderer/assets/{arrow-left-D1DbXrLA.js → arrow-left-C8HfBt2K.js} +1 -1
- package/dist/renderer/assets/{book-open-BxC1z1C1.js → book-open-BCdZWncQ.js} +1 -1
- package/dist/renderer/assets/channels-hgO3cAIx.js +6 -0
- package/dist/renderer/assets/chevron-down-BPk77tqY.js +11 -0
- package/dist/renderer/assets/index-BIKL3fTP.css +11 -0
- package/dist/renderer/assets/index-BlA4xPdd.js +41 -0
- package/dist/renderer/assets/index-wYpjqVqC.js +167 -0
- package/dist/renderer/assets/knowledge-7pl06KuH.js +1 -0
- package/dist/renderer/assets/{pencil-X44UaxwR.js → pencil-CB1SWZ9A.js} +1 -1
- package/dist/renderer/assets/{play-ujo-De38.js → play-BvsoXUrM.js} +1 -1
- package/dist/renderer/assets/{plus-BHgVdG_A.js → plus-CokBDnaL.js} +1 -1
- package/dist/renderer/assets/{save-Cz6giKrE.js → save-D-w4kATO.js} +1 -1
- package/dist/renderer/assets/{search-DKWvTqi5.js → search-Cnsn6i4Q.js} +1 -1
- package/dist/renderer/assets/{shield-check-V82O8AC1.js → shield-check-Cjja2Gh6.js} +1 -1
- package/dist/renderer/assets/threads-BCm6j4eI.js +1 -0
- package/dist/renderer/assets/{trash-2-_Fgwk8mc.js → trash-2-CIxz9qYY.js} +1 -1
- package/dist/renderer/index.html +2 -2
- package/dist-electron/packages/contracts/src/automation.js +2 -0
- package/dist-electron/packages/contracts/src/channels.js +2 -0
- package/dist-electron/packages/contracts/src/knowledge.js +2 -0
- package/dist-electron/packages/contracts/src/local-core.js +15 -0
- package/dist-electron/packages/contracts/src/runtime.js +2 -0
- package/dist-electron/packages/contracts/src/scheduler.js +2 -0
- package/dist-electron/packages/contracts/src/threads.js +2 -0
- package/dist-electron/packages/core-sdk/src/automation.js +32 -0
- package/dist-electron/packages/core-sdk/src/channels.js +121 -0
- package/dist-electron/packages/core-sdk/src/client.js +455 -0
- package/dist-electron/packages/core-sdk/src/index.js +43 -607
- package/dist-electron/packages/core-sdk/src/knowledge.js +85 -0
- package/dist-electron/packages/core-sdk/src/request.js +22 -0
- package/dist-electron/packages/core-sdk/src/runtime.js +214 -0
- package/dist-electron/packages/core-sdk/src/scheduler.js +32 -0
- package/dist-electron/packages/core-sdk/src/threads.js +67 -0
- package/dist-electron/packages/plugin-sdk/src/agents.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/automation.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/channels.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/index.js +21 -0
- package/dist-electron/packages/plugin-sdk/src/knowledge.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/runtime.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/scheduler.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/threads.js +2 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +6 -9
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-content.js +2 -2
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +3 -3
- package/dist-electron/services/local-ai-core/src/acp/store/agent-task-store.js +5 -5
- package/dist-electron/services/local-ai-core/src/acp/store/automation-monitor-store.js +12 -12
- package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +2 -2
- package/dist-electron/services/local-ai-core/src/acp/store/scheduler-store.js +11 -11
- package/dist-electron/services/local-ai-core/src/acp/store/security-store.js +3 -3
- package/dist-electron/services/local-ai-core/src/acp/store/thread-store.js +7 -7
- package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/claudecode/definition.js +3 -3
- package/dist-electron/services/local-ai-core/src/agents/codex/definition.js +3 -3
- package/dist-electron/services/local-ai-core/src/agents/localcore-acp/definition.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/localcore-acp/index.js +4 -4
- package/dist-electron/services/local-ai-core/src/agents/opencode/launch.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/pi/definition.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +3 -3
- package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +1 -1
- package/dist-electron/services/local-ai-core/src/agents/shared/agent-plugin.js +4 -4
- package/dist-electron/services/local-ai-core/src/channel/lark/cards.js +33 -18
- package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -2
- package/dist-electron/services/local-ai-core/src/channel/lark/gateway-utils.js +91 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/inbound-handler.js +180 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +52 -456
- package/dist-electron/services/local-ai-core/src/channel/lark/outbound-transport.js +124 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/inbound-attachment-store.js +93 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/inbound-authorization.js +54 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/config.js +2 -2
- package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-media.js +21 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-poller.js +167 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +98 -483
- package/dist-electron/services/local-ai-core/src/channel/weixin/runtime-state.js +156 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/text-utils.js +100 -0
- package/dist-electron/services/local-ai-core/src/cli/lac.js +6 -6
- package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +2 -2
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +28 -70
- package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +33 -5
- package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-ai-vector-plugin.js +2 -2
- package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-noop-plugin.js +2 -2
- package/dist-electron/services/local-ai-core/src/router/workspace-bridge-event-stream.js +29 -0
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +5 -5
- package/dist-electron/services/local-ai-core/src/router/workspace-router.js +47 -60
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -5
- package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +6 -6
- package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +3 -3
- package/dist-electron/services/local-ai-core/src/runtime/external-service.js +3 -1
- package/dist-electron/services/local-ai-core/src/runtime/handlers/automation-handler.js +11 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/channel-handler.js +12 -6
- package/dist-electron/services/local-ai-core/src/runtime/handlers/external-handler.js +10 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/knowledge-handler.js +18 -6
- package/dist-electron/services/local-ai-core/src/runtime/handlers/provider-handler.js +7 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +28 -3
- package/dist-electron/services/local-ai-core/src/runtime/handlers/scheduler-handler.js +10 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/security-handler.js +18 -5
- package/dist-electron/services/local-ai-core/src/runtime/handlers/task-handler.js +14 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/thread-handler.js +18 -15
- package/dist-electron/services/local-ai-core/src/runtime/handlers/workspace-handler.js +13 -2
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +35 -8
- package/dist-electron/services/local-ai-core/src/runtime/request-validation.js +79 -0
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +9 -9
- package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +10 -1
- package/dist-electron/services/local-ai-core/src/runtime/server.js +2 -1
- package/dist-electron/services/local-ai-core/src/runtime/workspace-project-registry.js +76 -0
- package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +8 -8
- package/dist-electron/services/local-ai-core/src/thread/agent-message-policy.js +75 -0
- package/dist-electron/shared/desktop.js +1 -64
- package/dist-electron/src/components/chat/chat-controller-state.js +60 -0
- package/dist-electron/src/components/chat/chat-event-gate.js +146 -0
- package/dist-electron/src/components/chat/markdown-code-block.js +8 -0
- package/dist-electron/src/pages/Desktop/workspace-model.js +212 -0
- package/dist-electron/src/pages/Threads/thread-chat-model.js +50 -51
- package/dist-electron/tests/contracts/agent-message-policy.test.js +21 -0
- package/dist-electron/tests/contracts/architecture-docs.test.js +56 -33
- package/dist-electron/tests/contracts/chat-event-gate.test.js +114 -0
- package/dist-electron/tests/contracts/chat-markdown.test.js +16 -0
- package/dist-electron/tests/contracts/thread-task-state.test.js +32 -0
- package/dist-electron/tests/contracts/workspace-identity.test.js +23 -0
- package/dist-electron/tests/electron/core-client.test.js +284 -0
- package/dist-electron/tests/electron/plugin-kernel.test.js +54 -0
- package/dist-electron/tests/electron/renderer-packaging.test.js +9 -0
- package/dist-electron/tests/electron/workspace-task-store.test.js +31 -0
- package/dist-electron/tests/integration/channel-inbound-attachment-store.test.js +117 -0
- package/dist-electron/tests/integration/channel-inbound-authorization.test.js +80 -0
- package/dist-electron/tests/integration/lark-gateway-utils.test.js +13 -0
- package/dist-electron/tests/integration/lark-gateway.test.js +58 -4
- package/dist-electron/tests/integration/local-core-errors.test.js +41 -0
- package/dist-electron/tests/integration/weixin-gateway.test.js +36 -0
- package/dist-electron/tests/integration/weixin-runtime-state.test.js +32 -0
- package/dist-electron/tests/integration/weixin-text-utils.test.js +15 -0
- package/package.json +9 -4
- package/dist/renderer/assets/Chat-BJveQQKu.js +0 -2
- package/dist/renderer/assets/ChatMarkdown-Bqn2HJ6f.js +0 -45
- package/dist/renderer/assets/Config-CMtZDRAE.js +0 -21
- package/dist/renderer/assets/CronList-C-ILB_Ae.js +0 -1
- package/dist/renderer/assets/Dashboard-CsKBSQIe.js +0 -26
- package/dist/renderer/assets/Logs-CktemGN0.js +0 -1
- package/dist/renderer/assets/MonitorList-B0hxjuOZ.js +0 -1
- package/dist/renderer/assets/Page-DL_Nv2i5.js +0 -1
- package/dist/renderer/assets/ProjectDetail-Djr9-MyT.js +0 -11
- package/dist/renderer/assets/ProjectList-BKl4eW7q.js +0 -1
- package/dist/renderer/assets/SessionChat-Dxv8D5DW.js +0 -1
- package/dist/renderer/assets/SessionList-BJ2GjXvR.js +0 -1
- package/dist/renderer/assets/ThreadChat-CAsIl9qf.js +0 -28
- package/dist/renderer/assets/Workspace-CaUhiGBX.js +0 -19
- package/dist/renderer/assets/bot-Fw3IzhJA.js +0 -6
- package/dist/renderer/assets/check-5zCTgp3A.js +0 -6
- package/dist/renderer/assets/chevron-down-N3PxTNxH.js +0 -6
- package/dist/renderer/assets/circle-C_chUflo.js +0 -6
- package/dist/renderer/assets/desktop-DkQTZNhe.js +0 -1
- package/dist/renderer/assets/desktop-JQkhNOF4.js +0 -5
- package/dist/renderer/assets/funnel-B8ZAv6I7.js +0 -6
- package/dist/renderer/assets/heart-M9A3E4Ed.js +0 -6
- package/dist/renderer/assets/index-Bwv855ID.js +0 -41
- package/dist/renderer/assets/index-CjCuR6DI.css +0 -11
- package/dist/renderer/assets/index-DJ8w4e0l.js +0 -182
- package/dist/renderer/assets/projects-DB1FLZ3A.js +0 -1
- package/dist/renderer/assets/server-BsuHcYl4.js +0 -11
- package/dist/renderer/assets/session-utils-DnAWL3eo.js +0 -6
- package/dist/renderer/assets/sessions-DptxO_BE.js +0 -1
- package/dist/renderer/assets/user-DQKTaUcR.js +0 -6
- package/dist/renderer/assets/wifi-off-vjH-MD2w.js +0 -11
- package/dist-electron/src/api/client.js +0 -73
- package/dist-electron/src/api/sessions.js +0 -21
- package/dist-electron/src/lib/session-utils.js +0 -51
- package/dist-electron/src/pages/Projects/project-provider-config.js +0 -75
- package/dist-electron/tests/electron/project-provider-config.test.js +0 -71
|
@@ -35,25 +35,20 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.LocalCoreLarkGateway = void 0;
|
|
37
37
|
const node_crypto_1 = require("node:crypto");
|
|
38
|
-
const node_fs_1 = require("node:fs");
|
|
39
|
-
const promises_1 = require("node:fs/promises");
|
|
40
|
-
const node_path_1 = require("node:path");
|
|
41
|
-
const promises_2 = require("node:stream/promises");
|
|
42
38
|
const local_core_errors_js_1 = require("../../kernel/local-core-errors.js");
|
|
43
|
-
const desktop_js_1 = require("../../../../../shared/desktop.js");
|
|
44
39
|
const content_js_1 = require("../shared/content.js");
|
|
45
|
-
const file_utils_js_1 = require("../shared/file-utils.js");
|
|
46
40
|
const thread_routing_js_1 = require("../shared/thread-routing.js");
|
|
47
41
|
const base_channel_gateway_js_1 = require("../shared/base-channel-gateway.js");
|
|
42
|
+
const inbound_authorization_js_1 = require("../shared/inbound-authorization.js");
|
|
48
43
|
const cards_js_1 = require("./cards.js");
|
|
49
44
|
const channel_keys_js_1 = require("../shared/channel-keys.js");
|
|
50
45
|
const config_js_1 = require("./config.js");
|
|
51
46
|
const registration_js_1 = require("./registration.js");
|
|
52
|
-
const messages_js_1 = require("./rendering/messages.js");
|
|
53
47
|
const inbound_js_1 = require("./inbound.js");
|
|
48
|
+
const inbound_handler_js_1 = require("./inbound-handler.js");
|
|
49
|
+
const outbound_transport_js_1 = require("./outbound-transport.js");
|
|
54
50
|
const runtime_state_js_1 = require("./runtime-state.js");
|
|
55
|
-
const
|
|
56
|
-
const LARK_MAX_UPLOAD_FILE_SIZE = 30 * 1024 * 1024;
|
|
51
|
+
const gateway_utils_js_1 = require("./gateway-utils.js");
|
|
57
52
|
const LARK_FINAL_PATCH_INTERVAL_MS = 900;
|
|
58
53
|
const LARK_PROGRESS_PATCH_INTERVAL_MS = 3000;
|
|
59
54
|
const LARK_EMPTY_RENDER_LOG_WINDOW_MS = 5 * 60 * 1000;
|
|
@@ -65,9 +60,20 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
65
60
|
mirrorPermissionStateInMainCard = false;
|
|
66
61
|
larkModulePromise = null;
|
|
67
62
|
emptyRenderLogWindows = new Map();
|
|
63
|
+
inboundHandler;
|
|
64
|
+
outboundTransport;
|
|
68
65
|
platform = 'lark';
|
|
69
66
|
constructor(options) {
|
|
70
67
|
super(options);
|
|
68
|
+
this.inboundHandler = new inbound_handler_js_1.LarkInboundHandler({
|
|
69
|
+
store: options.store,
|
|
70
|
+
getWorkspaceRouter: options.getWorkspaceRouter,
|
|
71
|
+
getRuntimeState: (workspaceId, instanceId) => this.resolveRuntimeState(workspaceId, instanceId).state,
|
|
72
|
+
getBinding: (workspaceId, instanceId) => this.getBinding(workspaceId, instanceId),
|
|
73
|
+
dispatchInboundMessage: (message) => this.handleInboundMessage(message),
|
|
74
|
+
log: options.log,
|
|
75
|
+
});
|
|
76
|
+
this.outboundTransport = new outbound_transport_js_1.LarkOutboundTransport(options.log);
|
|
71
77
|
}
|
|
72
78
|
// ==================== Lifecycle (platform-specific) ====================
|
|
73
79
|
async testConnection(workspaceId, instanceId) {
|
|
@@ -160,7 +166,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
160
166
|
async sendSessionCommandResult(input, result) {
|
|
161
167
|
const state = this.resolveRuntimeState(input.workspaceId, input.instanceId).state;
|
|
162
168
|
if (state?.client && state.connected && result.card?.actions?.length && state.cardActionsEnabled) {
|
|
163
|
-
await this.sendSessionCommandCard(state, input.chatId, result.displayText, result.card.actions, this.options.getWorkspaceRouter().getThreadSessionKey(input.currentThreadId), input.currentThreadId);
|
|
169
|
+
await this.outboundTransport.sendSessionCommandCard(state, input.chatId, result.displayText, result.card.actions, this.options.getWorkspaceRouter().getThreadSessionKey(input.currentThreadId), input.currentThreadId);
|
|
164
170
|
return;
|
|
165
171
|
}
|
|
166
172
|
await this.sendImmediateCard(input.workspaceId, input.chatId, result.displayText, input.instanceId);
|
|
@@ -185,7 +191,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
185
191
|
continue;
|
|
186
192
|
}
|
|
187
193
|
if (part.type === 'file') {
|
|
188
|
-
const sent = await this.sendFilePart(state, channelId, part);
|
|
194
|
+
const sent = await this.outboundTransport.sendFilePart(state, channelId, part);
|
|
189
195
|
messageIds.push(sent.messageId);
|
|
190
196
|
attachments.push({
|
|
191
197
|
kind: 'file',
|
|
@@ -231,46 +237,6 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
231
237
|
fileSize: attachment?.fileSize || 0,
|
|
232
238
|
};
|
|
233
239
|
}
|
|
234
|
-
async sendFilePart(state, channelId, part) {
|
|
235
|
-
const file = await (0, file_utils_js_1.prepareChannelFile)({
|
|
236
|
-
path: part.path,
|
|
237
|
-
fileName: part.fileName,
|
|
238
|
-
workspacePath: typeof part.metadata?.workspacePath === 'string' ? part.metadata.workspacePath : undefined,
|
|
239
|
-
maxBytes: LARK_MAX_UPLOAD_FILE_SIZE,
|
|
240
|
-
platformLabel: 'Lark',
|
|
241
|
-
});
|
|
242
|
-
const upload = await state.client.im.file.create({
|
|
243
|
-
data: {
|
|
244
|
-
file_type: this.resolveLarkUploadFileType(file.fileName),
|
|
245
|
-
file_name: file.fileName,
|
|
246
|
-
file: (0, node_fs_1.createReadStream)(file.path),
|
|
247
|
-
},
|
|
248
|
-
});
|
|
249
|
-
const fileKey = String(upload?.file_key || upload?.data?.file_key || '').trim();
|
|
250
|
-
if (!fileKey) {
|
|
251
|
-
throw new Error('Lark file upload did not return a file key');
|
|
252
|
-
}
|
|
253
|
-
const response = await state.client.im.message.create({
|
|
254
|
-
params: {
|
|
255
|
-
receive_id_type: this.resolveReceiveIdType(channelId),
|
|
256
|
-
},
|
|
257
|
-
data: {
|
|
258
|
-
receive_id: channelId,
|
|
259
|
-
msg_type: 'file',
|
|
260
|
-
content: JSON.stringify({ file_key: fileKey }),
|
|
261
|
-
},
|
|
262
|
-
});
|
|
263
|
-
const messageId = String(response?.data?.message_id || '').trim();
|
|
264
|
-
if (!messageId) {
|
|
265
|
-
throw new Error('Lark file message did not return a message id');
|
|
266
|
-
}
|
|
267
|
-
this.options.log?.(`localcore-lark sent file ${file.fileName} (${file.fileSize} bytes) to ${channelId}`);
|
|
268
|
-
return {
|
|
269
|
-
messageId,
|
|
270
|
-
fileKey,
|
|
271
|
-
file,
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
240
|
async onBridgeEvent(event) {
|
|
275
241
|
if (!event.sessionKey) {
|
|
276
242
|
this.options.log?.(`localcore-lark bridge event ignored without sessionKey: ${event.type}`);
|
|
@@ -327,7 +293,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
327
293
|
}
|
|
328
294
|
if (event.type === 'typing_start' && (turn.permissionMessageId || turn.awaitingPermission)) {
|
|
329
295
|
if (turn.permissionMessageId) {
|
|
330
|
-
await this.patchTextCard(state, turn.permissionMessageId, '**工具确认已处理**\n\n继续生成中...', [], sessionKey, bridgeThreadId);
|
|
296
|
+
await this.outboundTransport.patchTextCard(state, turn.permissionMessageId, '**工具确认已处理**\n\n继续生成中...', [], sessionKey, bridgeThreadId);
|
|
331
297
|
}
|
|
332
298
|
turn.permissionMessageId = undefined;
|
|
333
299
|
turn.awaitingPermission = false;
|
|
@@ -340,14 +306,14 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
340
306
|
const permissionCard = (0, cards_js_1.renderPermissionCard)(turn, event, Boolean(state.cardActionsEnabled));
|
|
341
307
|
if (permissionCard.text || permissionCard.buttonRows.length > 0) {
|
|
342
308
|
if (!turn.permissionMessageId) {
|
|
343
|
-
const createdId = await this.sendTextAsCard(state, route.chatId, permissionCard.text, permissionCard.buttonRows, sessionKey, bridgeThreadId);
|
|
309
|
+
const createdId = await this.outboundTransport.sendTextAsCard(state, route.chatId, permissionCard.text, permissionCard.buttonRows, sessionKey, bridgeThreadId);
|
|
344
310
|
if (createdId) {
|
|
345
311
|
turn.permissionMessageId = createdId;
|
|
346
312
|
this.options.log?.(`localcore-lark sent permission card ${createdId} for sessionKey=${sessionKey}`);
|
|
347
313
|
}
|
|
348
314
|
}
|
|
349
315
|
else {
|
|
350
|
-
await this.patchTextCard(state, turn.permissionMessageId, permissionCard.text, permissionCard.buttonRows, sessionKey, bridgeThreadId);
|
|
316
|
+
await this.outboundTransport.patchTextCard(state, turn.permissionMessageId, permissionCard.text, permissionCard.buttonRows, sessionKey, bridgeThreadId);
|
|
351
317
|
this.options.log?.(`localcore-lark patched permission card ${turn.permissionMessageId} for sessionKey=${sessionKey}`);
|
|
352
318
|
}
|
|
353
319
|
}
|
|
@@ -376,7 +342,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
376
342
|
const sentMessage = sendAsPlainMessage
|
|
377
343
|
? await this.sendTextAsMessage(state, route.chatId, renderedMessage.text)
|
|
378
344
|
: {
|
|
379
|
-
messageId: await this.sendTextAsCard(state, route.chatId, renderedMessage.text, renderedMessage.buttonRows, sessionKey, bridgeThreadId),
|
|
345
|
+
messageId: await this.outboundTransport.sendTextAsCard(state, route.chatId, renderedMessage.text, renderedMessage.buttonRows, sessionKey, bridgeThreadId),
|
|
380
346
|
renderKind: 'card',
|
|
381
347
|
};
|
|
382
348
|
const createdId = sentMessage.messageId;
|
|
@@ -392,7 +358,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
392
358
|
if (renderedMessage.delivery === 'message') {
|
|
393
359
|
continue;
|
|
394
360
|
}
|
|
395
|
-
await this.patchTextCard(state, existingMessageId, renderedMessage.text, renderedMessage.buttonRows, sessionKey, bridgeThreadId);
|
|
361
|
+
await this.outboundTransport.patchTextCard(state, existingMessageId, renderedMessage.text, renderedMessage.buttonRows, sessionKey, bridgeThreadId);
|
|
396
362
|
turn.lastPatchedAt = Date.now();
|
|
397
363
|
turn.lastPatchedAtByMessageId[existingMessageId] = turn.lastPatchedAt;
|
|
398
364
|
this.options.log?.(`localcore-lark patched card message ${existingMessageId} for sessionKey=${sessionKey}`);
|
|
@@ -426,7 +392,6 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
426
392
|
messageId: msg.messageId,
|
|
427
393
|
},
|
|
428
394
|
});
|
|
429
|
-
this.options.store.expirePendingPairings();
|
|
430
395
|
const runtimeState = this.resolveRuntimeState(msg.workspaceId, instanceId).state;
|
|
431
396
|
let binding;
|
|
432
397
|
try {
|
|
@@ -438,47 +403,28 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
438
403
|
}
|
|
439
404
|
this.options.log?.(`localcore-lark using active runtime binding snapshot for ${msg.workspaceId}/${instanceId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
440
405
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
this.notifyRuntimeStateChanged();
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
if (!authorized) {
|
|
461
|
-
const existingPending = this.options.store.listPendingPairings(msg.workspaceId).find((item) => item.platform === platformKey && item.platform_user_id === msg.platformUserId && item.chat_id === msg.chatId && item.status === 'pending');
|
|
462
|
-
let pairingCode = existingPending?.code || '';
|
|
463
|
-
if (!existingPending) {
|
|
464
|
-
const now = new Date();
|
|
465
|
-
pairingCode = this.generatePairingCode();
|
|
466
|
-
this.options.store.createPairingRequest({
|
|
467
|
-
code: pairingCode,
|
|
468
|
-
workspace_id: msg.workspaceId,
|
|
469
|
-
platform: platformKey,
|
|
470
|
-
platform_user_id: msg.platformUserId,
|
|
471
|
-
chat_id: msg.chatId,
|
|
472
|
-
display_name: msg.displayName,
|
|
473
|
-
requested_at: now.toISOString(),
|
|
474
|
-
expires_at: new Date(now.getTime() + PAIRING_EXPIRY_MS).toISOString(),
|
|
475
|
-
status: 'pending',
|
|
476
|
-
});
|
|
477
|
-
this.notifyRuntimeStateChanged();
|
|
478
|
-
}
|
|
479
|
-
await this.sendImmediateCard(msg.workspaceId, msg.chatId, (0, cards_js_1.renderPendingPairingCard)(pairingCode), instanceId);
|
|
406
|
+
const authorization = (0, inbound_authorization_js_1.resolveInboundChannelAuthorization)({
|
|
407
|
+
store: this.options.store,
|
|
408
|
+
identity: {
|
|
409
|
+
workspaceId: msg.workspaceId,
|
|
410
|
+
platformKey,
|
|
411
|
+
platformUserId: msg.platformUserId,
|
|
412
|
+
chatId: msg.chatId,
|
|
413
|
+
displayName: msg.displayName,
|
|
414
|
+
},
|
|
415
|
+
autoApprove: Boolean(binding?.autoApprove || runtimeState?.autoApprove),
|
|
416
|
+
authorizedUserIdPrefix: 'lark-user',
|
|
417
|
+
generatePairingCode: () => this.generatePairingCode(),
|
|
418
|
+
onStateChanged: () => this.notifyRuntimeStateChanged(),
|
|
419
|
+
});
|
|
420
|
+
if (authorization.status === 'pending') {
|
|
421
|
+
await this.sendImmediateCard(msg.workspaceId, msg.chatId, (0, cards_js_1.renderPendingPairingCard)(authorization.pairingCode), instanceId);
|
|
480
422
|
return; // { paired: false };
|
|
481
423
|
}
|
|
424
|
+
if (authorization.autoApproved) {
|
|
425
|
+
this.options.log?.(`localcore-lark auto-approved user for ${msg.workspaceId}: ${msg.platformUserId}`);
|
|
426
|
+
}
|
|
427
|
+
const authorized = authorization.authorized;
|
|
482
428
|
const router = this.options.getWorkspaceRouter();
|
|
483
429
|
let { threadId } = await (0, thread_routing_js_1.resolveChannelThreadRoute)({
|
|
484
430
|
store: this.options.store,
|
|
@@ -531,10 +477,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
531
477
|
return; // { paired: true, threadId };
|
|
532
478
|
}
|
|
533
479
|
this.options.store.clearPlatformThreadMessageId(msg.workspaceId, msg.chatId, msg.platformUserId);
|
|
534
|
-
|
|
535
|
-
? msg.text
|
|
536
|
-
: (0, desktop_js_1.wrapUserMessageWithSchedulerProtocol)(msg.text);
|
|
537
|
-
await router.sendThreadMessage(threadId, (0, content_js_1.createChannelThreadMessageInput)(wrappedText, msg.contentParts));
|
|
480
|
+
await router.sendThreadMessage(threadId, (0, content_js_1.createChannelThreadMessageInput)(msg.text, msg.contentParts));
|
|
538
481
|
return; // { paired: true, threadId };
|
|
539
482
|
}
|
|
540
483
|
async createSdkClientResult(binding) {
|
|
@@ -587,7 +530,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
587
530
|
this.runtime.set(key, status);
|
|
588
531
|
this.notifyRuntimeStateChanged();
|
|
589
532
|
try {
|
|
590
|
-
this.options.log?.(`localcore-lark starting workspace=${binding.workspaceId} app=${
|
|
533
|
+
this.options.log?.(`localcore-lark starting workspace=${binding.workspaceId} app=${(0, gateway_utils_js_1.maskLarkAppId)(binding.appId)} cardActions=${binding.cardActionsEnabled}`);
|
|
591
534
|
const mod = await this.getLarkModule();
|
|
592
535
|
status.client = new mod.Client({
|
|
593
536
|
appId: binding.appId,
|
|
@@ -610,7 +553,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
610
553
|
});
|
|
611
554
|
status.eventDispatcher.register({
|
|
612
555
|
'im.message.receive_v1': async (data) => {
|
|
613
|
-
this.options.log?.(`localcore-lark received im.message.receive_v1 for ${binding.workspaceId}/${binding.instanceId}: ${
|
|
556
|
+
this.options.log?.(`localcore-lark received im.message.receive_v1 for ${binding.workspaceId}/${binding.instanceId}: ${(0, inbound_js_1.summarizeLarkInboundPayload)(data)}`);
|
|
614
557
|
void this.handleMessageEvent(binding.workspaceId, binding.instanceId, binding.platformKey, data).catch((error) => {
|
|
615
558
|
this.options.log?.(`localcore-lark inbound message failed for ${binding.workspaceId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
616
559
|
});
|
|
@@ -629,7 +572,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
629
572
|
domain: mod.Domain.Feishu,
|
|
630
573
|
loggerLevel: mod.LoggerLevel.info,
|
|
631
574
|
});
|
|
632
|
-
|
|
575
|
+
(0, gateway_utils_js_1.attachLarkWsDiagnostics)(binding.workspaceId, status.wsClient, this.options.log);
|
|
633
576
|
this.options.log?.(`localcore-lark ws starting for ${binding.workspaceId}`);
|
|
634
577
|
await status.wsClient.start({
|
|
635
578
|
eventDispatcher: status.eventDispatcher,
|
|
@@ -656,249 +599,13 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
656
599
|
this.notifyRuntimeStateChanged();
|
|
657
600
|
}
|
|
658
601
|
async handleMessageEvent(workspaceId, instanceIdOrData, platformKeyOrData, maybeData) {
|
|
659
|
-
|
|
660
|
-
const instanceId = legacyCall ? 'default' : instanceIdOrData;
|
|
661
|
-
const platformKey = legacyCall ? 'lark' : String(platformKeyOrData || (0, channel_keys_js_1.channelPlatformKey)('lark', instanceId));
|
|
662
|
-
const data = (legacyCall ? instanceIdOrData : maybeData) || {};
|
|
663
|
-
const runtimeState = this.resolveRuntimeState(workspaceId, instanceId).state;
|
|
664
|
-
const normalized = (0, inbound_js_1.normalizeLarkInboundMessageEvent)(data, {
|
|
665
|
-
botOpenId: runtimeState?.botOpenId,
|
|
666
|
-
groupReplyAll: runtimeState?.groupReplyAll,
|
|
667
|
-
});
|
|
668
|
-
this.options.log?.(`localcore-lark handling message event for ${workspaceId}: ${(0, inbound_js_1.summarizeLarkInboundPayload)(data)}`);
|
|
669
|
-
if (!normalized.ok) {
|
|
670
|
-
this.options.log?.(`localcore-lark ignored message event for ${workspaceId}: reason=${normalized.reason}${normalized.detail ? ` ${normalized.detail}` : ''}`);
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
const { message, parsedContent, messageType, chatType, mentions, text, platformUserId, chatId, displayName, messageId, } = normalized.message;
|
|
674
|
-
const contentParts = [];
|
|
675
|
-
if (text) {
|
|
676
|
-
contentParts.push({ type: 'text', text });
|
|
677
|
-
}
|
|
678
|
-
if (messageType === 'image') {
|
|
679
|
-
const imageKey = String(parsedContent.image_key || parsedContent.file_key || '').trim();
|
|
680
|
-
if (imageKey) {
|
|
681
|
-
try {
|
|
682
|
-
contentParts.push(await this.downloadMessageImage(workspaceId, String(message.message_id || ''), imageKey, instanceId));
|
|
683
|
-
}
|
|
684
|
-
catch (error) {
|
|
685
|
-
const errorText = `[Image download failed: ${error instanceof Error ? error.message : String(error)}]`;
|
|
686
|
-
contentParts.push({ type: 'text', text: errorText });
|
|
687
|
-
this.options.log?.(`localcore-lark image download failed for ${workspaceId}: message=${String(message.message_id || '')} imageKey=${imageKey} error=${error instanceof Error ? error.message : String(error)}`);
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
if (messageType === 'file') {
|
|
692
|
-
const fileKey = String(parsedContent.file_key || '').trim();
|
|
693
|
-
if (fileKey) {
|
|
694
|
-
try {
|
|
695
|
-
contentParts.push(await this.downloadMessageFile(workspaceId, String(message.message_id || ''), fileKey, String(parsedContent.file_name || parsedContent.name || '').trim(), instanceId));
|
|
696
|
-
}
|
|
697
|
-
catch (error) {
|
|
698
|
-
const errorText = `[File download failed: ${error instanceof Error ? error.message : String(error)}]`;
|
|
699
|
-
contentParts.push({ type: 'text', text: errorText });
|
|
700
|
-
this.options.log?.(`localcore-lark file download failed for ${workspaceId}: message=${String(message.message_id || '')} fileKey=${fileKey} error=${error instanceof Error ? error.message : String(error)}`);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
if (contentParts.length === 0) {
|
|
705
|
-
this.options.log?.(`localcore-lark ignored unsupported message for ${workspaceId}: type=${String(message.message_type || 'unknown')} contentKeys=${JSON.stringify(Object.keys(parsedContent))}`);
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
const displayText = text || this.summarizeInboundContentParts(contentParts);
|
|
709
|
-
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))}`);
|
|
710
|
-
await this.handleInboundMessage({
|
|
711
|
-
workspaceId,
|
|
712
|
-
instanceId,
|
|
713
|
-
platformKey,
|
|
714
|
-
platformUserId,
|
|
715
|
-
chatId,
|
|
716
|
-
displayName,
|
|
717
|
-
text: displayText,
|
|
718
|
-
messageId,
|
|
719
|
-
contentParts,
|
|
720
|
-
});
|
|
602
|
+
await this.inboundHandler.handleMessageEvent(workspaceId, instanceIdOrData, platformKeyOrData, maybeData);
|
|
721
603
|
}
|
|
722
604
|
async downloadMessageImage(workspaceId, messageId, imageKey, instanceId) {
|
|
723
|
-
|
|
724
|
-
if (!state?.client) {
|
|
725
|
-
throw new Error('Lark client is not connected');
|
|
726
|
-
}
|
|
727
|
-
if (!messageId) {
|
|
728
|
-
throw new Error('Lark image message is missing message_id');
|
|
729
|
-
}
|
|
730
|
-
const resource = await state.client.im.messageResource.get({
|
|
731
|
-
path: {
|
|
732
|
-
message_id: messageId,
|
|
733
|
-
file_key: imageKey,
|
|
734
|
-
},
|
|
735
|
-
params: {
|
|
736
|
-
type: 'image',
|
|
737
|
-
},
|
|
738
|
-
});
|
|
739
|
-
const buffer = await this.readLarkResourceBuffer(resource);
|
|
740
|
-
if (buffer.length === 0) {
|
|
741
|
-
throw new Error('Lark image resource is empty');
|
|
742
|
-
}
|
|
743
|
-
const headerMime = this.extractHeaderMimeType(resource?.headers);
|
|
744
|
-
return {
|
|
745
|
-
type: 'image',
|
|
746
|
-
data: buffer.toString('base64'),
|
|
747
|
-
mimeType: headerMime || this.sniffImageMimeType(buffer),
|
|
748
|
-
fileName: `${imageKey}.${this.sniffImageExtension(buffer)}`,
|
|
749
|
-
};
|
|
605
|
+
return this.inboundHandler.downloadMessageImage(workspaceId, messageId, imageKey, instanceId);
|
|
750
606
|
}
|
|
751
607
|
async downloadMessageFile(workspaceId, messageId, fileKey, fileName, instanceId) {
|
|
752
|
-
|
|
753
|
-
if (!state?.client) {
|
|
754
|
-
throw new Error('Lark client is not connected');
|
|
755
|
-
}
|
|
756
|
-
if (!messageId) {
|
|
757
|
-
throw new Error('Lark file message is missing message_id');
|
|
758
|
-
}
|
|
759
|
-
const downloadsDir = await this.resolveInboundDownloadsDir(workspaceId, instanceId, state.downloadsDir);
|
|
760
|
-
const storedFileName = `${this.safeInboundFilePart(messageId, 'message')}-${this.safeInboundFilePart(fileName || fileKey, 'file')}`;
|
|
761
|
-
const filePath = (0, node_path_1.join)(downloadsDir, storedFileName);
|
|
762
|
-
const temporaryPath = `${filePath}.${(0, node_crypto_1.randomUUID)()}.part`;
|
|
763
|
-
const resource = await state.client.im.messageResource.get({
|
|
764
|
-
path: {
|
|
765
|
-
message_id: messageId,
|
|
766
|
-
file_key: fileKey,
|
|
767
|
-
},
|
|
768
|
-
params: {
|
|
769
|
-
type: 'file',
|
|
770
|
-
},
|
|
771
|
-
});
|
|
772
|
-
const readable = resource?.getReadableStream?.();
|
|
773
|
-
if (!readable || typeof readable.pipe !== 'function') {
|
|
774
|
-
throw new Error('Lark file resource did not provide a readable stream');
|
|
775
|
-
}
|
|
776
|
-
await (0, promises_1.mkdir)(downloadsDir, { recursive: true });
|
|
777
|
-
try {
|
|
778
|
-
await (0, promises_2.pipeline)(readable, (0, node_fs_1.createWriteStream)(temporaryPath, { flags: 'wx' }));
|
|
779
|
-
const temporaryStat = await (0, promises_1.stat)(temporaryPath);
|
|
780
|
-
if (temporaryStat.size === 0) {
|
|
781
|
-
throw new Error('Lark file resource is empty');
|
|
782
|
-
}
|
|
783
|
-
await (0, promises_1.rename)(temporaryPath, filePath);
|
|
784
|
-
}
|
|
785
|
-
catch (error) {
|
|
786
|
-
await (0, promises_1.rm)(temporaryPath, { force: true }).catch(() => undefined);
|
|
787
|
-
throw error;
|
|
788
|
-
}
|
|
789
|
-
const fileStat = await (0, promises_1.stat)(filePath);
|
|
790
|
-
return {
|
|
791
|
-
type: 'file',
|
|
792
|
-
path: filePath,
|
|
793
|
-
mimeType: this.extractHeaderMimeType(resource?.headers) || 'application/octet-stream',
|
|
794
|
-
fileName: fileName || fileKey,
|
|
795
|
-
size: fileStat.size,
|
|
796
|
-
};
|
|
797
|
-
}
|
|
798
|
-
async resolveInboundDownloadsDir(workspaceId, instanceId = 'default', runtimeDownloadsDir) {
|
|
799
|
-
const binding = runtimeDownloadsDir === undefined
|
|
800
|
-
? await this.getBinding(workspaceId, instanceId)
|
|
801
|
-
: undefined;
|
|
802
|
-
const configuredDir = String(runtimeDownloadsDir ?? binding?.downloadsDir ?? '').trim();
|
|
803
|
-
if (configuredDir && (0, node_path_1.isAbsolute)(configuredDir)) {
|
|
804
|
-
return configuredDir;
|
|
805
|
-
}
|
|
806
|
-
const workspace = await this.options.getWorkspaceRouter().getWorkspaceRegistryEntry(workspaceId);
|
|
807
|
-
return configuredDir
|
|
808
|
-
? (0, node_path_1.resolve)(workspace.path, configuredDir)
|
|
809
|
-
: (0, node_path_1.join)(workspace.path, '.agentdock', 'channel-uploads', 'lark', instanceId);
|
|
810
|
-
}
|
|
811
|
-
safeInboundFilePart(value, fallback) {
|
|
812
|
-
return String(value || fallback)
|
|
813
|
-
.replace(/[^a-zA-Z0-9._-]/g, '_')
|
|
814
|
-
.slice(0, 120) || fallback;
|
|
815
|
-
}
|
|
816
|
-
summarizeInboundContentParts(parts) {
|
|
817
|
-
const text = parts
|
|
818
|
-
.filter((part) => part.type === 'text')
|
|
819
|
-
.map((part) => part.text)
|
|
820
|
-
.filter(Boolean)
|
|
821
|
-
.join('\n\n')
|
|
822
|
-
.trim();
|
|
823
|
-
if (text)
|
|
824
|
-
return text;
|
|
825
|
-
const attachmentSummary = parts
|
|
826
|
-
.map((part) => {
|
|
827
|
-
if (part.type === 'image') {
|
|
828
|
-
return '[Image]';
|
|
829
|
-
}
|
|
830
|
-
if (part.type === 'file') {
|
|
831
|
-
return part.fileName ? `[File: ${part.fileName}]` : '[File]';
|
|
832
|
-
}
|
|
833
|
-
return '';
|
|
834
|
-
})
|
|
835
|
-
.filter(Boolean)
|
|
836
|
-
.join('\n');
|
|
837
|
-
return attachmentSummary;
|
|
838
|
-
}
|
|
839
|
-
async readLarkResourceBuffer(resource) {
|
|
840
|
-
const readable = resource?.getReadableStream?.();
|
|
841
|
-
if (!readable || typeof readable.on !== 'function') {
|
|
842
|
-
throw new Error('Lark resource did not provide a readable stream');
|
|
843
|
-
}
|
|
844
|
-
const chunks = [];
|
|
845
|
-
await new Promise((resolve, reject) => {
|
|
846
|
-
readable.on('data', (chunk) => {
|
|
847
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
848
|
-
});
|
|
849
|
-
readable.on('error', reject);
|
|
850
|
-
readable.on('end', resolve);
|
|
851
|
-
});
|
|
852
|
-
return Buffer.concat(chunks);
|
|
853
|
-
}
|
|
854
|
-
extractHeaderMimeType(headers) {
|
|
855
|
-
const value = headers && typeof headers === 'object'
|
|
856
|
-
? headers['content-type'] || headers['Content-Type']
|
|
857
|
-
: '';
|
|
858
|
-
return String(value || '').split(';')[0]?.trim() || '';
|
|
859
|
-
}
|
|
860
|
-
sniffImageMimeType(buffer) {
|
|
861
|
-
if (buffer[0] === 0xff && buffer[1] === 0xd8)
|
|
862
|
-
return 'image/jpeg';
|
|
863
|
-
if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47)
|
|
864
|
-
return 'image/png';
|
|
865
|
-
if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46)
|
|
866
|
-
return 'image/gif';
|
|
867
|
-
if (buffer[0] === 0x52 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x46)
|
|
868
|
-
return 'image/webp';
|
|
869
|
-
return 'application/octet-stream';
|
|
870
|
-
}
|
|
871
|
-
sniffImageExtension(buffer) {
|
|
872
|
-
const mimeType = this.sniffImageMimeType(buffer);
|
|
873
|
-
if (mimeType === 'image/jpeg')
|
|
874
|
-
return 'jpg';
|
|
875
|
-
if (mimeType === 'image/png')
|
|
876
|
-
return 'png';
|
|
877
|
-
if (mimeType === 'image/gif')
|
|
878
|
-
return 'gif';
|
|
879
|
-
if (mimeType === 'image/webp')
|
|
880
|
-
return 'webp';
|
|
881
|
-
return 'bin';
|
|
882
|
-
}
|
|
883
|
-
attachWsDiagnostics(workspaceId, wsClient) {
|
|
884
|
-
const on = typeof wsClient?.on === 'function' ? wsClient.on.bind(wsClient) : null;
|
|
885
|
-
if (!on) {
|
|
886
|
-
this.options.log?.(`localcore-lark ws diagnostics unavailable for ${workspaceId}: client has no on()`);
|
|
887
|
-
return;
|
|
888
|
-
}
|
|
889
|
-
for (const eventName of ['open', 'connect', 'connected', 'ready', 'close', 'closed', 'disconnect', 'error', 'reconnect']) {
|
|
890
|
-
try {
|
|
891
|
-
on(eventName, (...args) => {
|
|
892
|
-
this.options.log?.(`localcore-lark ws event ${eventName} for ${workspaceId}: ${this.summarizeWsArgs(args)}`);
|
|
893
|
-
});
|
|
894
|
-
}
|
|
895
|
-
catch (error) {
|
|
896
|
-
this.options.log?.(`localcore-lark ws diagnostic hook failed for ${workspaceId} event=${eventName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
summarizeLarkEvent(data) {
|
|
901
|
-
return (0, inbound_js_1.summarizeLarkInboundPayload)(data);
|
|
608
|
+
return this.inboundHandler.downloadMessageFile(workspaceId, messageId, fileKey, fileName, instanceId);
|
|
902
609
|
}
|
|
903
610
|
async fetchBotOpenId(state) {
|
|
904
611
|
const response = await state.client.request({
|
|
@@ -912,30 +619,6 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
912
619
|
}
|
|
913
620
|
return openId;
|
|
914
621
|
}
|
|
915
|
-
summarizeWsArgs(args) {
|
|
916
|
-
if (args.length === 0) {
|
|
917
|
-
return 'no-args';
|
|
918
|
-
}
|
|
919
|
-
return args.map((arg) => {
|
|
920
|
-
if (arg instanceof Error) {
|
|
921
|
-
return `${arg.name}: ${arg.message}`;
|
|
922
|
-
}
|
|
923
|
-
if (typeof arg === 'string') {
|
|
924
|
-
return arg.slice(0, 200);
|
|
925
|
-
}
|
|
926
|
-
if (arg && typeof arg === 'object') {
|
|
927
|
-
return JSON.stringify(Object.keys(arg));
|
|
928
|
-
}
|
|
929
|
-
return String(arg);
|
|
930
|
-
}).join(' ');
|
|
931
|
-
}
|
|
932
|
-
maskLarkAppId(appId) {
|
|
933
|
-
const value = String(appId || '').trim();
|
|
934
|
-
if (value.length <= 8) {
|
|
935
|
-
return value ? '***' : '';
|
|
936
|
-
}
|
|
937
|
-
return `${value.slice(0, 6)}...${value.slice(-4)}`;
|
|
938
|
-
}
|
|
939
622
|
makeThreadRoute(input, threadId) {
|
|
940
623
|
return {
|
|
941
624
|
workspaceId: input.workspaceId,
|
|
@@ -952,7 +635,6 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
952
635
|
});
|
|
953
636
|
}
|
|
954
637
|
buildStatusObject(state, _resolved) {
|
|
955
|
-
this.options.store.expirePendingPairings();
|
|
956
638
|
const resolved = this.resolveRuntimeState(state.workspaceId, state.instanceId);
|
|
957
639
|
const binding = resolved.state;
|
|
958
640
|
const platformKey = binding?.platformKey || (0, channel_keys_js_1.channelPlatformKey)('lark', resolved.instanceId);
|
|
@@ -1024,94 +706,8 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
1024
706
|
}
|
|
1025
707
|
return this.larkModulePromise;
|
|
1026
708
|
}
|
|
1027
|
-
async sendTextAsCard(state, chatId, text, buttonRows = [], sessionKey, threadId) {
|
|
1028
|
-
const startedAt = Date.now();
|
|
1029
|
-
const response = await state.client.im.message.create({
|
|
1030
|
-
params: {
|
|
1031
|
-
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1032
|
-
},
|
|
1033
|
-
data: {
|
|
1034
|
-
receive_id: chatId,
|
|
1035
|
-
msg_type: 'interactive',
|
|
1036
|
-
content: JSON.stringify((0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)),
|
|
1037
|
-
},
|
|
1038
|
-
});
|
|
1039
|
-
this.options.log?.(`localcore-lark card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1040
|
-
return String(response?.data?.message_id || '').trim();
|
|
1041
|
-
}
|
|
1042
|
-
async sendSessionCommandCard(state, chatId, text, actionRows, sessionKey, threadId) {
|
|
1043
|
-
const startedAt = Date.now();
|
|
1044
|
-
const response = await state.client.im.message.create({
|
|
1045
|
-
params: {
|
|
1046
|
-
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1047
|
-
},
|
|
1048
|
-
data: {
|
|
1049
|
-
receive_id: chatId,
|
|
1050
|
-
msg_type: 'interactive',
|
|
1051
|
-
content: JSON.stringify((0, cards_js_1.buildSessionCommandCard)(text, actionRows, sessionKey, threadId)),
|
|
1052
|
-
},
|
|
1053
|
-
});
|
|
1054
|
-
this.options.log?.(`localcore-lark session card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1055
|
-
return String(response?.data?.message_id || '').trim();
|
|
1056
|
-
}
|
|
1057
709
|
async sendTextAsMessage(state, chatId, text) {
|
|
1058
|
-
|
|
1059
|
-
const rendered = (0, messages_js_1.renderLarkTextMessage)(text);
|
|
1060
|
-
const response = await state.client.im.message.create({
|
|
1061
|
-
params: {
|
|
1062
|
-
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1063
|
-
},
|
|
1064
|
-
data: {
|
|
1065
|
-
receive_id: chatId,
|
|
1066
|
-
msg_type: rendered.msgType,
|
|
1067
|
-
content: JSON.stringify(rendered.content),
|
|
1068
|
-
},
|
|
1069
|
-
});
|
|
1070
|
-
this.options.log?.(`localcore-lark ${rendered.renderKind} create took ${Date.now() - startedAt}ms msgType=${rendered.msgType} reason=${rendered.reason} tableCount=${rendered.tableCount} textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1071
|
-
return {
|
|
1072
|
-
messageId: String(response?.data?.message_id || '').trim(),
|
|
1073
|
-
renderKind: rendered.renderKind,
|
|
1074
|
-
msgType: rendered.msgType,
|
|
1075
|
-
};
|
|
1076
|
-
}
|
|
1077
|
-
resolveReceiveIdType(receiveId) {
|
|
1078
|
-
return receiveId.startsWith('oc_') ? 'chat_id' : receiveId.startsWith('ou_') ? 'open_id' : 'user_id';
|
|
1079
|
-
}
|
|
1080
|
-
resolveLarkUploadFileType(fileName) {
|
|
1081
|
-
switch ((0, node_path_1.extname)(fileName).toLowerCase()) {
|
|
1082
|
-
case '.opus':
|
|
1083
|
-
return 'opus';
|
|
1084
|
-
case '.mp4':
|
|
1085
|
-
case '.mov':
|
|
1086
|
-
case '.m4v':
|
|
1087
|
-
return 'mp4';
|
|
1088
|
-
case '.pdf':
|
|
1089
|
-
return 'pdf';
|
|
1090
|
-
case '.doc':
|
|
1091
|
-
case '.docx':
|
|
1092
|
-
return 'doc';
|
|
1093
|
-
case '.xls':
|
|
1094
|
-
case '.xlsx':
|
|
1095
|
-
case '.csv':
|
|
1096
|
-
return 'xls';
|
|
1097
|
-
case '.ppt':
|
|
1098
|
-
case '.pptx':
|
|
1099
|
-
return 'ppt';
|
|
1100
|
-
default:
|
|
1101
|
-
return 'stream';
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
async patchTextCard(state, messageId, text, buttonRows = [], sessionKey, threadId) {
|
|
1105
|
-
const startedAt = Date.now();
|
|
1106
|
-
await state.client.im.message.patch({
|
|
1107
|
-
path: {
|
|
1108
|
-
message_id: messageId,
|
|
1109
|
-
},
|
|
1110
|
-
data: {
|
|
1111
|
-
content: JSON.stringify((0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)),
|
|
1112
|
-
},
|
|
1113
|
-
});
|
|
1114
|
-
this.options.log?.(`localcore-lark card patch took ${Date.now() - startedAt}ms message=${messageId} textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
710
|
+
return this.outboundTransport.sendTextAsMessage(state, chatId, text);
|
|
1115
711
|
}
|
|
1116
712
|
generatePairingCode() {
|
|
1117
713
|
return String((0, node_crypto_1.randomInt)(100000, 1000000));
|
|
@@ -1239,7 +835,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
1239
835
|
return;
|
|
1240
836
|
}
|
|
1241
837
|
try {
|
|
1242
|
-
await this.patchTextCard(state, messageId, [
|
|
838
|
+
await this.outboundTransport.patchTextCard(state, messageId, [
|
|
1243
839
|
'**工具确认已处理**',
|
|
1244
840
|
`已选择:${(0, cards_js_1.formatPermissionResponseLabel)(response)}`,
|
|
1245
841
|
'等待代理继续执行...',
|
|
@@ -1260,7 +856,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
1260
856
|
return '';
|
|
1261
857
|
}
|
|
1262
858
|
try {
|
|
1263
|
-
return await this.sendTextAsCard(state, chatId, text);
|
|
859
|
+
return await this.outboundTransport.sendTextAsCard(state, chatId, text);
|
|
1264
860
|
}
|
|
1265
861
|
catch (error) {
|
|
1266
862
|
this.options.log?.(`localcore-lark immediate card failed for ${workspaceId}: ${error instanceof Error ? error.message : String(error)}`);
|