@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.
- package/README.md +7 -0
- package/dist/renderer/assets/{Badge-DjcoXx2J.js → Badge-BfY1VaHS.js} +1 -1
- package/dist/renderer/assets/Card-DWA_Tww_.js +1 -0
- package/dist/renderer/assets/Config-nHj3g1U5.js +21 -0
- package/dist/renderer/assets/CronList-BwkA_I7v.js +1 -0
- package/dist/renderer/assets/Dashboard-D0_A7k02.js +41 -0
- package/dist/renderer/assets/{EmptyState-DIZLiccW.js → EmptyState-zatDjLj_.js} +1 -1
- package/dist/renderer/assets/HighlightedMarkdown-CsM5n70d.js +12 -0
- package/dist/renderer/assets/Input-R1XdFK1K.js +1 -0
- package/dist/renderer/assets/{KnowledgeDetail-CJ9IYOsa.js → KnowledgeDetail-Co5sxeGd.js} +2 -2
- package/dist/renderer/assets/{KnowledgeHome-BLGPwnBO.js → KnowledgeHome-DwziPw5m.js} +3 -3
- package/dist/renderer/assets/Logs-NwZUtR_G.js +6 -0
- package/dist/renderer/assets/{Modal-CQiUpfl4.js → Modal-CrcIwIFL.js} +3 -3
- package/dist/renderer/assets/MonitorList-CS1uLS5A.js +1 -0
- package/dist/renderer/assets/Page-Dp0obeSw.js +1 -0
- package/dist/renderer/assets/{Select-D6z65IT3.js → Select-6mVQaf84.js} +2 -2
- package/dist/renderer/assets/ThreadChat-BFzbn3L6.js +86 -0
- package/dist/renderer/assets/Workspace-DCmo8BMm.js +19 -0
- package/dist/renderer/assets/{arrow-left-CV5cL3f4.js → arrow-left-9rjg_Hp4.js} +1 -1
- package/dist/renderer/assets/{book-open-DThvB7pj.js → book-open-Bu8GCHnG.js} +1 -1
- package/dist/renderer/assets/channels-BxVbG-6j.js +6 -0
- package/dist/renderer/assets/chevron-down-BE8uQmWM.js +11 -0
- package/dist/renderer/assets/index-B7TeF6Es.js +41 -0
- package/dist/renderer/assets/index-BIKL3fTP.css +11 -0
- package/dist/renderer/assets/index-BkI9POxj.js +167 -0
- package/dist/renderer/assets/knowledge-Kl19SqGS.js +1 -0
- package/dist/renderer/assets/{pencil-Dv5WxhdC.js → pencil-CPB7SK1m.js} +1 -1
- package/dist/renderer/assets/{play-DnCnft83.js → play-DGAO4OCu.js} +1 -1
- package/dist/renderer/assets/{plus-DsxIagzS.js → plus-Bt26z-4q.js} +1 -1
- package/dist/renderer/assets/{save-CST01lIc.js → save-Une7GMxT.js} +1 -1
- package/dist/renderer/assets/{search-B_bqy6Wd.js → search-DE0agJjJ.js} +1 -1
- package/dist/renderer/assets/{shield-check-D6lG5Aoc.js → shield-check-De7xaXZh.js} +1 -1
- package/dist/renderer/assets/threads-BnsNL5ei.js +1 -0
- package/dist/renderer/assets/{trash-2-Cefngb6Q.js → trash-2-6iGF59Ac.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/automation/automation-conversation-executor.js +6 -47
- package/dist-electron/services/local-ai-core/src/automation/automation-monitor-service.js +2 -5
- 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 +58 -539
- package/dist-electron/services/local-ai-core/src/channel/lark/outbound-transport.js +112 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +5 -20
- package/dist-electron/services/local-ai-core/src/channel/shared/base-channel-gateway.js +37 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/bridge-event-helpers.js +23 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/channel-keys.js +6 -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 +55 -512
- package/dist-electron/services/local-ai-core/src/channel/weixin/runtime-state.js +149 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/text-utils.js +92 -0
- package/dist-electron/services/local-ai-core/src/cli/lac.js +9 -11
- package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +2 -2
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +28 -70
- package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +8 -0
- 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/opensandbox-client.js +3 -2
- package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +8 -8
- package/dist-electron/services/local-ai-core/src/scheduler/base-channel-schedule-adapter.js +77 -0
- package/dist-electron/services/local-ai-core/src/scheduler/lark-schedule-adapter.js +13 -79
- package/dist-electron/services/local-ai-core/src/scheduler/local-schedule-adapter.js +2 -10
- package/dist-electron/services/local-ai-core/src/scheduler/run-polling.js +19 -0
- package/dist-electron/services/local-ai-core/src/scheduler/scheduled-conversation-executor.js +3 -37
- package/dist-electron/services/local-ai-core/src/scheduler/scheduled-job-route.js +20 -0
- package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +15 -28
- package/dist-electron/services/local-ai-core/src/scheduler/thread-resolution.js +12 -0
- package/dist-electron/services/local-ai-core/src/scheduler/weixin-schedule-adapter.js +13 -79
- 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/local-core-refactor.test.js +15 -8
- 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/services/local-ai-core/src/scheduler/lark-execution-policies.js +0 -13
- package/dist-electron/services/local-ai-core/src/scheduler/weixin-execution-policies.js +0 -13
- 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,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
|
-
|
|
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
|
|
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,
|
|
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
|
+
}
|