@kafca/agentdock 0.1.39 → 0.1.41
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 +5 -0
- package/dist/renderer/assets/{Badge-B8Arb9Yy.js → Badge-BX3RC8l6.js} +1 -1
- package/dist/renderer/assets/{Chat-BpHN2UcX.js → Chat-DJwIciel.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-C_zHbGhg.js → ChatMarkdown-DfGbRR0S.js} +1 -1
- package/dist/renderer/assets/{Config-357M6MbD.js → Config-2x2RDL3j.js} +1 -1
- package/dist/renderer/assets/{CronList-BHgDIhFo.js → CronList-C6nPAmEo.js} +1 -1
- package/dist/renderer/assets/{Dashboard-CZQj79ep.js → Dashboard-2Wcx_bvJ.js} +2 -2
- package/dist/renderer/assets/{EmptyState-DpSPN3kz.js → EmptyState-DoCpF2tn.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Cbv2Oje7.js → KnowledgeDetail-CBRu2bXX.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-CEbNw_Za.js → KnowledgeHome-CItdlDVR.js} +1 -1
- package/dist/renderer/assets/{Logs-IXayiVGS.js → Logs-Cd_7ZOXc.js} +1 -1
- package/dist/renderer/assets/{Modal-BTKWx2e5.js → Modal-B4eOiBsB.js} +1 -1
- package/dist/renderer/assets/{Page-DCDVvqIU.js → Page-C5VH4D9U.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-C6as_oba.js → ProjectDetail-D_DA--IP.js} +1 -1
- package/dist/renderer/assets/{ProjectList-DJfBaPyw.js → ProjectList-CtCXJ50u.js} +1 -1
- package/dist/renderer/assets/{Select-BYijPrOF.js → Select-B6E68LcN.js} +1 -1
- package/dist/renderer/assets/{SessionChat-KapIGn1O.js → SessionChat-D1HtMdQS.js} +1 -1
- package/dist/renderer/assets/{SessionList-C0ATtS_m.js → SessionList-Do-5-Xx6.js} +1 -1
- package/dist/renderer/assets/{ThreadChat-CKWcyHia.js → ThreadChat-B1tEtE3V.js} +1 -1
- package/dist/renderer/assets/{Workspace-MYHdNNV2.js → Workspace-BlhS2RFw.js} +1 -1
- package/dist/renderer/assets/{arrow-left-Dl2cYCYQ.js → arrow-left-DF1_F9Pk.js} +1 -1
- package/dist/renderer/assets/{book-open-CJCjYKCj.js → book-open-DxRTGpWO.js} +1 -1
- package/dist/renderer/assets/{check-Cknz-_NI.js → check-BAqPPYkf.js} +1 -1
- package/dist/renderer/assets/{chevron-down-v4poAoll.js → chevron-down-DIZZgSb3.js} +1 -1
- package/dist/renderer/assets/{circle-BnxuF8S1.js → circle-B5raL_XK.js} +1 -1
- package/dist/renderer/assets/{desktop-B9xqa1yi.js → desktop-CFcnzwcY.js} +1 -1
- package/dist/renderer/assets/{funnel-Cl1EldnW.js → funnel-BPjLpVSB.js} +1 -1
- package/dist/renderer/assets/{heart-274KWkSA.js → heart-D2M1xN1N.js} +1 -1
- package/dist/renderer/assets/{index-GaRPrxQn.js → index-BijJAYmo.js} +1 -1
- package/dist/renderer/assets/{index-CAi_EMRl.js → index-Cx71F_Lz.js} +2 -2
- package/dist/renderer/assets/{pencil-BfYhgp9_.js → pencil-DlDr8Mmp.js} +1 -1
- package/dist/renderer/assets/{play-CLir9KyW.js → play-BOEG_mY8.js} +1 -1
- package/dist/renderer/assets/{plug-CTKL_TK4.js → plug-BI27elC-.js} +1 -1
- package/dist/renderer/assets/{plus-9pP7UU-H.js → plus-BhURuFIQ.js} +1 -1
- package/dist/renderer/assets/projects-DpR972HM.js +1 -0
- package/dist/renderer/assets/{save-DZOLXcQU.js → save-RwkHNm9e.js} +1 -1
- package/dist/renderer/assets/{search-DjFl-8XR.js → search-DMNtm2WP.js} +1 -1
- package/dist/renderer/assets/{server-UI3KEpUw.js → server-CNaxKyAq.js} +1 -1
- package/dist/renderer/assets/{session-utils-b9gwOizd.js → session-utils-vsALZkZN.js} +1 -1
- package/dist/renderer/assets/{sessions-DzSZ5A3m.js → sessions-BY-R1IL_.js} +1 -1
- package/dist/renderer/assets/{shield-check-6fT5xdT3.js → shield-check-BF-4oJbj.js} +1 -1
- package/dist/renderer/assets/{trash-2-DNBg0OLf.js → trash-2-DduflM4q.js} +1 -1
- package/dist/renderer/assets/{user-B0MGTipJ.js → user-DBcvnuW4.js} +1 -1
- package/dist/renderer/assets/{wifi-off-DBxNxGco.js → wifi-off-X1nXESYu.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +2 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +25 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +31 -8
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +21 -11
- package/dist-electron/services/local-ai-core/src/channel/lark/post.js +7 -70
- package/dist-electron/services/local-ai-core/src/channel/lark/rendering/markdown.js +94 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/rendering/messages.js +51 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +14 -0
- package/dist-electron/tests/integration/lark-rendering.test.js +123 -0
- package/dist-electron/tests/integration/local-core-refactor.test.js +176 -22
- package/package.json +1 -1
- package/dist/renderer/assets/projects-DRdvUEj2.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as t}from"./index-Cx71F_Lz.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as o}from"./index-
|
|
1
|
+
import{z as o}from"./index-Cx71F_Lz.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
|
package/dist/renderer/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>AgentDock</title>
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-Cx71F_Lz.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="./assets/index-CaQZSRbg.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="bg-[#f5f5f7] dark:bg-[#151516]">
|
|
@@ -324,6 +324,8 @@ class LocalCoreAcpBackend {
|
|
|
324
324
|
agentType: row.agent_type,
|
|
325
325
|
assistantText: '',
|
|
326
326
|
rawAssistantText: '',
|
|
327
|
+
assistantSequence: 1,
|
|
328
|
+
assistantMessageId: `${runId}-assistant-1`,
|
|
327
329
|
priorAssistantFinalMessages,
|
|
328
330
|
priorAssistantProgressMessages,
|
|
329
331
|
thoughtText: '',
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.applyAssistantMessageChunk = applyAssistantMessageChunk;
|
|
4
4
|
exports.applyThoughtChunk = applyThoughtChunk;
|
|
5
5
|
exports.closeThoughtSegment = closeThoughtSegment;
|
|
6
|
+
exports.closeAssistantMessageSegment = closeAssistantMessageSegment;
|
|
6
7
|
exports.registerPendingToolCall = registerPendingToolCall;
|
|
7
8
|
exports.resolveToolCallForUpdate = resolveToolCallForUpdate;
|
|
8
9
|
exports.resolveFallbackToolCall = resolveFallbackToolCall;
|
|
@@ -81,6 +82,30 @@ function closeThoughtSegment(currentTurn) {
|
|
|
81
82
|
currentTurn.thoughtMessageId = `${runId}-thought-${nextSequence}`;
|
|
82
83
|
currentTurn.thoughtPreviewHandle = `${runId}-thought-preview-${nextSequence}`;
|
|
83
84
|
}
|
|
85
|
+
function closeAssistantMessageSegment(currentTurn) {
|
|
86
|
+
const content = currentTurn.assistantText || '';
|
|
87
|
+
if (!content.trim()) {
|
|
88
|
+
resetAssistantMessageSegment(currentTurn);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const messageId = currentTurn.assistantMessageId || currentTurn.previewHandle;
|
|
92
|
+
resetAssistantMessageSegment(currentTurn);
|
|
93
|
+
return {
|
|
94
|
+
messageId,
|
|
95
|
+
content,
|
|
96
|
+
bridgeKind: 'assistant',
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function resetAssistantMessageSegment(currentTurn) {
|
|
100
|
+
const runId = currentTurn.runId || 'assistant';
|
|
101
|
+
const nextSequence = (currentTurn.assistantSequence || 1) + 1;
|
|
102
|
+
currentTurn.assistantSequence = nextSequence;
|
|
103
|
+
currentTurn.assistantText = '';
|
|
104
|
+
currentTurn.rawAssistantText = '';
|
|
105
|
+
currentTurn.previewStarted = false;
|
|
106
|
+
currentTurn.assistantMessageId = `${runId}-assistant-${nextSequence}`;
|
|
107
|
+
currentTurn.previewHandle = `${runId}-assistant-preview-${nextSequence}`;
|
|
108
|
+
}
|
|
84
109
|
function mergeThoughtSegment(current, next) {
|
|
85
110
|
if (!current) {
|
|
86
111
|
return { fullText: next, segmentText: next };
|
|
@@ -17,6 +17,31 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
17
17
|
if (currentTurn)
|
|
18
18
|
(0, local_core_acp_progress_js_1.closeThoughtSegment)(currentTurn);
|
|
19
19
|
}
|
|
20
|
+
closePendingAssistantSegment(session) {
|
|
21
|
+
const currentTurn = session.currentTurn;
|
|
22
|
+
const currentRunId = session.currentRunId;
|
|
23
|
+
if (!currentTurn || !currentRunId) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const projection = (0, local_core_acp_progress_js_1.closeAssistantMessageSegment)(currentTurn);
|
|
27
|
+
if (!projection) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (this.options.upsertMessage) {
|
|
31
|
+
this.options.upsertMessage(session.threadId, projection.messageId, 'assistant', projection.content, 'progress', undefined, projection.bridgeKind);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.options.appendMessage(session.threadId, 'assistant', projection.content, 'progress', undefined, projection.bridgeKind);
|
|
35
|
+
}
|
|
36
|
+
this.options.emitBridge({
|
|
37
|
+
type: 'reply',
|
|
38
|
+
sessionKey: session.bridgeSessionKey,
|
|
39
|
+
replyCtx: currentRunId,
|
|
40
|
+
messageId: projection.messageId,
|
|
41
|
+
bridgeKind: projection.bridgeKind,
|
|
42
|
+
content: projection.content,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
20
45
|
flushPendingToolCall(session) {
|
|
21
46
|
const currentTurn = session.currentTurn;
|
|
22
47
|
const currentRunId = session.currentRunId;
|
|
@@ -112,6 +137,7 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
112
137
|
params: payload.params,
|
|
113
138
|
}) || parsedOptions;
|
|
114
139
|
const toolTitle = (0, workspace_acp_permissions_js_1.formatToolCallContent)(payload.params?.toolCall);
|
|
140
|
+
this.closePendingAssistantSegment(session);
|
|
115
141
|
this.closePendingThoughtSegment(session);
|
|
116
142
|
const effectiveAgentMode = session.launchPermissionMode || this.options.getThreadAgentMode?.(session.threadId) || local_core_slash_commands_js_1.DEFAULT_AGENT_MODE;
|
|
117
143
|
if (effectiveAgentMode === 'bypassPermissions') {
|
|
@@ -213,6 +239,7 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
213
239
|
return;
|
|
214
240
|
}
|
|
215
241
|
if (isToolScopedAssistantUpdate(update) || consumeRawAssistantProgressChunk(session, String(update.content.text || ''))) {
|
|
242
|
+
this.closePendingAssistantSegment(session);
|
|
216
243
|
const content = String(update.content.text || '').trim();
|
|
217
244
|
if (content) {
|
|
218
245
|
if (this.shouldSuppressProgress(currentTurn, 'tool', content)) {
|
|
@@ -246,17 +273,10 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
246
273
|
if (!projection) {
|
|
247
274
|
return;
|
|
248
275
|
}
|
|
249
|
-
this.options.emitBridge({
|
|
250
|
-
type: projection.bridgeType,
|
|
251
|
-
sessionKey: session.bridgeSessionKey,
|
|
252
|
-
replyCtx: currentRunId,
|
|
253
|
-
previewHandle: projection.previewHandle,
|
|
254
|
-
bridgeKind: projection.bridgeKind,
|
|
255
|
-
content: projection.content,
|
|
256
|
-
});
|
|
257
276
|
return;
|
|
258
277
|
}
|
|
259
278
|
case 'agent_thought_chunk': {
|
|
279
|
+
this.closePendingAssistantSegment(session);
|
|
260
280
|
if (update.content?.type !== 'text') {
|
|
261
281
|
return;
|
|
262
282
|
}
|
|
@@ -282,6 +302,7 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
282
302
|
return;
|
|
283
303
|
}
|
|
284
304
|
case 'tool_call': {
|
|
305
|
+
this.closePendingAssistantSegment(session);
|
|
285
306
|
this.closePendingThoughtSegment(session);
|
|
286
307
|
const toolCall = (0, local_core_acp_progress_js_1.registerPendingToolCall)({ currentTurn, runId: currentRunId, update });
|
|
287
308
|
if (this.isKnownPriorToolInput(currentTurn, toolCall.title, toolCall.input)) {
|
|
@@ -298,6 +319,7 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
298
319
|
return;
|
|
299
320
|
}
|
|
300
321
|
case 'tool_call_update': {
|
|
322
|
+
this.closePendingAssistantSegment(session);
|
|
301
323
|
this.closePendingThoughtSegment(session);
|
|
302
324
|
const title = String(update.title || 'Tool update').trim();
|
|
303
325
|
const status = String(update.status || '').trim();
|
|
@@ -366,6 +388,7 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
366
388
|
return;
|
|
367
389
|
}
|
|
368
390
|
case 'plan': {
|
|
391
|
+
this.closePendingAssistantSegment(session);
|
|
369
392
|
this.closePendingThoughtSegment(session);
|
|
370
393
|
this.flushPendingToolCall(session);
|
|
371
394
|
const entries = Array.isArray(update.entries) ? update.entries : [];
|
|
@@ -44,7 +44,7 @@ const file_utils_js_1 = require("../shared/file-utils.js");
|
|
|
44
44
|
const cards_js_1 = require("./cards.js");
|
|
45
45
|
const config_js_1 = require("./config.js");
|
|
46
46
|
const registration_js_1 = require("./registration.js");
|
|
47
|
-
const
|
|
47
|
+
const messages_js_1 = require("./rendering/messages.js");
|
|
48
48
|
const runtime_state_js_1 = require("./runtime-state.js");
|
|
49
49
|
const PAIRING_EXPIRY_MS = 10 * 60 * 1000;
|
|
50
50
|
const LARK_MAX_UPLOAD_FILE_SIZE = 30 * 1024 * 1024;
|
|
@@ -219,7 +219,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
219
219
|
if (part.type === 'text') {
|
|
220
220
|
const text = String(part.text || '').trim();
|
|
221
221
|
if (text) {
|
|
222
|
-
messageIds.push(await this.
|
|
222
|
+
messageIds.push((await this.sendTextAsMessage(state, channelId, text)).messageId);
|
|
223
223
|
}
|
|
224
224
|
continue;
|
|
225
225
|
}
|
|
@@ -514,15 +514,20 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
514
514
|
continue;
|
|
515
515
|
}
|
|
516
516
|
if (!existingMessageId) {
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
|
|
517
|
+
const sendAsPlainMessage = renderedMessage.delivery === 'message' && renderedMessage.buttonRows.length === 0;
|
|
518
|
+
const sentMessage = sendAsPlainMessage
|
|
519
|
+
? await this.sendTextAsMessage(state, route.chatId, renderedMessage.text)
|
|
520
|
+
: {
|
|
521
|
+
messageId: await this.sendTextAsCard(state, route.chatId, renderedMessage.text, renderedMessage.buttonRows, sessionKey, bridgeThreadId),
|
|
522
|
+
renderKind: 'card',
|
|
523
|
+
};
|
|
524
|
+
const createdId = sentMessage.messageId;
|
|
520
525
|
if (createdId) {
|
|
521
526
|
(0, runtime_state_js_1.setLarkRenderedMessageId)(turn, renderedMessage, createdId);
|
|
522
527
|
if (renderedMessage.isFinal) {
|
|
523
528
|
this.options.store.updatePlatformThreadMessageId(route.workspaceId, route.chatId, route.platformUserId, createdId, routePlatformKey);
|
|
524
529
|
}
|
|
525
|
-
this.options.log?.(`localcore-lark sent new ${
|
|
530
|
+
this.options.log?.(`localcore-lark sent new ${sentMessage.renderKind} message ${createdId} for sessionKey=${sessionKey}`);
|
|
526
531
|
}
|
|
527
532
|
continue;
|
|
528
533
|
}
|
|
@@ -1152,20 +1157,25 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1152
1157
|
this.options.log?.(`localcore-lark card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1153
1158
|
return String(response?.data?.message_id || '').trim();
|
|
1154
1159
|
}
|
|
1155
|
-
async
|
|
1160
|
+
async sendTextAsMessage(state, chatId, text) {
|
|
1156
1161
|
const startedAt = Date.now();
|
|
1162
|
+
const rendered = (0, messages_js_1.renderLarkTextMessage)(text);
|
|
1157
1163
|
const response = await state.client.im.message.create({
|
|
1158
1164
|
params: {
|
|
1159
1165
|
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
1160
1166
|
},
|
|
1161
1167
|
data: {
|
|
1162
1168
|
receive_id: chatId,
|
|
1163
|
-
msg_type:
|
|
1164
|
-
content: JSON.stringify(
|
|
1169
|
+
msg_type: rendered.msgType,
|
|
1170
|
+
content: JSON.stringify(rendered.content),
|
|
1165
1171
|
},
|
|
1166
1172
|
});
|
|
1167
|
-
this.options.log?.(`localcore-lark
|
|
1168
|
-
return
|
|
1173
|
+
this.options.log?.(`localcore-lark ${rendered.renderKind} create took ${Date.now() - startedAt}ms msgType=${rendered.msgType} reason=${rendered.reason} tableCount=${rendered.tableCount} textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1174
|
+
return {
|
|
1175
|
+
messageId: String(response?.data?.message_id || '').trim(),
|
|
1176
|
+
renderKind: rendered.renderKind,
|
|
1177
|
+
msgType: rendered.msgType,
|
|
1178
|
+
};
|
|
1169
1179
|
}
|
|
1170
1180
|
resolveReceiveIdType(receiveId) {
|
|
1171
1181
|
return receiveId.startsWith('oc_') ? 'chat_id' : receiveId.startsWith('ou_') ? 'open_id' : 'user_id';
|
|
@@ -1,72 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildLarkPostContent =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
function renderLarkPostLines(markdown) {
|
|
13
|
-
const lines = String(markdown || '').replace(/\r\n/g, '\n').split('\n');
|
|
14
|
-
const rendered = [];
|
|
15
|
-
let codeFence = null;
|
|
16
|
-
for (const line of lines) {
|
|
17
|
-
const fence = matchFence(line);
|
|
18
|
-
if (fence) {
|
|
19
|
-
if (codeFence && fence.marker[0] === codeFence.marker[0] && fence.marker.length >= codeFence.marker.length) {
|
|
20
|
-
rendered.push([{
|
|
21
|
-
tag: 'code_block',
|
|
22
|
-
language: codeFence.language,
|
|
23
|
-
text: codeFence.lines.join('\n'),
|
|
24
|
-
}]);
|
|
25
|
-
codeFence = null;
|
|
26
|
-
}
|
|
27
|
-
else if (!codeFence) {
|
|
28
|
-
codeFence = {
|
|
29
|
-
marker: fence.marker,
|
|
30
|
-
language: fence.language,
|
|
31
|
-
lines: [],
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
codeFence.lines.push(line);
|
|
36
|
-
}
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (codeFence) {
|
|
40
|
-
codeFence.lines.push(line);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (!line.trim()) {
|
|
44
|
-
rendered.push([{ tag: 'text', text: '' }]);
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
rendered.push([{ tag: 'md', text: sanitizeLarkPostMarkdown(line) }]);
|
|
48
|
-
}
|
|
49
|
-
if (codeFence) {
|
|
50
|
-
rendered.push([{
|
|
51
|
-
tag: 'code_block',
|
|
52
|
-
language: codeFence.language,
|
|
53
|
-
text: codeFence.lines.join('\n'),
|
|
54
|
-
}]);
|
|
55
|
-
}
|
|
56
|
-
return rendered;
|
|
57
|
-
}
|
|
58
|
-
function matchFence(line) {
|
|
59
|
-
const match = line.trim().match(/^(`{3,}|~{3,})([A-Za-z0-9_-]*)\s*$/);
|
|
60
|
-
if (!match) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
marker: match[1],
|
|
65
|
-
language: match[2] || '',
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function sanitizeLarkPostMarkdown(markdown) {
|
|
69
|
-
return markdown.replace(/\[([^\]]*)\]\(([^)]+)\)/g, (match, label, href) => {
|
|
70
|
-
return /^https?:\/\//i.test(href) ? match : `${label} (${href})`;
|
|
71
|
-
});
|
|
72
|
-
}
|
|
3
|
+
exports.shouldUseLarkMarkdownCard = exports.renderLarkTextMessage = exports.normalizeMarkdownTablesForLarkPost = exports.buildLarkPostContent = exports.buildLarkMarkdownCardContent = void 0;
|
|
4
|
+
var messages_js_1 = require("./rendering/messages.js");
|
|
5
|
+
Object.defineProperty(exports, "buildLarkMarkdownCardContent", { enumerable: true, get: function () { return messages_js_1.buildLarkMarkdownCardContent; } });
|
|
6
|
+
Object.defineProperty(exports, "buildLarkPostContent", { enumerable: true, get: function () { return messages_js_1.buildLarkPostContent; } });
|
|
7
|
+
Object.defineProperty(exports, "normalizeMarkdownTablesForLarkPost", { enumerable: true, get: function () { return messages_js_1.normalizeMarkdownTablesForLarkPost; } });
|
|
8
|
+
Object.defineProperty(exports, "renderLarkTextMessage", { enumerable: true, get: function () { return messages_js_1.renderLarkTextMessage; } });
|
|
9
|
+
Object.defineProperty(exports, "shouldUseLarkMarkdownCard", { enumerable: true, get: function () { return messages_js_1.shouldUseLarkMarkdownCard; } });
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LARK_CARD_MARKDOWN_TABLE_LIMIT = void 0;
|
|
4
|
+
exports.sanitizeLarkMarkdown = sanitizeLarkMarkdown;
|
|
5
|
+
exports.countMarkdownTables = countMarkdownTables;
|
|
6
|
+
exports.shouldUseLarkMarkdownCard = shouldUseLarkMarkdownCard;
|
|
7
|
+
exports.normalizeMarkdownTablesForLarkPost = normalizeMarkdownTablesForLarkPost;
|
|
8
|
+
exports.LARK_CARD_MARKDOWN_TABLE_LIMIT = 5;
|
|
9
|
+
function sanitizeLarkMarkdown(markdown) {
|
|
10
|
+
return markdown.replace(/\[([^\]]*)\]\(([^)]+)\)/g, (match, label, href) => {
|
|
11
|
+
return /^https?:\/\//i.test(href) ? match : `${label} (${href})`;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function countMarkdownTables(markdown) {
|
|
15
|
+
const lines = String(markdown || '').split('\n');
|
|
16
|
+
let count = 0;
|
|
17
|
+
let inTable = false;
|
|
18
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
19
|
+
const isTableStart = isMarkdownTableLine(lines[index]) && isMarkdownTableSeparatorLine(lines[index + 1]);
|
|
20
|
+
const isTableBody = inTable && isMarkdownTableLine(lines[index]);
|
|
21
|
+
if (isTableStart && !inTable) {
|
|
22
|
+
count += 1;
|
|
23
|
+
inTable = true;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (!isTableBody) {
|
|
27
|
+
inTable = false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return count;
|
|
31
|
+
}
|
|
32
|
+
function shouldUseLarkMarkdownCard(markdown) {
|
|
33
|
+
const tableCount = countMarkdownTables(markdown);
|
|
34
|
+
return tableCount > 0 && tableCount <= exports.LARK_CARD_MARKDOWN_TABLE_LIMIT;
|
|
35
|
+
}
|
|
36
|
+
function normalizeMarkdownTablesForLarkPost(markdown) {
|
|
37
|
+
const lines = markdown.split('\n');
|
|
38
|
+
const output = [];
|
|
39
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
40
|
+
if (isMarkdownTableLine(lines[index]) && isMarkdownTableSeparatorLine(lines[index + 1])) {
|
|
41
|
+
const tableLines = [lines[index], lines[index + 1]];
|
|
42
|
+
index += 2;
|
|
43
|
+
while (index < lines.length && isMarkdownTableLine(lines[index])) {
|
|
44
|
+
tableLines.push(lines[index]);
|
|
45
|
+
index += 1;
|
|
46
|
+
}
|
|
47
|
+
index -= 1;
|
|
48
|
+
output.push(renderMarkdownTableAsList(tableLines));
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
output.push(lines[index]);
|
|
52
|
+
}
|
|
53
|
+
return output.join('\n');
|
|
54
|
+
}
|
|
55
|
+
function isMarkdownTableLine(line) {
|
|
56
|
+
const trimmed = String(line || '').trim();
|
|
57
|
+
return trimmed.length > 1 && trimmed.startsWith('|') && trimmed.endsWith('|');
|
|
58
|
+
}
|
|
59
|
+
function isMarkdownTableSeparatorLine(line) {
|
|
60
|
+
if (!isMarkdownTableLine(line)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const cells = splitMarkdownTableRow(String(line));
|
|
64
|
+
return cells.length > 0 && cells.every((cell) => /^:?-{3,}:?$/.test(cell.trim()));
|
|
65
|
+
}
|
|
66
|
+
function splitMarkdownTableRow(line) {
|
|
67
|
+
return line.trim().replace(/^\|/, '').replace(/\|$/, '').split('|').map((cell) => cell.trim());
|
|
68
|
+
}
|
|
69
|
+
function renderMarkdownTableAsList(tableLines) {
|
|
70
|
+
const headers = splitMarkdownTableRow(tableLines[0] || '');
|
|
71
|
+
const bodyRows = tableLines.slice(2).map(splitMarkdownTableRow);
|
|
72
|
+
if (headers.length === 0 || bodyRows.length === 0) {
|
|
73
|
+
return tableLines.join('\n');
|
|
74
|
+
}
|
|
75
|
+
return bodyRows
|
|
76
|
+
.map((cells, rowIndex) => renderMarkdownTableRow(headers, cells, rowIndex))
|
|
77
|
+
.join('\n');
|
|
78
|
+
}
|
|
79
|
+
function renderMarkdownTableRow(headers, cells, rowIndex) {
|
|
80
|
+
const hasNumberColumn = headers[0]?.trim() === '#';
|
|
81
|
+
const explicitNumber = hasNumberColumn ? cells[0]?.trim() : '';
|
|
82
|
+
const prefix = explicitNumber && /^\d+$/.test(explicitNumber) ? `${explicitNumber}.` : `${rowIndex + 1}.`;
|
|
83
|
+
const startIndex = hasNumberColumn ? 1 : 0;
|
|
84
|
+
const parts = [];
|
|
85
|
+
for (let index = startIndex; index < headers.length; index += 1) {
|
|
86
|
+
const header = headers[index]?.trim();
|
|
87
|
+
const value = cells[index]?.trim();
|
|
88
|
+
if (!header || !value) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
parts.push(`${header}: ${value}`);
|
|
92
|
+
}
|
|
93
|
+
return parts.length > 0 ? `${prefix} ${parts.join(';')}` : `${prefix} ${cells.join(';')}`;
|
|
94
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shouldUseLarkMarkdownCard = exports.normalizeMarkdownTablesForLarkPost = void 0;
|
|
4
|
+
exports.renderLarkTextMessage = renderLarkTextMessage;
|
|
5
|
+
exports.buildLarkPostContent = buildLarkPostContent;
|
|
6
|
+
exports.buildLarkMarkdownCardContent = buildLarkMarkdownCardContent;
|
|
7
|
+
const markdown_js_1 = require("./markdown.js");
|
|
8
|
+
Object.defineProperty(exports, "normalizeMarkdownTablesForLarkPost", { enumerable: true, get: function () { return markdown_js_1.normalizeMarkdownTablesForLarkPost; } });
|
|
9
|
+
Object.defineProperty(exports, "shouldUseLarkMarkdownCard", { enumerable: true, get: function () { return markdown_js_1.shouldUseLarkMarkdownCard; } });
|
|
10
|
+
function renderLarkTextMessage(markdown) {
|
|
11
|
+
const tableCount = (0, markdown_js_1.countMarkdownTables)(markdown);
|
|
12
|
+
if ((0, markdown_js_1.shouldUseLarkMarkdownCard)(markdown)) {
|
|
13
|
+
return {
|
|
14
|
+
msgType: 'interactive',
|
|
15
|
+
content: buildLarkMarkdownCardContent(markdown),
|
|
16
|
+
renderKind: 'markdown_card',
|
|
17
|
+
reason: 'markdown_table',
|
|
18
|
+
tableCount,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
msgType: 'post',
|
|
23
|
+
content: buildLarkPostContent(markdown),
|
|
24
|
+
renderKind: 'post_md',
|
|
25
|
+
reason: tableCount > 0 ? 'table_limit_fallback' : 'plain_markdown',
|
|
26
|
+
tableCount,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function buildLarkPostContent(markdown) {
|
|
30
|
+
const normalized = (0, markdown_js_1.normalizeMarkdownTablesForLarkPost)(String(markdown || '').trim() || ' ');
|
|
31
|
+
return {
|
|
32
|
+
zh_cn: {
|
|
33
|
+
content: [[{
|
|
34
|
+
tag: 'md',
|
|
35
|
+
text: (0, markdown_js_1.sanitizeLarkMarkdown)(normalized),
|
|
36
|
+
}]],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function buildLarkMarkdownCardContent(markdown) {
|
|
41
|
+
return {
|
|
42
|
+
schema: '2.0',
|
|
43
|
+
config: { wide_screen_mode: true },
|
|
44
|
+
body: {
|
|
45
|
+
elements: [{
|
|
46
|
+
tag: 'markdown',
|
|
47
|
+
content: (0, markdown_js_1.sanitizeLarkMarkdown)(String(markdown || '').trim() || ' '),
|
|
48
|
+
}],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -114,6 +114,10 @@ function consumeLarkBridgeEvent(turn, event, options) {
|
|
|
114
114
|
pushUniqueLarkTurnLine(turn.statusLines, content.slice(3).trim());
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
|
+
if (bridgeKind === 'assistant' && event.messageId) {
|
|
118
|
+
turn.previewText = content;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
117
121
|
turn.finalText = content;
|
|
118
122
|
turn.previewText = content;
|
|
119
123
|
}
|
|
@@ -148,6 +152,9 @@ function renderLarkBridgeEventMessage(turn, event) {
|
|
|
148
152
|
if (bridgeKind === 'status') {
|
|
149
153
|
return renderProgressMessage(progressKey('status', event), content);
|
|
150
154
|
}
|
|
155
|
+
if (bridgeKind === 'assistant' && event.messageId) {
|
|
156
|
+
return renderAssistantSegmentMessage(progressKey('assistant', event), content);
|
|
157
|
+
}
|
|
151
158
|
return {
|
|
152
159
|
key: 'final',
|
|
153
160
|
text: content,
|
|
@@ -217,6 +224,13 @@ function renderToolMessage(key, text) {
|
|
|
217
224
|
updatePolicy: 'create-only',
|
|
218
225
|
};
|
|
219
226
|
}
|
|
227
|
+
function renderAssistantSegmentMessage(key, text) {
|
|
228
|
+
return {
|
|
229
|
+
...renderProgressMessage(key, text),
|
|
230
|
+
delivery: 'message',
|
|
231
|
+
updatePolicy: 'create-only',
|
|
232
|
+
};
|
|
233
|
+
}
|
|
220
234
|
function progressKey(prefix, event) {
|
|
221
235
|
const stableId = String(event.messageId || event.previewHandle || '').trim();
|
|
222
236
|
if (stableId) {
|