@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.
Files changed (57) hide show
  1. package/README.md +5 -0
  2. package/dist/renderer/assets/{Badge-B8Arb9Yy.js → Badge-BX3RC8l6.js} +1 -1
  3. package/dist/renderer/assets/{Chat-BpHN2UcX.js → Chat-DJwIciel.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-C_zHbGhg.js → ChatMarkdown-DfGbRR0S.js} +1 -1
  5. package/dist/renderer/assets/{Config-357M6MbD.js → Config-2x2RDL3j.js} +1 -1
  6. package/dist/renderer/assets/{CronList-BHgDIhFo.js → CronList-C6nPAmEo.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-CZQj79ep.js → Dashboard-2Wcx_bvJ.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-DpSPN3kz.js → EmptyState-DoCpF2tn.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-Cbv2Oje7.js → KnowledgeDetail-CBRu2bXX.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeHome-CEbNw_Za.js → KnowledgeHome-CItdlDVR.js} +1 -1
  11. package/dist/renderer/assets/{Logs-IXayiVGS.js → Logs-Cd_7ZOXc.js} +1 -1
  12. package/dist/renderer/assets/{Modal-BTKWx2e5.js → Modal-B4eOiBsB.js} +1 -1
  13. package/dist/renderer/assets/{Page-DCDVvqIU.js → Page-C5VH4D9U.js} +1 -1
  14. package/dist/renderer/assets/{ProjectDetail-C6as_oba.js → ProjectDetail-D_DA--IP.js} +1 -1
  15. package/dist/renderer/assets/{ProjectList-DJfBaPyw.js → ProjectList-CtCXJ50u.js} +1 -1
  16. package/dist/renderer/assets/{Select-BYijPrOF.js → Select-B6E68LcN.js} +1 -1
  17. package/dist/renderer/assets/{SessionChat-KapIGn1O.js → SessionChat-D1HtMdQS.js} +1 -1
  18. package/dist/renderer/assets/{SessionList-C0ATtS_m.js → SessionList-Do-5-Xx6.js} +1 -1
  19. package/dist/renderer/assets/{ThreadChat-CKWcyHia.js → ThreadChat-B1tEtE3V.js} +1 -1
  20. package/dist/renderer/assets/{Workspace-MYHdNNV2.js → Workspace-BlhS2RFw.js} +1 -1
  21. package/dist/renderer/assets/{arrow-left-Dl2cYCYQ.js → arrow-left-DF1_F9Pk.js} +1 -1
  22. package/dist/renderer/assets/{book-open-CJCjYKCj.js → book-open-DxRTGpWO.js} +1 -1
  23. package/dist/renderer/assets/{check-Cknz-_NI.js → check-BAqPPYkf.js} +1 -1
  24. package/dist/renderer/assets/{chevron-down-v4poAoll.js → chevron-down-DIZZgSb3.js} +1 -1
  25. package/dist/renderer/assets/{circle-BnxuF8S1.js → circle-B5raL_XK.js} +1 -1
  26. package/dist/renderer/assets/{desktop-B9xqa1yi.js → desktop-CFcnzwcY.js} +1 -1
  27. package/dist/renderer/assets/{funnel-Cl1EldnW.js → funnel-BPjLpVSB.js} +1 -1
  28. package/dist/renderer/assets/{heart-274KWkSA.js → heart-D2M1xN1N.js} +1 -1
  29. package/dist/renderer/assets/{index-GaRPrxQn.js → index-BijJAYmo.js} +1 -1
  30. package/dist/renderer/assets/{index-CAi_EMRl.js → index-Cx71F_Lz.js} +2 -2
  31. package/dist/renderer/assets/{pencil-BfYhgp9_.js → pencil-DlDr8Mmp.js} +1 -1
  32. package/dist/renderer/assets/{play-CLir9KyW.js → play-BOEG_mY8.js} +1 -1
  33. package/dist/renderer/assets/{plug-CTKL_TK4.js → plug-BI27elC-.js} +1 -1
  34. package/dist/renderer/assets/{plus-9pP7UU-H.js → plus-BhURuFIQ.js} +1 -1
  35. package/dist/renderer/assets/projects-DpR972HM.js +1 -0
  36. package/dist/renderer/assets/{save-DZOLXcQU.js → save-RwkHNm9e.js} +1 -1
  37. package/dist/renderer/assets/{search-DjFl-8XR.js → search-DMNtm2WP.js} +1 -1
  38. package/dist/renderer/assets/{server-UI3KEpUw.js → server-CNaxKyAq.js} +1 -1
  39. package/dist/renderer/assets/{session-utils-b9gwOizd.js → session-utils-vsALZkZN.js} +1 -1
  40. package/dist/renderer/assets/{sessions-DzSZ5A3m.js → sessions-BY-R1IL_.js} +1 -1
  41. package/dist/renderer/assets/{shield-check-6fT5xdT3.js → shield-check-BF-4oJbj.js} +1 -1
  42. package/dist/renderer/assets/{trash-2-DNBg0OLf.js → trash-2-DduflM4q.js} +1 -1
  43. package/dist/renderer/assets/{user-B0MGTipJ.js → user-DBcvnuW4.js} +1 -1
  44. package/dist/renderer/assets/{wifi-off-DBxNxGco.js → wifi-off-X1nXESYu.js} +1 -1
  45. package/dist/renderer/index.html +1 -1
  46. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +2 -0
  47. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +25 -0
  48. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +31 -8
  49. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +21 -11
  50. package/dist-electron/services/local-ai-core/src/channel/lark/post.js +7 -70
  51. package/dist-electron/services/local-ai-core/src/channel/lark/rendering/markdown.js +94 -0
  52. package/dist-electron/services/local-ai-core/src/channel/lark/rendering/messages.js +51 -0
  53. package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +14 -0
  54. package/dist-electron/tests/integration/lark-rendering.test.js +123 -0
  55. package/dist-electron/tests/integration/local-core-refactor.test.js +176 -22
  56. package/package.json +1 -1
  57. package/dist/renderer/assets/projects-DRdvUEj2.js +0 -1
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-CAi_EMRl.js";/**
1
+ import{c as a}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-CAi_EMRl.js";/**
1
+ import{c as o}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-CAi_EMRl.js";/**
1
+ import{c as o}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-CAi_EMRl.js";/**
1
+ import{c as e}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -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,4 +1,4 @@
1
- import{c as a}from"./index-CAi_EMRl.js";/**
1
+ import{c as a}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-CAi_EMRl.js";/**
1
+ import{c}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-CAi_EMRl.js";/**
1
+ import{c as e}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-CAi_EMRl.js";/**
1
+ import{c as o}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{z as o}from"./index-CAi_EMRl.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};
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};
@@ -1,4 +1,4 @@
1
- import{c}from"./index-CAi_EMRl.js";/**
1
+ import{c}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-CAi_EMRl.js";/**
1
+ import{c as e}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-CAi_EMRl.js";/**
1
+ import{c as e}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-CAi_EMRl.js";/**
1
+ import{c as a}from"./index-Cx71F_Lz.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -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-CAi_EMRl.js"></script>
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 post_js_1 = require("./post.js");
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.sendTextAsPost(state, channelId, text));
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 createdId = renderedMessage.delivery === 'message' && renderedMessage.buttonRows.length === 0
518
- ? await this.sendTextAsPost(state, route.chatId, renderedMessage.text)
519
- : await this.sendTextAsCard(state, route.chatId, renderedMessage.text, renderedMessage.buttonRows, sessionKey, bridgeThreadId);
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 ${renderedMessage.delivery === 'message' ? 'post' : 'card'} message ${createdId} for sessionKey=${sessionKey}`);
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 sendTextAsPost(state, chatId, text) {
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: 'post',
1164
- content: JSON.stringify((0, post_js_1.buildLarkPostContent)(text)),
1169
+ msg_type: rendered.msgType,
1170
+ content: JSON.stringify(rendered.content),
1165
1171
  },
1166
1172
  });
1167
- this.options.log?.(`localcore-lark post create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
1168
- return String(response?.data?.message_id || '').trim();
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 = buildLarkPostContent;
4
- function buildLarkPostContent(markdown) {
5
- const content = renderLarkPostLines(markdown);
6
- return {
7
- zh_cn: {
8
- content: content.length > 0 ? content : [[{ tag: 'text', text: ' ' }]],
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) {