@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
|
@@ -9,7 +9,7 @@ exports.extractCardActionValue = extractCardActionValue;
|
|
|
9
9
|
exports.extractSessionCommandActionValue = extractSessionCommandActionValue;
|
|
10
10
|
exports.formatPermissionButtonLabel = formatPermissionButtonLabel;
|
|
11
11
|
exports.formatPermissionResponseLabel = formatPermissionResponseLabel;
|
|
12
|
-
const
|
|
12
|
+
const superai_contracts_1 = require("../../../../../packages/contracts/src/index.js");
|
|
13
13
|
function buildInteractiveCard(text, buttonRows = [], sessionKey, threadId) {
|
|
14
14
|
const elements = [];
|
|
15
15
|
if (text) {
|
|
@@ -27,7 +27,7 @@ function buildInteractiveCard(text, buttonRows = [], sessionKey, threadId) {
|
|
|
27
27
|
type: resolveLarkButtonType(button, index),
|
|
28
28
|
value: {
|
|
29
29
|
action: 'permission_response',
|
|
30
|
-
response: (0,
|
|
30
|
+
response: (0, superai_contracts_1.normalizePermissionResponse)(button.data) || button.data,
|
|
31
31
|
session_key: sessionKey || '',
|
|
32
32
|
thread_id: threadId || '',
|
|
33
33
|
},
|
|
@@ -61,7 +61,7 @@ function renderPermissionCard(turn, event, cardActionsEnabled) {
|
|
|
61
61
|
.filter((button) => Boolean(button?.text && button?.data))
|
|
62
62
|
.map((button) => ({
|
|
63
63
|
text: formatPermissionButtonLabel(button),
|
|
64
|
-
data: (0,
|
|
64
|
+
data: (0, superai_contracts_1.normalizePermissionResponse)(button.data) || button.data,
|
|
65
65
|
}))
|
|
66
66
|
: [])
|
|
67
67
|
.filter((row) => row.length > 0)
|
|
@@ -129,14 +129,12 @@ function extractCardActionMessageId(...payloads) {
|
|
|
129
129
|
return '';
|
|
130
130
|
}
|
|
131
131
|
function extractCardActionValue(payload) {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
: payload;
|
|
135
|
-
const value = event?.action?.value;
|
|
136
|
-
if (!value || value.action !== 'permission_response') {
|
|
132
|
+
const action = readLarkCardAction(payload, 'permission_response');
|
|
133
|
+
if (!action) {
|
|
137
134
|
return null;
|
|
138
135
|
}
|
|
139
|
-
const
|
|
136
|
+
const { event, value } = action;
|
|
137
|
+
const response = (0, superai_contracts_1.normalizePermissionResponse)(String(value.response || '').trim()) || String(value.response || '').trim();
|
|
140
138
|
const threadId = String(value.thread_id || '').trim();
|
|
141
139
|
const sessionKey = String(value.session_key || '').trim();
|
|
142
140
|
if (!response || !threadId) {
|
|
@@ -144,20 +142,18 @@ function extractCardActionValue(payload) {
|
|
|
144
142
|
}
|
|
145
143
|
return {
|
|
146
144
|
event,
|
|
147
|
-
value
|
|
145
|
+
value,
|
|
148
146
|
response,
|
|
149
147
|
threadId,
|
|
150
148
|
sessionKey,
|
|
151
149
|
};
|
|
152
150
|
}
|
|
153
151
|
function extractSessionCommandActionValue(payload) {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
: payload;
|
|
157
|
-
const value = event?.action?.value;
|
|
158
|
-
if (!value || value.action !== 'session_command') {
|
|
152
|
+
const action = readLarkCardAction(payload, 'session_command');
|
|
153
|
+
if (!action) {
|
|
159
154
|
return null;
|
|
160
155
|
}
|
|
156
|
+
const { event, value } = action;
|
|
161
157
|
const command = String(value.command || '').trim();
|
|
162
158
|
const threadId = String(value.thread_id || '').trim();
|
|
163
159
|
const sessionKey = String(value.session_key || '').trim();
|
|
@@ -166,17 +162,36 @@ function extractSessionCommandActionValue(payload) {
|
|
|
166
162
|
}
|
|
167
163
|
return {
|
|
168
164
|
event,
|
|
169
|
-
value
|
|
165
|
+
value,
|
|
170
166
|
command,
|
|
171
167
|
threadId,
|
|
172
168
|
sessionKey,
|
|
173
169
|
};
|
|
174
170
|
}
|
|
171
|
+
function readLarkCardAction(payload, expectedAction) {
|
|
172
|
+
const eventCandidate = payload.event;
|
|
173
|
+
const event = eventCandidate && typeof eventCandidate === 'object'
|
|
174
|
+
? eventCandidate
|
|
175
|
+
: payload;
|
|
176
|
+
const actionCandidate = event.action;
|
|
177
|
+
if (!actionCandidate || typeof actionCandidate !== 'object') {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
const valueCandidate = actionCandidate.value;
|
|
181
|
+
if (!valueCandidate || typeof valueCandidate !== 'object') {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
const value = valueCandidate;
|
|
185
|
+
if (value.action !== expectedAction) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
return { event, value };
|
|
189
|
+
}
|
|
175
190
|
function formatPermissionButtonLabel(button) {
|
|
176
191
|
return formatPermissionResponseLabel(button.data || button.text);
|
|
177
192
|
}
|
|
178
193
|
function formatPermissionResponseLabel(response) {
|
|
179
|
-
switch ((0,
|
|
194
|
+
switch ((0, superai_contracts_1.normalizePermissionResponse)(response) || response) {
|
|
180
195
|
case 'allow':
|
|
181
196
|
return '允许一次';
|
|
182
197
|
case 'allow all':
|
|
@@ -188,7 +203,7 @@ function formatPermissionResponseLabel(response) {
|
|
|
188
203
|
}
|
|
189
204
|
}
|
|
190
205
|
function resolveLarkButtonType(button, index) {
|
|
191
|
-
const response = (0,
|
|
206
|
+
const response = (0, superai_contracts_1.normalizePermissionResponse)(button.data) || (0, superai_contracts_1.normalizePermissionResponse)(button.text);
|
|
192
207
|
if (response === 'deny') {
|
|
193
208
|
return 'danger';
|
|
194
209
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.collectLarkWorkspaceBindings = collectLarkWorkspaceBindings;
|
|
4
|
-
const
|
|
4
|
+
const superai_contracts_1 = require("../../../../../packages/contracts/src/index.js");
|
|
5
5
|
const channel_keys_js_1 = require("../shared/channel-keys.js");
|
|
6
6
|
function collectLarkWorkspaceBindings(config, options) {
|
|
7
7
|
const projects = Array.isArray(config?.projects) ? config.projects : [];
|
|
@@ -9,7 +9,7 @@ function collectLarkWorkspaceBindings(config, options) {
|
|
|
9
9
|
const platforms = Array.isArray(project.platforms) ? project.platforms : [];
|
|
10
10
|
return platforms
|
|
11
11
|
.map((platform) => ({
|
|
12
|
-
platformType: (0,
|
|
12
|
+
platformType: (0, superai_contracts_1.normalizeDesktopPlatformType)(platform?.type),
|
|
13
13
|
options: platform?.options && typeof platform.options === 'object'
|
|
14
14
|
? platform.options
|
|
15
15
|
: {},
|
|
@@ -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;
|