@kafca/agentdock 0.1.40 → 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 +3 -0
  2. package/dist/renderer/assets/{Badge-CmP99fZV.js → Badge-BX3RC8l6.js} +1 -1
  3. package/dist/renderer/assets/{Chat-BHxpB0Vz.js → Chat-DJwIciel.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-Cnhe-XvR.js → ChatMarkdown-DfGbRR0S.js} +1 -1
  5. package/dist/renderer/assets/{Config-CreR5RZX.js → Config-2x2RDL3j.js} +1 -1
  6. package/dist/renderer/assets/{CronList-OHg6JWsr.js → CronList-C6nPAmEo.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-C083Q4zC.js → Dashboard-2Wcx_bvJ.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-Br-H8kqG.js → EmptyState-DoCpF2tn.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-DKhVUY4_.js → KnowledgeDetail-CBRu2bXX.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeHome-BM3TMxhj.js → KnowledgeHome-CItdlDVR.js} +1 -1
  11. package/dist/renderer/assets/{Logs-debYolKz.js → Logs-Cd_7ZOXc.js} +1 -1
  12. package/dist/renderer/assets/{Modal-BIetew5T.js → Modal-B4eOiBsB.js} +1 -1
  13. package/dist/renderer/assets/{Page-183Y5-ef.js → Page-C5VH4D9U.js} +1 -1
  14. package/dist/renderer/assets/{ProjectDetail-CB6-zRBY.js → ProjectDetail-D_DA--IP.js} +1 -1
  15. package/dist/renderer/assets/{ProjectList-BEUflZUB.js → ProjectList-CtCXJ50u.js} +1 -1
  16. package/dist/renderer/assets/{Select-CNIQBVMx.js → Select-B6E68LcN.js} +1 -1
  17. package/dist/renderer/assets/{SessionChat-CLpfIftJ.js → SessionChat-D1HtMdQS.js} +1 -1
  18. package/dist/renderer/assets/{SessionList-BUwfQcGl.js → SessionList-Do-5-Xx6.js} +1 -1
  19. package/dist/renderer/assets/{ThreadChat-B9EcRcki.js → ThreadChat-B1tEtE3V.js} +1 -1
  20. package/dist/renderer/assets/{Workspace-D82il8Vz.js → Workspace-BlhS2RFw.js} +1 -1
  21. package/dist/renderer/assets/{arrow-left-T9D9J6Ln.js → arrow-left-DF1_F9Pk.js} +1 -1
  22. package/dist/renderer/assets/{book-open-Bfdr9s70.js → book-open-DxRTGpWO.js} +1 -1
  23. package/dist/renderer/assets/{check-CPJsC_C4.js → check-BAqPPYkf.js} +1 -1
  24. package/dist/renderer/assets/{chevron-down-BDoIQdna.js → chevron-down-DIZZgSb3.js} +1 -1
  25. package/dist/renderer/assets/{circle-CRGTgPlR.js → circle-B5raL_XK.js} +1 -1
  26. package/dist/renderer/assets/{desktop-DJ_OjjxL.js → desktop-CFcnzwcY.js} +1 -1
  27. package/dist/renderer/assets/{funnel-BISvzz6U.js → funnel-BPjLpVSB.js} +1 -1
  28. package/dist/renderer/assets/{heart-EllaLuEV.js → heart-D2M1xN1N.js} +1 -1
  29. package/dist/renderer/assets/{index-Db87Dhd_.js → index-BijJAYmo.js} +1 -1
  30. package/dist/renderer/assets/{index-YUnN4zTb.js → index-Cx71F_Lz.js} +2 -2
  31. package/dist/renderer/assets/{pencil-w4F5pFB6.js → pencil-DlDr8Mmp.js} +1 -1
  32. package/dist/renderer/assets/{play-CNY6DepD.js → play-BOEG_mY8.js} +1 -1
  33. package/dist/renderer/assets/{plug-DnMzECJy.js → plug-BI27elC-.js} +1 -1
  34. package/dist/renderer/assets/{plus-D33HMCG5.js → plus-BhURuFIQ.js} +1 -1
  35. package/dist/renderer/assets/projects-DpR972HM.js +1 -0
  36. package/dist/renderer/assets/{save-B0PXgtN_.js → save-RwkHNm9e.js} +1 -1
  37. package/dist/renderer/assets/{search-zNtpxpxG.js → search-DMNtm2WP.js} +1 -1
  38. package/dist/renderer/assets/{server-DIsU-ww0.js → server-CNaxKyAq.js} +1 -1
  39. package/dist/renderer/assets/{session-utils-CxQ3KCei.js → session-utils-vsALZkZN.js} +1 -1
  40. package/dist/renderer/assets/{sessions-DFDVZGz-.js → sessions-BY-R1IL_.js} +1 -1
  41. package/dist/renderer/assets/{shield-check-5hrgmi9Y.js → shield-check-BF-4oJbj.js} +1 -1
  42. package/dist/renderer/assets/{trash-2-DWftp5eL.js → trash-2-DduflM4q.js} +1 -1
  43. package/dist/renderer/assets/{user-CKjiW1bV.js → user-DBcvnuW4.js} +1 -1
  44. package/dist/renderer/assets/{wifi-off-DyBtTbdO.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 -16
  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 +170 -4
  56. package/package.json +1 -1
  57. package/dist/renderer/assets/projects-DcYpVq_W.js +0 -1
@@ -35,7 +35,7 @@ function extractLarkCreatedMessage(request) {
35
35
  }
36
36
  function extractLarkCreatedMessageText(msgType, content) {
37
37
  if (msgType === 'interactive') {
38
- return String(content.elements?.[0]?.content || '');
38
+ return String(content.elements?.[0]?.content || content.body?.elements?.[0]?.content || '');
39
39
  }
40
40
  if (msgType === 'post') {
41
41
  return (content.zh_cn?.content || [])
@@ -1142,6 +1142,92 @@ function findLarkPostMdText(content) {
1142
1142
  strict_1.default.equal(emitted[0]?.content, '🔧 Terminal');
1143
1143
  strict_1.default.equal(session.currentTurn.assistantText, 'done');
1144
1144
  });
1145
+ (0, node_test_1.default)('ACP closes assistant message segments at event boundaries without folding them into final', () => {
1146
+ const upserted = [];
1147
+ const emitted = [];
1148
+ const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
1149
+ appendMessage: () => { },
1150
+ upsertMessage: (_threadId, id, _role, content, _kind, _toolCall, bridgeKind) => {
1151
+ upserted.push({ id, content, bridgeKind });
1152
+ },
1153
+ emitBridge: (event) => emitted.push(event),
1154
+ updateRunStatus: () => { },
1155
+ sendRaw: () => true,
1156
+ });
1157
+ const session = {
1158
+ threadId: 'thread-1',
1159
+ bridgeSessionKey: 'session:thread-1',
1160
+ currentRunId: 'run-1',
1161
+ currentTurn: {
1162
+ runId: 'run-1',
1163
+ replyCtx: 'run-1',
1164
+ previewHandle: 'run-1-assistant-preview-1',
1165
+ assistantMessageId: 'run-1-assistant-1',
1166
+ assistantSequence: 1,
1167
+ thoughtPreviewHandle: 'thought-preview-1',
1168
+ thoughtMessageId: 'run-1-thought-1',
1169
+ assistantText: '',
1170
+ rawAssistantText: '',
1171
+ thoughtText: '',
1172
+ typingStarted: true,
1173
+ previewStarted: false,
1174
+ thoughtPreviewStarted: false,
1175
+ pendingToolCalls: {},
1176
+ pendingToolCallOrder: [],
1177
+ toolCallSequence: 0,
1178
+ toolObservations: [],
1179
+ permission: null,
1180
+ },
1181
+ loadReplayMode: false,
1182
+ schedulerJobCreatedByRun: new Map(),
1183
+ };
1184
+ coordinator.handleAgentNotification(session, {
1185
+ method: 'session/update',
1186
+ params: {
1187
+ update: {
1188
+ sessionUpdate: 'agent_message_chunk',
1189
+ content: { type: 'text', text: '我先检查一下' },
1190
+ },
1191
+ },
1192
+ });
1193
+ strict_1.default.deepEqual(emitted, []);
1194
+ strict_1.default.deepEqual(upserted, []);
1195
+ coordinator.handleAgentNotification(session, {
1196
+ method: 'session/update',
1197
+ params: {
1198
+ update: {
1199
+ sessionUpdate: 'tool_call',
1200
+ title: 'Terminal',
1201
+ },
1202
+ },
1203
+ });
1204
+ strict_1.default.deepEqual(upserted, [{
1205
+ id: 'run-1-assistant-1',
1206
+ content: '我先检查一下',
1207
+ bridgeKind: 'assistant',
1208
+ }]);
1209
+ strict_1.default.equal(emitted.length, 1);
1210
+ strict_1.default.equal(emitted[0]?.type, 'reply');
1211
+ strict_1.default.equal(emitted[0]?.content, '我先检查一下');
1212
+ strict_1.default.equal(emitted[0]?.messageId, 'run-1-assistant-1');
1213
+ strict_1.default.equal(emitted[0]?.bridgeKind, 'assistant');
1214
+ strict_1.default.equal(session.currentTurn.assistantText, '');
1215
+ strict_1.default.equal(session.currentTurn.rawAssistantText, '');
1216
+ coordinator.handleAgentNotification(session, {
1217
+ method: 'session/update',
1218
+ params: {
1219
+ update: {
1220
+ sessionUpdate: 'agent_message_chunk',
1221
+ content: { type: 'text', text: '最终回答' },
1222
+ },
1223
+ },
1224
+ });
1225
+ strict_1.default.equal(session.currentTurn.assistantText, '最终回答');
1226
+ strict_1.default.equal(session.currentTurn.rawAssistantText, '最终回答');
1227
+ strict_1.default.equal(upserted.filter((entry) => entry.bridgeKind === 'assistant').length, 1);
1228
+ strict_1.default.equal(emitted.length, 2);
1229
+ strict_1.default.equal(emitted[1]?.bridgeKind, 'tool');
1230
+ });
1145
1231
  (0, node_test_1.default)('ACP tool-scoped assistant chunks stay out of final assistant buffer', () => {
1146
1232
  const appended = [];
1147
1233
  const emitted = [];
@@ -1237,7 +1323,7 @@ function findLarkPostMdText(content) {
1237
1323
  });
1238
1324
  }
