@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
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.summarizeLarkInboundContentParts = summarizeLarkInboundContentParts;
|
|
4
|
+
exports.extractLarkHeaderMimeType = extractLarkHeaderMimeType;
|
|
5
|
+
exports.sniffLarkImageMimeType = sniffLarkImageMimeType;
|
|
6
|
+
exports.sniffLarkImageExtension = sniffLarkImageExtension;
|
|
7
|
+
exports.attachLarkWsDiagnostics = attachLarkWsDiagnostics;
|
|
8
|
+
exports.maskLarkAppId = maskLarkAppId;
|
|
9
|
+
function summarizeLarkInboundContentParts(parts) {
|
|
10
|
+
const text = parts
|
|
11
|
+
.filter((part) => part.type === 'text')
|
|
12
|
+
.map((part) => part.text)
|
|
13
|
+
.filter(Boolean)
|
|
14
|
+
.join('\n\n')
|
|
15
|
+
.trim();
|
|
16
|
+
if (text)
|
|
17
|
+
return text;
|
|
18
|
+
return parts
|
|
19
|
+
.map((part) => part.type === 'image'
|
|
20
|
+
? '[Image]'
|
|
21
|
+
: part.type === 'file'
|
|
22
|
+
? part.fileName ? `[File: ${part.fileName}]` : '[File]'
|
|
23
|
+
: '')
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.join('\n');
|
|
26
|
+
}
|
|
27
|
+
function extractLarkHeaderMimeType(headers) {
|
|
28
|
+
const value = headers && typeof headers === 'object'
|
|
29
|
+
? headers['content-type'] || headers['Content-Type']
|
|
30
|
+
: '';
|
|
31
|
+
return String(value || '').split(';')[0]?.trim() || '';
|
|
32
|
+
}
|
|
33
|
+
function sniffLarkImageMimeType(buffer) {
|
|
34
|
+
if (buffer[0] === 0xff && buffer[1] === 0xd8)
|
|
35
|
+
return 'image/jpeg';
|
|
36
|
+
if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47)
|
|
37
|
+
return 'image/png';
|
|
38
|
+
if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46)
|
|
39
|
+
return 'image/gif';
|
|
40
|
+
if (buffer[0] === 0x52 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x46)
|
|
41
|
+
return 'image/webp';
|
|
42
|
+
return 'application/octet-stream';
|
|
43
|
+
}
|
|
44
|
+
function sniffLarkImageExtension(buffer) {
|
|
45
|
+
const mimeType = sniffLarkImageMimeType(buffer);
|
|
46
|
+
if (mimeType === 'image/jpeg')
|
|
47
|
+
return 'jpg';
|
|
48
|
+
if (mimeType === 'image/png')
|
|
49
|
+
return 'png';
|
|
50
|
+
if (mimeType === 'image/gif')
|
|
51
|
+
return 'gif';
|
|
52
|
+
if (mimeType === 'image/webp')
|
|
53
|
+
return 'webp';
|
|
54
|
+
return 'bin';
|
|
55
|
+
}
|
|
56
|
+
function summarizeWsArgs(args) {
|
|
57
|
+
if (args.length === 0)
|
|
58
|
+
return 'no-args';
|
|
59
|
+
return args.map((arg) => {
|
|
60
|
+
if (arg instanceof Error)
|
|
61
|
+
return `${arg.name}: ${arg.message}`;
|
|
62
|
+
if (typeof arg === 'string')
|
|
63
|
+
return arg.slice(0, 200);
|
|
64
|
+
if (arg && typeof arg === 'object')
|
|
65
|
+
return JSON.stringify(Object.keys(arg));
|
|
66
|
+
return String(arg);
|
|
67
|
+
}).join(' ');
|
|
68
|
+
}
|
|
69
|
+
function attachLarkWsDiagnostics(workspaceId, wsClient, log) {
|
|
70
|
+
const on = typeof wsClient?.on === 'function' ? wsClient.on.bind(wsClient) : null;
|
|
71
|
+
if (!on) {
|
|
72
|
+
log?.(`localcore-lark ws diagnostics unavailable for ${workspaceId}: client has no on()`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
for (const eventName of ['open', 'connect', 'connected', 'ready', 'close', 'closed', 'disconnect', 'error', 'reconnect']) {
|
|
76
|
+
try {
|
|
77
|
+
on(eventName, (...args) => {
|
|
78
|
+
log?.(`localcore-lark ws event ${eventName} for ${workspaceId}: ${summarizeWsArgs(args)}`);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
log?.(`localcore-lark ws diagnostic hook failed for ${workspaceId} event=${eventName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function maskLarkAppId(appId) {
|
|
87
|
+
const value = String(appId || '').trim();
|
|
88
|
+
if (value.length <= 8)
|
|
89
|
+
return value ? '***' : '';
|
|
90
|
+
return `${value.slice(0, 6)}...${value.slice(-4)}`;
|
|
91
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LarkInboundHandler = void 0;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const inbound_attachment_store_js_1 = require("../shared/inbound-attachment-store.js");
|
|
6
|
+
const channel_keys_js_1 = require("../shared/channel-keys.js");
|
|
7
|
+
const inbound_js_1 = require("./inbound.js");
|
|
8
|
+
const gateway_utils_js_1 = require("./gateway-utils.js");
|
|
9
|
+
const LARK_MAX_INBOUND_FILE_SIZE = 30 * 1024 * 1024;
|
|
10
|
+
class LarkInboundHandler {
|
|
11
|
+
options;
|
|
12
|
+
attachmentStore = new inbound_attachment_store_js_1.FileSystemInboundAttachmentStore();
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
async handleMessageEvent(workspaceId, instanceIdOrData, platformKeyOrData, maybeData) {
|
|
17
|
+
const legacyCall = typeof instanceIdOrData === 'object';
|
|
18
|
+
const instanceId = legacyCall ? 'default' : instanceIdOrData;
|
|
19
|
+
const platformKey = legacyCall ? 'lark' : String(platformKeyOrData || (0, channel_keys_js_1.channelPlatformKey)('lark', instanceId));
|
|
20
|
+
const data = (legacyCall ? instanceIdOrData : maybeData) || {};
|
|
21
|
+
const runtimeState = this.options.getRuntimeState(workspaceId, instanceId);
|
|
22
|
+
const normalized = (0, inbound_js_1.normalizeLarkInboundMessageEvent)(data, {
|
|
23
|
+
botOpenId: runtimeState?.botOpenId,
|
|
24
|
+
groupReplyAll: runtimeState?.groupReplyAll,
|
|
25
|
+
});
|
|
26
|
+
this.options.log?.(`localcore-lark handling message event for ${workspaceId}: ${(0, inbound_js_1.summarizeLarkInboundPayload)(data)}`);
|
|
27
|
+
if (!normalized.ok) {
|
|
28
|
+
this.options.log?.(`localcore-lark ignored message event for ${workspaceId}: reason=${normalized.reason}${normalized.detail ? ` ${normalized.detail}` : ''}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const { message, parsedContent, messageType, chatType, mentions, text, platformUserId, chatId, displayName, messageId, } = normalized.message;
|
|
32
|
+
const mayMaterializeAttachments = Boolean(runtimeState?.autoApprove || this.options.store.getAuthorizedUser(workspaceId, platformUserId, platformKey));
|
|
33
|
+
const contentParts = text ? [{ type: 'text', text }] : [];
|
|
34
|
+
if (messageType === 'image') {
|
|
35
|
+
const imageKey = String(parsedContent.image_key || parsedContent.file_key || '').trim();
|
|
36
|
+
if (imageKey) {
|
|
37
|
+
if (!mayMaterializeAttachments) {
|
|
38
|
+
contentParts.push({ type: 'text', text: '[Image]' });
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
try {
|
|
42
|
+
contentParts.push(await this.downloadMessageImage(workspaceId, String(message.message_id || ''), imageKey, instanceId));
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
contentParts.push({ type: 'text', text: `[Image download failed: ${error instanceof Error ? error.message : String(error)}]` });
|
|
46
|
+
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)}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (messageType === 'file') {
|
|
52
|
+
const fileKey = String(parsedContent.file_key || '').trim();
|
|
53
|
+
if (fileKey) {
|
|
54
|
+
if (!mayMaterializeAttachments) {
|
|
55
|
+
const inboundFileName = String(parsedContent.file_name || parsedContent.name || '').trim();
|
|
56
|
+
contentParts.push({ type: 'text', text: inboundFileName ? `[File: ${inboundFileName}]` : '[File]' });
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
try {
|
|
60
|
+
contentParts.push(await this.downloadMessageFile(workspaceId, String(message.message_id || ''), fileKey, String(parsedContent.file_name || parsedContent.name || '').trim(), instanceId));
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
contentParts.push({ type: 'text', text: `[File download failed: ${error instanceof Error ? error.message : String(error)}]` });
|
|
64
|
+
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)}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (contentParts.length === 0) {
|
|
70
|
+
this.options.log?.(`localcore-lark ignored unsupported message for ${workspaceId}: type=${String(message.message_type || 'unknown')} contentKeys=${JSON.stringify(Object.keys(parsedContent))}`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const displayText = text || (0, gateway_utils_js_1.summarizeLarkInboundContentParts)(contentParts);
|
|
74
|
+
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))}`);
|
|
75
|
+
await this.options.dispatchInboundMessage({
|
|
76
|
+
workspaceId,
|
|
77
|
+
instanceId,
|
|
78
|
+
platformKey,
|
|
79
|
+
platformUserId,
|
|
80
|
+
chatId,
|
|
81
|
+
displayName,
|
|
82
|
+
text: displayText,
|
|
83
|
+
messageId,
|
|
84
|
+
contentParts,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async downloadMessageImage(workspaceId, messageId, imageKey, instanceId = 'default') {
|
|
88
|
+
const state = this.options.getRuntimeState(workspaceId, instanceId);
|
|
89
|
+
if (!state?.client)
|
|
90
|
+
throw new Error('Lark client is not connected');
|
|
91
|
+
if (!messageId)
|
|
92
|
+
throw new Error('Lark image message is missing message_id');
|
|
93
|
+
const downloadsDir = await this.resolveDownloadsDir(workspaceId, instanceId, state.downloadsDir);
|
|
94
|
+
const stored = await this.attachmentStore.save({
|
|
95
|
+
directory: downloadsDir,
|
|
96
|
+
storedFileName: `${messageId}-${imageKey}`,
|
|
97
|
+
displayFileName: imageKey,
|
|
98
|
+
maxBytes: LARK_MAX_INBOUND_FILE_SIZE,
|
|
99
|
+
includeBase64: true,
|
|
100
|
+
finalizeStoredFileName: ({ storedFileName, prefix }) => `${storedFileName}.${(0, gateway_utils_js_1.sniffLarkImageExtension)(prefix)}`,
|
|
101
|
+
source: {
|
|
102
|
+
open: async () => {
|
|
103
|
+
const resource = await state.client.im.messageResource.get({
|
|
104
|
+
path: { message_id: messageId, file_key: imageKey },
|
|
105
|
+
params: { type: 'image' },
|
|
106
|
+
});
|
|
107
|
+
const stream = resource?.getReadableStream?.();
|
|
108
|
+
if (!stream || typeof stream.pipe !== 'function')
|
|
109
|
+
throw new Error('Lark image resource did not provide a readable stream');
|
|
110
|
+
return { stream, mimeType: (0, gateway_utils_js_1.extractLarkHeaderMimeType)(resource?.headers) };
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
const extension = (0, node_path_1.extname)(stored.path).slice(1) || 'bin';
|
|
115
|
+
const uri = await this.resolveAttachmentUri(workspaceId, stored.path, instanceId);
|
|
116
|
+
return {
|
|
117
|
+
type: 'image',
|
|
118
|
+
data: stored.data || '',
|
|
119
|
+
...(uri ? { uri } : {}),
|
|
120
|
+
mimeType: stored.mimeType || (0, gateway_utils_js_1.sniffLarkImageMimeType)(stored.prefix),
|
|
121
|
+
fileName: `${imageKey}.${extension}`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
async downloadMessageFile(workspaceId, messageId, fileKey, fileName, instanceId = 'default') {
|
|
125
|
+
const state = this.options.getRuntimeState(workspaceId, instanceId);
|
|
126
|
+
if (!state?.client)
|
|
127
|
+
throw new Error('Lark client is not connected');
|
|
128
|
+
if (!messageId)
|
|
129
|
+
throw new Error('Lark file message is missing message_id');
|
|
130
|
+
const downloadsDir = await this.resolveDownloadsDir(workspaceId, instanceId, state.downloadsDir);
|
|
131
|
+
const displayFileName = fileName || fileKey;
|
|
132
|
+
const stored = await this.attachmentStore.save({
|
|
133
|
+
directory: downloadsDir,
|
|
134
|
+
storedFileName: `${messageId}-${displayFileName}`,
|
|
135
|
+
displayFileName,
|
|
136
|
+
maxBytes: LARK_MAX_INBOUND_FILE_SIZE,
|
|
137
|
+
source: {
|
|
138
|
+
open: async () => {
|
|
139
|
+
const resource = await state.client.im.messageResource.get({
|
|
140
|
+
path: { message_id: messageId, file_key: fileKey },
|
|
141
|
+
params: { type: 'file' },
|
|
142
|
+
});
|
|
143
|
+
const stream = resource?.getReadableStream?.();
|
|
144
|
+
if (!stream || typeof stream.pipe !== 'function')
|
|
145
|
+
throw new Error('Lark file resource did not provide a readable stream');
|
|
146
|
+
return { stream, mimeType: (0, gateway_utils_js_1.extractLarkHeaderMimeType)(resource?.headers) || 'application/octet-stream' };
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
return { type: 'file', path: stored.path, fileName: stored.fileName, mimeType: stored.mimeType, size: stored.size };
|
|
151
|
+
}
|
|
152
|
+
async resolveDownloadsDir(workspaceId, instanceId, runtimeDownloadsDir) {
|
|
153
|
+
const binding = runtimeDownloadsDir === undefined ? await this.options.getBinding(workspaceId, instanceId) : undefined;
|
|
154
|
+
const configuredDir = String(runtimeDownloadsDir ?? binding?.downloadsDir ?? '').trim();
|
|
155
|
+
if (configuredDir && (0, node_path_1.isAbsolute)(configuredDir))
|
|
156
|
+
return configuredDir;
|
|
157
|
+
const workspace = await this.options.getWorkspaceRouter().getWorkspaceRegistryEntry(workspaceId);
|
|
158
|
+
return configuredDir
|
|
159
|
+
? (0, node_path_1.resolve)(workspace.path, configuredDir)
|
|
160
|
+
: (0, node_path_1.join)(workspace.path, '.agentdock', 'channel-uploads', 'lark', instanceId);
|
|
161
|
+
}
|
|
162
|
+
async resolveAttachmentUri(workspaceId, filePath, instanceId) {
|
|
163
|
+
const binding = await this.options.getBinding(workspaceId, instanceId).catch(() => undefined);
|
|
164
|
+
if (!binding)
|
|
165
|
+
return undefined;
|
|
166
|
+
const sandbox = binding.project.agent?.options?.sandbox;
|
|
167
|
+
if (!sandbox?.enabled)
|
|
168
|
+
return (0, inbound_attachment_store_js_1.resolveInboundAttachmentUri)({ filePath });
|
|
169
|
+
const workspace = await this.options.getWorkspaceRouter().getWorkspaceRegistryEntry(workspaceId).catch(() => undefined);
|
|
170
|
+
if (!workspace)
|
|
171
|
+
return undefined;
|
|
172
|
+
return (0, inbound_attachment_store_js_1.resolveInboundAttachmentUri)({
|
|
173
|
+
filePath,
|
|
174
|
+
workspacePath: workspace.path,
|
|
175
|
+
sandboxEnabled: true,
|
|
176
|
+
sandboxWorkspacePath: sandbox.workspace_mount_path,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.LarkInboundHandler = LarkInboundHandler;
|