@kafca/agentdock 0.1.56 → 0.1.58

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 (200) hide show
  1. package/README.md +7 -0
  2. package/dist/renderer/assets/{Badge-DjcoXx2J.js → Badge-BfY1VaHS.js} +1 -1
  3. package/dist/renderer/assets/Card-DWA_Tww_.js +1 -0
  4. package/dist/renderer/assets/Config-nHj3g1U5.js +21 -0
  5. package/dist/renderer/assets/CronList-BwkA_I7v.js +1 -0
  6. package/dist/renderer/assets/Dashboard-D0_A7k02.js +41 -0
  7. package/dist/renderer/assets/{EmptyState-DIZLiccW.js → EmptyState-zatDjLj_.js} +1 -1
  8. package/dist/renderer/assets/HighlightedMarkdown-CsM5n70d.js +12 -0
  9. package/dist/renderer/assets/Input-R1XdFK1K.js +1 -0
  10. package/dist/renderer/assets/{KnowledgeDetail-CJ9IYOsa.js → KnowledgeDetail-Co5sxeGd.js} +2 -2
  11. package/dist/renderer/assets/{KnowledgeHome-BLGPwnBO.js → KnowledgeHome-DwziPw5m.js} +3 -3
  12. package/dist/renderer/assets/Logs-NwZUtR_G.js +6 -0
  13. package/dist/renderer/assets/{Modal-CQiUpfl4.js → Modal-CrcIwIFL.js} +3 -3
  14. package/dist/renderer/assets/MonitorList-CS1uLS5A.js +1 -0
  15. package/dist/renderer/assets/Page-Dp0obeSw.js +1 -0
  16. package/dist/renderer/assets/{Select-D6z65IT3.js → Select-6mVQaf84.js} +2 -2
  17. package/dist/renderer/assets/ThreadChat-BFzbn3L6.js +86 -0
  18. package/dist/renderer/assets/Workspace-DCmo8BMm.js +19 -0
  19. package/dist/renderer/assets/{arrow-left-CV5cL3f4.js → arrow-left-9rjg_Hp4.js} +1 -1
  20. package/dist/renderer/assets/{book-open-DThvB7pj.js → book-open-Bu8GCHnG.js} +1 -1
  21. package/dist/renderer/assets/channels-BxVbG-6j.js +6 -0
  22. package/dist/renderer/assets/chevron-down-BE8uQmWM.js +11 -0
  23. package/dist/renderer/assets/index-B7TeF6Es.js +41 -0
  24. package/dist/renderer/assets/index-BIKL3fTP.css +11 -0
  25. package/dist/renderer/assets/index-BkI9POxj.js +167 -0
  26. package/dist/renderer/assets/knowledge-Kl19SqGS.js +1 -0
  27. package/dist/renderer/assets/{pencil-Dv5WxhdC.js → pencil-CPB7SK1m.js} +1 -1
  28. package/dist/renderer/assets/{play-DnCnft83.js → play-DGAO4OCu.js} +1 -1
  29. package/dist/renderer/assets/{plus-DsxIagzS.js → plus-Bt26z-4q.js} +1 -1
  30. package/dist/renderer/assets/{save-CST01lIc.js → save-Une7GMxT.js} +1 -1
  31. package/dist/renderer/assets/{search-B_bqy6Wd.js → search-DE0agJjJ.js} +1 -1
  32. package/dist/renderer/assets/{shield-check-D6lG5Aoc.js → shield-check-De7xaXZh.js} +1 -1
  33. package/dist/renderer/assets/threads-BnsNL5ei.js +1 -0
  34. package/dist/renderer/assets/{trash-2-Cefngb6Q.js → trash-2-6iGF59Ac.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/automation/automation-conversation-executor.js +6 -47
  80. package/dist-electron/services/local-ai-core/src/automation/automation-monitor-service.js +2 -5
  81. package/dist-electron/services/local-ai-core/src/channel/lark/cards.js +33 -18
  82. package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -2
  83. package/dist-electron/services/local-ai-core/src/channel/lark/gateway-utils.js +91 -0
  84. package/dist-electron/services/local-ai-core/src/channel/lark/inbound-handler.js +180 -0
  85. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +58 -539
  86. package/dist-electron/services/local-ai-core/src/channel/lark/outbound-transport.js +112 -0
  87. package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +5 -20
  88. package/dist-electron/services/local-ai-core/src/channel/shared/base-channel-gateway.js +37 -0
  89. package/dist-electron/services/local-ai-core/src/channel/shared/bridge-event-helpers.js +23 -0
  90. package/dist-electron/services/local-ai-core/src/channel/shared/channel-keys.js +6 -0
  91. package/dist-electron/services/local-ai-core/src/channel/shared/inbound-authorization.js +54 -0
  92. package/dist-electron/services/local-ai-core/src/channel/weixin/config.js +2 -2
  93. package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-media.js +21 -0
  94. package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-poller.js +167 -0
  95. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +55 -512
  96. package/dist-electron/services/local-ai-core/src/channel/weixin/runtime-state.js +149 -0
  97. package/dist-electron/services/local-ai-core/src/channel/weixin/text-utils.js +92 -0
  98. package/dist-electron/services/local-ai-core/src/cli/lac.js +9 -11
  99. package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +2 -2
  100. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +28 -70
  101. package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +8 -0
  102. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-ai-vector-plugin.js +2 -2
  103. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-noop-plugin.js +2 -2
  104. package/dist-electron/services/local-ai-core/src/router/workspace-bridge-event-stream.js +29 -0
  105. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +5 -5
  106. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +47 -60
  107. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -5
  108. package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +6 -6
  109. package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +3 -3
  110. package/dist-electron/services/local-ai-core/src/runtime/external-service.js +3 -1
  111. package/dist-electron/services/local-ai-core/src/runtime/handlers/automation-handler.js +11 -2
  112. package/dist-electron/services/local-ai-core/src/runtime/handlers/channel-handler.js +12 -6
  113. package/dist-electron/services/local-ai-core/src/runtime/handlers/external-handler.js +10 -2
  114. package/dist-electron/services/local-ai-core/src/runtime/handlers/knowledge-handler.js +18 -6
  115. package/dist-electron/services/local-ai-core/src/runtime/handlers/provider-handler.js +7 -2
  116. package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +28 -3
  117. package/dist-electron/services/local-ai-core/src/runtime/handlers/scheduler-handler.js +10 -2
  118. package/dist-electron/services/local-ai-core/src/runtime/handlers/security-handler.js +18 -5
  119. package/dist-electron/services/local-ai-core/src/runtime/handlers/task-handler.js +14 -2
  120. package/dist-electron/services/local-ai-core/src/runtime/handlers/thread-handler.js +18 -15
  121. package/dist-electron/services/local-ai-core/src/runtime/handlers/workspace-handler.js +13 -2
  122. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +35 -8
  123. package/dist-electron/services/local-ai-core/src/runtime/request-validation.js +79 -0
  124. package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +9 -9
  125. package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +10 -1
  126. package/dist-electron/services/local-ai-core/src/runtime/server.js +2 -1
  127. package/dist-electron/services/local-ai-core/src/runtime/workspace-project-registry.js +76 -0
  128. package/dist-electron/services/local-ai-core/src/sandbox/opensandbox-client.js +3 -2
  129. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +8 -8
  130. package/dist-electron/services/local-ai-core/src/scheduler/base-channel-schedule-adapter.js +77 -0
  131. package/dist-electron/services/local-ai-core/src/scheduler/lark-schedule-adapter.js +13 -79
  132. package/dist-electron/services/local-ai-core/src/scheduler/local-schedule-adapter.js +2 -10
  133. package/dist-electron/services/local-ai-core/src/scheduler/run-polling.js +19 -0
  134. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-conversation-executor.js +3 -37
  135. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-job-route.js +20 -0
  136. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +15 -28
  137. package/dist-electron/services/local-ai-core/src/scheduler/thread-resolution.js +12 -0
  138. package/dist-electron/services/local-ai-core/src/scheduler/weixin-schedule-adapter.js +13 -79
  139. package/dist-electron/services/local-ai-core/src/thread/agent-message-policy.js +75 -0
  140. package/dist-electron/shared/desktop.js +1 -64
  141. package/dist-electron/src/components/chat/chat-controller-state.js +60 -0
  142. package/dist-electron/src/components/chat/chat-event-gate.js +146 -0
  143. package/dist-electron/src/components/chat/markdown-code-block.js +8 -0
  144. package/dist-electron/src/pages/Desktop/workspace-model.js +212 -0
  145. package/dist-electron/src/pages/Threads/thread-chat-model.js +50 -51
  146. package/dist-electron/tests/contracts/agent-message-policy.test.js +21 -0
  147. package/dist-electron/tests/contracts/architecture-docs.test.js +56 -33
  148. package/dist-electron/tests/contracts/chat-event-gate.test.js +114 -0
  149. package/dist-electron/tests/contracts/chat-markdown.test.js +16 -0
  150. package/dist-electron/tests/contracts/thread-task-state.test.js +32 -0
  151. package/dist-electron/tests/contracts/workspace-identity.test.js +23 -0
  152. package/dist-electron/tests/electron/core-client.test.js +284 -0
  153. package/dist-electron/tests/electron/plugin-kernel.test.js +54 -0
  154. package/dist-electron/tests/electron/renderer-packaging.test.js +9 -0
  155. package/dist-electron/tests/electron/workspace-task-store.test.js +31 -0
  156. package/dist-electron/tests/integration/channel-inbound-authorization.test.js +80 -0
  157. package/dist-electron/tests/integration/lark-gateway-utils.test.js +13 -0
  158. package/dist-electron/tests/integration/lark-gateway.test.js +4 -4
  159. package/dist-electron/tests/integration/local-core-refactor.test.js +15 -8
  160. package/dist-electron/tests/integration/weixin-runtime-state.test.js +32 -0
  161. package/dist-electron/tests/integration/weixin-text-utils.test.js +15 -0
  162. package/package.json +9 -4
  163. package/dist/renderer/assets/Chat-C5Bkm9-M.js +0 -2
  164. package/dist/renderer/assets/ChatMarkdown-uc36EzyD.js +0 -45
  165. package/dist/renderer/assets/Config-DHtQuuLy.js +0 -21
  166. package/dist/renderer/assets/CronList-BYUnhzSC.js +0 -1
  167. package/dist/renderer/assets/Dashboard-BPnGMDg3.js +0 -26
  168. package/dist/renderer/assets/Logs-Dyd2Uwlt.js +0 -1
  169. package/dist/renderer/assets/MonitorList-Byg3E3Gt.js +0 -1
  170. package/dist/renderer/assets/Page-7DxXvTMm.js +0 -1
  171. package/dist/renderer/assets/ProjectDetail-Dfr5s0Ja.js +0 -11
  172. package/dist/renderer/assets/ProjectList-CDDQjAQ_.js +0 -1
  173. package/dist/renderer/assets/SessionChat-s7CAaCPL.js +0 -1
  174. package/dist/renderer/assets/SessionList-D-OycKKS.js +0 -1
  175. package/dist/renderer/assets/ThreadChat-CLdFynB5.js +0 -28
  176. package/dist/renderer/assets/Workspace-xfT5z4j_.js +0 -19
  177. package/dist/renderer/assets/bot-CWQ5-ovl.js +0 -6
  178. package/dist/renderer/assets/check-DKM7zfWG.js +0 -6
  179. package/dist/renderer/assets/chevron-down-Dfw2KU87.js +0 -6
  180. package/dist/renderer/assets/circle-CoP4RA4s.js +0 -6
  181. package/dist/renderer/assets/desktop-CsDYrOOU.js +0 -1
  182. package/dist/renderer/assets/desktop-JQkhNOF4.js +0 -5
  183. package/dist/renderer/assets/funnel-DpVLlG3g.js +0 -6
  184. package/dist/renderer/assets/heart-BMD36ejP.js +0 -6
  185. package/dist/renderer/assets/index-COxSYBjE.js +0 -182
  186. package/dist/renderer/assets/index-CTGTI-cm.js +0 -41
  187. package/dist/renderer/assets/index-CjCuR6DI.css +0 -11
  188. package/dist/renderer/assets/projects-DgjHcNgt.js +0 -1
  189. package/dist/renderer/assets/server-ecH4GNwa.js +0 -11
  190. package/dist/renderer/assets/session-utils-Dd_WKMYW.js +0 -6
  191. package/dist/renderer/assets/sessions-BQ33Mv4k.js +0 -1
  192. package/dist/renderer/assets/user-D_8RSH-T.js +0 -6
  193. package/dist/renderer/assets/wifi-off-DB9D-pOu.js +0 -11
  194. package/dist-electron/services/local-ai-core/src/scheduler/lark-execution-policies.js +0 -13
  195. package/dist-electron/services/local-ai-core/src/scheduler/weixin-execution-policies.js +0 -13
  196. package/dist-electron/src/api/client.js +0 -73
  197. package/dist-electron/src/api/sessions.js +0 -21
  198. package/dist-electron/src/lib/session-utils.js +0 -51
  199. package/dist-electron/src/pages/Projects/project-provider-config.js +0 -75
  200. package/dist-electron/tests/electron/project-provider-config.test.js +0 -71
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LarkOutboundTransport = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const file_utils_js_1 = require("../shared/file-utils.js");
7
+ const cards_js_1 = require("./cards.js");
8
+ const messages_js_1 = require("./rendering/messages.js");
9
+ const LARK_MAX_UPLOAD_FILE_SIZE = 30 * 1024 * 1024;
10
+ class LarkOutboundTransport {
11
+ log;
12
+ constructor(log) {
13
+ this.log = log;
14
+ }
15
+ async sendFilePart(state, channelId, part) {
16
+ const file = await (0, file_utils_js_1.prepareChannelFile)({
17
+ path: part.path,
18
+ fileName: part.fileName,
19
+ workspacePath: typeof part.metadata?.workspacePath === 'string' ? part.metadata.workspacePath : undefined,
20
+ maxBytes: LARK_MAX_UPLOAD_FILE_SIZE,
21
+ platformLabel: 'Lark',
22
+ });
23
+ const upload = await state.client.im.file.create({
24
+ data: {
25
+ file_type: resolveLarkUploadFileType(file.fileName),
26
+ file_name: file.fileName,
27
+ file: (0, node_fs_1.createReadStream)(file.path),
28
+ },
29
+ });
30
+ const fileKey = String(upload?.file_key || upload?.data?.file_key || '').trim();
31
+ if (!fileKey) {
32
+ throw new Error('Lark file upload did not return a file key');
33
+ }
34
+ const response = await state.client.im.message.create({
35
+ params: {
36
+ receive_id_type: resolveReceiveIdType(channelId),
37
+ },
38
+ data: {
39
+ receive_id: channelId,
40
+ msg_type: 'file',
41
+ content: JSON.stringify({ file_key: fileKey }),
42
+ },
43
+ });
44
+ const messageId = String(response?.data?.message_id || '').trim();
45
+ if (!messageId) {
46
+ throw new Error('Lark file message did not return a message id');
47
+ }
48
+ this.log?.(`localcore-lark sent file ${file.fileName} (${file.fileSize} bytes) to ${channelId}`);
49
+ return { messageId, fileKey, file };
50
+ }
51
+ async sendTextAsCard(state, chatId, text, buttonRows = [], sessionKey, threadId) {
52
+ return this.timed('card create', '', text, () => this.createMessage(state, chatId, 'interactive', (0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)));
53
+ }
54
+ async sendSessionCommandCard(state, chatId, text, actionRows, sessionKey, threadId) {
55
+ return this.timed('session card create', '', text, () => this.createMessage(state, chatId, 'interactive', (0, cards_js_1.buildSessionCommandCard)(text, actionRows, sessionKey, threadId)));
56
+ }
57
+ async sendTextAsMessage(state, chatId, text) {
58
+ const rendered = (0, messages_js_1.renderLarkTextMessage)(text);
59
+ const messageId = await this.timed(`${rendered.renderKind} create`, `msgType=${rendered.msgType} reason=${rendered.reason} tableCount=${rendered.tableCount}`, text, () => this.createMessage(state, chatId, rendered.msgType, rendered.content));
60
+ return {
61
+ messageId,
62
+ renderKind: rendered.renderKind,
63
+ msgType: rendered.msgType,
64
+ };
65
+ }
66
+ async patchTextCard(state, messageId, text, buttonRows = [], sessionKey, threadId) {
67
+ await this.timed('card patch', `message=${messageId}`, text, async () => {
68
+ await state.client.im.message.patch({
69
+ path: { message_id: messageId },
70
+ data: { content: JSON.stringify((0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)) },
71
+ });
72
+ });
73
+ }
74
+ async createMessage(state, chatId, msgType, content) {
75
+ const response = await state.client.im.message.create({
76
+ params: { receive_id_type: resolveReceiveIdType(chatId) },
77
+ data: {
78
+ receive_id: chatId,
79
+ msg_type: msgType,
80
+ content: JSON.stringify(content),
81
+ },
82
+ });
83
+ return String(response?.data?.message_id || '').trim();
84
+ }
85
+ async timed(label, fields, text, action) {
86
+ const startedAt = Date.now();
87
+ const result = await action();
88
+ this.log?.(`localcore-lark ${label} took ${Date.now() - startedAt}ms${fields ? ` ${fields}` : ''} textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
89
+ return result;
90
+ }
91
+ }
92
+ exports.LarkOutboundTransport = LarkOutboundTransport;
93
+ function resolveReceiveIdType(receiveId) {
94
+ return receiveId.startsWith('oc_') ? 'chat_id' : receiveId.startsWith('ou_') ? 'open_id' : 'user_id';
95
+ }
96
+ function resolveLarkUploadFileType(fileName) {
97
+ switch ((0, node_path_1.extname)(fileName).toLowerCase()) {
98
+ case '.opus': return 'opus';
99
+ case '.mp4':
100
+ case '.mov':
101
+ case '.m4v': return 'mp4';
102
+ case '.pdf': return 'pdf';
103
+ case '.doc':
104
+ case '.docx': return 'doc';
105
+ case '.xls':
106
+ case '.xlsx':
107
+ case '.csv': return 'xls';
108
+ case '.ppt':
109
+ case '.pptx': return 'ppt';
110
+ default: return 'stream';
111
+ }
112
+ }
@@ -9,6 +9,7 @@ exports.renderLarkBridgeEventMessage = renderLarkBridgeEventMessage;
9
9
  exports.renderLarkBridgeEventMessages = renderLarkBridgeEventMessages;
10
10
  exports.getLarkRenderedMessageId = getLarkRenderedMessageId;
11
11
  exports.setLarkRenderedMessageId = setLarkRenderedMessageId;
12
+ const bridge_event_helpers_js_1 = require("../shared/bridge-event-helpers.js");
12
13
  function createLarkTurnState(sessionKey, sourceMessageId) {
13
14
  const turn = {
14
15
  sessionKey,
@@ -49,7 +50,7 @@ function isPendingToolProgressForLark(event) {
49
50
  }
50
51
  function consumeLarkBridgeEvent(turn, event, options) {
51
52
  const content = foldToolResultForLark(String(event.content || '').trim());
52
- const bridgeKind = resolveBridgeEventKind(event);
53
+ const bridgeKind = (0, bridge_event_helpers_js_1.resolveBridgeEventKind)(event);
53
54
  if (event.type === 'typing_start') {
54
55
  turn.messageId = undefined;
55
56
  turn.finalMessageId = undefined;
@@ -123,7 +124,7 @@ function consumeLarkBridgeEvent(turn, event, options) {
123
124
  }
124
125
  function renderLarkBridgeEventMessage(turn, event) {
125
126
  const content = foldToolResultForLark(String(event.content || '').trim());
126
- const bridgeKind = resolveBridgeEventKind(event);
127
+ const bridgeKind = (0, bridge_event_helpers_js_1.resolveBridgeEventKind)(event);
127
128
  if (event.type === 'preview_start' || event.type === 'update_message') {
128
129
  if (bridgeKind === 'thought') {
129
130
  return { key: 'noop', text: '', buttonRows: [], isFinal: false };
@@ -240,15 +241,9 @@ function progressKey(prefix, event) {
240
241
  return `${prefix}:${content.slice(0, 120)}`;
241
242
  }
242
243
  function isThoughtBridgeEvent(event) {
243
- const kind = resolveBridgeEventKind(event);
244
+ const kind = (0, bridge_event_helpers_js_1.resolveBridgeEventKind)(event);
244
245
  return kind === 'thought' || kind === 'plan';
245
246
  }
246
- function resolveBridgeEventKind(event) {
247
- if (event.bridgeKind) {
248
- return event.bridgeKind;
249
- }
250
- return event.type === 'status' ? 'status' : 'assistant';
251
- }
252
247
  function renderProcessText(kind, content) {
253
248
  const text = content.trim();
254
249
  return kind === 'plan' ? `计划\n${text}` : text;
@@ -279,15 +274,5 @@ function fencedCode(value, language = '') {
279
274
  return `${fence}${language}\n${normalized}\n${fence}`;
280
275
  }
281
276
  function pushUniqueLarkTurnLine(target, value) {
282
- const normalized = value.trim();
283
- if (!normalized) {
284
- return;
285
- }
286
- if (target[target.length - 1] === normalized) {
287
- return;
288
- }
289
- target.push(normalized);
290
- if (target.length > 6) {
291
- target.splice(0, target.length - 6);
292
- }
277
+ (0, bridge_event_helpers_js_1.pushUniqueLine)(target, value, 6);
293
278
  }
@@ -232,6 +232,30 @@ class BaseChannelGateway extends node_events_1.EventEmitter {
232
232
  async executeSessionCommand(input) {
233
233
  return this.sessionCommandRuntime.execute(input);
234
234
  }
235
+ async resolveDefaultAgentType(workspaceId, threadId) {
236
+ const router = this.options.getWorkspaceRouter();
237
+ if (typeof router.getWorkspaceDefaultAgentType === 'function') {
238
+ return router.getWorkspaceDefaultAgentType(workspaceId);
239
+ }
240
+ return this.options.store.getThreadRow(threadId)?.agent_type || 'codex';
241
+ }
242
+ findAwaitingPermissionThreadId(workspaceId, chatId, platformUserId, platformKey) {
243
+ for (const [sessionKey, route] of this.threadRouting.entries()) {
244
+ if (route.workspaceId !== workspaceId
245
+ || route.chatId !== chatId
246
+ || route.platformUserId !== platformUserId) {
247
+ continue;
248
+ }
249
+ if (platformKey !== undefined && route.platformKey !== platformKey) {
250
+ continue;
251
+ }
252
+ const turn = this.outboundTurns.get(sessionKey);
253
+ if (turn?.awaitingPermission && route.threadId) {
254
+ return route.threadId;
255
+ }
256
+ }
257
+ return '';
258
+ }
235
259
  // ==================== Runtime Management ====================
236
260
  resolveRuntimeState(workspaceId, instanceId) {
237
261
  const key = resolveRuntimeKey(workspaceId, instanceId);
@@ -280,6 +304,19 @@ class BaseChannelGateway extends node_events_1.EventEmitter {
280
304
  },
281
305
  });
282
306
  }
307
+ scheduleOutboundChain(sessionKey, work) {
308
+ const previous = this.outboundEventChains.get(sessionKey) || Promise.resolve();
309
+ const current = previous
310
+ .catch(() => undefined)
311
+ .then(work)
312
+ .finally(() => {
313
+ if (this.outboundEventChains.get(sessionKey) === current) {
314
+ this.outboundEventChains.delete(sessionKey);
315
+ }
316
+ });
317
+ this.outboundEventChains.set(sessionKey, current);
318
+ return current;
319
+ }
283
320
  clearRuntimeError(state) {
284
321
  state.lastError = undefined;
285
322
  state.lastErrorInfo = undefined;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveBridgeEventKind = resolveBridgeEventKind;
4
+ exports.pushUniqueLine = pushUniqueLine;
5
+ function resolveBridgeEventKind(event) {
6
+ if (event.bridgeKind) {
7
+ return event.bridgeKind;
8
+ }
9
+ return event.type === 'status' ? 'status' : 'assistant';
10
+ }
11
+ function pushUniqueLine(target, value, maxLines) {
12
+ const normalized = value.trim();
13
+ if (!normalized) {
14
+ return;
15
+ }
16
+ if (target[target.length - 1] === normalized) {
17
+ return;
18
+ }
19
+ target.push(normalized);
20
+ if (target.length > maxLines) {
21
+ target.splice(0, target.length - maxLines);
22
+ }
23
+ }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeChannelInstanceId = normalizeChannelInstanceId;
4
4
  exports.channelPlatformKey = channelPlatformKey;
5
+ exports.extractChannelInstanceId = extractChannelInstanceId;
5
6
  exports.runtimeKey = runtimeKey;
6
7
  function normalizeChannelInstanceId(value, fallback) {
7
8
  const raw = String(value || '').trim();
@@ -11,6 +12,11 @@ function normalizeChannelInstanceId(value, fallback) {
11
12
  function channelPlatformKey(platform, instanceId) {
12
13
  return instanceId === 'default' ? platform : `${platform}:${instanceId}`;
13
14
  }
15
+ function extractChannelInstanceId(platform, prefix) {
16
+ const normalized = String(platform || '').trim();
17
+ const tag = `${prefix}:`;
18
+ return normalized.startsWith(tag) ? normalized.slice(tag.length).trim() : '';
19
+ }
14
20
  function runtimeKey(workspaceId, instanceId) {
15
21
  return `${workspaceId}::${instanceId}`;
16
22
  }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveInboundChannelAuthorization = resolveInboundChannelAuthorization;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const DEFAULT_PAIRING_EXPIRY_MS = 10 * 60 * 1000;
6
+ function resolveInboundChannelAuthorization(input) {
7
+ const { store, identity } = input;
8
+ store.expirePendingPairings();
9
+ let authorized = store.getAuthorizedUser(identity.workspaceId, identity.platformUserId, identity.platformKey);
10
+ let autoApproved = false;
11
+ if (!authorized && input.autoApprove) {
12
+ const authorizedAt = (input.now?.() || new Date()).toISOString();
13
+ store.createAuthorizedUser({
14
+ id: `${input.authorizedUserIdPrefix}-${(0, node_crypto_1.randomUUID)()}`,
15
+ workspace_id: identity.workspaceId,
16
+ platform: identity.platformKey,
17
+ platform_user_id: identity.platformUserId,
18
+ chat_id: identity.chatId,
19
+ display_name: identity.displayName,
20
+ thread_id: null,
21
+ authorized_at: authorizedAt,
22
+ });
23
+ authorized = store.getAuthorizedUser(identity.workspaceId, identity.platformUserId, identity.platformKey);
24
+ autoApproved = Boolean(authorized);
25
+ if (autoApproved) {
26
+ input.onStateChanged?.();
27
+ }
28
+ }
29
+ if (authorized) {
30
+ return { status: 'authorized', authorized, autoApproved };
31
+ }
32
+ const existingPending = store.listPendingPairings(identity.workspaceId).find((item) => item.platform === identity.platformKey &&
33
+ item.platform_user_id === identity.platformUserId &&
34
+ item.chat_id === identity.chatId &&
35
+ item.status === 'pending');
36
+ if (existingPending) {
37
+ return { status: 'pending', pairingCode: existingPending.code };
38
+ }
39
+ const now = input.now?.() || new Date();
40
+ const pairingCode = input.generatePairingCode();
41
+ store.createPairingRequest({
42
+ code: pairingCode,
43
+ workspace_id: identity.workspaceId,
44
+ platform: identity.platformKey,
45
+ platform_user_id: identity.platformUserId,
46
+ chat_id: identity.chatId,
47
+ display_name: identity.displayName,
48
+ requested_at: now.toISOString(),
49
+ expires_at: new Date(now.getTime() + (input.pairingExpiryMs || DEFAULT_PAIRING_EXPIRY_MS)).toISOString(),
50
+ status: 'pending',
51
+ });
52
+ input.onStateChanged?.();
53
+ return { status: 'pending', pairingCode };
54
+ }
@@ -15,7 +15,7 @@ exports.saveWeixinBuf = saveWeixinBuf;
15
15
  exports.collectWeixinWorkspaceBindings = collectWeixinWorkspaceBindings;
16
16
  const node_fs_1 = __importDefault(require("node:fs"));
17
17
  const node_path_1 = __importDefault(require("node:path"));
18
- const desktop_js_1 = require("../../../../../shared/desktop.js");
18
+ const superai_contracts_1 = require("../../../../../packages/contracts/src/index.js");
19
19
  const channel_keys_js_1 = require("../shared/channel-keys.js");
20
20
  exports.DEFAULT_BASE_URL = 'https://ilinkai.weixin.qq.com';
21
21
  exports.DEFAULT_CDN_BASE_URL = 'https://novac2c.cdn.weixin.qq.com/c2c';
@@ -75,7 +75,7 @@ function collectWeixinWorkspaceBindings(config) {
75
75
  const platforms = Array.isArray(project.platforms) ? project.platforms : [];
76
76
  return platforms
77
77
  .map((platform) => ({
78
- platformType: (0, desktop_js_1.normalizeDesktopPlatformType)(platform?.type),
78
+ platformType: (0, superai_contracts_1.normalizeDesktopPlatformType)(platform?.type),
79
79
  options: platform?.options && typeof platform.options === 'object'
80
80
  ? platform.options
81
81
  : {},
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createWeixinAttachmentContentPart = createWeixinAttachmentContentPart;
4
+ function createWeixinAttachmentContentPart(att) {
5
+ if (att.kind === 'image') {
6
+ if (!att.data)
7
+ return null;
8
+ return {
9
+ type: 'image',
10
+ data: att.data,
11
+ ...(att.uri ? { uri: att.uri } : {}),
12
+ mimeType: att.mimeType,
13
+ fileName: att.name,
14
+ };
15
+ }
16
+ return {
17
+ type: 'file',
18
+ path: att.path,
19
+ fileName: att.name,
20
+ };
21
+ }
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runWeixinInboundPoller = runWeixinInboundPoller;
4
+ const node_path_1 = require("node:path");
5
+ const local_core_errors_js_1 = require("../../kernel/local-core-errors.js");
6
+ const config_js_1 = require("./config.js");
7
+ const transport_js_1 = require("./transport.js");
8
+ const text_utils_js_1 = require("./text-utils.js");
9
+ const inbound_media_js_1 = require("./inbound-media.js");
10
+ const RETRY_DELAY_MS = 2_000;
11
+ const MAX_CONSECUTIVE_FAILURES = 3;
12
+ const ERROR_LOG_WINDOW_MS = 5 * 60 * 1000;
13
+ function computeRetryDelay(failures) {
14
+ if (failures <= 1)
15
+ return RETRY_DELAY_MS;
16
+ if (failures === 2)
17
+ return 5_000;
18
+ if (failures === 3)
19
+ return 15_000;
20
+ if (failures === 4)
21
+ return 30_000;
22
+ return 60_000;
23
+ }
24
+ async function runWeixinInboundPoller(input) {
25
+ const { binding, signal } = input;
26
+ const errorLogWindows = new Map();
27
+ let buf = (0, config_js_1.loadWeixinBuf)(binding);
28
+ let consecutiveFailures = 0;
29
+ const logPollError = (errorKey, message) => {
30
+ const key = `${binding.workspaceId}:${binding.instanceId}`;
31
+ const now = Date.now();
32
+ const current = errorLogWindows.get(key);
33
+ if (!current || current.errorKey !== errorKey || now - current.at >= ERROR_LOG_WINDOW_MS) {
34
+ input.log?.(current?.count && current.count > 1 ? `${message} (repeated ${current.count} times)` : message);
35
+ errorLogWindows.set(key, { at: now, count: 1, errorKey });
36
+ return;
37
+ }
38
+ current.count += 1;
39
+ errorLogWindows.set(key, current);
40
+ };
41
+ while (!signal.aborted) {
42
+ try {
43
+ const resp = await (0, transport_js_1.getWeixinUpdates)(binding, buf, signal);
44
+ const isApiError = (resp.ret !== undefined && resp.ret !== 0) || (resp.errcode !== undefined && resp.errcode !== 0);
45
+ if (isApiError) {
46
+ consecutiveFailures += 1;
47
+ const state = input.getRuntimeState();
48
+ const retryDelayMs = computeRetryDelay(consecutiveFailures);
49
+ if (resp.errcode === -14 || resp.ret === -14) {
50
+ if (state) {
51
+ state.status = 'error';
52
+ state.connected = false;
53
+ state.consecutiveFailures = consecutiveFailures;
54
+ state.nextRetryAt = new Date(Date.now() + retryDelayMs).toISOString();
55
+ input.setRuntimeError(state, (0, local_core_errors_js_1.toLocalCoreErrorInfo)(new local_core_errors_js_1.LocalCoreError('channel_session_expired', 'WeChat login expired.')));
56
+ input.notifyRuntimeStateChanged();
57
+ }
58
+ }
59
+ logPollError(`ret=${resp.ret} errcode=${resp.errcode} errmsg=${resp.errmsg || ''}`, `localcore-weixin getUpdates failed for ${binding.workspaceId}: ret=${resp.ret} errcode=${resp.errcode}${resp.errmsg ? ` errmsg=${resp.errmsg}` : ''} (${consecutiveFailures})`);
60
+ if (state && resp.errcode !== -14 && resp.ret !== -14) {
61
+ state.consecutiveFailures = consecutiveFailures;
62
+ state.nextRetryAt = new Date(Date.now() + retryDelayMs).toISOString();
63
+ }
64
+ await (0, text_utils_js_1.waitForWeixinRetry)(retryDelayMs, signal);
65
+ if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
66
+ consecutiveFailures = MAX_CONSECUTIVE_FAILURES;
67
+ }
68
+ continue;
69
+ }
70
+ consecutiveFailures = 0;
71
+ const state = input.getRuntimeState();
72
+ if (state) {
73
+ input.clearRuntimeError(state);
74
+ state.status = 'running';
75
+ state.connected = true;
76
+ input.notifyRuntimeStateChanged();
77
+ }
78
+ if (resp.get_updates_buf) {
79
+ buf = resp.get_updates_buf;
80
+ (0, config_js_1.saveWeixinBuf)(binding, buf);
81
+ }
82
+ for (const msg of resp.msgs ?? []) {
83
+ const items = msg.item_list ?? [];
84
+ const textItem = items.find((item) => item.type === transport_js_1.TEXT_ITEM_TYPE);
85
+ const voiceTextItems = items.filter((item) => item.type === transport_js_1.VOICE_ITEM_TYPE && item.voice_item?.text);
86
+ const mediaItems = items.filter((item) => item.type === transport_js_1.IMAGE_ITEM_TYPE || item.type === transport_js_1.FILE_ITEM_TYPE);
87
+ if (!textItem && voiceTextItems.length === 0 && mediaItems.length === 0)
88
+ continue;
89
+ const conversationId = msg.from_user_id ?? '';
90
+ const text = [textItem?.text_item?.text?.trim(), ...voiceTextItems.map((item) => item.voice_item?.text?.trim())]
91
+ .filter((part) => Boolean(part))
92
+ .join('\n\n');
93
+ const msgId = msg.msg_id ?? String(Date.now());
94
+ let attachmentText = '';
95
+ const attachmentParts = [];
96
+ if (mediaItems.length > 0) {
97
+ const uploadsDir = (0, node_path_1.join)(binding.stateDir, 'weixin-uploads');
98
+ const mayMaterializeAttachments = binding.allowFrom === '*' || Boolean(input.getAuthorizedUser(binding.workspaceId, conversationId, binding.platformKey));
99
+ if (!mayMaterializeAttachments) {
100
+ for (const item of mediaItems) {
101
+ const itemData = item.image_item ?? item.file_item ?? null;
102
+ const declaredName = String(itemData?.file_name ?? (item.type === transport_js_1.IMAGE_ITEM_TYPE ? 'image' : 'file'));
103
+ attachmentText += attachmentText ? '\n' : '';
104
+ attachmentText += item.type === transport_js_1.IMAGE_ITEM_TYPE ? '[Image]' : `[File: ${declaredName}]`;
105
+ }
106
+ }
107
+ else {
108
+ const downloads = await Promise.all(mediaItems.map(async (item, index) => {
109
+ try {
110
+ return await input.downloadMediaItem(item, msgId, index, uploadsDir, binding);
111
+ }
112
+ catch (error) {
113
+ input.log?.(`localcore-weixin attachment download failed (${conversationId}#${index}): ${(0, local_core_errors_js_1.formatSafeError)(error)}`);
114
+ return null;
115
+ }
116
+ }));
117
+ for (const attachment of downloads) {
118
+ if (!attachment) {
119
+ continue;
120
+ }
121
+ attachmentText += attachmentText ? '\n' : '';
122
+ attachmentText += attachment.kind === 'image'
123
+ ? `[Image: ${attachment.path}]`
124
+ : `[File "${attachment.name}": ${attachment.path}]`;
125
+ const part = (0, inbound_media_js_1.createWeixinAttachmentContentPart)(attachment);
126
+ if (part)
127
+ attachmentParts.push(part);
128
+ }
129
+ }
130
+ }
131
+ const fullText = [text, attachmentText].filter(Boolean).join('\n\n');
132
+ if (!fullText)
133
+ continue;
134
+ await input.handleInboundMessage({
135
+ workspaceId: binding.workspaceId,
136
+ instanceId: binding.instanceId,
137
+ platformKey: binding.platformKey,
138
+ platformUserId: conversationId,
139
+ chatId: conversationId,
140
+ displayName: conversationId.slice(-6),
141
+ text: fullText,
142
+ messageId: msgId,
143
+ contextToken: msg.context_token,
144
+ contentParts: [
145
+ ...(text ? [{ type: 'text', text }] : []),
146
+ ...attachmentParts,
147
+ ],
148
+ });
149
+ }
150
+ }
151
+ catch (error) {
152
+ if (signal.aborted)
153
+ return;
154
+ consecutiveFailures += 1;
155
+ const retryDelayMs = computeRetryDelay(consecutiveFailures);
156
+ const state = input.getRuntimeState();
157
+ if (state) {
158
+ state.consecutiveFailures = consecutiveFailures;
159
+ state.nextRetryAt = new Date(Date.now() + retryDelayMs).toISOString();
160
+ input.setRuntimeError(state, (0, local_core_errors_js_1.toLocalCoreErrorInfo)(error));
161
+ input.notifyRuntimeStateChanged();
162
+ }
163
+ logPollError((0, local_core_errors_js_1.formatSafeError)(error), `localcore-weixin getUpdates error for ${binding.workspaceId} (${consecutiveFailures}): ${(0, local_core_errors_js_1.formatSafeError)(error)}`);
164
+ await (0, text_utils_js_1.waitForWeixinRetry)(retryDelayMs, signal);
165
+ }
166
+ }
167
+ }