1239
1325
  strict_1.default.equal(session.currentTurn.assistantText, '确认删除前需要你确认。');
1240
- strict_1.default.deepEqual(emitted.map((event) => event.content), ['确认删除前需要你确认。']);
1326
+ strict_1.default.deepEqual(emitted.map((event) => event.content), []);
1241
1327
  });
1242
1328
  (0, node_test_1.default)('Hermes ACP assistant chunks strip replay even when stored prior final is already polluted', () => {
1243
1329
  const emitted = [];
@@ -1291,7 +1377,7 @@ function findLarkPostMdText(content) {
1291
1377
  });
1292
1378
  }
1293
1379
  strict_1.default.equal(session.currentTurn.assistantText, '已删除 **Sisyphus_介绍.txt**,现在 Text 文件夹是空的了。');
1294
- strict_1.default.deepEqual(emitted.map((event) => event.content), ['已删除 **Sisyphus_介绍.txt**,现在 Text 文件夹是空的了。']);
1380
+ strict_1.default.deepEqual(emitted.map((event) => event.content), []);
1295
1381
  });
1296
1382
  (0, node_test_1.default)('Hermes ACP assistant chunks keep a fresh answer when no replay anchor is present', () => {
1297
1383
  const emitted = [];
@@ -1330,7 +1416,7 @@ function findLarkPostMdText(content) {
1330
1416
  },
1331
1417
  });
