@kafca/agentdock 0.1.24 → 0.1.25
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 +2 -0
- package/dist/renderer/assets/{Badge-CXcUMqb-.js → Badge-Bn2h-Qkf.js} +1 -1
- package/dist/renderer/assets/{Chat-BRxdPzi-.js → Chat-Cgo9aneg.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-sWGBIfIb.js → ChatMarkdown-CYzHfSiR.js} +1 -1
- package/dist/renderer/assets/{Config-DqxuxIGg.js → Config-DljB2-eP.js} +1 -1
- package/dist/renderer/assets/{CronList-OgHxbti5.js → CronList-DeVbiY9a.js} +1 -1
- package/dist/renderer/assets/{Dashboard-DmklXiH1.js → Dashboard-fSqx5sm8.js} +2 -2
- package/dist/renderer/assets/{EmptyState-BvDmi8dq.js → EmptyState-DgqKDwlq.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Bj59Hdpo.js → KnowledgeDetail-u8s2SmPV.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-CigQ-nSo.js → KnowledgeHome-BdQw8nbY.js} +1 -1
- package/dist/renderer/assets/{Logs-Bfc7gBpY.js → Logs-DSbndMpy.js} +1 -1
- package/dist/renderer/assets/{Modal-CfmiFknz.js → Modal-0d0EmAuK.js} +1 -1
- package/dist/renderer/assets/{Page-BxtLEw_b.js → Page-CVbOH_Kh.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-CcUphxGm.js → ProjectDetail-C91tF7uA.js} +1 -1
- package/dist/renderer/assets/{ProjectList-CVkvDIfy.js → ProjectList-D78Pc-BQ.js} +1 -1
- package/dist/renderer/assets/{Select-DgQMZ0MD.js → Select-BbKzAIuO.js} +1 -1
- package/dist/renderer/assets/{SessionChat-CRmGKfBx.js → SessionChat-BERvL5e4.js} +1 -1
- package/dist/renderer/assets/{SessionList-D0E8XbYw.js → SessionList-Bomz335M.js} +1 -1
- package/dist/renderer/assets/ThreadChat-CLr3amU2.js +23 -0
- package/dist/renderer/assets/{Workspace-Q4g4rlRT.js → Workspace-In91z4W2.js} +1 -1
- package/dist/renderer/assets/{arrow-left-BySN_zhF.js → arrow-left-FBnVKKBl.js} +1 -1
- package/dist/renderer/assets/{book-open-BGlrnrTc.js → book-open-4_CuP6Sa.js} +1 -1
- package/dist/renderer/assets/{check-BiJogEa5.js → check-vsoVjvac.js} +1 -1
- package/dist/renderer/assets/{chevron-down-D2fHRJv6.js → chevron-down-DFpmFTJW.js} +1 -1
- package/dist/renderer/assets/{circle-CIcjixmI.js → circle-vRULegER.js} +1 -1
- package/dist/renderer/assets/{desktop-DAXY9Bxv.js → desktop-BkMW-h5p.js} +2 -2
- package/dist/renderer/assets/{desktop-DyA_NYew.js → desktop-ul0Tpzyc.js} +1 -1
- package/dist/renderer/assets/{funnel-BUzwb-id.js → funnel-Gu0E_hJ_.js} +1 -1
- package/dist/renderer/assets/{heart-DZEQ1z_V.js → heart-DsdofOHf.js} +1 -1
- package/dist/renderer/assets/{index-CB_KyLOr.js → index-BD3aCyBa.js} +3 -3
- package/dist/renderer/assets/{index-DgsIo4vJ.js → index-pJUFobU7.js} +1 -1
- package/dist/renderer/assets/{pencil-DGL4agcl.js → pencil-DbKmV8nD.js} +1 -1
- package/dist/renderer/assets/{play-DzasCLM4.js → play-BDMsRxSm.js} +1 -1
- package/dist/renderer/assets/{plug-dubNMe_m.js → plug-t2dMl78-.js} +1 -1
- package/dist/renderer/assets/{plus-DN4kML4k.js → plus-BUb6zOAe.js} +1 -1
- package/dist/renderer/assets/projects-4F6D_Q8t.js +1 -0
- package/dist/renderer/assets/{save-CNIc9tjl.js → save-C-_5rQdv.js} +1 -1
- package/dist/renderer/assets/{search-C0EGbF3I.js → search-R3ekHFPM.js} +1 -1
- package/dist/renderer/assets/{server-BMxQ4zmc.js → server-BTuvHf5n.js} +1 -1
- package/dist/renderer/assets/{session-utils-Bf5O-iMi.js → session-utils-ClX6VPFG.js} +1 -1
- package/dist/renderer/assets/{sessions-BMSs6rEI.js → sessions-AFKIC-ub.js} +1 -1
- package/dist/renderer/assets/{shield-check-i3Tf1TUz.js → shield-check-CqMW8CHe.js} +1 -1
- package/dist/renderer/assets/{trash-2-SKrcp18f.js → trash-2-BNLcHyUw.js} +1 -1
- package/dist/renderer/assets/{user-cNUZddjZ.js → user-BCCN8FYK.js} +1 -1
- package/dist/renderer/assets/{wifi-off-Dyb84ANR.js → wifi-off-BsNsx3oX.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/electron/agent-runtime-detector.test.js +64 -0
- package/dist-electron/electron/architecture-docs.test.js +56 -0
- package/dist-electron/electron/channel-content.test.js +8 -0
- package/dist-electron/electron/lac-cli.test.js +248 -0
- package/dist-electron/electron/local-core-refactor.test.js +666 -3
- package/dist-electron/electron/plugin-kernel.test.js +108 -0
- package/dist-electron/electron/renderer-packaging.test.js +77 -0
- package/dist-electron/electron/workspace-task-store.test.js +57 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +67 -6
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-permission-lifecycle.js +76 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +201 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +29 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +30 -18
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +112 -210
- package/dist-electron/services/local-ai-core/src/acp/local-core-slash-commands.js +60 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +15 -3
- package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +11 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/file-utils.js +13 -1
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +8 -1
- package/dist-electron/services/local-ai-core/src/cli/lac.js +3 -1
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +1 -0
- package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +9 -0
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +221 -10
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +39 -9
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +439 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +208 -303
- package/dist-electron/shared/desktop.js +7 -3
- package/dist-electron/src/pages/Threads/thread-chat-message-blocks.js +187 -0
- package/dist-electron/src/pages/Threads/thread-chat-model.js +1 -0
- package/dist-electron/src/pages/Threads/thread-chat-page-state.js +96 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.js +18 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +277 -0
- package/package.json +4 -2
- package/dist/renderer/assets/ThreadChat-DUgqZSBB.js +0 -23
- package/dist/renderer/assets/projects-migPtfRe.js +0 -1
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LocalCoreAcpTurnCoordinator = void 0;
|
|
4
4
|
const desktop_js_1 = require("../../../../shared/desktop.js");
|
|
5
|
+
const local_core_acp_progress_js_1 = require("./local-core-acp-progress.js");
|
|
6
|
+
const local_core_acp_permission_lifecycle_js_1 = require("./local-core-acp-permission-lifecycle.js");
|
|
5
7
|
const workspace_acp_permissions_js_1 = require("./workspace-acp-permissions.js");
|
|
8
|
+
const local_core_slash_commands_js_1 = require("./local-core-slash-commands.js");
|
|
6
9
|
class LocalCoreAcpTurnCoordinator {
|
|
7
10
|
options;
|
|
8
11
|
constructor(options) {
|
|
@@ -14,7 +17,7 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
14
17
|
if (!currentTurn || !currentRunId) {
|
|
15
18
|
return;
|
|
16
19
|
}
|
|
17
|
-
const pending =
|
|
20
|
+
const pending = (0, local_core_acp_progress_js_1.getToolCallsInOrder)(currentTurn)
|
|
18
21
|
.filter((toolCall) => !toolCall.emitted);
|
|
19
22
|
if (pending.length === 0) {
|
|
20
23
|
const title = currentTurn.pendingToolCallTitle?.trim();
|
|
@@ -25,14 +28,26 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
25
28
|
currentTurn.pendingToolCallTitle = undefined;
|
|
26
29
|
currentTurn.pendingToolCallId = undefined;
|
|
27
30
|
currentTurn.pendingToolCallDetail = undefined;
|
|
28
|
-
this.emitProgress(session, currentRunId, `🔧 ${title}`, messageId
|
|
31
|
+
this.emitProgress(session, currentRunId, `🔧 ${title}`, messageId, createToolCallPayload({
|
|
32
|
+
id: currentTurn.activeToolCallKey,
|
|
33
|
+
name: title,
|
|
34
|
+
status: 'running',
|
|
35
|
+
content: '',
|
|
36
|
+
}));
|
|
29
37
|
return;
|
|
30
38
|
}
|
|
31
39
|
for (const toolCall of pending) {
|
|
32
40
|
toolCall.emitted = true;
|
|
33
|
-
this.emitProgress(session, currentRunId, `🔧 ${toolCall.title}`, toolCall.messageId
|
|
41
|
+
this.emitProgress(session, currentRunId, `🔧 ${toolCall.title}`, toolCall.messageId, createToolCallPayload({
|
|
42
|
+
id: toolCall.key,
|
|
43
|
+
name: toolCall.title,
|
|
44
|
+
status: 'running',
|
|
45
|
+
input: toolCall.input,
|
|
46
|
+
detail: toolCall.detail,
|
|
47
|
+
content: '',
|
|
48
|
+
}));
|
|
34
49
|
}
|
|
35
|
-
|
|
50
|
+
(0, local_core_acp_progress_js_1.syncLegacyPendingToolCall)(currentTurn, (0, local_core_acp_progress_js_1.resolveFallbackToolCall)(currentTurn));
|
|
36
51
|
}
|
|
37
52
|
getPendingPermissionRequest(session, detail) {
|
|
38
53
|
const runId = session?.currentRunId;
|
|
@@ -80,22 +95,29 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
80
95
|
});
|
|
81
96
|
return;
|
|
82
97
|
}
|
|
83
|
-
const options =
|
|
84
|
-
? payload.params.options
|
|
85
|
-
.map((option) => ({
|
|
86
|
-
optionId: String(option?.optionId || '').trim(),
|
|
87
|
-
name: String(option?.name || option?.optionId || '').trim(),
|
|
88
|
-
kind: String(option?.kind || '').trim(),
|
|
89
|
-
normalizedAction: (0, workspace_acp_permissions_js_1.normalizePermissionOptionAction)({
|
|
90
|
-
optionId: option?.optionId,
|
|
91
|
-
name: option?.name,
|
|
92
|
-
kind: option?.kind,
|
|
93
|
-
}),
|
|
94
|
-
}))
|
|
95
|
-
.filter((option) => option.optionId)
|
|
96
|
-
: [];
|
|
98
|
+
const options = (0, local_core_acp_permission_lifecycle_js_1.parsePermissionOptions)(payload.params?.options);
|
|
97
99
|
const toolTitle = (0, workspace_acp_permissions_js_1.formatToolCallContent)(payload.params?.toolCall);
|
|
98
|
-
|
|
100
|
+
if ((this.options.getThreadAgentMode?.(session.threadId) || local_core_slash_commands_js_1.DEFAULT_AGENT_MODE) === 'bypassPermissions') {
|
|
101
|
+
const selected = options.find((option) => option.normalizedAction === 'allow all')
|
|
102
|
+
|| options.find((option) => option.normalizedAction === 'allow')
|
|
103
|
+
|| options.find((option) => option.normalizedAction !== 'deny');
|
|
104
|
+
this.options.sendRaw(session, {
|
|
105
|
+
jsonrpc: '2.0',
|
|
106
|
+
id: payload.id,
|
|
107
|
+
result: {
|
|
108
|
+
outcome: selected
|
|
109
|
+
? {
|
|
110
|
+
outcome: 'selected',
|
|
111
|
+
optionId: selected.optionId,
|
|
112
|
+
}
|
|
113
|
+
: {
|
|
114
|
+
outcome: 'cancelled',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const isSchedulerAdd = (0, local_core_acp_permission_lifecycle_js_1.isSchedulerAddCommand)(toolTitle);
|
|
99
121
|
if (isSchedulerAdd && session.schedulerJobCreatedByRun.get(currentRunId)) {
|
|
100
122
|
this.options.sendRaw(session, {
|
|
101
123
|
jsonrpc: '2.0',
|
|
@@ -117,45 +139,27 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
117
139
|
return;
|
|
118
140
|
}
|
|
119
141
|
const buttonRows = (0, workspace_acp_permissions_js_1.toPermissionButtonRows)(options, desktop_js_1.normalizeDesktopBridgeButtonOption);
|
|
120
|
-
const
|
|
142
|
+
const approvalId = this.options.createApprovalRequest?.((0, local_core_acp_permission_lifecycle_js_1.createPermissionApprovalInput)({
|
|
143
|
+
threadId: session.threadId,
|
|
144
|
+
runId: currentRunId,
|
|
145
|
+
toolTitle,
|
|
146
|
+
options,
|
|
147
|
+
}));
|
|
148
|
+
const permissionRequest = (0, local_core_acp_permission_lifecycle_js_1.createRunningPermissionRequest)({
|
|
121
149
|
requestId: payload.id,
|
|
122
150
|
toolTitle,
|
|
123
|
-
isSchedulerAdd,
|
|
124
151
|
options,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
152
|
+
approvalId,
|
|
153
|
+
});
|
|
154
|
+
(0, local_core_acp_permission_lifecycle_js_1.applyPendingPermissionRequest)({
|
|
155
|
+
session,
|
|
128
156
|
runId: currentRunId,
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
options,
|
|
157
|
+
permissionRequest,
|
|
158
|
+
resolveFallbackToolCall: local_core_acp_progress_js_1.resolveFallbackToolCall,
|
|
159
|
+
syncLegacyPendingToolCall: local_core_acp_progress_js_1.syncLegacyPendingToolCall,
|
|
133
160
|
});
|
|
134
|
-
if (approvalId) {
|
|
135
|
-
permissionRequest.approvalId = approvalId;
|
|
136
|
-
}
|
|
137
|
-
session.pendingPermissionByRun.set(currentRunId, permissionRequest);
|
|
138
|
-
if (session.currentTurn) {
|
|
139
|
-
session.currentTurn.permission = permissionRequest;
|
|
140
|
-
if (toolTitle && toolTitle !== 'Permission required before continuing.') {
|
|
141
|
-
session.currentTurn.pendingToolCallDetail = toolTitle;
|
|
142
|
-
const toolCall = this.resolveFallbackToolCall(session.currentTurn);
|
|
143
|
-
if (toolCall) {
|
|
144
|
-
toolCall.detail = toolTitle;
|
|
145
|
-
this.syncLegacyPendingToolCall(session.currentTurn, toolCall);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
161
|
this.options.updateRunStatus(currentRunId, session.threadId, 'awaiting_input');
|
|
150
|
-
const permissionPrompt =
|
|
151
|
-
'等待工具确认',
|
|
152
|
-
'',
|
|
153
|
-
toolTitle,
|
|
154
|
-
'',
|
|
155
|
-
'请选择一个选项继续执行。',
|
|
156
|
-
'',
|
|
157
|
-
'若按钮没有显示,请直接回复:allow all / allow / deny',
|
|
158
|
-
].join('\n');
|
|
162
|
+
const permissionPrompt = (0, local_core_acp_permission_lifecycle_js_1.createPermissionPrompt)(toolTitle);
|
|
159
163
|
this.options.appendMessage(session.threadId, 'assistant', permissionPrompt, 'progress');
|
|
160
164
|
this.options.emitBridge({
|
|
161
165
|
type: 'buttons',
|
|
@@ -181,24 +185,16 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
181
185
|
if (update.content?.type !== 'text') {
|
|
182
186
|
return;
|
|
183
187
|
}
|
|
184
|
-
currentTurn
|
|
185
|
-
if (!
|
|
186
|
-
currentTurn.previewStarted = true;
|
|
187
|
-
this.options.emitBridge({
|
|
188
|
-
type: 'preview_start',
|
|
189
|
-
sessionKey: session.bridgeSessionKey,
|
|
190
|
-
replyCtx: currentRunId,
|
|
191
|
-
previewHandle: currentTurn.previewHandle,
|
|
192
|
-
content: currentTurn.assistantText,
|
|
193
|
-
});
|
|
188
|
+
const projection = (0, local_core_acp_progress_js_1.applyAssistantMessageChunk)(currentTurn, String(update.content.text || ''));
|
|
189
|
+
if (!projection) {
|
|
194
190
|
return;
|
|
195
191
|
}
|
|
196
192
|
this.options.emitBridge({
|
|
197
|
-
type:
|
|
193
|
+
type: projection.bridgeType,
|
|
198
194
|
sessionKey: session.bridgeSessionKey,
|
|
199
195
|
replyCtx: currentRunId,
|
|
200
|
-
previewHandle:
|
|
201
|
-
content:
|
|
196
|
+
previewHandle: projection.previewHandle,
|
|
197
|
+
content: projection.content,
|
|
202
198
|
});
|
|
203
199
|
return;
|
|
204
200
|
}
|
|
@@ -207,92 +203,64 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
207
203
|
if (update.content?.type !== 'text') {
|
|
208
204
|
return;
|
|
209
205
|
}
|
|
210
|
-
const
|
|
211
|
-
if (!
|
|
206
|
+
const projection = (0, local_core_acp_progress_js_1.applyThoughtChunk)(currentTurn, String(update.content.text || ''));
|
|
207
|
+
if (!projection) {
|
|
212
208
|
return;
|
|
213
209
|
}
|
|
214
|
-
currentTurn.thoughtText += thoughtChunk;
|
|
215
|
-
const content = `💭 ${currentTurn.thoughtText.trim()}`;
|
|
216
210
|
if (this.options.upsertMessage) {
|
|
217
|
-
this.options.upsertMessage(session.threadId,
|
|
218
|
-
}
|
|
219
|
-
if (!currentTurn.thoughtPreviewStarted) {
|
|
220
|
-
currentTurn.thoughtPreviewStarted = true;
|
|
221
|
-
this.options.emitBridge({
|
|
222
|
-
type: 'preview_start',
|
|
223
|
-
sessionKey: session.bridgeSessionKey,
|
|
224
|
-
replyCtx: currentRunId,
|
|
225
|
-
previewHandle: currentTurn.thoughtPreviewHandle,
|
|
226
|
-
content,
|
|
227
|
-
});
|
|
228
|
-
return;
|
|
211
|
+
this.options.upsertMessage(session.threadId, projection.messageId, 'assistant', projection.content, 'progress');
|
|
229
212
|
}
|
|
230
213
|
this.options.emitBridge({
|
|
231
|
-
type:
|
|
214
|
+
type: projection.bridgeType,
|
|
232
215
|
sessionKey: session.bridgeSessionKey,
|
|
233
216
|
replyCtx: currentRunId,
|
|
234
|
-
previewHandle:
|
|
235
|
-
content,
|
|
217
|
+
previewHandle: projection.previewHandle,
|
|
218
|
+
content: projection.content,
|
|
236
219
|
});
|
|
237
220
|
return;
|
|
238
221
|
}
|
|
239
222
|
case 'tool_call': {
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
currentTurn.toolCallSequence = nextSequence;
|
|
243
|
-
const key = this.extractToolCallKey(update) || `sequence:${nextSequence}`;
|
|
244
|
-
const toolCall = {
|
|
245
|
-
key,
|
|
246
|
-
title,
|
|
247
|
-
messageId: `${currentRunId}-tool-${nextSequence}`,
|
|
248
|
-
sequence: nextSequence,
|
|
249
|
-
emitted: false,
|
|
250
|
-
};
|
|
251
|
-
currentTurn.pendingToolCalls = {
|
|
252
|
-
...(currentTurn.pendingToolCalls || {}),
|
|
253
|
-
[key]: toolCall,
|
|
254
|
-
};
|
|
255
|
-
currentTurn.pendingToolCallOrder = [
|
|
256
|
-
...(currentTurn.pendingToolCallOrder || []).filter((item) => item !== key),
|
|
257
|
-
key,
|
|
258
|
-
];
|
|
259
|
-
currentTurn.activeToolCallKey = key;
|
|
260
|
-
this.syncLegacyPendingToolCall(currentTurn, toolCall);
|
|
223
|
+
const toolCall = (0, local_core_acp_progress_js_1.registerPendingToolCall)({ currentTurn, runId: currentRunId, update });
|
|
224
|
+
(0, local_core_acp_progress_js_1.syncLegacyPendingToolCall)(currentTurn, toolCall);
|
|
261
225
|
return;
|
|
262
226
|
}
|
|
263
227
|
case 'tool_call_update': {
|
|
264
228
|
const title = String(update.title || 'Tool update').trim();
|
|
265
229
|
const status = String(update.status || '').trim();
|
|
266
|
-
const content =
|
|
267
|
-
if (isSchedulerAddCommand(title) && /Created scheduler job\b/.test(content)) {
|
|
230
|
+
const content = (0, local_core_acp_progress_js_1.extractToolUpdateContent)(update.content);
|
|
231
|
+
if ((0, local_core_acp_permission_lifecycle_js_1.isSchedulerAddCommand)(title) && /Created scheduler job\b/.test(content)) {
|
|
268
232
|
session.schedulerJobCreatedByRun.set(currentRunId, true);
|
|
269
233
|
}
|
|
270
|
-
const toolCall =
|
|
234
|
+
const toolCall = (0, local_core_acp_progress_js_1.resolveToolCallForUpdate)(currentTurn, update);
|
|
235
|
+
const updateInput = (0, local_core_acp_progress_js_1.extractToolCallInput)(update);
|
|
236
|
+
if (toolCall && updateInput !== undefined) {
|
|
237
|
+
toolCall.input = updateInput;
|
|
238
|
+
}
|
|
271
239
|
const toolName = toolCall?.title.trim() || currentTurn.pendingToolCallTitle?.trim();
|
|
272
240
|
const messageId = toolCall?.messageId || currentTurn.pendingToolCallId;
|
|
273
241
|
const priorDetail = toolCall ? toolCall.detail?.trim() : currentTurn.pendingToolCallDetail?.trim();
|
|
274
|
-
if (
|
|
242
|
+
if ((0, local_core_acp_progress_js_1.isEmptyRunningToolUpdate)({ title, status, content })) {
|
|
275
243
|
if (toolCall) {
|
|
276
|
-
|
|
244
|
+
(0, local_core_acp_progress_js_1.deletePendingToolCall)(currentTurn, toolCall.key);
|
|
277
245
|
}
|
|
278
246
|
else {
|
|
279
247
|
currentTurn.pendingToolCallTitle = undefined;
|
|
280
248
|
currentTurn.pendingToolCallId = undefined;
|
|
281
249
|
currentTurn.pendingToolCallDetail = undefined;
|
|
282
250
|
}
|
|
283
|
-
|
|
251
|
+
(0, local_core_acp_progress_js_1.syncLegacyPendingToolCall)(currentTurn, (0, local_core_acp_progress_js_1.resolveFallbackToolCall)(currentTurn));
|
|
284
252
|
return;
|
|
285
253
|
}
|
|
286
|
-
const displayTitle =
|
|
287
|
-
if (!
|
|
254
|
+
const displayTitle = (0, local_core_acp_progress_js_1.resolveToolUpdateDisplayTitle)({ title, status, priorDetail });
|
|
255
|
+
if (!(0, local_core_acp_progress_js_1.isTerminalToolStatus)(status) && displayTitle && !/^tool update$/i.test(displayTitle)) {
|
|
288
256
|
if (toolCall) {
|
|
289
257
|
toolCall.detail = displayTitle;
|
|
290
258
|
}
|
|
291
259
|
currentTurn.pendingToolCallDetail = displayTitle;
|
|
292
260
|
}
|
|
293
|
-
if (
|
|
261
|
+
if ((0, local_core_acp_progress_js_1.isTerminalToolStatus)(status)) {
|
|
294
262
|
if (toolCall) {
|
|
295
|
-
|
|
263
|
+
(0, local_core_acp_progress_js_1.deletePendingToolCall)(currentTurn, toolCall.key);
|
|
296
264
|
}
|
|
297
265
|
else {
|
|
298
266
|
currentTurn.pendingToolCallTitle = undefined;
|
|
@@ -300,8 +268,16 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
300
268
|
currentTurn.pendingToolCallDetail = undefined;
|
|
301
269
|
}
|
|
302
270
|
}
|
|
303
|
-
|
|
304
|
-
|
|
271
|
+
const toolCallPayload = createToolCallPayload({
|
|
272
|
+
id: toolCall?.key || currentTurn.activeToolCallKey,
|
|
273
|
+
name: toolName || displayTitle || 'Tool update',
|
|
274
|
+
status,
|
|
275
|
+
input: updateInput === undefined ? toolCall?.input : updateInput,
|
|
276
|
+
detail: displayTitle,
|
|
277
|
+
content,
|
|
278
|
+
});
|
|
279
|
+
this.emitProgress(session, currentRunId, (0, local_core_acp_progress_js_1.formatToolProgressMessage)({ toolName, title: displayTitle, status, content }), messageId, toolCallPayload);
|
|
280
|
+
(0, local_core_acp_progress_js_1.syncLegacyPendingToolCall)(currentTurn, (0, local_core_acp_progress_js_1.resolveFallbackToolCall)(currentTurn));
|
|
305
281
|
return;
|
|
306
282
|
}
|
|
307
283
|
case 'plan': {
|
|
@@ -310,11 +286,10 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
310
286
|
if (entries.length === 0) {
|
|
311
287
|
return;
|
|
312
288
|
}
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
const content = `💭 ${summary}`;
|
|
289
|
+
const content = (0, local_core_acp_progress_js_1.formatPlanProgress)(entries);
|
|
290
|
+
if (!content) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
318
293
|
this.options.appendMessage(session.threadId, 'assistant', content, 'progress');
|
|
319
294
|
this.options.emitBridge({
|
|
320
295
|
type: 'reply',
|
|
@@ -328,12 +303,12 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
328
303
|
return;
|
|
329
304
|
}
|
|
330
305
|
}
|
|
331
|
-
emitProgress(session, currentRunId, content, messageId) {
|
|
306
|
+
emitProgress(session, currentRunId, content, messageId, toolCall) {
|
|
332
307
|
if (messageId && this.options.upsertMessage) {
|
|
333
|
-
this.options.upsertMessage(session.threadId, messageId, 'assistant', content, 'progress');
|
|
308
|
+
this.options.upsertMessage(session.threadId, messageId, 'assistant', content, 'progress', toolCall);
|
|
334
309
|
}
|
|
335
310
|
else {
|
|
336
|
-
this.options.appendMessage(session.threadId, 'assistant', content, 'progress');
|
|
311
|
+
this.options.appendMessage(session.threadId, 'assistant', content, 'progress', toolCall);
|
|
337
312
|
}
|
|
338
313
|
this.options.emitBridge({
|
|
339
314
|
type: 'reply',
|
|
@@ -341,93 +316,20 @@ class LocalCoreAcpTurnCoordinator {
|
|
|
341
316
|
replyCtx: currentRunId,
|
|
342
317
|
messageId,
|
|
343
318
|
content,
|
|
319
|
+
toolCall,
|
|
344
320
|
});
|
|
345
321
|
}
|
|
346
|
-
extractToolUpdateContent(content) {
|
|
347
|
-
return Array.isArray(content)
|
|
348
|
-
? content
|
|
349
|
-
.map((entry) => entry?.type === 'content' && entry?.content?.type === 'text'
|
|
350
|
-
? String(entry.content.text || '')
|
|
351
|
-
: '')
|
|
352
|
-
.filter(Boolean)
|
|
353
|
-
.join('\n')
|
|
354
|
-
: '';
|
|
355
|
-
}
|
|
356
|
-
formatToolProgressMessage(toolName, title, status, content) {
|
|
357
|
-
const detail = [title, status, content].filter(Boolean).join(' - ');
|
|
358
|
-
return toolName ? `🔧 ${toolName}: ${detail || 'Tool update'}` : `🔧 ${detail || 'Tool update'}`;
|
|
359
|
-
}
|
|
360
|
-
resolveToolUpdateDisplayTitle(title, status, priorDetail) {
|
|
361
|
-
if (priorDetail && (this.isTerminalToolStatus(status) || /^tool update$/i.test(title.trim()))) {
|
|
362
|
-
return priorDetail;
|
|
363
|
-
}
|
|
364
|
-
if (this.isTerminalToolStatus(status) && /^tool update$/i.test(title.trim())) {
|
|
365
|
-
return '';
|
|
366
|
-
}
|
|
367
|
-
return title;
|
|
368
|
-
}
|
|
369
|
-
isEmptyRunningToolUpdate(title, status, content) {
|
|
370
|
-
return !content.trim() &&
|
|
371
|
-
/^running$/i.test(status) &&
|
|
372
|
-
(!title.trim() || /^tool update$/i.test(title));
|
|
373
|
-
}
|
|
374
|
-
isTerminalToolStatus(status) {
|
|
375
|
-
return /^(completed|failed|error|cancelled|canceled)$/i.test(status.trim());
|
|
376
|
-
}
|
|
377
|
-
extractToolCallKey(update) {
|
|
378
|
-
for (const key of ['toolCallId', 'tool_call_id', 'callId', 'call_id', 'invocationId', 'invocation_id', 'id']) {
|
|
379
|
-
const value = update[key];
|
|
380
|
-
if (typeof value === 'string' || typeof value === 'number') {
|
|
381
|
-
const normalized = String(value).trim();
|
|
382
|
-
if (normalized) {
|
|
383
|
-
return normalized;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
return '';
|
|
388
|
-
}
|
|
389
|
-
resolveToolCallForUpdate(currentTurn, update) {
|
|
390
|
-
const explicitKey = this.extractToolCallKey(update);
|
|
391
|
-
if (explicitKey && currentTurn.pendingToolCalls?.[explicitKey]) {
|
|
392
|
-
currentTurn.activeToolCallKey = explicitKey;
|
|
393
|
-
return currentTurn.pendingToolCalls[explicitKey];
|
|
394
|
-
}
|
|
395
|
-
return this.resolveFallbackToolCall(currentTurn);
|
|
396
|
-
}
|
|
397
|
-
resolveFallbackToolCall(currentTurn) {
|
|
398
|
-
const active = currentTurn.activeToolCallKey
|
|
399
|
-
? currentTurn.pendingToolCalls?.[currentTurn.activeToolCallKey]
|
|
400
|
-
: undefined;
|
|
401
|
-
if (active) {
|
|
402
|
-
return active;
|
|
403
|
-
}
|
|
404
|
-
const ordered = this.getToolCallsInOrder(currentTurn);
|
|
405
|
-
return ordered[ordered.length - 1];
|
|
406
|
-
}
|
|
407
|
-
getToolCallsInOrder(currentTurn) {
|
|
408
|
-
const toolCalls = currentTurn.pendingToolCalls || {};
|
|
409
|
-
const orderedKeys = currentTurn.pendingToolCallOrder || [];
|
|
410
|
-
return orderedKeys
|
|
411
|
-
.map((key) => toolCalls[key])
|
|
412
|
-
.filter((toolCall) => Boolean(toolCall));
|
|
413
|
-
}
|
|
414
|
-
deleteToolCall(currentTurn, key) {
|
|
415
|
-
if (currentTurn.pendingToolCalls) {
|
|
416
|
-
delete currentTurn.pendingToolCalls[key];
|
|
417
|
-
}
|
|
418
|
-
currentTurn.pendingToolCallOrder = (currentTurn.pendingToolCallOrder || []).filter((item) => item !== key);
|
|
419
|
-
if (currentTurn.activeToolCallKey === key) {
|
|
420
|
-
currentTurn.activeToolCallKey = undefined;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
syncLegacyPendingToolCall(currentTurn, toolCall) {
|
|
424
|
-
currentTurn.pendingToolCallTitle = toolCall?.title;
|
|
425
|
-
currentTurn.pendingToolCallId = toolCall?.messageId;
|
|
426
|
-
currentTurn.pendingToolCallDetail = toolCall?.detail;
|
|
427
|
-
currentTurn.activeToolCallKey = toolCall?.key;
|
|
428
|
-
}
|
|
429
322
|
}
|
|
430
323
|
exports.LocalCoreAcpTurnCoordinator = LocalCoreAcpTurnCoordinator;
|
|
431
|
-
function
|
|
432
|
-
|
|
324
|
+
function createToolCallPayload(input) {
|
|
325
|
+
const status = input.status.trim() || 'running';
|
|
326
|
+
return {
|
|
327
|
+
id: input.id,
|
|
328
|
+
name: input.name.trim() || 'Tool call',
|
|
329
|
+
status,
|
|
330
|
+
input: input.input,
|
|
331
|
+
output: input.content,
|
|
332
|
+
detail: input.detail?.trim() || undefined,
|
|
333
|
+
label: /^running$/i.test(status) ? '工具调用' : '工具结果',
|
|
334
|
+
};
|
|
433
335
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_AGENT_MODE = void 0;
|
|
4
|
+
exports.parseSlashCommand = parseSlashCommand;
|
|
5
|
+
exports.normalizeAgentMode = normalizeAgentMode;
|
|
6
|
+
exports.formatAgentMode = formatAgentMode;
|
|
7
|
+
exports.modeHelpText = modeHelpText;
|
|
8
|
+
exports.DEFAULT_AGENT_MODE = 'default';
|
|
9
|
+
const MODE_ALIASES = {
|
|
10
|
+
auto: 'auto',
|
|
11
|
+
default: 'default',
|
|
12
|
+
acceptedits: 'acceptEdits',
|
|
13
|
+
'accept-edits': 'acceptEdits',
|
|
14
|
+
accept_edits: 'acceptEdits',
|
|
15
|
+
dontask: 'dontAsk',
|
|
16
|
+
"don'task": 'dontAsk',
|
|
17
|
+
'dont-ask': 'dontAsk',
|
|
18
|
+
dont_ask: 'dontAsk',
|
|
19
|
+
plan: 'plan',
|
|
20
|
+
bypass: 'bypassPermissions',
|
|
21
|
+
bypasspermissions: 'bypassPermissions',
|
|
22
|
+
'bypass-permissions': 'bypassPermissions',
|
|
23
|
+
bypass_permissions: 'bypassPermissions',
|
|
24
|
+
yolo: 'bypassPermissions',
|
|
25
|
+
};
|
|
26
|
+
const MODE_LABELS = {
|
|
27
|
+
auto: 'auto',
|
|
28
|
+
default: 'default',
|
|
29
|
+
acceptEdits: 'acceptEdits',
|
|
30
|
+
dontAsk: 'dontAsk',
|
|
31
|
+
plan: 'plan',
|
|
32
|
+
bypassPermissions: 'yolo',
|
|
33
|
+
};
|
|
34
|
+
function parseSlashCommand(text) {
|
|
35
|
+
const normalized = String(text || '').trim();
|
|
36
|
+
if (!normalized.startsWith('/')) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const [name = '', ...args] = normalized.slice(1).split(/\s+/);
|
|
40
|
+
const commandName = name.trim().toLowerCase();
|
|
41
|
+
if (!commandName) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return { name: commandName, args };
|
|
45
|
+
}
|
|
46
|
+
function normalizeAgentMode(mode) {
|
|
47
|
+
const key = String(mode || '').trim().toLowerCase();
|
|
48
|
+
return MODE_ALIASES[key] || '';
|
|
49
|
+
}
|
|
50
|
+
function formatAgentMode(mode) {
|
|
51
|
+
const normalized = normalizeAgentMode(mode) || mode || exports.DEFAULT_AGENT_MODE;
|
|
52
|
+
return MODE_LABELS[normalized] || normalized;
|
|
53
|
+
}
|
|
54
|
+
function modeHelpText(currentMode) {
|
|
55
|
+
return [
|
|
56
|
+
`当前模式:${formatAgentMode(currentMode)}`,
|
|
57
|
+
'可用模式:default, auto, acceptEdits, dontAsk, plan, yolo。',
|
|
58
|
+
'`/mode yolo` 会跳过工具权限申请;使用 `/mode default` 可恢复默认权限。'
|
|
59
|
+
].join('\n');
|
|
60
|
+
}
|
|
@@ -47,6 +47,8 @@ const registration_js_1 = require("./registration.js");
|
|
|
47
47
|
const runtime_state_js_1 = require("./runtime-state.js");
|
|
48
48
|
const PAIRING_EXPIRY_MS = 10 * 60 * 1000;
|
|
49
49
|
const LARK_MAX_UPLOAD_FILE_SIZE = 30 * 1024 * 1024;
|
|
50
|
+
const LARK_FINAL_PATCH_INTERVAL_MS = 900;
|
|
51
|
+
const LARK_PROGRESS_PATCH_INTERVAL_MS = 3000;
|
|
50
52
|
class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
51
53
|
options;
|
|
52
54
|
// Lark returns 200340 when card action events are not enabled in the app's
|
|
@@ -246,6 +248,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
246
248
|
const file = await (0, file_utils_js_1.prepareChannelFile)({
|
|
247
249
|
path: part.path,
|
|
248
250
|
fileName: part.fileName,
|
|
251
|
+
workspacePath: typeof part.metadata?.workspacePath === 'string' ? part.metadata.workspacePath : undefined,
|
|
249
252
|
maxBytes: LARK_MAX_UPLOAD_FILE_SIZE,
|
|
250
253
|
platformLabel: 'Lark',
|
|
251
254
|
});
|
|
@@ -475,9 +478,8 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
475
478
|
}
|
|
476
479
|
const existingMessageId = (0, runtime_state_js_1.getLarkRenderedMessageId)(turn, rendered);
|
|
477
480
|
const shouldThrottle = event.type === 'update_message' &&
|
|
478
|
-
rendered.isFinal &&
|
|
479
481
|
existingMessageId &&
|
|
480
|
-
Date.now() - (turn.lastPatchedAtByMessageId[existingMessageId] || 0) <
|
|
482
|
+
Date.now() - (turn.lastPatchedAtByMessageId[existingMessageId] || 0) < (rendered.isFinal ? LARK_FINAL_PATCH_INTERVAL_MS : LARK_PROGRESS_PATCH_INTERVAL_MS);
|
|
481
483
|
this.options.log?.(`localcore-lark bridge event type=${event.type} sessionKey=${sessionKey} hasMessageId=${Boolean(existingMessageId)} throttle=${shouldThrottle}`);
|
|
482
484
|
if (shouldThrottle) {
|
|
483
485
|
return;
|
|
@@ -620,6 +622,10 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
620
622
|
if (slashCommand?.name === 'new') {
|
|
621
623
|
const title = slashCommand.args.join(' ').trim() || `${input.displayName || 'Lark'} ${new Date().toLocaleTimeString()}`;
|
|
622
624
|
const nextThread = await router.createThread(input.workspaceId, title);
|
|
625
|
+
const inheritedMode = this.options.store.getThreadRow?.(threadId)?.agent_mode || '';
|
|
626
|
+
if (inheritedMode && inheritedMode !== 'default') {
|
|
627
|
+
this.options.store.updateThreadAgentMode?.(nextThread.id, inheritedMode);
|
|
628
|
+
}
|
|
623
629
|
const now = new Date().toISOString();
|
|
624
630
|
this.options.store.updateAuthorizedUserThread(input.workspaceId, input.platformUserId, nextThread.id, platformKey);
|
|
625
631
|
this.options.store.upsertPlatformThreadBinding({
|
|
@@ -650,7 +656,9 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
650
656
|
return { paired: true, threadId };
|
|
651
657
|
}
|
|
652
658
|
this.options.store.clearPlatformThreadMessageId(input.workspaceId, input.chatId, input.platformUserId);
|
|
653
|
-
const wrappedText =
|
|
659
|
+
const wrappedText = slashCommand
|
|
660
|
+
? input.text
|
|
661
|
+
: (0, desktop_js_1.wrapUserMessageWithSchedulerProtocol)(input.text);
|
|
654
662
|
await router.sendThreadMessage(threadId, (0, content_js_1.createChannelThreadMessageInput)(wrappedText, input.contentParts));
|
|
655
663
|
return { paired: true, threadId };
|
|
656
664
|
}
|
|
@@ -1095,6 +1103,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1095
1103
|
return this.larkModulePromise;
|
|
1096
1104
|
}
|
|
1097
1105
|
async sendTextAsCard(state, chatId, text, buttonRows = [], sessionKey, threadId) {
|
|
1106
|
+
const startedAt = Date.now();
|
|
1098
1107
|
const response = await state.client.im.message.create({
|
|
1099
1108
|
params: {
|
|
1100
1109
|
receive_id_type: this.resolveReceiveIdType(chatId),
|
|
@@ -1105,6 +1114,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1105
1114
|
content: JSON.stringify((0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)),
|
|
1106
1115
|
},
|
|
1107
1116
|
});
|
|
1117
|
+
this.options.log?.(`localcore-lark card create took ${Date.now() - startedAt}ms textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1108
1118
|
return String(response?.data?.message_id || '').trim();
|
|
1109
1119
|
}
|
|
1110
1120
|
resolveReceiveIdType(receiveId) {
|
|
@@ -1135,6 +1145,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1135
1145
|
}
|
|
1136
1146
|
}
|
|
1137
1147
|
async patchTextCard(state, messageId, text, buttonRows = [], sessionKey, threadId) {
|
|
1148
|
+
const startedAt = Date.now();
|
|
1138
1149
|
await state.client.im.message.patch({
|
|
1139
1150
|
path: {
|
|
1140
1151
|
message_id: messageId,
|
|
@@ -1143,6 +1154,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1143
1154
|
content: JSON.stringify((0, cards_js_1.buildInteractiveCard)(text, buttonRows, sessionKey, threadId)),
|
|
1144
1155
|
},
|
|
1145
1156
|
});
|
|
1157
|
+
this.options.log?.(`localcore-lark card patch took ${Date.now() - startedAt}ms message=${messageId} textBytes=${Buffer.byteLength(text || '', 'utf8')}`);
|
|
1146
1158
|
}
|
|
1147
1159
|
generatePairingCode() {
|
|
1148
1160
|
return String((0, node_crypto_1.randomInt)(100000, 1000000));
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createLarkTurnState = createLarkTurnState;
|
|
4
4
|
exports.foldToolResultForLark = foldToolResultForLark;
|
|
5
|
+
exports.isPendingToolProgressForLark = isPendingToolProgressForLark;
|
|
5
6
|
exports.consumeLarkBridgeEvent = consumeLarkBridgeEvent;
|
|
6
7
|
exports.renderLarkBridgeEventMessage = renderLarkBridgeEventMessage;
|
|
7
8
|
exports.getLarkRenderedMessageId = getLarkRenderedMessageId;
|
|
@@ -33,6 +34,10 @@ function foldToolResultForLark(content) {
|
|
|
33
34
|
return normalized;
|
|
34
35
|
return parts.slice(0, 2).join(' - ');
|
|
35
36
|
}
|
|
37
|
+
function isPendingToolProgressForLark(content) {
|
|
38
|
+
const normalized = foldToolResultForLark(content).toLowerCase();
|
|
39
|
+
return normalized.startsWith('🔧 ') && normalized.includes(' - pending');
|
|
40
|
+
}
|
|
36
41
|
function consumeLarkBridgeEvent(turn, event, options) {
|
|
37
42
|
const content = foldToolResultForLark(String(event.content || '').trim());
|
|
38
43
|
if (event.type === 'typing_start') {
|
|
@@ -98,6 +103,9 @@ function renderLarkBridgeEventMessage(turn, event) {
|
|
|
98
103
|
return renderProgressMessage(event.previewHandle || 'thinking-preview', content);
|
|
99
104
|
}
|
|
100
105
|
if (content.startsWith('🔧 ')) {
|
|
106
|
+
if (isPendingToolProgressForLark(content)) {
|
|
107
|
+
return { key: 'noop', text: '', buttonRows: [], isFinal: false };
|
|
108
|
+
}
|
|
101
109
|
return renderProgressMessage(progressKey('tool', event), content);
|
|
102
110
|
}
|
|
103
111
|
return {
|
|
@@ -116,6 +124,9 @@ function renderLarkBridgeEventMessage(turn, event) {
|
|
|
116
124
|
return renderProgressMessage(progressKey('thinking', event), content);
|
|
117
125
|
}
|
|
118
126
|
if (content.startsWith('🔧 ')) {
|
|
127
|
+
if (isPendingToolProgressForLark(content)) {
|
|
128
|
+
return { key: 'noop', text: '', buttonRows: [], isFinal: false };
|
|
129
|
+
}
|
|
119
130
|
return renderProgressMessage(progressKey('tool', event), content);
|
|
120
131
|
}
|
|
121
132
|
if (content.startsWith('⏳ ') || content.startsWith('📤 ')) {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.prepareChannelFile = prepareChannelFile;
|
|
4
|
+
exports.resolveChannelFilePath = resolveChannelFilePath;
|
|
4
5
|
exports.sanitizeChannelFileName = sanitizeChannelFileName;
|
|
5
6
|
const promises_1 = require("node:fs/promises");
|
|
6
7
|
const node_path_1 = require("node:path");
|
|
7
8
|
async function prepareChannelFile(input) {
|
|
8
|
-
const filePath =
|
|
9
|
+
const filePath = resolveChannelFilePath(input.path, input.workspacePath);
|
|
9
10
|
if (!filePath) {
|
|
10
11
|
throw new Error('Missing file path');
|
|
11
12
|
}
|
|
@@ -27,6 +28,17 @@ async function prepareChannelFile(input) {
|
|
|
27
28
|
fileSize: fileStat.size,
|
|
28
29
|
};
|
|
29
30
|
}
|
|
31
|
+
function resolveChannelFilePath(filePath, workspacePath) {
|
|
32
|
+
const normalized = String(filePath || '').trim();
|
|
33
|
+
if (!normalized) {
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
if ((0, node_path_1.isAbsolute)(normalized)) {
|
|
37
|
+
return normalized;
|
|
38
|
+
}
|
|
39
|
+
const workspaceRoot = String(workspacePath || '').trim();
|
|
40
|
+
return workspaceRoot ? (0, node_path_1.resolve)(workspaceRoot, normalized) : normalized;
|
|
41
|
+
}
|
|
30
42
|
function sanitizeChannelFileName(fileName) {
|
|
31
43
|
const normalized = String(fileName || '').trim().replace(/[\/\\]+/g, '_');
|
|
32
44
|
return normalized || 'file';
|