@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.
Files changed (180) hide show
  1. package/README.md +7 -0
  2. package/dist/renderer/assets/{Badge-DjcoXx2J.js → Badge-CDTbmw1h.js} +1 -1
  3. package/dist/renderer/assets/Card-DayUo35w.js +1 -0
  4. package/dist/renderer/assets/Config-ByGMQuzR.js +21 -0
  5. package/dist/renderer/assets/CronList-XqHdVlgu.js +1 -0
  6. package/dist/renderer/assets/Dashboard-CZj-oANw.js +41 -0
  7. package/dist/renderer/assets/{EmptyState-DIZLiccW.js → EmptyState-EFMkOjZO.js} +1 -1
  8. package/dist/renderer/assets/HighlightedMarkdown-DyvF3DHK.js +12 -0
  9. package/dist/renderer/assets/Input-DxoWVc9d.js +1 -0
  10. package/dist/renderer/assets/{KnowledgeDetail-CJ9IYOsa.js → KnowledgeDetail-CbUb2tG7.js} +2 -2
  11. package/dist/renderer/assets/{KnowledgeHome-BLGPwnBO.js → KnowledgeHome-BWV1gz4f.js} +3 -3
  12. package/dist/renderer/assets/Logs-DqnanQTc.js +6 -0
  13. package/dist/renderer/assets/{Modal-CQiUpfl4.js → Modal-yY7TzR0x.js} +3 -3
  14. package/dist/renderer/assets/MonitorList-CIjGQkFs.js +1 -0
  15. package/dist/renderer/assets/Page-vwHNUdoj.js +1 -0
  16. package/dist/renderer/assets/{Select-D6z65IT3.js → Select-CmbK36pN.js} +2 -2
  17. package/dist/renderer/assets/ThreadChat-4OceMgM4.js +86 -0
  18. package/dist/renderer/assets/Workspace-DplPJOjJ.js +19 -0
  19. package/dist/renderer/assets/{arrow-left-CV5cL3f4.js → arrow-left-C8HfBt2K.js} +1 -1
  20. package/dist/renderer/assets/{book-open-DThvB7pj.js → book-open-BCdZWncQ.js} +1 -1
  21. package/dist/renderer/assets/channels-hgO3cAIx.js +6 -0
  22. package/dist/renderer/assets/chevron-down-BPk77tqY.js +11 -0
  23. package/dist/renderer/assets/index-BIKL3fTP.css +11 -0
  24. package/dist/renderer/assets/index-BlA4xPdd.js +41 -0
  25. package/dist/renderer/assets/index-wYpjqVqC.js +167 -0
  26. package/dist/renderer/assets/knowledge-7pl06KuH.js +1 -0
  27. package/dist/renderer/assets/{pencil-Dv5WxhdC.js → pencil-CB1SWZ9A.js} +1 -1
  28. package/dist/renderer/assets/{play-DnCnft83.js → play-BvsoXUrM.js} +1 -1
  29. package/dist/renderer/assets/{plus-DsxIagzS.js → plus-CokBDnaL.js} +1 -1
  30. package/dist/renderer/assets/{save-CST01lIc.js → save-D-w4kATO.js} +1 -1
  31. package/dist/renderer/assets/{search-B_bqy6Wd.js → search-Cnsn6i4Q.js} +1 -1
  32. package/dist/renderer/assets/{shield-check-D6lG5Aoc.js → shield-check-Cjja2Gh6.js} +1 -1
  33. package/dist/renderer/assets/threads-BCm6j4eI.js +1 -0
  34. package/dist/renderer/assets/{trash-2-Cefngb6Q.js → trash-2-CIxz9qYY.js} +1 -1
  35. package/dist/renderer/index.html +2 -2
  36. package/dist-electron/packages/contracts/src/automation.js +2 -0
  37. package/dist-electron/packages/contracts/src/channels.js +2 -0
  38. package/dist-electron/packages/contracts/src/knowledge.js +2 -0
  39. package/dist-electron/packages/contracts/src/local-core.js +15 -0
  40. package/dist-electron/packages/contracts/src/runtime.js +2 -0
  41. package/dist-electron/packages/contracts/src/scheduler.js +2 -0
  42. package/dist-electron/packages/contracts/src/threads.js +2 -0
  43. package/dist-electron/packages/core-sdk/src/automation.js +32 -0
  44. package/dist-electron/packages/core-sdk/src/channels.js +121 -0
  45. package/dist-electron/packages/core-sdk/src/client.js +455 -0
  46. package/dist-electron/packages/core-sdk/src/index.js +43 -607
  47. package/dist-electron/packages/core-sdk/src/knowledge.js +85 -0
  48. package/dist-electron/packages/core-sdk/src/request.js +22 -0
  49. package/dist-electron/packages/core-sdk/src/runtime.js +214 -0
  50. package/dist-electron/packages/core-sdk/src/scheduler.js +32 -0
  51. package/dist-electron/packages/core-sdk/src/threads.js +67 -0
  52. package/dist-electron/packages/plugin-sdk/src/agents.js +2 -0
  53. package/dist-electron/packages/plugin-sdk/src/automation.js +2 -0
  54. package/dist-electron/packages/plugin-sdk/src/channels.js +2 -0
  55. package/dist-electron/packages/plugin-sdk/src/index.js +21 -0
  56. package/dist-electron/packages/plugin-sdk/src/knowledge.js +2 -0
  57. package/dist-electron/packages/plugin-sdk/src/runtime.js +2 -0
  58. package/dist-electron/packages/plugin-sdk/src/scheduler.js +2 -0
  59. package/dist-electron/packages/plugin-sdk/src/threads.js +2 -0
  60. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +5 -8
  61. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-content.js +2 -2
  62. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +3 -3
  63. package/dist-electron/services/local-ai-core/src/acp/store/agent-task-store.js +5 -5
  64. package/dist-electron/services/local-ai-core/src/acp/store/automation-monitor-store.js +12 -12
  65. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +2 -2
  66. package/dist-electron/services/local-ai-core/src/acp/store/scheduler-store.js +11 -11
  67. package/dist-electron/services/local-ai-core/src/acp/store/security-store.js +3 -3
  68. package/dist-electron/services/local-ai-core/src/acp/store/thread-store.js +7 -7
  69. package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +2 -2
  70. package/dist-electron/services/local-ai-core/src/agents/claudecode/definition.js +3 -3
  71. package/dist-electron/services/local-ai-core/src/agents/codex/definition.js +3 -3
  72. package/dist-electron/services/local-ai-core/src/agents/localcore-acp/definition.js +2 -2
  73. package/dist-electron/services/local-ai-core/src/agents/localcore-acp/index.js +4 -4
  74. package/dist-electron/services/local-ai-core/src/agents/opencode/launch.js +2 -2
  75. package/dist-electron/services/local-ai-core/src/agents/pi/definition.js +2 -2
  76. package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +3 -3
  77. package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +1 -1
  78. package/dist-electron/services/local-ai-core/src/agents/shared/agent-plugin.js +4 -4
  79. package/dist-electron/services/local-ai-core/src/channel/lark/cards.js +33 -18
  80. package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -2
  81. package/dist-electron/services/local-ai-core/src/channel/lark/gateway-utils.js +91 -0
  82. package/dist-electron/services/local-ai-core/src/channel/lark/inbound-handler.js +180 -0
  83. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +52 -486
  84. package/dist-electron/services/local-ai-core/src/channel/lark/outbound-transport.js +124 -0
  85. package/dist-electron/services/local-ai-core/src/channel/shared/inbound-authorization.js +54 -0
  86. package/dist-electron/services/local-ai-core/src/channel/weixin/config.js +2 -2
  87. package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-media.js +21 -0
  88. package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-poller.js +167 -0
  89. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +50 -469
  90. package/dist-electron/services/local-ai-core/src/channel/weixin/runtime-state.js +156 -0
  91. package/dist-electron/services/local-ai-core/src/channel/weixin/text-utils.js +100 -0
  92. package/dist-electron/services/local-ai-core/src/cli/lac.js +6 -6
  93. package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +2 -2
  94. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +28 -70
  95. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-ai-vector-plugin.js +2 -2
  96. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-noop-plugin.js +2 -2
  97. package/dist-electron/services/local-ai-core/src/router/workspace-bridge-event-stream.js +29 -0
  98. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +5 -5
  99. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +47 -60
  100. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -5
  101. package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +6 -6
  102. package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +3 -3
  103. package/dist-electron/services/local-ai-core/src/runtime/external-service.js +3 -1
  104. package/dist-electron/services/local-ai-core/src/runtime/handlers/automation-handler.js +11 -2
  105. package/dist-electron/services/local-ai-core/src/runtime/handlers/channel-handler.js +12 -6
  106. package/dist-electron/services/local-ai-core/src/runtime/handlers/external-handler.js +10 -2
  107. package/dist-electron/services/local-ai-core/src/runtime/handlers/knowledge-handler.js +18 -6
  108. package/dist-electron/services/local-ai-core/src/runtime/handlers/provider-handler.js +7 -2
  109. package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +28 -3
  110. package/dist-electron/services/local-ai-core/src/runtime/handlers/scheduler-handler.js +10 -2
  111. package/dist-electron/services/local-ai-core/src/runtime/handlers/security-handler.js +18 -5
  112. package/dist-electron/services/local-ai-core/src/runtime/handlers/task-handler.js +14 -2
  113. package/dist-electron/services/local-ai-core/src/runtime/handlers/thread-handler.js +18 -15
  114. package/dist-electron/services/local-ai-core/src/runtime/handlers/workspace-handler.js +13 -2
  115. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +35 -8
  116. package/dist-electron/services/local-ai-core/src/runtime/request-validation.js +79 -0
  117. package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +9 -9
  118. package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +10 -1
  119. package/dist-electron/services/local-ai-core/src/runtime/server.js +2 -1
  120. package/dist-electron/services/local-ai-core/src/runtime/workspace-project-registry.js +76 -0
  121. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +8 -8
  122. package/dist-electron/services/local-ai-core/src/thread/agent-message-policy.js +75 -0
  123. package/dist-electron/shared/desktop.js +1 -64
  124. package/dist-electron/src/components/chat/chat-controller-state.js +60 -0
  125. package/dist-electron/src/components/chat/chat-event-gate.js +146 -0
  126. package/dist-electron/src/components/chat/markdown-code-block.js +8 -0
  127. package/dist-electron/src/pages/Desktop/workspace-model.js +212 -0
  128. package/dist-electron/src/pages/Threads/thread-chat-model.js +50 -51
  129. package/dist-electron/tests/contracts/agent-message-policy.test.js +21 -0
  130. package/dist-electron/tests/contracts/architecture-docs.test.js +56 -33
  131. package/dist-electron/tests/contracts/chat-event-gate.test.js +114 -0
  132. package/dist-electron/tests/contracts/chat-markdown.test.js +16 -0
  133. package/dist-electron/tests/contracts/thread-task-state.test.js +32 -0
  134. package/dist-electron/tests/contracts/workspace-identity.test.js +23 -0
  135. package/dist-electron/tests/electron/core-client.test.js +284 -0
  136. package/dist-electron/tests/electron/plugin-kernel.test.js +54 -0
  137. package/dist-electron/tests/electron/renderer-packaging.test.js +9 -0
  138. package/dist-electron/tests/electron/workspace-task-store.test.js +31 -0
  139. package/dist-electron/tests/integration/channel-inbound-authorization.test.js +80 -0
  140. package/dist-electron/tests/integration/lark-gateway-utils.test.js +13 -0
  141. package/dist-electron/tests/integration/lark-gateway.test.js +4 -4
  142. package/dist-electron/tests/integration/weixin-runtime-state.test.js +32 -0
  143. package/dist-electron/tests/integration/weixin-text-utils.test.js +15 -0
  144. package/package.json +9 -4
  145. package/dist/renderer/assets/Chat-C5Bkm9-M.js +0 -2
  146. package/dist/renderer/assets/ChatMarkdown-uc36EzyD.js +0 -45
  147. package/dist/renderer/assets/Config-DHtQuuLy.js +0 -21
  148. package/dist/renderer/assets/CronList-BYUnhzSC.js +0 -1
  149. package/dist/renderer/assets/Dashboard-BPnGMDg3.js +0 -26
  150. package/dist/renderer/assets/Logs-Dyd2Uwlt.js +0 -1
  151. package/dist/renderer/assets/MonitorList-Byg3E3Gt.js +0 -1
  152. package/dist/renderer/assets/Page-7DxXvTMm.js +0 -1
  153. package/dist/renderer/assets/ProjectDetail-Dfr5s0Ja.js +0 -11
  154. package/dist/renderer/assets/ProjectList-CDDQjAQ_.js +0 -1
  155. package/dist/renderer/assets/SessionChat-s7CAaCPL.js +0 -1
  156. package/dist/renderer/assets/SessionList-D-OycKKS.js +0 -1
  157. package/dist/renderer/assets/ThreadChat-CLdFynB5.js +0 -28
  158. package/dist/renderer/assets/Workspace-xfT5z4j_.js +0 -19
  159. package/dist/renderer/assets/bot-CWQ5-ovl.js +0 -6
  160. package/dist/renderer/assets/check-DKM7zfWG.js +0 -6
  161. package/dist/renderer/assets/chevron-down-Dfw2KU87.js +0 -6
  162. package/dist/renderer/assets/circle-CoP4RA4s.js +0 -6
  163. package/dist/renderer/assets/desktop-CsDYrOOU.js +0 -1
  164. package/dist/renderer/assets/desktop-JQkhNOF4.js +0 -5
  165. package/dist/renderer/assets/funnel-DpVLlG3g.js +0 -6
  166. package/dist/renderer/assets/heart-BMD36ejP.js +0 -6
  167. package/dist/renderer/assets/index-COxSYBjE.js +0 -182
  168. package/dist/renderer/assets/index-CTGTI-cm.js +0 -41
  169. package/dist/renderer/assets/index-CjCuR6DI.css +0 -11
  170. package/dist/renderer/assets/projects-DgjHcNgt.js +0 -1
  171. package/dist/renderer/assets/server-ecH4GNwa.js +0 -11
  172. package/dist/renderer/assets/session-utils-Dd_WKMYW.js +0 -6
  173. package/dist/renderer/assets/sessions-BQ33Mv4k.js +0 -1
  174. package/dist/renderer/assets/user-D_8RSH-T.js +0 -6
  175. package/dist/renderer/assets/wifi-off-DB9D-pOu.js +0 -11
  176. package/dist-electron/src/api/client.js +0 -73
  177. package/dist-electron/src/api/sessions.js +0 -21
  178. package/dist-electron/src/lib/session-utils.js +0 -51
  179. package/dist-electron/src/pages/Projects/project-provider-config.js +0 -75
  180. 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;