@kafca/agentdock 0.1.56 → 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 +7 -0
- package/dist/renderer/assets/{Badge-DjcoXx2J.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-DIZLiccW.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-CJ9IYOsa.js → KnowledgeDetail-CbUb2tG7.js} +2 -2
- package/dist/renderer/assets/{KnowledgeHome-BLGPwnBO.js → KnowledgeHome-BWV1gz4f.js} +3 -3
- package/dist/renderer/assets/Logs-DqnanQTc.js +6 -0
- package/dist/renderer/assets/{Modal-CQiUpfl4.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-D6z65IT3.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-CV5cL3f4.js → arrow-left-C8HfBt2K.js} +1 -1
- package/dist/renderer/assets/{book-open-DThvB7pj.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-Dv5WxhdC.js → pencil-CB1SWZ9A.js} +1 -1
- package/dist/renderer/assets/{play-DnCnft83.js → play-BvsoXUrM.js} +1 -1
- package/dist/renderer/assets/{plus-DsxIagzS.js → plus-CokBDnaL.js} +1 -1
- package/dist/renderer/assets/{save-CST01lIc.js → save-D-w4kATO.js} +1 -1
- package/dist/renderer/assets/{search-B_bqy6Wd.js → search-Cnsn6i4Q.js} +1 -1
- package/dist/renderer/assets/{shield-check-D6lG5Aoc.js → shield-check-Cjja2Gh6.js} +1 -1
- package/dist/renderer/assets/threads-BCm6j4eI.js +1 -0
- package/dist/renderer/assets/{trash-2-Cefngb6Q.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 +5 -8
- 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 -486
- 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-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 +50 -469
- 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/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-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 +4 -4
- 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-C5Bkm9-M.js +0 -2
- package/dist/renderer/assets/ChatMarkdown-uc36EzyD.js +0 -45
- package/dist/renderer/assets/Config-DHtQuuLy.js +0 -21
- package/dist/renderer/assets/CronList-BYUnhzSC.js +0 -1
- package/dist/renderer/assets/Dashboard-BPnGMDg3.js +0 -26
- package/dist/renderer/assets/Logs-Dyd2Uwlt.js +0 -1
- package/dist/renderer/assets/MonitorList-Byg3E3Gt.js +0 -1
- package/dist/renderer/assets/Page-7DxXvTMm.js +0 -1
- package/dist/renderer/assets/ProjectDetail-Dfr5s0Ja.js +0 -11
- package/dist/renderer/assets/ProjectList-CDDQjAQ_.js +0 -1
- package/dist/renderer/assets/SessionChat-s7CAaCPL.js +0 -1
- package/dist/renderer/assets/SessionList-D-OycKKS.js +0 -1
- package/dist/renderer/assets/ThreadChat-CLdFynB5.js +0 -28
- package/dist/renderer/assets/Workspace-xfT5z4j_.js +0 -19
- package/dist/renderer/assets/bot-CWQ5-ovl.js +0 -6
- package/dist/renderer/assets/check-DKM7zfWG.js +0 -6
- package/dist/renderer/assets/chevron-down-Dfw2KU87.js +0 -6
- package/dist/renderer/assets/circle-CoP4RA4s.js +0 -6
- package/dist/renderer/assets/desktop-CsDYrOOU.js +0 -1
- package/dist/renderer/assets/desktop-JQkhNOF4.js +0 -5
- package/dist/renderer/assets/funnel-DpVLlG3g.js +0 -6
- package/dist/renderer/assets/heart-BMD36ejP.js +0 -6
- package/dist/renderer/assets/index-COxSYBjE.js +0 -182
- package/dist/renderer/assets/index-CTGTI-cm.js +0 -41
- package/dist/renderer/assets/index-CjCuR6DI.css +0 -11
- package/dist/renderer/assets/projects-DgjHcNgt.js +0 -1
- package/dist/renderer/assets/server-ecH4GNwa.js +0 -11
- package/dist/renderer/assets/session-utils-Dd_WKMYW.js +0 -6
- package/dist/renderer/assets/sessions-BQ33Mv4k.js +0 -1
- package/dist/renderer/assets/user-D_8RSH-T.js +0 -6
- package/dist/renderer/assets/wifi-off-DB9D-pOu.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,24 +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 node_path_1 = require("node:path");
|
|
40
38
|
const local_core_errors_js_1 = require("../../kernel/local-core-errors.js");
|
|
41
|
-
const desktop_js_1 = require("../../../../../shared/desktop.js");
|
|
42
39
|
const content_js_1 = require("../shared/content.js");
|
|
43
|
-
const file_utils_js_1 = require("../shared/file-utils.js");
|
|
44
|
-
const inbound_attachment_store_js_1 = require("../shared/inbound-attachment-store.js");
|
|
45
40
|
const thread_routing_js_1 = require("../shared/thread-routing.js");
|
|
46
41
|
const base_channel_gateway_js_1 = require("../shared/base-channel-gateway.js");
|
|
42
|
+
const inbound_authorization_js_1 = require("../shared/inbound-authorization.js");
|
|
47
43
|
const cards_js_1 = require("./cards.js");
|
|
48
44
|
const channel_keys_js_1 = require("../shared/channel-keys.js");
|
|
49
45
|
const config_js_1 = require("./config.js");
|
|
50
46
|
const registration_js_1 = require("./registration.js");
|
|
51
|
-
const messages_js_1 = require("./rendering/messages.js");
|
|
52
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");
|
|
53
50
|
const runtime_state_js_1 = require("./runtime-state.js");
|
|
54
|
-
const
|
|
55
|
-
const LARK_MAX_UPLOAD_FILE_SIZE = 30 * 1024 * 1024;
|
|
51
|
+
const gateway_utils_js_1 = require("./gateway-utils.js");
|
|
56
52
|
const LARK_FINAL_PATCH_INTERVAL_MS = 900;
|
|
57
53
|
const LARK_PROGRESS_PATCH_INTERVAL_MS = 3000;
|
|
58
54
|
const LARK_EMPTY_RENDER_LOG_WINDOW_MS = 5 * 60 * 1000;
|
|
@@ -64,10 +60,20 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
64
60
|
mirrorPermissionStateInMainCard = false;
|
|
65
61
|
larkModulePromise = null;
|
|
66
62
|
emptyRenderLogWindows = new Map();
|
|
67
|
-
|
|
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,279 +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 mayMaterializeAttachments = Boolean(runtimeState?.autoApprove
|
|
675
|
-
|| this.options.store.getAuthorizedUser(workspaceId, platformUserId, platformKey));
|
|
676
|
-
const contentParts = [];
|
|
677
|
-
if (text) {
|
|
678
|
-
contentParts.push({ type: 'text', text });
|
|
679
|
-
}
|
|
680
|
-
if (messageType === 'image') {
|
|
681
|
-
const imageKey = String(parsedContent.image_key || parsedContent.file_key || '').trim();
|
|
682
|
-
if (imageKey) {
|
|
683
|
-
if (!mayMaterializeAttachments) {
|
|
684
|
-
contentParts.push({ type: 'text', text: '[Image]' });
|
|
685
|
-
}
|
|
686
|
-
else {
|
|
687
|
-
try {
|
|
688
|
-
contentParts.push(await this.downloadMessageImage(workspaceId, String(message.message_id || ''), imageKey, instanceId));
|
|
689
|
-
}
|
|
690
|
-
catch (error) {
|
|
691
|
-
const errorText = `[Image download failed: ${error instanceof Error ? error.message : String(error)}]`;
|
|
692
|
-
contentParts.push({ type: 'text', text: errorText });
|
|
693
|
-
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)}`);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
if (messageType === 'file') {
|
|
699
|
-
const fileKey = String(parsedContent.file_key || '').trim();
|
|
700
|
-
if (fileKey) {
|
|
701
|
-
if (!mayMaterializeAttachments) {
|
|
702
|
-
const inboundFileName = String(parsedContent.file_name || parsedContent.name || '').trim();
|
|
703
|
-
contentParts.push({ type: 'text', text: inboundFileName ? `[File: ${inboundFileName}]` : '[File]' });
|
|
704
|
-
}
|
|
705
|
-
else {
|
|
706
|
-
try {
|
|
707
|
-
contentParts.push(await this.downloadMessageFile(workspaceId, String(message.message_id || ''), fileKey, String(parsedContent.file_name || parsedContent.name || '').trim(), instanceId));
|
|
708
|
-
}
|
|
709
|
-
catch (error) {
|
|
710
|
-
const errorText = `[File download failed: ${error instanceof Error ? error.message : String(error)}]`;
|
|
711
|
-
contentParts.push({ type: 'text', text: errorText });
|
|
712
|
-
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)}`);
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
if (contentParts.length === 0) {
|
|
718
|
-
this.options.log?.(`localcore-lark ignored unsupported message for ${workspaceId}: type=${String(message.message_type || 'unknown')} contentKeys=${JSON.stringify(Object.keys(parsedContent))}`);
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
const displayText = text || this.summarizeInboundContentParts(contentParts);
|
|
722
|
-
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))}`);
|
|
723
|
-
await this.handleInboundMessage({
|
|
724
|
-
workspaceId,
|
|
725
|
-
instanceId,
|
|
726
|
-
platformKey,
|
|
727
|
-
platformUserId,
|
|
728
|
-
chatId,
|
|
729
|
-
displayName,
|
|
730
|
-
text: displayText,
|
|
731
|
-
messageId,
|
|
732
|
-
contentParts,
|
|
733
|
-
});
|
|
602
|
+
await this.inboundHandler.handleMessageEvent(workspaceId, instanceIdOrData, platformKeyOrData, maybeData);
|
|
734
603
|
}
|
|
735
604
|
async downloadMessageImage(workspaceId, messageId, imageKey, instanceId) {
|
|
736
|
-
|
|
737
|
-
if (!state?.client) {
|
|
738
|
-
throw new Error('Lark client is not connected');
|
|
739
|
-
}
|
|
740
|
-
if (!messageId) {
|
|
741
|
-
throw new Error('Lark image message is missing message_id');
|
|
742
|
-
}
|
|
743
|
-
const downloadsDir = await this.resolveInboundDownloadsDir(workspaceId, instanceId, state.downloadsDir);
|
|
744
|
-
const stored = await this.inboundAttachmentStore.save({
|
|
745
|
-
directory: downloadsDir,
|
|
746
|
-
storedFileName: `${messageId}-${imageKey}`,
|
|
747
|
-
displayFileName: imageKey,
|
|
748
|
-
maxBytes: LARK_MAX_UPLOAD_FILE_SIZE,
|
|
749
|
-
includeBase64: true,
|
|
750
|
-
finalizeStoredFileName: ({ storedFileName, prefix }) => `${storedFileName}.${this.sniffImageExtension(prefix)}`,
|
|
751
|
-
source: {
|
|
752
|
-
open: async () => {
|
|
753
|
-
const resource = await state.client.im.messageResource.get({
|
|
754
|
-
path: {
|
|
755
|
-
message_id: messageId,
|
|
756
|
-
file_key: imageKey,
|
|
757
|
-
},
|
|
758
|
-
params: {
|
|
759
|
-
type: 'image',
|
|
760
|
-
},
|
|
761
|
-
});
|
|
762
|
-
const stream = resource?.getReadableStream?.();
|
|
763
|
-
if (!stream || typeof stream.pipe !== 'function') {
|
|
764
|
-
throw new Error('Lark image resource did not provide a readable stream');
|
|
765
|
-
}
|
|
766
|
-
return {
|
|
767
|
-
stream,
|
|
768
|
-
mimeType: this.extractHeaderMimeType(resource?.headers),
|
|
769
|
-
};
|
|
770
|
-
},
|
|
771
|
-
},
|
|
772
|
-
});
|
|
773
|
-
const extension = (0, node_path_1.extname)(stored.path).slice(1) || 'bin';
|
|
774
|
-
const uri = await this.resolveInboundAttachmentUri(workspaceId, stored.path, instanceId);
|
|
775
|
-
return {
|
|
776
|
-
type: 'image',
|
|
777
|
-
data: stored.data || '',
|
|
778
|
-
...(uri ? { uri } : {}),
|
|
779
|
-
mimeType: stored.mimeType || this.sniffImageMimeType(stored.prefix),
|
|
780
|
-
fileName: `${imageKey}.${extension}`,
|
|
781
|
-
};
|
|
605
|
+
return this.inboundHandler.downloadMessageImage(workspaceId, messageId, imageKey, instanceId);
|
|
782
606
|
}
|
|
783
607
|
async downloadMessageFile(workspaceId, messageId, fileKey, fileName, instanceId) {
|
|
784
|
-
|
|
785
|
-
if (!state?.client) {
|
|
786
|
-
throw new Error('Lark client is not connected');
|
|
787
|
-
}
|
|
788
|
-
if (!messageId) {
|
|
789
|
-
throw new Error('Lark file message is missing message_id');
|
|
790
|
-
}
|
|
791
|
-
const downloadsDir = await this.resolveInboundDownloadsDir(workspaceId, instanceId, state.downloadsDir);
|
|
792
|
-
const displayFileName = fileName || fileKey;
|
|
793
|
-
const stored = await this.inboundAttachmentStore.save({
|
|
794
|
-
directory: downloadsDir,
|
|
795
|
-
storedFileName: `${messageId}-${displayFileName}`,
|
|
796
|
-
displayFileName,
|
|
797
|
-
maxBytes: LARK_MAX_UPLOAD_FILE_SIZE,
|
|
798
|
-
source: {
|
|
799
|
-
open: async () => {
|
|
800
|
-
const resource = await state.client.im.messageResource.get({
|
|
801
|
-
path: {
|
|
802
|
-
message_id: messageId,
|
|
803
|
-
file_key: fileKey,
|
|
804
|
-
},
|
|
805
|
-
params: {
|
|
806
|
-
type: 'file',
|
|
807
|
-
},
|
|
808
|
-
});
|
|
809
|
-
const stream = resource?.getReadableStream?.();
|
|
810
|
-
if (!stream || typeof stream.pipe !== 'function') {
|
|
811
|
-
throw new Error('Lark file resource did not provide a readable stream');
|
|
812
|
-
}
|
|
813
|
-
return {
|
|
814
|
-
stream,
|
|
815
|
-
mimeType: this.extractHeaderMimeType(resource?.headers) || 'application/octet-stream',
|
|
816
|
-
};
|
|
817
|
-
},
|
|
818
|
-
},
|
|
819
|
-
});
|
|
820
|
-
return {
|
|
821
|
-
type: 'file',
|
|
822
|
-
path: stored.path,
|
|
823
|
-
fileName: stored.fileName,
|
|
824
|
-
mimeType: stored.mimeType,
|
|
825
|
-
size: stored.size,
|
|
826
|
-
};
|
|
827
|
-
}
|
|
828
|
-
async resolveInboundDownloadsDir(workspaceId, instanceId = 'default', runtimeDownloadsDir) {
|
|
829
|
-
const binding = runtimeDownloadsDir === undefined
|
|
830
|
-
? await this.getBinding(workspaceId, instanceId)
|
|
831
|
-
: undefined;
|
|
832
|
-
const configuredDir = String(runtimeDownloadsDir ?? binding?.downloadsDir ?? '').trim();
|
|
833
|
-
if (configuredDir && (0, node_path_1.isAbsolute)(configuredDir)) {
|
|
834
|
-
return configuredDir;
|
|
835
|
-
}
|
|
836
|
-
const workspace = await this.options.getWorkspaceRouter().getWorkspaceRegistryEntry(workspaceId);
|
|
837
|
-
return configuredDir
|
|
838
|
-
? (0, node_path_1.resolve)(workspace.path, configuredDir)
|
|
839
|
-
: (0, node_path_1.join)(workspace.path, '.agentdock', 'channel-uploads', 'lark', instanceId);
|
|
840
|
-
}
|
|
841
|
-
async resolveInboundAttachmentUri(workspaceId, filePath, instanceId = 'default') {
|
|
842
|
-
const binding = await this.getBinding(workspaceId, instanceId).catch(() => undefined);
|
|
843
|
-
if (!binding) {
|
|
844
|
-
return undefined;
|
|
845
|
-
}
|
|
846
|
-
const sandbox = binding.project.agent?.options?.sandbox;
|
|
847
|
-
if (!sandbox?.enabled) {
|
|
848
|
-
return (0, inbound_attachment_store_js_1.resolveInboundAttachmentUri)({ filePath });
|
|
849
|
-
}
|
|
850
|
-
const workspace = await this.options.getWorkspaceRouter().getWorkspaceRegistryEntry(workspaceId).catch(() => undefined);
|
|
851
|
-
if (!workspace) {
|
|
852
|
-
return undefined;
|
|
853
|
-
}
|
|
854
|
-
return (0, inbound_attachment_store_js_1.resolveInboundAttachmentUri)({
|
|
855
|
-
filePath,
|
|
856
|
-
workspacePath: workspace.path,
|
|
857
|
-
sandboxEnabled: true,
|
|
858
|
-
sandboxWorkspacePath: sandbox.workspace_mount_path,
|
|
859
|
-
});
|
|
860
|
-
}
|
|
861
|
-
summarizeInboundContentParts(parts) {
|
|
862
|
-
const text = parts
|
|
863
|
-
.filter((part) => part.type === 'text')
|
|
864
|
-
.map((part) => part.text)
|
|
865
|
-
.filter(Boolean)
|
|
866
|
-
.join('\n\n')
|
|
867
|
-
.trim();
|
|
868
|
-
if (text)
|
|
869
|
-
return text;
|
|
870
|
-
const attachmentSummary = parts
|
|
871
|
-
.map((part) => {
|
|
872
|
-
if (part.type === 'image') {
|
|
873
|
-
return '[Image]';
|
|
874
|
-
}
|
|
875
|
-
if (part.type === 'file') {
|
|
876
|
-
return part.fileName ? `[File: ${part.fileName}]` : '[File]';
|
|
877
|
-
}
|
|
878
|
-
return '';
|
|
879
|
-
})
|
|
880
|
-
.filter(Boolean)
|
|
881
|
-
.join('\n');
|
|
882
|
-
return attachmentSummary;
|
|
883
|
-
}
|
|
884
|
-
extractHeaderMimeType(headers) {
|
|
885
|
-
const value = headers && typeof headers === 'object'
|
|
886
|
-
? headers['content-type'] || headers['Content-Type']
|
|
887
|
-
: '';
|
|
888
|
-
return String(value || '').split(';')[0]?.trim() || '';
|
|
889
|
-
}
|
|
890
|
-
sniffImageMimeType(buffer) {
|
|
891
|
-
if (buffer[0] === 0xff && buffer[1] === 0xd8)
|
|
892
|
-
return 'image/jpeg';
|
|
893
|
-
if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47)
|
|
894
|
-
return 'image/png';
|
|
895
|
-
if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46)
|
|
896
|
-
return 'image/gif';
|
|
897
|
-
if (buffer[0] === 0x52 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x46)
|
|
898
|
-
return 'image/webp';
|
|
899
|
-
return 'application/octet-stream';
|
|
900
|
-
}
|
|
901
|
-
sniffImageExtension(buffer) {
|
|
902
|
-
const mimeType = this.sniffImageMimeType(buffer);
|
|
903
|
-
if (mimeType === 'image/jpeg')
|
|
904
|
-
return 'jpg';
|
|
905
|
-
if (mimeType === 'image/png')
|
|
906
|
-
return 'png';
|
|
907
|
-
if (mimeType === 'image/gif')
|
|
908
|
-
return 'gif';
|
|
909
|
-
if (mimeType === 'image/webp')
|
|
910
|
-
return 'webp';
|
|
911
|
-
return 'bin';
|
|
912
|
-
}
|
|
913
|
-
attachWsDiagnostics(workspaceId, wsClient) {
|
|
914
|
-
const on = typeof wsClient?.on === 'function' ? wsClient.on.bind(wsClient) : null;
|
|
915
|
-
if (!on) {
|
|
916
|
-
this.options.log?.(`localcore-lark ws diagnostics unavailable for ${workspaceId}: client has no on()`);
|
|
917
|
-
return;
|
|
918
|
-
}
|
|
919
|
-
for (const eventName of ['open', 'connect', 'connected', 'ready', 'close', 'closed', 'disconnect', 'error', 'reconnect']) {
|
|
920
|
-
try {
|
|
921
|
-
on(eventName, (...args) => {
|
|
922
|
-
this.options.log?.(`localcore-lark ws event ${eventName} for ${workspaceId}: ${this.summarizeWsArgs(args)}`);
|
|
923
|
-
});
|
|
924
|
-
}
|
|
925
|
-
catch (error) {
|
|
926
|
-
this.options.log?.(`localcore-lark ws diagnostic hook failed for ${workspaceId} event=${eventName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
summarizeLarkEvent(data) {
|
|
931
|
-
return (0, inbound_js_1.summarizeLarkInboundPayload)(data);
|
|
608
|
+
return this.inboundHandler.downloadMessageFile(workspaceId, messageId, fileKey, fileName, instanceId);
|
|
932
609
|
}
|
|
933
610
|
async fetchBotOpenId(state) {
|
|
934
611
|
const response = await state.client.request({
|
|
@@ -942,30 +619,6 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
942
619
|
}
|
|
943
620
|
return openId;
|
|
944
621
|
}
|
|
945
|
-
summarizeWsArgs(args) {
|
|
946
|
-
if (args.length === 0) {
|
|
947
|
-
return 'no-args';
|
|
948
|
-
}
|
|
949
|
-
return args.map((arg) => {
|
|
950
|
-
if (arg instanceof Error) {
|
|
951
|
-
return `${arg.name}: ${arg.message}`;
|
|
952
|
-
}
|
|
953
|
-
if (typeof arg === 'string') {
|
|
954
|
-
return arg.slice(0, 200);
|
|
955
|
-
}
|
|
956
|
-
if (arg && typeof arg === 'object') {
|
|
957
|
-
return JSON.stringify(Object.keys(arg));
|
|
958
|
-
}
|
|
959
|
-
return String(arg);
|
|
960
|
-
}).join(' ');
|
|
961
|
-
}
|
|
962
|
-
maskLarkAppId(appId) {
|
|
963
|
-
const value = String(appId || '').trim();
|
|
964
|
-
if (value.length <= 8) {
|
|
965
|
-
return value ? '***' : '';
|
|
966
|
-
}
|
|
967
|
-
return `${value.slice(0, 6)}...${value.slice(-4)}`;
|
|
968
|
-
}
|
|
969
622
|
makeThreadRoute(input, threadId) {
|
|
970
623
|
return {
|
|
971
624
|
workspaceId: input.workspaceId,
|
|
@@ -982,7 +635,6 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
982
635
|
});
|
|
983
636
|
}
|
|
984
637
|
buildStatusObject(state, _resolved) {
|
|
985
|
-
this.options.store.expirePendingPairings();
|
|
986
638
|
const resolved = this.resolveRuntimeState(state.workspaceId, state.instanceId);
|
|
987
639
|
const binding = resolved.state;
|
|
988
640
|
const platformKey = binding?.platformKey || (0, channel_keys_js_1.channelPlatformKey)('lark', resolved.instanceId);
|
|
@@ -1054,94 +706,8 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
1054
706
|
}
|
|
1055
707
|
return this.larkModulePromise;
|
|
1056
708
|
}
|
|
1057
|
-
async sendTextAsCard(state, chatId, text, buttonRows = [], sessionKey, threadId) {
|
|
1058
|
-
const startedAt = Date.now();
|
|
1059
|
-
const response = await state.client.im.message.create({
|
|
1060
|
-
params: {
|
|
1061
|
-
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1062
|
-
},
|
|
1063
|
-
data: {
|
|
1064
|
-
receive_id: chatId,
|
|
1065
|
-
msg_type: 'interactive',
|
|
1066
|
-
content: JSON.stringify((0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)),
|
|
1067
|
-
},
|
|
1068
|
-
});
|
|
1069
|
-
this.options.log?.(`localcore-lark card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1070
|
-
return String(response?.data?.message_id || '').trim();
|
|
1071
|
-
}
|
|
1072
|
-
async sendSessionCommandCard(state, chatId, text, actionRows, sessionKey, threadId) {
|
|
1073
|
-
const startedAt = Date.now();
|
|
1074
|
-
const response = await state.client.im.message.create({
|
|
1075
|
-
params: {
|
|
1076
|
-
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1077
|
-
},
|
|
1078
|
-
data: {
|
|
1079
|
-
receive_id: chatId,
|
|
1080
|
-
msg_type: 'interactive',
|
|
1081
|
-
content: JSON.stringify((0, cards_js_1.buildSessionCommandCard)(text, actionRows, sessionKey, threadId)),
|
|
1082
|
-
},
|
|
1083
|
-
});
|
|
1084
|
-
this.options.log?.(`localcore-lark session card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1085
|
-
return String(response?.data?.message_id || '').trim();
|
|
1086
|
-
}
|
|
1087
709
|
async sendTextAsMessage(state, chatId, text) {
|
|
1088
|
-
|
|
1089
|
-
const rendered = (0, messages_js_1.renderLarkTextMessage)(text);
|
|
1090
|
-
const response = await state.client.im.message.create({
|
|
1091
|
-
params: {
|
|
1092
|
-
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1093
|
-
},
|
|
1094
|
-
data: {
|
|
1095
|
-
receive_id: chatId,
|
|
1096
|
-
msg_type: rendered.msgType,
|
|
1097
|
-
content: JSON.stringify(rendered.content),
|
|
1098
|
-
},
|
|
1099
|
-
});
|
|
1100
|
-
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')}`);
|
|
1101
|
-
return {
|
|
1102
|
-
messageId: String(response?.data?.message_id || '').trim(),
|
|
1103
|
-
renderKind: rendered.renderKind,
|
|
1104
|
-
msgType: rendered.msgType,
|
|
1105
|
-
};
|
|
1106
|
-
}
|
|
1107
|
-
resolveReceiveIdType(receiveId) {
|
|
1108
|
-
return receiveId.startsWith('oc_') ? 'chat_id' : receiveId.startsWith('ou_') ? 'open_id' : 'user_id';
|
|
1109
|
-
}
|
|
1110
|
-
resolveLarkUploadFileType(fileName) {
|
|
1111
|
-
switch ((0, node_path_1.extname)(fileName).toLowerCase()) {
|
|
1112
|
-
case '.opus':
|
|
1113
|
-
return 'opus';
|
|
1114
|
-
case '.mp4':
|
|
1115
|
-
case '.mov':
|
|
1116
|
-
case '.m4v':
|
|
1117
|
-
return 'mp4';
|
|
1118
|
-
case '.pdf':
|
|
1119
|
-
return 'pdf';
|
|
1120
|
-
case '.doc':
|
|
1121
|
-
case '.docx':
|
|
1122
|
-
return 'doc';
|
|
1123
|
-
case '.xls':
|
|
1124
|
-
case '.xlsx':
|
|
1125
|
-
case '.csv':
|
|
1126
|
-
return 'xls';
|
|
1127
|
-
case '.ppt':
|
|
1128
|
-
case '.pptx':
|
|
1129
|
-
return 'ppt';
|
|
1130
|
-
default:
|
|
1131
|
-
return 'stream';
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
async patchTextCard(state, messageId, text, buttonRows = [], sessionKey, threadId) {
|
|
1135
|
-
const startedAt = Date.now();
|
|
1136
|
-
await state.client.im.message.patch({
|
|
1137
|
-
path: {
|
|
1138
|
-
message_id: messageId,
|
|
1139
|
-
},
|
|
1140
|
-
data: {
|
|
1141
|
-
content: JSON.stringify((0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)),
|
|
1142
|
-
},
|
|
1143
|
-
});
|
|
1144
|
-
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);
|
|
1145
711
|
}
|
|
1146
712
|
generatePairingCode() {
|
|
1147
713
|
return String((0, node_crypto_1.randomInt)(100000, 1000000));
|
|
@@ -1269,7 +835,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
1269
835
|
return;
|
|
1270
836
|
}
|
|
1271
837
|
try {
|
|
1272
|
-
await this.patchTextCard(state, messageId, [
|
|
838
|
+
await this.outboundTransport.patchTextCard(state, messageId, [
|
|
1273
839
|
'**工具确认已处理**',
|
|
1274
840
|
`已选择:${(0, cards_js_1.formatPermissionResponseLabel)(response)}`,
|
|
1275
841
|
'等待代理继续执行...',
|
|
@@ -1290,7 +856,7 @@ class LocalCoreLarkGateway extends base_channel_gateway_js_1.BaseChannelGateway
|
|
|
1290
856
|
return '';
|
|
1291
857
|
}
|
|
1292
858
|
try {
|
|
1293
|
-
return await this.sendTextAsCard(state, chatId, text);
|
|
859
|
+
return await this.outboundTransport.sendTextAsCard(state, chatId, text);
|
|
1294
860
|
}
|
|
1295
861
|
catch (error) {
|
|
1296
862
|
this.options.log?.(`localcore-lark immediate card failed for ${workspaceId}: ${error instanceof Error ? error.message : String(error)}`);
|