@kafca/agentdock 0.1.30 → 0.1.31
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 +4 -0
- package/dist/renderer/assets/{Badge-DlVJI1Ys.js → Badge-DaHt-aUT.js} +1 -1
- package/dist/renderer/assets/{Chat-oa8OjaHQ.js → Chat-Dzeq3kiD.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-C-N8KS5C.js → ChatMarkdown-B-L5Roai.js} +1 -1
- package/dist/renderer/assets/{Config-D9sL_d4D.js → Config-BI4LJ7Fw.js} +1 -1
- package/dist/renderer/assets/{CronList-Z5JU3DHk.js → CronList-Dic7pblj.js} +1 -1
- package/dist/renderer/assets/{Dashboard-D3BwbG43.js → Dashboard-C0_ATyGe.js} +2 -2
- package/dist/renderer/assets/{EmptyState-QOj765Ul.js → EmptyState-SQsG1DZP.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-J7n01mPu.js → KnowledgeDetail-D4yUJzp7.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-BFnH0NVk.js → KnowledgeHome-L0tsg-oo.js} +1 -1
- package/dist/renderer/assets/{Logs-DfSUifXc.js → Logs-C2Jdr3uQ.js} +1 -1
- package/dist/renderer/assets/{Modal-QjEGhyru.js → Modal-GUH3iPXo.js} +1 -1
- package/dist/renderer/assets/{Page-qdHFSw7x.js → Page-m42FBy97.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-DS_rfvhh.js → ProjectDetail-RF_sagPO.js} +1 -1
- package/dist/renderer/assets/{ProjectList-COtyZd7H.js → ProjectList-Cyr8RDK3.js} +1 -1
- package/dist/renderer/assets/{Select-BQ8mncVu.js → Select-CRlDgI5s.js} +1 -1
- package/dist/renderer/assets/{SessionChat-DjVnjuQy.js → SessionChat-_HhzMwEO.js} +1 -1
- package/dist/renderer/assets/{SessionList-88dgGZJ8.js → SessionList-DNwZjGTv.js} +1 -1
- package/dist/renderer/assets/ThreadChat-DxBmdsAm.js +23 -0
- package/dist/renderer/assets/{Workspace-D_hzSJjX.js → Workspace-DFphG85O.js} +1 -1
- package/dist/renderer/assets/{arrow-left-BMpknulW.js → arrow-left-bILMzse7.js} +1 -1
- package/dist/renderer/assets/{book-open-CiaOeQbU.js → book-open-BNBWEEve.js} +1 -1
- package/dist/renderer/assets/{check-CgwYH4GF.js → check-MGp5kvnb.js} +1 -1
- package/dist/renderer/assets/{chevron-down-BzD2S1OO.js → chevron-down-zsfoTlh7.js} +1 -1
- package/dist/renderer/assets/{circle-BDHD7g7l.js → circle-BX_xUSg-.js} +1 -1
- package/dist/renderer/assets/{desktop-BiR5LPL5.js → desktop-CgrO_cdQ.js} +1 -1
- package/dist/renderer/assets/{desktop-BkMW-h5p.js → desktop-O8_6ZCVZ.js} +2 -2
- package/dist/renderer/assets/{funnel-Bruf5FYA.js → funnel-7442U1wq.js} +1 -1
- package/dist/renderer/assets/{heart-D7Mz04B0.js → heart-B3d8bnSH.js} +1 -1
- package/dist/renderer/assets/{index-gZIRr4_o.js → index-5YUqCvBf.js} +1 -1
- package/dist/renderer/assets/{index-CL1e8m3U.js → index-BBaYsVjU.js} +2 -2
- package/dist/renderer/assets/{pencil-C6gzDMse.js → pencil-QzWgkmoH.js} +1 -1
- package/dist/renderer/assets/{play-DqTXX-Pr.js → play-Bsc8hSI7.js} +1 -1
- package/dist/renderer/assets/{plug-ykmbeaO3.js → plug-CRY7sjvB.js} +1 -1
- package/dist/renderer/assets/{plus-DHE60vMX.js → plus-Dr5Ei8Ud.js} +1 -1
- package/dist/renderer/assets/projects-BDYSOFIJ.js +1 -0
- package/dist/renderer/assets/{save-CGIvrdQI.js → save-giJnp2Ki.js} +1 -1
- package/dist/renderer/assets/{search-D7IFAwyE.js → search-DcvHLmKs.js} +1 -1
- package/dist/renderer/assets/{server-aOsirp7I.js → server-D_Qu8If5.js} +1 -1
- package/dist/renderer/assets/{session-utils-Dxfp4ohQ.js → session-utils-CsASahfU.js} +1 -1
- package/dist/renderer/assets/{sessions-Db1XPbG2.js → sessions-eMpPqp4P.js} +1 -1
- package/dist/renderer/assets/{shield-check-ChXeQK-d.js → shield-check-BpF0uIw-.js} +1 -1
- package/dist/renderer/assets/{trash-2-CfN-c1zw.js → trash-2-OJFmx3xk.js} +1 -1
- package/dist/renderer/assets/{user-C7OHaBp4.js → user-GL_ivaV6.js} +1 -1
- package/dist/renderer/assets/{wifi-off-CpaJigye.js → wifi-off-CQT5VNQl.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/electron/agent-runtime-detector.test.js +30 -0
- package/dist-electron/electron/local-core-refactor.test.js +422 -0
- package/dist-electron/electron/plugin-kernel.test.js +81 -1
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +28 -3
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +102 -15
- package/dist-electron/services/local-ai-core/src/agents/claudecode/behavior.js +5 -0
- package/dist-electron/services/local-ai-core/src/agents/claudecode/definition.js +36 -0
- package/dist-electron/services/local-ai-core/src/agents/claudecode/index.js +15 -0
- package/dist-electron/services/local-ai-core/src/agents/codex/behavior.js +5 -0
- package/dist-electron/services/local-ai-core/src/agents/codex/definition.js +24 -0
- package/dist-electron/services/local-ai-core/src/agents/codex/index.js +15 -0
- package/dist-electron/services/local-ai-core/src/agents/hermes/behavior.js +29 -0
- package/dist-electron/services/local-ai-core/src/agents/hermes/definition.js +22 -0
- package/dist-electron/services/local-ai-core/src/agents/hermes/index.js +15 -0
- package/dist-electron/services/local-ai-core/src/agents/index.js +98 -0
- package/dist-electron/services/local-ai-core/src/agents/localcore-acp/behavior.js +5 -0
- package/dist-electron/services/local-ai-core/src/agents/localcore-acp/definition.js +14 -0
- package/dist-electron/services/local-ai-core/src/agents/localcore-acp/index.js +27 -0
- package/dist-electron/services/local-ai-core/src/agents/opencode/behavior.js +5 -0
- package/dist-electron/services/local-ai-core/src/agents/opencode/definition.js +18 -0
- package/dist-electron/services/local-ai-core/src/agents/opencode/index.js +15 -0
- package/dist-electron/services/local-ai-core/src/agents/opencode/launch.js +119 -0
- package/dist-electron/services/local-ai-core/src/agents/pi/behavior.js +5 -0
- package/dist-electron/services/local-ai-core/src/agents/pi/definition.js +23 -0
- package/dist-electron/services/local-ai-core/src/agents/pi/index.js +15 -0
- package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +139 -0
- package/dist-electron/services/local-ai-core/src/agents/shared/acp-behavior.js +11 -0
- package/dist-electron/services/local-ai-core/src/agents/shared/agent-plugin.js +60 -0
- package/dist-electron/services/local-ai-core/src/agents/shared/definition.js +12 -0
- package/dist-electron/services/local-ai-core/src/agents/shared/launch-utils.js +122 -0
- package/dist-electron/services/local-ai-core/src/agents/shared/progress-replay.js +19 -0
- package/dist-electron/services/local-ai-core/src/agents/shared/replay-prefix.js +68 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +0 -2
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +0 -1
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +8 -7
- package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +9 -130
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +22 -397
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +9 -45
- package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +62 -1
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +2 -12
- package/dist-electron/shared/desktop.js +3 -1
- package/dist-electron/src/pages/Threads/thread-chat-model.js +27 -18
- package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +57 -18
- package/package.json +1 -1
- package/dist/renderer/assets/ThreadChat-BCdbTxBo.js +0 -23
- package/dist/renderer/assets/projects-Bx5p10th.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as t}from"./index-BBaYsVjU.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-BBaYsVjU.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-BBaYsVjU.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="./assets/index-DFiJR0vv.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="bg-[#f5f5f7] dark:bg-[#151516]">
|
|
@@ -9,6 +9,15 @@ const node_fs_1 = require("node:fs");
|
|
|
9
9
|
const node_path_1 = require("node:path");
|
|
10
10
|
const node_os_1 = require("node:os");
|
|
11
11
|
const agent_runtime_detector_js_1 = require("../services/local-ai-core/src/runtime/agent-runtime-detector.js");
|
|
12
|
+
const index_js_1 = require("../services/local-ai-core/src/agents/index.js");
|
|
13
|
+
(0, node_test_1.default)('agent runtime definitions own runtime detection metadata', () => {
|
|
14
|
+
strict_1.default.deepEqual((0, index_js_1.resolveAgentRuntimeDefinition)('hermes')?.detection?.commandCandidates, ['hermes']);
|
|
15
|
+
strict_1.default.deepEqual((0, index_js_1.resolveAgentRuntimeDefinition)('codex')?.detection?.bundledRuntimes?.[0], {
|
|
16
|
+
packageName: '@zed-industries/codex-acp',
|
|
17
|
+
candidates: ['bin/codex-acp.js'],
|
|
18
|
+
});
|
|
19
|
+
strict_1.default.equal((0, index_js_1.resolveAgentRuntimeDefinition)('localcore-acp')?.detection?.builtin, true);
|
|
20
|
+
});
|
|
12
21
|
(0, node_test_1.default)('agent runtime detector only marks commands present on PATH as installed', () => {
|
|
13
22
|
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agent-runtime-detector-'));
|
|
14
23
|
try {
|
|
@@ -30,6 +39,8 @@ const agent_runtime_detector_js_1 = require("../services/local-ai-core/src/runti
|
|
|
30
39
|
strict_1.default.equal(byType.get('pi')?.status, 'not_installed');
|
|
31
40
|
strict_1.default.equal(byType.get('codex')?.installed, false);
|
|
32
41
|
strict_1.default.equal(byType.get('codex')?.status, 'not_installed');
|
|
42
|
+
strict_1.default.equal(byType.get('hermes')?.installed, false);
|
|
43
|
+
strict_1.default.equal(byType.get('hermes')?.status, 'not_installed');
|
|
33
44
|
strict_1.default.equal(byType.get('localcore-acp')?.installed, true);
|
|
34
45
|
strict_1.default.equal(byType.get('localcore-acp')?.status, 'installed');
|
|
35
46
|
strict_1.default.equal(byType.get('localcore-acp')?.source, 'builtin');
|
|
@@ -179,6 +190,25 @@ const agent_runtime_detector_js_1 = require("../services/local-ai-core/src/runti
|
|
|
179
190
|
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
180
191
|
}
|
|
181
192
|
});
|
|
193
|
+
(0, node_test_1.default)('agent runtime detector reports Hermes when hermes command is available', () => {
|
|
194
|
+
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agent-runtime-hermes-version-'));
|
|
195
|
+
try {
|
|
196
|
+
const hermes = (0, node_path_1.join)(dir, 'hermes');
|
|
197
|
+
(0, node_fs_1.writeFileSync)(hermes, '#!/bin/sh\necho "hermes 0.9.1"\n', 'utf8');
|
|
198
|
+
(0, node_fs_1.chmodSync)(hermes, 0o755);
|
|
199
|
+
const hermesRuntime = (0, agent_runtime_detector_js_1.detectInstalledAgentRuntimes)({
|
|
200
|
+
env: { PATH: dir },
|
|
201
|
+
}).find((runtime) => runtime.agentType === 'hermes');
|
|
202
|
+
strict_1.default.equal(hermesRuntime?.status, 'installed');
|
|
203
|
+
strict_1.default.equal(hermesRuntime?.source, 'path');
|
|
204
|
+
strict_1.default.equal(hermesRuntime?.command, hermes);
|
|
205
|
+
strict_1.default.equal(hermesRuntime?.version, '0.9.1');
|
|
206
|
+
strict_1.default.equal(hermesRuntime?.issues.length, 0);
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
210
|
+
}
|
|
211
|
+
});
|
|
182
212
|
(0, node_test_1.default)('agent runtime detector keeps runtime installed when version command fails', () => {
|
|
183
213
|
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agent-runtime-version-fail-'));
|
|
184
214
|
try {
|
|
@@ -955,6 +955,56 @@ const server_routes_js_1 = require("../services/local-ai-core/src/runtime/server
|
|
|
955
955
|
]]);
|
|
956
956
|
strict_1.default.equal(session.pendingPermissionByRun.get('run-1')?.options[1]?.optionId, 'approve-always');
|
|
957
957
|
});
|
|
958
|
+
(0, node_test_1.default)('Hermes ACP permission options respect allow_permanent false', () => {
|
|
959
|
+
const emitted = [];
|
|
960
|
+
const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
|
|
961
|
+
appendMessage: () => { },
|
|
962
|
+
emitBridge: (event) => emitted.push(event),
|
|
963
|
+
updateRunStatus: () => { },
|
|
964
|
+
sendRaw: () => true,
|
|
965
|
+
});
|
|
966
|
+
const session = {
|
|
967
|
+
threadId: 'thread-1',
|
|
968
|
+
bridgeSessionKey: 'session:thread-1',
|
|
969
|
+
currentRunId: 'run-1',
|
|
970
|
+
currentTurn: {
|
|
971
|
+
runId: 'run-1',
|
|
972
|
+
replyCtx: 'run-1',
|
|
973
|
+
previewHandle: 'preview-1',
|
|
974
|
+
assistantText: '',
|
|
975
|
+
typingStarted: true,
|
|
976
|
+
previewStarted: false,
|
|
977
|
+
permission: null,
|
|
978
|
+
agentType: 'hermes',
|
|
979
|
+
},
|
|
980
|
+
pendingPermissionByRun: new Map(),
|
|
981
|
+
loadReplayMode: false,
|
|
982
|
+
schedulerJobCreatedByRun: new Map(),
|
|
983
|
+
};
|
|
984
|
+
coordinator.handleAgentRequest(session, {
|
|
985
|
+
method: 'session/request_permission',
|
|
986
|
+
id: 42,
|
|
987
|
+
params: {
|
|
988
|
+
allow_permanent: false,
|
|
989
|
+
toolCall: {
|
|
990
|
+
title: 'Terminal',
|
|
991
|
+
parameters: {
|
|
992
|
+
command: 'system_profiler SPHardwareDataType',
|
|
993
|
+
},
|
|
994
|
+
},
|
|
995
|
+
options: [
|
|
996
|
+
{ optionId: 'approve-once', name: 'Allow once', kind: 'allow' },
|
|
997
|
+
{ optionId: 'approve-always', name: 'Always allow', kind: 'allow' },
|
|
998
|
+
{ optionId: 'reject', name: 'Reject', kind: 'reject' },
|
|
999
|
+
],
|
|
1000
|
+
},
|
|
1001
|
+
});
|
|
1002
|
+
strict_1.default.deepEqual(emitted[0]?.buttonRows, [[
|
|
1003
|
+
{ text: 'allow', data: 'allow' },
|
|
1004
|
+
{ text: 'deny', data: 'deny' },
|
|
1005
|
+
]]);
|
|
1006
|
+
strict_1.default.deepEqual(session.pendingPermissionByRun.get('run-1')?.options.map((option) => option.optionId), ['approve-once', 'reject']);
|
|
1007
|
+
});
|
|
958
1008
|
(0, node_test_1.default)('ACP yolo mode auto-selects permission requests without rendering cards', () => {
|
|
959
1009
|
const emitted = [];
|
|
960
1010
|
const appended = [];
|
|
@@ -1113,6 +1163,355 @@ const server_routes_js_1 = require("../services/local-ai-core/src/runtime/server
|
|
|
1113
1163
|
strict_1.default.equal(emitted[0]?.content, 'tool scoped transcript');
|
|
1114
1164
|
strict_1.default.equal(session.currentTurn.assistantText, 'final answer');
|
|
1115
1165
|
});
|
|
1166
|
+
(0, node_test_1.default)('Hermes ACP assistant chunks strip restored history replay inside its own behavior', () => {
|
|
1167
|
+
const emitted = [];
|
|
1168
|
+
const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
|
|
1169
|
+
appendMessage: () => { },
|
|
1170
|
+
emitBridge: (event) => emitted.push(event),
|
|
1171
|
+
updateRunStatus: () => { },
|
|
1172
|
+
sendRaw: () => true,
|
|
1173
|
+
});
|
|
1174
|
+
const session = {
|
|
1175
|
+
threadId: 'thread-1',
|
|
1176
|
+
bridgeSessionKey: 'session:thread-1',
|
|
1177
|
+
currentRunId: 'run-1',
|
|
1178
|
+
currentTurn: {
|
|
1179
|
+
runId: 'run-1',
|
|
1180
|
+
replyCtx: 'run-1',
|
|
1181
|
+
previewHandle: 'preview-1',
|
|
1182
|
+
agentType: 'hermes',
|
|
1183
|
+
assistantText: '',
|
|
1184
|
+
rawAssistantText: '',
|
|
1185
|
+
priorAssistantFinalMessages: ['Hi! 😊 How can I help you today?', '我是 Hermes Agent。'],
|
|
1186
|
+
typingStarted: true,
|
|
1187
|
+
previewStarted: false,
|
|
1188
|
+
permission: null,
|
|
1189
|
+
},
|
|
1190
|
+
loadReplayMode: false,
|
|
1191
|
+
schedulerJobCreatedByRun: new Map(),
|
|
1192
|
+
};
|
|
1193
|
+
for (const text of ['Hi! 😊 How can I help you today?', '我是 Hermes Agent。', '确认删除前需要你确认。']) {
|
|
1194
|
+
coordinator.handleAgentNotification(session, {
|
|
1195
|
+
method: 'session/update',
|
|
1196
|
+
params: {
|
|
1197
|
+
update: {
|
|
1198
|
+
sessionUpdate: 'agent_message_chunk',
|
|
1199
|
+
content: { type: 'text', text },
|
|
1200
|
+
},
|
|
1201
|
+
},
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
strict_1.default.equal(session.currentTurn.assistantText, '确认删除前需要你确认。');
|
|
1205
|
+
strict_1.default.deepEqual(emitted.map((event) => event.content), ['确认删除前需要你确认。']);
|
|
1206
|
+
});
|
|
1207
|
+
(0, node_test_1.default)('Hermes ACP assistant chunks strip replay even when stored prior final is already polluted', () => {
|
|
1208
|
+
const emitted = [];
|
|
1209
|
+
const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
|
|
1210
|
+
appendMessage: () => { },
|
|
1211
|
+
emitBridge: (event) => emitted.push(event),
|
|
1212
|
+
updateRunStatus: () => { },
|
|
1213
|
+
sendRaw: () => true,
|
|
1214
|
+
});
|
|
1215
|
+
const previousCleanFinal = '你确定要删除 **Sisyphus_介绍.txt** 这个文件吗?删除后无法恢复。确认的话我马上执行。';
|
|
1216
|
+
const pollutedStoredFinal = [
|
|
1217
|
+
'Hi! How can I help you today?',
|
|
1218
|
+
'我是 Hermes Agent,你的 AI 助手。',
|
|
1219
|
+
'好的,让我看看你的桌面文件。',
|
|
1220
|
+
previousCleanFinal,
|
|
1221
|
+
].join('');
|
|
1222
|
+
const session = {
|
|
1223
|
+
threadId: 'thread-1',
|
|
1224
|
+
bridgeSessionKey: 'session:thread-1',
|
|
1225
|
+
currentRunId: 'run-1',
|
|
1226
|
+
currentTurn: {
|
|
1227
|
+
runId: 'run-1',
|
|
1228
|
+
replyCtx: 'run-1',
|
|
1229
|
+
previewHandle: 'preview-1',
|
|
1230
|
+
agentType: 'hermes',
|
|
1231
|
+
assistantText: '',
|
|
1232
|
+
rawAssistantText: '',
|
|
1233
|
+
priorAssistantFinalMessages: [pollutedStoredFinal],
|
|
1234
|
+
typingStarted: true,
|
|
1235
|
+
previewStarted: false,
|
|
1236
|
+
permission: null,
|
|
1237
|
+
},
|
|
1238
|
+
loadReplayMode: false,
|
|
1239
|
+
schedulerJobCreatedByRun: new Map(),
|
|
1240
|
+
};
|
|
1241
|
+
for (const text of [
|
|
1242
|
+
'Hi! How can I help you today?',
|
|
1243
|
+
'我是 Hermes Agent,你的 AI 助手。',
|
|
1244
|
+
'好的,让我看看你的桌面文件。',
|
|
1245
|
+
previousCleanFinal,
|
|
1246
|
+
'已删除 **Sisyphus_介绍.txt**,现在 Text 文件夹是空的了。',
|
|
1247
|
+
]) {
|
|
1248
|
+
coordinator.handleAgentNotification(session, {
|
|
1249
|
+
method: 'session/update',
|
|
1250
|
+
params: {
|
|
1251
|
+
update: {
|
|
1252
|
+
sessionUpdate: 'agent_message_chunk',
|
|
1253
|
+
content: { type: 'text', text },
|
|
1254
|
+
},
|
|
1255
|
+
},
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
strict_1.default.equal(session.currentTurn.assistantText, '已删除 **Sisyphus_介绍.txt**,现在 Text 文件夹是空的了。');
|
|
1259
|
+
strict_1.default.deepEqual(emitted.map((event) => event.content), ['已删除 **Sisyphus_介绍.txt**,现在 Text 文件夹是空的了。']);
|
|
1260
|
+
});
|
|
1261
|
+
(0, node_test_1.default)('Hermes ACP assistant chunks keep a fresh answer when no replay anchor is present', () => {
|
|
1262
|
+
const emitted = [];
|
|
1263
|
+
const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
|
|
1264
|
+
appendMessage: () => { },
|
|
1265
|
+
emitBridge: (event) => emitted.push(event),
|
|
1266
|
+
updateRunStatus: () => { },
|
|
1267
|
+
sendRaw: () => true,
|
|
1268
|
+
});
|
|
1269
|
+
const session = {
|
|
1270
|
+
threadId: 'thread-1',
|
|
1271
|
+
bridgeSessionKey: 'session:thread-1',
|
|
1272
|
+
currentRunId: 'run-1',
|
|
1273
|
+
currentTurn: {
|
|
1274
|
+
runId: 'run-1',
|
|
1275
|
+
replyCtx: 'run-1',
|
|
1276
|
+
previewHandle: 'preview-1',
|
|
1277
|
+
agentType: 'hermes',
|
|
1278
|
+
assistantText: '',
|
|
1279
|
+
rawAssistantText: '',
|
|
1280
|
+
priorAssistantFinalMessages: ['上一轮已经污染的历史,但是它不会出现在这次新回复里。'],
|
|
1281
|
+
typingStarted: true,
|
|
1282
|
+
previewStarted: false,
|
|
1283
|
+
permission: null,
|
|
1284
|
+
},
|
|
1285
|
+
loadReplayMode: false,
|
|
1286
|
+
schedulerJobCreatedByRun: new Map(),
|
|
1287
|
+
};
|
|
1288
|
+
coordinator.handleAgentNotification(session, {
|
|
1289
|
+
method: 'session/update',
|
|
1290
|
+
params: {
|
|
1291
|
+
update: {
|
|
1292
|
+
sessionUpdate: 'agent_message_chunk',
|
|
1293
|
+
content: { type: 'text', text: '已删除文件。' },
|
|
1294
|
+
},
|
|
1295
|
+
},
|
|
1296
|
+
});
|
|
1297
|
+
strict_1.default.equal(session.currentTurn.assistantText, '已删除文件。');
|
|
1298
|
+
strict_1.default.deepEqual(emitted.map((event) => event.content), ['已删除文件。']);
|
|
1299
|
+
});
|
|
1300
|
+
(0, node_test_1.default)('Hermes ACP progress updates suppress restored tool and thought replay only', () => {
|
|
1301
|
+
const upserted = [];
|
|
1302
|
+
const emitted = [];
|
|
1303
|
+
const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
|
|
1304
|
+
appendMessage: () => strict_1.default.fail('tool updates should be upserted'),
|
|
1305
|
+
upsertMessage: (_threadId, id, _role, content, _kind, _toolCall, bridgeKind) => {
|
|
1306
|
+
upserted.push({ id, content, bridgeKind });
|
|
1307
|
+
},
|
|
1308
|
+
emitBridge: (event) => emitted.push(event),
|
|
1309
|
+
updateRunStatus: () => { },
|
|
1310
|
+
sendRaw: () => true,
|
|
1311
|
+
});
|
|
1312
|
+
const session = {
|
|
1313
|
+
threadId: 'thread-1',
|
|
1314
|
+
bridgeSessionKey: 'session:thread-1',
|
|
1315
|
+
currentRunId: 'run-1',
|
|
1316
|
+
currentTurn: {
|
|
1317
|
+
runId: 'run-1',
|
|
1318
|
+
replyCtx: 'run-1',
|
|
1319
|
+
previewHandle: 'preview-1',
|
|
1320
|
+
thoughtPreviewHandle: 'thought-preview-1',
|
|
1321
|
+
thoughtMessageId: 'run-1-thought-1',
|
|
1322
|
+
agentType: 'hermes',
|
|
1323
|
+
assistantText: '',
|
|
1324
|
+
thoughtText: '',
|
|
1325
|
+
thoughtSequence: 1,
|
|
1326
|
+
typingStarted: true,
|
|
1327
|
+
previewStarted: false,
|
|
1328
|
+
thoughtPreviewStarted: false,
|
|
1329
|
+
priorAssistantProgressMessages: [
|
|
1330
|
+
{
|
|
1331
|
+
kind: 'tool',
|
|
1332
|
+
content: '🔧 terminal: rm ~/Desktop/Text/Sisyphus_介绍.txt: completed - terminal result\n- **exit_code:** 0',
|
|
1333
|
+
},
|
|
1334
|
+
{
|
|
1335
|
+
kind: 'thought',
|
|
1336
|
+
content: 'The user confirmed they want to delete the file. Let me delete it.',
|
|
1337
|
+
},
|
|
1338
|
+
],
|
|
1339
|
+
permission: null,
|
|
1340
|
+
},
|
|
1341
|
+
loadReplayMode: false,
|
|
1342
|
+
schedulerJobCreatedByRun: new Map(),
|
|
1343
|
+
};
|
|
1344
|
+
coordinator.handleAgentNotification(session, {
|
|
1345
|
+
method: 'session/update',
|
|
1346
|
+
params: {
|
|
1347
|
+
update: {
|
|
1348
|
+
sessionUpdate: 'tool_call',
|
|
1349
|
+
id: 'old-tool',
|
|
1350
|
+
title: 'terminal',
|
|
1351
|
+
rawInput: { command: 'rm ~/Desktop/Text/Sisyphus_介绍.txt' },
|
|
1352
|
+
},
|
|
1353
|
+
},
|
|
1354
|
+
});
|
|
1355
|
+
coordinator.handleAgentNotification(session, {
|
|
1356
|
+
method: 'session/update',
|
|
1357
|
+
params: {
|
|
1358
|
+
update: {
|
|
1359
|
+
sessionUpdate: 'tool_call_update',
|
|
1360
|
+
id: 'old-tool',
|
|
1361
|
+
title: 'tool update',
|
|
1362
|
+
status: 'completed',
|
|
1363
|
+
content: [
|
|
1364
|
+
{
|
|
1365
|
+
type: 'content',
|
|
1366
|
+
content: {
|
|
1367
|
+
type: 'text',
|
|
1368
|
+
text: 'terminal result\n- **exit_code:** 0',
|
|
1369
|
+
},
|
|
1370
|
+
},
|
|
1371
|
+
],
|
|
1372
|
+
},
|
|
1373
|
+
},
|
|
1374
|
+
});
|
|
1375
|
+
coordinator.handleAgentNotification(session, {
|
|
1376
|
+
method: 'session/update',
|
|
1377
|
+
params: {
|
|
1378
|
+
update: {
|
|
1379
|
+
sessionUpdate: 'agent_thought_chunk',
|
|
1380
|
+
content: {
|
|
1381
|
+
type: 'text',
|
|
1382
|
+
text: 'The user confirmed they want to delete the file. Let me delete it.',
|
|
1383
|
+
},
|
|
1384
|
+
},
|
|
1385
|
+
},
|
|
1386
|
+
});
|
|
1387
|
+
coordinator.handleAgentNotification(session, {
|
|
1388
|
+
method: 'session/update',
|
|
1389
|
+
params: {
|
|
1390
|
+
update: {
|
|
1391
|
+
sessionUpdate: 'tool_call',
|
|
1392
|
+
id: 'new-tool',
|
|
1393
|
+
title: 'terminal',
|
|
1394
|
+
rawInput: { command: 'ls -la ~/Desktop/PDF/' },
|
|
1395
|
+
},
|
|
1396
|
+
},
|
|
1397
|
+
});
|
|
1398
|
+
coordinator.handleAgentNotification(session, {
|
|
1399
|
+
method: 'session/update',
|
|
1400
|
+
params: {
|
|
1401
|
+
update: {
|
|
1402
|
+
sessionUpdate: 'tool_call_update',
|
|
1403
|
+
id: 'new-tool',
|
|
1404
|
+
title: 'tool update',
|
|
1405
|
+
status: 'completed',
|
|
1406
|
+
content: [
|
|
1407
|
+
{
|
|
1408
|
+
type: 'content',
|
|
1409
|
+
content: {
|
|
1410
|
+
type: 'text',
|
|
1411
|
+
text: 'terminal result\n- **output:** pdf files\n- **exit_code:** 0',
|
|
1412
|
+
},
|
|
1413
|
+
},
|
|
1414
|
+
],
|
|
1415
|
+
},
|
|
1416
|
+
},
|
|
1417
|
+
});
|
|
1418
|
+
coordinator.handleAgentNotification(session, {
|
|
1419
|
+
method: 'session/update',
|
|
1420
|
+
params: {
|
|
1421
|
+
update: {
|
|
1422
|
+
sessionUpdate: 'agent_thought_chunk',
|
|
1423
|
+
content: {
|
|
1424
|
+
type: 'text',
|
|
1425
|
+
text: 'Let me present the PDF files to the user.',
|
|
1426
|
+
},
|
|
1427
|
+
},
|
|
1428
|
+
},
|
|
1429
|
+
});
|
|
1430
|
+
strict_1.default.deepEqual(upserted.map((entry) => entry.content), [
|
|
1431
|
+
'🔧 terminal: completed - terminal result\n- **output:** pdf files\n- **exit_code:** 0',
|
|
1432
|
+
'Let me present the PDF files to the user.',
|
|
1433
|
+
]);
|
|
1434
|
+
strict_1.default.deepEqual(emitted.map((event) => event.content), [
|
|
1435
|
+
'🔧 terminal: completed - terminal result\n- **output:** pdf files\n- **exit_code:** 0',
|
|
1436
|
+
'Let me present the PDF files to the user.',
|
|
1437
|
+
]);
|
|
1438
|
+
});
|
|
1439
|
+
(0, node_test_1.default)('Hermes ACP progress updates suppress restored plan and tool-scoped assistant chunks', () => {
|
|
1440
|
+
const appended = [];
|
|
1441
|
+
const emitted = [];
|
|
1442
|
+
const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
|
|
1443
|
+
appendMessage: (_threadId, _role, content, _kind, _toolCall, bridgeKind) => appended.push({ content, bridgeKind }),
|
|
1444
|
+
emitBridge: (event) => emitted.push(event),
|
|
1445
|
+
updateRunStatus: () => { },
|
|
1446
|
+
sendRaw: () => true,
|
|
1447
|
+
});
|
|
1448
|
+
const session = {
|
|
1449
|
+
threadId: 'thread-1',
|
|
1450
|
+
bridgeSessionKey: 'session:thread-1',
|
|
1451
|
+
currentRunId: 'run-1',
|
|
1452
|
+
currentTurn: {
|
|
1453
|
+
runId: 'run-1',
|
|
1454
|
+
replyCtx: 'run-1',
|
|
1455
|
+
previewHandle: 'preview-1',
|
|
1456
|
+
agentType: 'hermes',
|
|
1457
|
+
assistantText: '',
|
|
1458
|
+
priorAssistantProgressMessages: [
|
|
1459
|
+
{ kind: 'plan', content: '旧计划 | 已完成' },
|
|
1460
|
+
{ kind: 'tool', content: 'raw restored command output' },
|
|
1461
|
+
],
|
|
1462
|
+
typingStarted: true,
|
|
1463
|
+
previewStarted: false,
|
|
1464
|
+
permission: null,
|
|
1465
|
+
},
|
|
1466
|
+
loadReplayMode: false,
|
|
1467
|
+
schedulerJobCreatedByRun: new Map(),
|
|
1468
|
+
pendingRawAssistantProgressChunks: ['raw restored command output', 'fresh command output'],
|
|
1469
|
+
};
|
|
1470
|
+
coordinator.handleAgentNotification(session, {
|
|
1471
|
+
method: 'session/update',
|
|
1472
|
+
params: {
|
|
1473
|
+
update: {
|
|
1474
|
+
sessionUpdate: 'plan',
|
|
1475
|
+
entries: [{ content: '旧计划' }, { content: '已完成' }],
|
|
1476
|
+
},
|
|
1477
|
+
},
|
|
1478
|
+
});
|
|
1479
|
+
coordinator.handleAgentNotification(session, {
|
|
1480
|
+
method: 'session/update',
|
|
1481
|
+
params: {
|
|
1482
|
+
update: {
|
|
1483
|
+
sessionUpdate: 'agent_message_chunk',
|
|
1484
|
+
content: { type: 'text', text: 'raw restored command output' },
|
|
1485
|
+
},
|
|
1486
|
+
},
|
|
1487
|
+
});
|
|
1488
|
+
coordinator.handleAgentNotification(session, {
|
|
1489
|
+
method: 'session/update',
|
|
1490
|
+
params: {
|
|
1491
|
+
update: {
|
|
1492
|
+
sessionUpdate: 'plan',
|
|
1493
|
+
entries: [{ content: '新计划' }, { content: '进行中' }],
|
|
1494
|
+
},
|
|
1495
|
+
},
|
|
1496
|
+
});
|
|
1497
|
+
coordinator.handleAgentNotification(session, {
|
|
1498
|
+
method: 'session/update',
|
|
1499
|
+
params: {
|
|
1500
|
+
update: {
|
|
1501
|
+
sessionUpdate: 'agent_message_chunk',
|
|
1502
|
+
content: { type: 'text', text: 'fresh command output' },
|
|
1503
|
+
},
|
|
1504
|
+
},
|
|
1505
|
+
});
|
|
1506
|
+
strict_1.default.deepEqual(appended, [
|
|
1507
|
+
{ content: '新计划 | 进行中', bridgeKind: 'plan' },
|
|
1508
|
+
{ content: 'fresh command output', bridgeKind: 'tool' },
|
|
1509
|
+
]);
|
|
1510
|
+
strict_1.default.deepEqual(emitted.map((event) => ({ content: event.content, bridgeKind: event.bridgeKind })), [
|
|
1511
|
+
{ content: '新计划 | 进行中', bridgeKind: 'plan' },
|
|
1512
|
+
{ content: 'fresh command output', bridgeKind: 'tool' },
|
|
1513
|
+
]);
|
|
1514
|
+
});
|
|
1116
1515
|
(0, node_test_1.default)('ACP raw local command output assistant chunks stay out of final assistant buffer', () => {
|
|
1117
1516
|
const appended = [];
|
|
1118
1517
|
const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
|
|
@@ -1405,6 +1804,29 @@ const server_routes_js_1 = require("../services/local-ai-core/src/runtime/server
|
|
|
1405
1804
|
(0, node_fs_1.rmSync)(userDataPath, { recursive: true, force: true });
|
|
1406
1805
|
}
|
|
1407
1806
|
});
|
|
1807
|
+
(0, node_test_1.default)('channel gateways ignore unowned bridge events without route miss log noise', async () => {
|
|
1808
|
+
const logs = [];
|
|
1809
|
+
const commonOptions = {
|
|
1810
|
+
store: {},
|
|
1811
|
+
readConfig: async () => null,
|
|
1812
|
+
getWorkspaceRouter: () => ({}),
|
|
1813
|
+
eventBus: { emit: () => { }, on: () => () => { } },
|
|
1814
|
+
log: (line) => logs.push(line),
|
|
1815
|
+
};
|
|
1816
|
+
const larkGateway = new local_core_lark_gateway_js_1.LocalCoreLarkGateway(commonOptions);
|
|
1817
|
+
const weixinGateway = new local_core_weixin_gateway_js_1.LocalCoreWeixinGateway(commonOptions);
|
|
1818
|
+
await larkGateway.onBridgeEvent({
|
|
1819
|
+
type: 'update_message',
|
|
1820
|
+
sessionKey: 'localcore-acp:project-1:thread-1',
|
|
1821
|
+
content: 'stream chunk',
|
|
1822
|
+
});
|
|
1823
|
+
await weixinGateway.onBridgeEvent({
|
|
1824
|
+
type: 'update_message',
|
|
1825
|
+
sessionKey: 'localcore-acp:project-1:thread-1',
|
|
1826
|
+
content: 'stream chunk',
|
|
1827
|
+
});
|
|
1828
|
+
strict_1.default.deepEqual(logs, []);
|
|
1829
|
+
});
|
|
1408
1830
|
(0, node_test_1.default)('lark bridge sends completed thought once before final answer', async () => {
|
|
1409
1831
|
const createdCards = [];
|
|
1410
1832
|
const patchedCards = [];
|