@kafca/agentdock 0.1.29 → 0.1.30
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/dist/renderer/assets/{Badge-ngf0eCzI.js → Badge-DlVJI1Ys.js} +1 -1
- package/dist/renderer/assets/{Chat-tCGY5odh.js → Chat-oa8OjaHQ.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-vqDWgVNb.js → ChatMarkdown-C-N8KS5C.js} +1 -1
- package/dist/renderer/assets/{Config-YsVDQmIs.js → Config-D9sL_d4D.js} +1 -1
- package/dist/renderer/assets/{CronList-DQN0T7Yc.js → CronList-Z5JU3DHk.js} +1 -1
- package/dist/renderer/assets/{Dashboard-C2O6Yxq3.js → Dashboard-D3BwbG43.js} +2 -2
- package/dist/renderer/assets/{EmptyState-CTkA-fBQ.js → EmptyState-QOj765Ul.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-DjLZDItQ.js → KnowledgeDetail-J7n01mPu.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-2NHeRZxW.js → KnowledgeHome-BFnH0NVk.js} +1 -1
- package/dist/renderer/assets/{Logs-CQ6j-Sct.js → Logs-DfSUifXc.js} +1 -1
- package/dist/renderer/assets/{Modal-9g1uWJfC.js → Modal-QjEGhyru.js} +1 -1
- package/dist/renderer/assets/{Page-B4mPLn6n.js → Page-qdHFSw7x.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-pBXOAeL4.js → ProjectDetail-DS_rfvhh.js} +1 -1
- package/dist/renderer/assets/{ProjectList-B9PYfZaS.js → ProjectList-COtyZd7H.js} +1 -1
- package/dist/renderer/assets/{Select-BWFQJ2R8.js → Select-BQ8mncVu.js} +1 -1
- package/dist/renderer/assets/{SessionChat-fBrzJs3A.js → SessionChat-DjVnjuQy.js} +1 -1
- package/dist/renderer/assets/{SessionList-DjHOsk7X.js → SessionList-88dgGZJ8.js} +1 -1
- package/dist/renderer/assets/{ThreadChat-MagPeJD0.js → ThreadChat-BCdbTxBo.js} +1 -1
- package/dist/renderer/assets/{Workspace-nfTcxlhw.js → Workspace-D_hzSJjX.js} +1 -1
- package/dist/renderer/assets/{arrow-left-CIWZ6JEB.js → arrow-left-BMpknulW.js} +1 -1
- package/dist/renderer/assets/{book-open-Ck6BgBhN.js → book-open-CiaOeQbU.js} +1 -1
- package/dist/renderer/assets/{check-CtB2ZLVE.js → check-CgwYH4GF.js} +1 -1
- package/dist/renderer/assets/{chevron-down--8lODnN0.js → chevron-down-BzD2S1OO.js} +1 -1
- package/dist/renderer/assets/{circle-CKQOJcbh.js → circle-BDHD7g7l.js} +1 -1
- package/dist/renderer/assets/{desktop-Do2I28CT.js → desktop-BiR5LPL5.js} +1 -1
- package/dist/renderer/assets/{funnel-CkZuFIwa.js → funnel-Bruf5FYA.js} +1 -1
- package/dist/renderer/assets/{heart-CAX_CqFQ.js → heart-D7Mz04B0.js} +1 -1
- package/dist/renderer/assets/{index-DvAYflFj.js → index-CL1e8m3U.js} +2 -2
- package/dist/renderer/assets/{index--_L0Y77h.js → index-gZIRr4_o.js} +1 -1
- package/dist/renderer/assets/{pencil-sIRhtchu.js → pencil-C6gzDMse.js} +1 -1
- package/dist/renderer/assets/{play-CJNRbCL5.js → play-DqTXX-Pr.js} +1 -1
- package/dist/renderer/assets/{plug-DsFe9GBx.js → plug-ykmbeaO3.js} +1 -1
- package/dist/renderer/assets/{plus-KDwEI-Rs.js → plus-DHE60vMX.js} +1 -1
- package/dist/renderer/assets/projects-Bx5p10th.js +1 -0
- package/dist/renderer/assets/{save-C-p5r3K-.js → save-CGIvrdQI.js} +1 -1
- package/dist/renderer/assets/{search-BZxQJb2k.js → search-D7IFAwyE.js} +1 -1
- package/dist/renderer/assets/{server-BV-K022I.js → server-aOsirp7I.js} +1 -1
- package/dist/renderer/assets/{session-utils-ClQTa8yS.js → session-utils-Dxfp4ohQ.js} +1 -1
- package/dist/renderer/assets/{sessions-B0FSCA9O.js → sessions-Db1XPbG2.js} +1 -1
- package/dist/renderer/assets/{shield-check-B6AjkXUd.js → shield-check-ChXeQK-d.js} +1 -1
- package/dist/renderer/assets/{trash-2-41Pv4qRx.js → trash-2-CfN-c1zw.js} +1 -1
- package/dist/renderer/assets/{user-NKKHCKm9.js → user-C7OHaBp4.js} +1 -1
- package/dist/renderer/assets/{wifi-off-E1ZNhLG5.js → wifi-off-CpaJigye.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/electron/local-core-refactor.test.js +301 -18
- package/dist-electron/electron/workspace-task-store.test.js +7 -1
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +7 -2
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +239 -7
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +10 -6
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +1 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +79 -2
- package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +1 -1
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +13 -1
- package/package.json +1 -1
- package/dist/renderer/assets/projects-CJUs2vaq.js +0 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.applyAssistantMessageChunk = applyAssistantMessageChunk;
|
|
4
4
|
exports.applyThoughtChunk = applyThoughtChunk;
|
|
5
|
+
exports.closeThoughtSegment = closeThoughtSegment;
|
|
5
6
|
exports.registerPendingToolCall = registerPendingToolCall;
|
|
6
7
|
exports.resolveToolCallForUpdate = resolveToolCallForUpdate;
|
|
7
8
|
exports.resolveFallbackToolCall = resolveFallbackToolCall;
|
|
@@ -16,6 +17,8 @@ exports.isTerminalToolStatus = isTerminalToolStatus;
|
|
|
16
17
|
exports.formatPlanProgress = formatPlanProgress;
|
|
17
18
|
exports.extractToolCallKey = extractToolCallKey;
|
|
18
19
|
exports.extractToolCallInput = extractToolCallInput;
|
|
20
|
+
exports.recordToolObservation = recordToolObservation;
|
|
21
|
+
exports.stripObservedToolTranscriptsFromAssistantText = stripObservedToolTranscriptsFromAssistantText;
|
|
19
22
|
function applyAssistantMessageChunk(currentTurn, text) {
|
|
20
23
|
if (!text) {
|
|
21
24
|
return null;
|
|
@@ -41,8 +44,12 @@ function applyThoughtChunk(currentTurn, text) {
|
|
|
41
44
|
if (!text) {
|
|
42
45
|
return null;
|
|
43
46
|
}
|
|
44
|
-
|
|
47
|
+
const projection = mergeThoughtSegment(currentTurn.thoughtText, text);
|
|
48
|
+
currentTurn.thoughtText = projection.fullText;
|
|
45
49
|
const content = currentTurn.thoughtText.trim();
|
|
50
|
+
if (!content) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
46
53
|
if (!currentTurn.thoughtPreviewStarted) {
|
|
47
54
|
currentTurn.thoughtPreviewStarted = true;
|
|
48
55
|
return {
|
|
@@ -61,23 +68,67 @@ function applyThoughtChunk(currentTurn, text) {
|
|
|
61
68
|
bridgeKind: 'thought',
|
|
62
69
|
};
|
|
63
70
|
}
|
|
64
|
-
function
|
|
71
|
+
function closeThoughtSegment(currentTurn) {
|
|
72
|
+
const thoughtText = currentTurn.thoughtText || '';
|
|
73
|
+
if (!thoughtText.trim()) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const nextSequence = (currentTurn.thoughtSequence || 1) + 1;
|
|
77
|
+
const runId = currentTurn.runId || 'thought';
|
|
78
|
+
currentTurn.thoughtSequence = nextSequence;
|
|
79
|
+
currentTurn.thoughtText = '';
|
|
80
|
+
currentTurn.thoughtPreviewStarted = false;
|
|
81
|
+
currentTurn.thoughtMessageId = `${runId}-thought-${nextSequence}`;
|
|
82
|
+
currentTurn.thoughtPreviewHandle = `${runId}-thought-preview-${nextSequence}`;
|
|
83
|
+
}
|
|
84
|
+
function mergeThoughtSegment(current, next) {
|
|
65
85
|
if (!current) {
|
|
66
|
-
return next;
|
|
86
|
+
return { fullText: next, segmentText: next };
|
|
67
87
|
}
|
|
68
88
|
if (next.startsWith(current)) {
|
|
69
|
-
return
|
|
89
|
+
return {
|
|
90
|
+
fullText: next,
|
|
91
|
+
segmentText: next.slice(current.length),
|
|
92
|
+
};
|
|
70
93
|
}
|
|
71
94
|
if (current.endsWith(next)) {
|
|
72
|
-
return
|
|
95
|
+
return {
|
|
96
|
+
fullText: current,
|
|
97
|
+
segmentText: '',
|
|
98
|
+
};
|
|
73
99
|
}
|
|
74
100
|
const maxOverlap = Math.min(current.length, next.length);
|
|
75
101
|
for (let size = maxOverlap; size > 0; size -= 1) {
|
|
76
102
|
if (current.endsWith(next.slice(0, size))) {
|
|
77
|
-
|
|
103
|
+
const suffix = next.slice(size);
|
|
104
|
+
return {
|
|
105
|
+
fullText: current + suffix,
|
|
106
|
+
segmentText: suffix,
|
|
107
|
+
};
|
|
78
108
|
}
|
|
79
109
|
}
|
|
80
|
-
return
|
|
110
|
+
return {
|
|
111
|
+
fullText: appendThoughtPiece(current, next),
|
|
112
|
+
segmentText: next,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function appendThoughtPiece(current, next) {
|
|
116
|
+
if (!current.trim()) {
|
|
117
|
+
return next;
|
|
118
|
+
}
|
|
119
|
+
if (!next.trim()) {
|
|
120
|
+
return current;
|
|
121
|
+
}
|
|
122
|
+
if (/^[,.;:!?,。;:!?、)】》]/.test(next.trimStart())) {
|
|
123
|
+
return current.trimEnd() + next.trimStart();
|
|
124
|
+
}
|
|
125
|
+
if (/^[-/]/.test(next.trimStart()) || /[-/][A-Za-z0-9]*$/.test(current.trimEnd())) {
|
|
126
|
+
return current.trimEnd() + next.trimStart();
|
|
127
|
+
}
|
|
128
|
+
if (/\s$/.test(current) || /^\s/.test(next)) {
|
|
129
|
+
return current + next;
|
|
130
|
+
}
|
|
131
|
+
return `${current.trimEnd()} ${next.trimStart()}`;
|
|
81
132
|
}
|
|
82
133
|
function registerPendingToolCall(input) {
|
|
83
134
|
const title = String(input.update.title || 'Running tool').trim();
|
|
@@ -203,3 +254,184 @@ function extractToolCallInput(update) {
|
|
|
203
254
|
}
|
|
204
255
|
return undefined;
|
|
205
256
|
}
|
|
257
|
+
function recordToolObservation(currentTurn, observation) {
|
|
258
|
+
const normalized = {
|
|
259
|
+
...observation,
|
|
260
|
+
name: observation.name?.trim() || undefined,
|
|
261
|
+
title: observation.title?.trim() || undefined,
|
|
262
|
+
status: observation.status?.trim() || undefined,
|
|
263
|
+
outputText: observation.outputText?.trim() || undefined,
|
|
264
|
+
};
|
|
265
|
+
if (!normalized.name && !normalized.title && normalized.input === undefined && !normalized.outputText) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
currentTurn.toolObservations = [
|
|
269
|
+
...(currentTurn.toolObservations || []),
|
|
270
|
+
normalized,
|
|
271
|
+
];
|
|
272
|
+
}
|
|
273
|
+
function stripObservedToolTranscriptsFromAssistantText(text, observations) {
|
|
274
|
+
let remaining = String(text || '');
|
|
275
|
+
const knownObservations = observations || [];
|
|
276
|
+
for (let guard = 0; guard < knownObservations.length; guard += 1) {
|
|
277
|
+
const stripped = stripOneObservedToolTranscriptPrefix(remaining, knownObservations);
|
|
278
|
+
if (stripped === remaining) {
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
remaining = stripped;
|
|
282
|
+
}
|
|
283
|
+
return remaining.trim();
|
|
284
|
+
}
|
|
285
|
+
function stripOneObservedToolTranscriptPrefix(text, observations) {
|
|
286
|
+
const trimmedStart = text.replace(/^\s+/, '');
|
|
287
|
+
if (!trimmedStart) {
|
|
288
|
+
return text;
|
|
289
|
+
}
|
|
290
|
+
const matchingEvidence = observations
|
|
291
|
+
.map((observation) => createToolObservationEvidence(observation))
|
|
292
|
+
.find((evidence) => matchesObservedToolTranscriptPrefix(trimmedStart, evidence));
|
|
293
|
+
if (!matchingEvidence) {
|
|
294
|
+
return text;
|
|
295
|
+
}
|
|
296
|
+
const boundary = findToolTranscriptPrefixBoundary(trimmedStart, matchingEvidence);
|
|
297
|
+
if (boundary <= 0) {
|
|
298
|
+
return text;
|
|
299
|
+
}
|
|
300
|
+
return trimmedStart.slice(boundary);
|
|
301
|
+
}
|
|
302
|
+
function createToolObservationEvidence(observation) {
|
|
303
|
+
const serializedInput = serializeObservationValue(observation.input);
|
|
304
|
+
const serializedOutput = observation.outputText || '';
|
|
305
|
+
const structuredValues = collectStructuredStringValues(serializedOutput);
|
|
306
|
+
return {
|
|
307
|
+
toolNames: uniqueNonEmpty([
|
|
308
|
+
observation.name,
|
|
309
|
+
observation.title,
|
|
310
|
+
].map((value) => normalizeEvidencePhrase(value || ''))),
|
|
311
|
+
urls: uniqueNonEmpty([
|
|
312
|
+
...extractUrls(serializedInput),
|
|
313
|
+
...extractUrls(serializedOutput),
|
|
314
|
+
]),
|
|
315
|
+
phrases: uniqueNonEmpty([
|
|
316
|
+
...structuredValues,
|
|
317
|
+
observation.title,
|
|
318
|
+
serializedInput.length <= 300 ? serializedInput : '',
|
|
319
|
+
].map((value) => normalizeEvidencePhrase(value || '')).filter((value) => value.length >= 12)),
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function matchesObservedToolTranscriptPrefix(text, evidence) {
|
|
323
|
+
const prefix = text.slice(0, 3000);
|
|
324
|
+
const normalizedPrefix = normalizeEvidencePhrase(prefix);
|
|
325
|
+
const hasToolName = evidence.toolNames.some((name) => name && normalizedPrefix.includes(name));
|
|
326
|
+
const urlMatches = evidence.urls.filter((url) => prefix.includes(url)).length;
|
|
327
|
+
const phraseMatches = evidence.phrases.filter((phrase) => normalizedPrefix.includes(phrase)).length;
|
|
328
|
+
if (hasToolName && (urlMatches > 0 || phraseMatches > 0)) {
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
return urlMatches > 0 && phraseMatches > 0;
|
|
332
|
+
}
|
|
333
|
+
function findToolTranscriptPrefixBoundary(text, evidence) {
|
|
334
|
+
const lines = text.split(/\n/);
|
|
335
|
+
const firstContentLine = lines.find((line) => line.trim());
|
|
336
|
+
if (!firstContentLine || !isTranscriptStartLine(firstContentLine, evidence)) {
|
|
337
|
+
return 0;
|
|
338
|
+
}
|
|
339
|
+
let offset = 0;
|
|
340
|
+
let seenEvidence = false;
|
|
341
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
342
|
+
const line = lines[index] || '';
|
|
343
|
+
const lineWithNewlineLength = line.length + (index < lines.length - 1 ? 1 : 0);
|
|
344
|
+
if (lineContainsObservationEvidence(line, evidence)) {
|
|
345
|
+
seenEvidence = true;
|
|
346
|
+
}
|
|
347
|
+
if (seenEvidence && index > 0 && line.trim() && !isStructuredTranscriptLine(line, evidence)) {
|
|
348
|
+
return offset;
|
|
349
|
+
}
|
|
350
|
+
offset += lineWithNewlineLength;
|
|
351
|
+
}
|
|
352
|
+
return 0;
|
|
353
|
+
}
|
|
354
|
+
function isTranscriptStartLine(line, evidence) {
|
|
355
|
+
const trimmed = line.trim();
|
|
356
|
+
return lineContainsObservationEvidence(line, evidence) &&
|
|
357
|
+
(/^(```|\{|\[|\*\*[^*]+\*\*|#+\s)/.test(trimmed) || /^[A-Za-z0-9_.-]+:/.test(trimmed));
|
|
358
|
+
}
|
|
359
|
+
function isStructuredTranscriptLine(line, evidence) {
|
|
360
|
+
const trimmed = line.trim();
|
|
361
|
+
if (!trimmed) {
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
if (lineContainsObservationEvidence(line, evidence)) {
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
return /^(```|\{|\}|\[|\]|".+":|\*\*[^*]+:\*\*|\*[^*]+\*|#+\s)/.test(trimmed) ||
|
|
368
|
+
/[::]\s*$/.test(trimmed) ||
|
|
369
|
+
/[{}\[\]"]/g.test(trimmed) ||
|
|
370
|
+
/^[A-Za-z0-9_.-]+:/.test(trimmed);
|
|
371
|
+
}
|
|
372
|
+
function lineContainsObservationEvidence(line, evidence) {
|
|
373
|
+
const normalizedLine = normalizeEvidencePhrase(line);
|
|
374
|
+
return evidence.toolNames.some((name) => name && normalizedLine.includes(name)) ||
|
|
375
|
+
evidence.urls.some((url) => line.includes(url)) ||
|
|
376
|
+
evidence.phrases.some((phrase) => phrase && normalizedLine.includes(phrase));
|
|
377
|
+
}
|
|
378
|
+
function serializeObservationValue(value) {
|
|
379
|
+
if (value == null) {
|
|
380
|
+
return '';
|
|
381
|
+
}
|
|
382
|
+
if (typeof value === 'string') {
|
|
383
|
+
return value;
|
|
384
|
+
}
|
|
385
|
+
try {
|
|
386
|
+
return JSON.stringify(value);
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
return String(value);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function collectStructuredStringValues(text) {
|
|
393
|
+
const values = [];
|
|
394
|
+
try {
|
|
395
|
+
collectStringValues(JSON.parse(text), values);
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
const matches = text.matchAll(/"(title|description|url|name|summary)"\s*:\s*"([^"]{12,})"/gi);
|
|
399
|
+
for (const match of matches) {
|
|
400
|
+
values.push(match[2] || '');
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return values;
|
|
404
|
+
}
|
|
405
|
+
function collectStringValues(value, values) {
|
|
406
|
+
if (typeof value === 'string') {
|
|
407
|
+
values.push(value);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (Array.isArray(value)) {
|
|
411
|
+
for (const item of value) {
|
|
412
|
+
collectStringValues(item, values);
|
|
413
|
+
}
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
if (!value || typeof value !== 'object') {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
for (const entry of Object.values(value)) {
|
|
420
|
+
collectStringValues(entry, values);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function extractUrls(text) {
|
|
424
|
+
return [...text.matchAll(/https?:\/\/[^\s"'`<>),\]}]+/g)]
|
|
425
|
+
.map((match) => match[0])
|
|
426
|
+
.filter(Boolean);
|
|
427
|
+
}
|
|
428
|
+
function normalizeEvidencePhrase(value) {
|
|
429
|
+
return String(value || '')
|
|
430
|
+
.replace(/\\[nrt]/g, ' ')
|
|
431
|
+
.replace(/\s+/g, ' ')
|
|
432
|
+
.trim()
|
|
433
|
+
.toLowerCase();
|
|
434
|
+
}
|
|
435
|
+
function uniqueNonEmpty(values) {
|
|
436
|
+
return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
|
|
437
|
+
}
|
|
@@ -194,14 +194,18 @@ class LocalCoreAcpSessionCoordinator {
|
|
|
194
194
|
}
|
|
195
195
|
buildSessionMeta(threadId, permissionModeOverride = '') {
|
|
196
196
|
const mode = this.resolveLaunchPermissionMode(threadId, permissionModeOverride);
|
|
197
|
-
if (!mode) {
|
|
198
|
-
return undefined;
|
|
199
|
-
}
|
|
200
197
|
return {
|
|
201
198
|
claudeCode: {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
emitRawSDKMessages: [
|
|
200
|
+
{ type: 'system', subtype: 'local_command_output' },
|
|
201
|
+
],
|
|
202
|
+
...(mode
|
|
203
|
+
? {
|
|
204
|
+
options: {
|
|
205
|
+
permissionMode: mode,
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
: {}),
|
|
205
209
|
},
|
|
206
210
|
};
|
|
207
211
|
}
|
|
@@ -11,6 +11,11 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
11
11
|
constructor(options) {
|
|
12
12
|
this.options = options;
|
|
13
13
|
}
|
|
14
|
+
closePendingThoughtSegment(session) {
|
|
15
|
+
const currentTurn = session.currentTurn;
|
|
16
|
+
if (currentTurn)
|
|
17
|
+
(0, local_core_acp_progress_js_1.closeThoughtSegment)(currentTurn);
|
|
18
|
+
}
|
|
14
19
|
flushPendingToolCall(session) {
|
|
15
20
|
const currentTurn = session.currentTurn;
|
|
16
21
|
const currentRunId = session.currentRunId;
|
|
@@ -97,6 +102,7 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
97
102
|
}
|
|
98
103
|
const options = (0, local_core_acp_permission_lifecycle_js_1.parsePermissionOptions)(payload.params?.options);
|
|
99
104
|
const toolTitle = (0, workspace_acp_permissions_js_1.formatToolCallContent)(payload.params?.toolCall);
|
|
105
|
+
this.closePendingThoughtSegment(session);
|
|
100
106
|
if ((this.options.getThreadAgentMode?.(session.threadId) || local_core_slash_commands_js_1.DEFAULT_AGENT_MODE) === 'bypassPermissions') {
|
|
101
107
|
const selected = options.find((option) => option.normalizedAction === 'allow all')
|
|
102
108
|
|| options.find((option) => option.normalizedAction === 'allow')
|
|
@@ -172,7 +178,14 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
172
178
|
});
|
|
173
179
|
}
|
|
174
180
|
handleAgentNotification(session, payload) {
|
|
175
|
-
if (session.loadReplayMode
|
|
181
|
+
if (session.loadReplayMode) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (payload.method === '_claude/sdkMessage') {
|
|
185
|
+
this.handleClaudeSdkMessage(session, payload.params?.message);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (payload.method !== 'session/update') {
|
|
176
189
|
return;
|
|
177
190
|
}
|
|
178
191
|
const update = payload.params?.update;
|
|
@@ -183,10 +196,25 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
183
196
|
}
|
|
184
197
|
switch (String(update.sessionUpdate || '')) {
|
|
185
198
|
case 'agent_message_chunk': {
|
|
199
|
+
this.closePendingThoughtSegment(session);
|
|
186
200
|
this.flushPendingToolCall(session);
|
|
187
201
|
if (update.content?.type !== 'text') {
|
|
188
202
|
return;
|
|
189
203
|
}
|
|
204
|
+
if (isToolScopedAssistantUpdate(update) || consumeRawAssistantProgressChunk(session, String(update.content.text || ''))) {
|
|
205
|
+
const content = String(update.content.text || '').trim();
|
|
206
|
+
if (content) {
|
|
207
|
+
this.options.appendMessage(session.threadId, 'assistant', content, 'progress', undefined, 'tool');
|
|
208
|
+
this.options.emitBridge({
|
|
209
|
+
type: 'reply',
|
|
210
|
+
sessionKey: session.bridgeSessionKey,
|
|
211
|
+
replyCtx: currentRunId,
|
|
212
|
+
bridgeKind: 'tool',
|
|
213
|
+
content,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
190
218
|
const projection = (0, local_core_acp_progress_js_1.applyAssistantMessageChunk)(currentTurn, String(update.content.text || ''));
|
|
191
219
|
if (!projection) {
|
|
192
220
|
return;
|
|
@@ -202,7 +230,6 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
202
230
|
return;
|
|
203
231
|
}
|
|
204
232
|
case 'agent_thought_chunk': {
|
|
205
|
-
this.flushPendingToolCall(session);
|
|
206
233
|
if (update.content?.type !== 'text') {
|
|
207
234
|
return;
|
|
208
235
|
}
|
|
@@ -224,11 +251,18 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
224
251
|
return;
|
|
225
252
|
}
|
|
226
253
|
case 'tool_call': {
|
|
254
|
+
this.closePendingThoughtSegment(session);
|
|
227
255
|
const toolCall = (0, local_core_acp_progress_js_1.registerPendingToolCall)({ currentTurn, runId: currentRunId, update });
|
|
256
|
+
(0, local_core_acp_progress_js_1.recordToolObservation)(currentTurn, {
|
|
257
|
+
name: toolCall.title,
|
|
258
|
+
title: toolCall.title,
|
|
259
|
+
input: toolCall.input,
|
|
260
|
+
});
|
|
228
261
|
(0, local_core_acp_progress_js_1.syncLegacyPendingToolCall)(currentTurn, toolCall);
|
|
229
262
|
return;
|
|
230
263
|
}
|
|
231
264
|
case 'tool_call_update': {
|
|
265
|
+
this.closePendingThoughtSegment(session);
|
|
232
266
|
const title = String(update.title || 'Tool update').trim();
|
|
233
267
|
const status = String(update.status || '').trim();
|
|
234
268
|
const content = (0, local_core_acp_progress_js_1.extractToolUpdateContent)(update.content);
|
|
@@ -280,11 +314,19 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
280
314
|
detail: displayTitle,
|
|
281
315
|
content,
|
|
282
316
|
});
|
|
317
|
+
(0, local_core_acp_progress_js_1.recordToolObservation)(currentTurn, {
|
|
318
|
+
name: toolName || displayTitle || title,
|
|
319
|
+
title: displayTitle || title,
|
|
320
|
+
status,
|
|
321
|
+
input: updateInput === undefined ? toolCall?.input : updateInput,
|
|
322
|
+
outputText: content,
|
|
323
|
+
});
|
|
283
324
|
this.emitProgress(session, currentRunId, (0, local_core_acp_progress_js_1.formatToolProgressMessage)({ toolName, title: displayTitle, status, content }), messageId, toolCallPayload);
|
|
284
325
|
(0, local_core_acp_progress_js_1.syncLegacyPendingToolCall)(currentTurn, (0, local_core_acp_progress_js_1.resolveFallbackToolCall)(currentTurn));
|
|
285
326
|
return;
|
|
286
327
|
}
|
|
287
328
|
case 'plan': {
|
|
329
|
+
this.closePendingThoughtSegment(session);
|
|
288
330
|
this.flushPendingToolCall(session);
|
|
289
331
|
const entries = Array.isArray(update.entries) ? update.entries : [];
|
|
290
332
|
if (entries.length === 0) {
|
|
@@ -308,6 +350,19 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
308
350
|
return;
|
|
309
351
|
}
|
|
310
352
|
}
|
|
353
|
+
handleClaudeSdkMessage(session, message) {
|
|
354
|
+
if (!session.currentTurn || message?.type !== 'system' || message?.subtype !== 'local_command_output') {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const content = typeof message.content === 'string' ? message.content : '';
|
|
358
|
+
if (!content) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
session.pendingRawAssistantProgressChunks = [
|
|
362
|
+
...(session.pendingRawAssistantProgressChunks || []),
|
|
363
|
+
content,
|
|
364
|
+
];
|
|
365
|
+
}
|
|
311
366
|
emitProgress(session, currentRunId, content, messageId, toolCall) {
|
|
312
367
|
if (messageId && this.options.upsertMessage) {
|
|
313
368
|
this.options.upsertMessage(session.threadId, messageId, 'assistant', content, 'progress', toolCall, toolCall ? 'tool' : undefined);
|
|
@@ -327,6 +382,28 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
327
382
|
}
|
|
328
383
|
}
|
|
329
384
|
exports.LocalCoreAcpTurnCoordinator = LocalCoreAcpTurnCoordinator;
|
|
385
|
+
function isToolScopedAssistantUpdate(update) {
|
|
386
|
+
const meta = update._meta;
|
|
387
|
+
if (!meta || typeof meta !== 'object') {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
const claudeCode = meta.claudeCode;
|
|
391
|
+
if (!claudeCode || typeof claudeCode !== 'object') {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
const parentToolUseId = claudeCode.parentToolUseId;
|
|
395
|
+
return typeof parentToolUseId === 'string' && parentToolUseId.trim().length > 0;
|
|
396
|
+
}
|
|
397
|
+
function consumeRawAssistantProgressChunk(session, text) {
|
|
398
|
+
const pending = session.pendingRawAssistantProgressChunks || [];
|
|
399
|
+
const index = pending.findIndex((candidate) => candidate === text);
|
|
400
|
+
if (index < 0) {
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
pending.splice(index, 1);
|
|
404
|
+
session.pendingRawAssistantProgressChunks = pending;
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
330
407
|
function createToolCallPayload(input) {
|
|
331
408
|
const status = input.status.trim() || 'running';
|
|
332
409
|
return {
|
|
@@ -188,7 +188,7 @@ function takePendingLarkThoughtRender(turn) {
|
|
|
188
188
|
}
|
|
189
189
|
function getLarkRenderedMessageId(turn, rendered) {
|
|
190
190
|
if (rendered.isFinal) {
|
|
191
|
-
return
|
|
191
|
+
return undefined;
|
|
192
192
|
}
|
|
193
193
|
return turn.progressMessageIds[rendered.key];
|
|
194
194
|
}
|
package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js
CHANGED
|
@@ -1058,6 +1058,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
1058
1058
|
previewText: '',
|
|
1059
1059
|
finalText: '',
|
|
1060
1060
|
thinkingSteps: [],
|
|
1061
|
+
pendingThoughtText: undefined,
|
|
1061
1062
|
statusLines: [],
|
|
1062
1063
|
buttonRows: [],
|
|
1063
1064
|
lastSentAt: 0,
|
|
@@ -1077,6 +1078,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
1077
1078
|
turn.previewText = '';
|
|
1078
1079
|
turn.finalText = '';
|
|
1079
1080
|
turn.thinkingSteps = [];
|
|
1081
|
+
turn.pendingThoughtText = undefined;
|
|
1080
1082
|
turn.statusLines = [];
|
|
1081
1083
|
turn.buttonRows = [];
|
|
1082
1084
|
return;
|
|
@@ -1087,12 +1089,15 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
1087
1089
|
}
|
|
1088
1090
|
if (event.type === 'preview_start' || event.type === 'update_message') {
|
|
1089
1091
|
if (bridgeKind === 'thought') {
|
|
1090
|
-
|
|
1092
|
+
turn.pendingThoughtText = content;
|
|
1091
1093
|
return;
|
|
1092
1094
|
}
|
|
1093
1095
|
turn.previewText = content;
|
|
1094
1096
|
return;
|
|
1095
1097
|
}
|
|
1098
|
+
if (bridgeKind !== 'thought') {
|
|
1099
|
+
this.flushPendingThought(turn);
|
|
1100
|
+
}
|
|
1096
1101
|
if (event.type === 'status') {
|
|
1097
1102
|
if (content) {
|
|
1098
1103
|
this.pushUnique(turn.statusLines, content);
|
|
@@ -1148,6 +1153,13 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
1148
1153
|
}
|
|
1149
1154
|
return sections.join('\n\n').trim();
|
|
1150
1155
|
}
|
|
1156
|
+
flushPendingThought(turn) {
|
|
1157
|
+
const text = String(turn.pendingThoughtText || '').trim();
|
|
1158
|
+
if (!text)
|
|
1159
|
+
return;
|
|
1160
|
+
this.pushUnique(turn.thinkingSteps, text);
|
|
1161
|
+
turn.pendingThoughtText = undefined;
|
|
1162
|
+
}
|
|
1151
1163
|
isTerminalBridgeMessage(event, rendered) {
|
|
1152
1164
|
if (event.type === 'buttons')
|
|
1153
1165
|
return true;
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{z as t}from"./index-DvAYflFj.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};
|