1332
1418
  strict_1.default.equal(session.currentTurn.assistantText, '已删除文件。');
1333
- strict_1.default.deepEqual(emitted.map((event) => event.content), ['已删除文件。']);
1419
+ strict_1.default.deepEqual(emitted.map((event) => event.content), []);
1334
1420
  });
1335
1421
  (0, node_test_1.default)('Hermes ACP progress updates suppress restored tool and thought replay only', () => {
1336
1422
  const upserted = [];
@@ -2029,6 +2115,86 @@ function findLarkPostMdText(content) {
2029
2115
  strict_1.default.deepEqual(patchedCards, []);
2030
2116
  strict_1.default.deepEqual(storedMessageIds, ['lark-msg-1']);
2031
2117
  });
2118
+ (0, node_test_1.default)('lark bridge sends completed assistant segments as separate non-final messages', async () => {
2119
+ const createdMessages = [];
2120
+ const patchedCards = [];
2121
+ const storedMessageIds = [];
2122
+ const client = {
2123
+ im: {
2124
+ message: {
2125
+ create: async (request) => {
2126
+ const messageId = `lark-msg-${createdMessages.length + 1}`;
2127
+ const message = extractLarkCreatedMessage(request);
2128
+ createdMessages.push({
2129
+ messageId,
2130
+ msgType: message.msgType,
2131
+ text: message.text,
2132
+ content: message.content,
2133
+ });
2134
+ return { data: { message_id: messageId } };
2135
+ },
2136
+ patch: async (request) => {
2137
+ const card = JSON.parse(String(request.data.content || '{}'));
2138
+ patchedCards.push({
2139
+ messageId: String(request.path.message_id || ''),
2140
+ text: String(card.elements?.[0]?.content || ''),
2141
+ });
2142
+ },
2143
+ },
2144
+ },
2145
+ };
2146
+ const gateway = new local_core_lark_gateway_js_1.LocalCoreLarkGateway({
2147
+ store: {
2148
+ getPlatformThreadBinding: () => ({
2149
+ workspace_id: 'default',
2150
+ platform: 'lark',
2151
+ chat_id: 'chat-1',
2152
+ platform_user_id: 'user-1',
2153
+ thread_id: 'thread-1',
2154
+ last_platform_message_id: null,
2155
+ }),
2156
+ updatePlatformThreadMessageId: (_workspaceId, _chatId, _platformUserId, messageId) => {
2157
+ storedMessageIds.push(messageId);
2158
+ },
2159
+ },
2160
+ readConfig: async () => null,
2161
+ getWorkspaceRouter: () => ({}),
2162
+ eventBus: { emit: () => { }, on: () => () => { } },
2163
+ });
2164
+ const internals = gateway;
2165
+ internals.runtime.set('default', {
2166
+ workspaceId: 'default',
2167
+ enabled: true,
2168
+ status: 'running',
2169
+ connected: true,
2170
+ appId: 'app-1',
2171
+ client,
2172
+ });
2173
+ internals.threadRouting.set('session:thread-1', {
2174
+ workspaceId: 'default',
2175
+ platformUserId: 'user-1',
2176
+ chatId: 'chat-1',
2177
+ threadId: 'thread-1',
2178
+ });
2179
+ await gateway.onBridgeEvent({
2180
+ type: 'reply',
2181
+ sessionKey: 'session:thread-1',
2182
+ replyCtx: 'run-1',
2183
+ messageId: 'run-1-assistant-1',
2184
+ bridgeKind: 'assistant',
2185
+ content: '我先检查一下',
2186
+ });
2187
+ await gateway.onBridgeEvent({
2188
+ type: 'reply',
2189
+ sessionKey: 'session:thread-1',
2190
+ replyCtx: 'run-1',
2191
+ content: '最终回答',
2192
+ });
2193
+ strict_1.default.deepEqual(createdMessages.map((message) => message.msgType), ['post', 'post']);
2194
+ strict_1.default.deepEqual(createdMessages.map((message) => message.text), ['我先检查一下', '最终回答']);
2195
+ strict_1.default.deepEqual(patchedCards, []);
2196
+ strict_1.default.deepEqual(storedMessageIds, ['lark-msg-2']);
2197
+ });
2032
2198
  (0, node_test_1.default)('lark bridge creates final replies without patching prior final messages', async () => {
2033
2199
  const createdMessages = [];
2034
2200
  const patchedCards = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kafca/agentdock",
3
- "version": "0.1.40",
3
+ "version": "0.1.41",
4
4
  "license": "PolyForm-Noncommercial-1.0.0",
5
5
  "type": "module",
6
6
  "main": "dist-electron/electron/main.js",
@@ -1 +0,0 @@
1
- import{z as t}from"./index-YUnN4zTb.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};