@kafca/agentdock 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/renderer/assets/{Badge-DXt7cKFc.js → Badge-DcFVSGwl.js} +1 -1
  2. package/dist/renderer/assets/Chat-CTy10fKR.js +2 -0
  3. package/dist/renderer/assets/{ChatMarkdown-BJUbKIWx.js → ChatMarkdown-C-ci0dQL.js} +4 -4
  4. package/dist/renderer/assets/{Config-Cy7Bghwk.js → Config-Bl5vuqBS.js} +1 -1
  5. package/dist/renderer/assets/{CronList-CDLl1ZzX.js → CronList-BQOEXhHD.js} +1 -1
  6. package/dist/renderer/assets/{Dashboard-GInRzjlA.js → Dashboard-CauX4_SR.js} +2 -2
  7. package/dist/renderer/assets/{EmptyState-Blxa5wT6.js → EmptyState-DVYGGFl9.js} +1 -1
  8. package/dist/renderer/assets/{KnowledgeDetail-DG5ACw7Z.js → KnowledgeDetail-BlV8Twrx.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeHome-Co82W8Gm.js → KnowledgeHome-vd6AO-Fn.js} +1 -1
  10. package/dist/renderer/assets/{Logs-CX-AZ4l9.js → Logs-BrtF26F7.js} +1 -1
  11. package/dist/renderer/assets/{Modal-BfZUw-Vc.js → Modal-D6ucs8W2.js} +1 -1
  12. package/dist/renderer/assets/{Page-Bj33TMID.js → Page-BdF9afpu.js} +1 -1
  13. package/dist/renderer/assets/{ProjectDetail-Br1_6OXA.js → ProjectDetail-RuoRHs1Q.js} +1 -1
  14. package/dist/renderer/assets/{ProjectList-DtfMApqf.js → ProjectList-r9MXhUu7.js} +1 -1
  15. package/dist/renderer/assets/{Select-zyP8Fyv-.js → Select-CEsAkZ5j.js} +1 -1
  16. package/dist/renderer/assets/SessionChat-DwnZpTVu.js +1 -0
  17. package/dist/renderer/assets/{SessionList-C5Qm9meA.js → SessionList-C89Z6STB.js} +1 -1
  18. package/dist/renderer/assets/{ThreadChat-mXwKVnjn.js → ThreadChat-JB9GY3La.js} +5 -5
  19. package/dist/renderer/assets/{Workspace-D33Uehab.js → Workspace-Cftl8zps.js} +1 -1
  20. package/dist/renderer/assets/{arrow-left-CHaLGNIO.js → arrow-left-DuiS0IaQ.js} +1 -1
  21. package/dist/renderer/assets/{book-open-ErTuahLF.js → book-open-B6l3y70b.js} +1 -1
  22. package/dist/renderer/assets/{check-DdHpkvai.js → check-CfewkzaJ.js} +1 -1
  23. package/dist/renderer/assets/{circle-jGjPqcBV.js → circle-qzty4gzl.js} +1 -1
  24. package/dist/renderer/assets/{desktop-DTOHffl0.js → desktop-DTAjgvNs.js} +1 -1
  25. package/dist/renderer/assets/{funnel-SfDR1vLQ.js → funnel-CwjI0g4c.js} +1 -1
  26. package/dist/renderer/assets/{heart-uLLDdrUQ.js → heart-CVHUi-lA.js} +1 -1
  27. package/dist/renderer/assets/index-3CzgyQYB.css +11 -0
  28. package/dist/renderer/assets/{index-CTOb2Qbz.js → index-BbDTSo1y.js} +1 -1
  29. package/dist/renderer/assets/{index-DbqC4-hV.js → index-tQ6A4Zff.js} +2 -2
  30. package/dist/renderer/assets/{pencil-CmkSVcVi.js → pencil-BvQPZxH6.js} +1 -1
  31. package/dist/renderer/assets/{play-D4sbHoXa.js → play-hJkkCcS6.js} +1 -1
  32. package/dist/renderer/assets/{plug-CTnt9Fqi.js → plug-BGtbkjYJ.js} +1 -1
  33. package/dist/renderer/assets/{plus-C88o4pqU.js → plus-DrYsrZyx.js} +1 -1
  34. package/dist/renderer/assets/projects-DcNm9FDK.js +1 -0
  35. package/dist/renderer/assets/{save-D8aBjpdR.js → save-C8W3Wq2Z.js} +1 -1
  36. package/dist/renderer/assets/{search-CR2u_AT7.js → search-BuSByDes.js} +1 -1
  37. package/dist/renderer/assets/{server-DD_yCA3I.js → server-B9wEMLdo.js} +1 -1
  38. package/dist/renderer/assets/{session-utils-DzI7rMtW.js → session-utils-K8E4S3Qx.js} +1 -1
  39. package/dist/renderer/assets/{sessions-qYxQCCGN.js → sessions-B-QTvESY.js} +1 -1
  40. package/dist/renderer/assets/{shield-check-Du9pUUbm.js → shield-check-C-oxstVp.js} +1 -1
  41. package/dist/renderer/assets/{trash-2-DwMqg4qR.js → trash-2-BQpE15-6.js} +1 -1
  42. package/dist/renderer/assets/{user-cFDevW5m.js → user-CM4R9QVx.js} +1 -1
  43. package/dist/renderer/assets/{wifi-off-opRy17vp.js → wifi-off-CoaA7hVn.js} +1 -1
  44. package/dist/renderer/index.html +2 -2
  45. package/dist-electron/electron/local-core-refactor.test.js +84 -0
  46. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +3 -0
  47. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +123 -20
  48. package/package.json +1 -1
  49. package/dist/renderer/assets/Chat-KI72IiDR.js +0 -2
  50. package/dist/renderer/assets/SessionChat-DaU2m8t8.js +0 -1
  51. package/dist/renderer/assets/index-CVrF_DwQ.css +0 -11
  52. package/dist/renderer/assets/projects-CxhcfuFo.js +0 -1
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-DbqC4-hV.js";/**
1
+ import{c as a}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-DbqC4-hV.js";/**
1
+ import{c as o}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-DbqC4-hV.js";/**
1
+ import{c as o}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-DbqC4-hV.js";/**
1
+ import{c as e}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1 @@
1
+ import{y as t}from"./index-tQ6A4Zff.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-DbqC4-hV.js";/**
1
+ import{c as a}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-DbqC4-hV.js";/**
1
+ import{c}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-DbqC4-hV.js";/**
1
+ import{c as e}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-DbqC4-hV.js";/**
1
+ import{c as o}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{y as o}from"./index-DbqC4-hV.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
1
+ import{y as o}from"./index-tQ6A4Zff.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
@@ -1,4 +1,4 @@
1
- import{c}from"./index-DbqC4-hV.js";/**
1
+ import{c}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-DbqC4-hV.js";/**
1
+ import{c as e}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-DbqC4-hV.js";/**
1
+ import{c as e}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-DbqC4-hV.js";/**
1
+ import{c as a}from"./index-tQ6A4Zff.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -5,8 +5,8 @@
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-DbqC4-hV.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-CVrF_DwQ.css">
8
+ <script type="module" crossorigin src="./assets/index-tQ6A4Zff.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-3CzgyQYB.css">
10
10
  </head>
11
11
  <body class="bg-[#f5f5f7] dark:bg-[#151516]">
12
12
  <div id="root"></div>
@@ -141,6 +141,90 @@ const local_core_acp_store_js_1 = require("../services/local-ai-core/src/acp/loc
141
141
  strict_1.default.equal(emitted.length, 2);
142
142
  strict_1.default.deepEqual(emitted.map((event) => event.messageId), ['run-1-tool-1', 'run-1-tool-1']);
143
143
  });
144
+ (0, node_test_1.default)('ACP concurrent tool call updates are matched by call id', () => {
145
+ const upserted = [];
146
+ const emitted = [];
147
+ const coordinator = new local_core_acp_turn_coordinator_js_1.LocalCoreAcpTurnCoordinator({
148
+ appendMessage: () => strict_1.default.fail('tool updates should be upserted'),
149
+ upsertMessage: (_threadId, id, _role, content, kind) => upserted.push({ id, content, kind }),
150
+ emitBridge: (event) => emitted.push(event),
151
+ updateRunStatus: () => { },
152
+ sendRaw: () => true,
153
+ });
154
+ const session = {
155
+ threadId: 'thread-1',
156
+ bridgeSessionKey: 'session:thread-1',
157
+ currentRunId: 'run-1',
158
+ currentTurn: {
159
+ runId: 'run-1',
160
+ replyCtx: 'run-1',
161
+ previewHandle: 'preview-1',
162
+ assistantText: '',
163
+ typingStarted: true,
164
+ previewStarted: false,
165
+ permission: null,
166
+ },
167
+ loadReplayMode: false,
168
+ schedulerJobCreatedByRun: new Map(),
169
+ };
170
+ coordinator.handleAgentNotification(session, {
171
+ method: 'session/update',
172
+ params: {
173
+ update: {
174
+ sessionUpdate: 'tool_call',
175
+ id: 'call-a',
176
+ title: 'Terminal',
177
+ },
178
+ },
179
+ });
180
+ coordinator.handleAgentNotification(session, {
181
+ method: 'session/update',
182
+ params: {
183
+ update: {
184
+ sessionUpdate: 'tool_call',
185
+ id: 'call-b',
186
+ title: 'Read',
187
+ },
188
+ },
189
+ });
190
+ coordinator.handleAgentNotification(session, {
191
+ method: 'session/update',
192
+ params: {
193
+ update: {
194
+ sessionUpdate: 'tool_call_update',
195
+ id: 'call-b',
196
+ title: 'Read package.json',
197
+ status: 'running',
198
+ },
199
+ },
200
+ });
201
+ coordinator.handleAgentNotification(session, {
202
+ method: 'session/update',
203
+ params: {
204
+ update: {
205
+ sessionUpdate: 'tool_call_update',
206
+ id: 'call-a',
207
+ title: 'Tool update',
208
+ status: 'completed',
209
+ content: [
210
+ {
211
+ type: 'content',
212
+ content: {
213
+ type: 'text',
214
+ text: 'terminal output',
215
+ },
216
+ },
217
+ ],
218
+ },
219
+ },
220
+ });
221
+ strict_1.default.equal(upserted.length, 2);
222
+ strict_1.default.equal(upserted[0]?.id, 'run-1-tool-2');
223
+ strict_1.default.equal(upserted[0]?.content, '🔧 Read: Read package.json - running');
224
+ strict_1.default.equal(upserted[1]?.id, 'run-1-tool-1');
225
+ strict_1.default.equal(upserted[1]?.content, '🔧 Terminal: completed - terminal output');
226
+ strict_1.default.deepEqual(emitted.map((event) => event.messageId), ['run-1-tool-2', 'run-1-tool-1']);
227
+ });
144
228
  (0, node_test_1.default)('ACP permission tool parameters are preserved in completed tool cards', () => {
145
229
  const upserted = [];
146
230
  const emitted = [];
@@ -247,6 +247,9 @@ class LocalCoreAcpBackend {
247
247
  pendingToolCallTitle: undefined,
248
248
  pendingToolCallId: undefined,
249
249
  pendingToolCallDetail: undefined,
250
+ activeToolCallKey: undefined,
251
+ pendingToolCalls: {},
252
+ pendingToolCallOrder: [],
250
253
  toolCallSequence: 0,
251
254
  permission: null,
252
255
  };
@@ -11,15 +11,28 @@ class LocalCoreAcpTurnCoordinator {
11
11
  flushPendingToolCall(session) {
12
12
  const currentTurn = session.currentTurn;
13
13
  const currentRunId = session.currentRunId;
14
- const title = currentTurn?.pendingToolCallTitle?.trim();
15
- if (!currentTurn || !currentRunId || !title) {
14
+ if (!currentTurn || !currentRunId) {
16
15
  return;
17
16
  }
18
- const messageId = currentTurn.pendingToolCallId;
19
- currentTurn.pendingToolCallTitle = undefined;
20
- currentTurn.pendingToolCallId = undefined;
21
- currentTurn.pendingToolCallDetail = undefined;
22
- this.emitProgress(session, currentRunId, `🔧 ${title}`, messageId);
17
+ const pending = this.getToolCallsInOrder(currentTurn)
18
+ .filter((toolCall) => !toolCall.emitted);
19
+ if (pending.length === 0) {
20
+ const title = currentTurn.pendingToolCallTitle?.trim();
21
+ if (!title) {
22
+ return;
23
+ }
24
+ const messageId = currentTurn.pendingToolCallId;
25
+ currentTurn.pendingToolCallTitle = undefined;
26
+ currentTurn.pendingToolCallId = undefined;
27
+ currentTurn.pendingToolCallDetail = undefined;
28
+ this.emitProgress(session, currentRunId, `🔧 ${title}`, messageId);
29
+ return;
30
+ }
31
+ for (const toolCall of pending) {
32
+ toolCall.emitted = true;
33
+ this.emitProgress(session, currentRunId, `🔧 ${toolCall.title}`, toolCall.messageId);
34
+ }
35
+ this.syncLegacyPendingToolCall(currentTurn, this.resolveFallbackToolCall(currentTurn));
23
36
  }
24
37
  getPendingPermissionRequest(session, detail) {
25
38
  const runId = session?.currentRunId;
@@ -122,6 +135,11 @@ class LocalCoreAcpTurnCoordinator {
122
135
  session.currentTurn.permission = permissionRequest;
123
136
  if (toolTitle && toolTitle !== 'Permission required before continuing.') {
124
137
  session.currentTurn.pendingToolCallDetail = toolTitle;
138
+ const toolCall = this.resolveFallbackToolCall(session.currentTurn);
139
+ if (toolCall) {
140
+ toolCall.detail = toolTitle;
141
+ this.syncLegacyPendingToolCall(session.currentTurn, toolCall);
142
+ }
125
143
  }
126
144
  }
127
145
  this.options.updateRunStatus(currentRunId, session.threadId, 'awaiting_input');
@@ -216,12 +234,26 @@ class LocalCoreAcpTurnCoordinator {
216
234
  }
217
235
  case 'tool_call': {
218
236
  const title = String(update.title || 'Running tool').trim();
219
- this.flushPendingToolCall(session);
220
237
  const nextSequence = (currentTurn.toolCallSequence || 0) + 1;
221
238
  currentTurn.toolCallSequence = nextSequence;
222
- currentTurn.pendingToolCallTitle = title;
223
- currentTurn.pendingToolCallId = `${currentRunId}-tool-${nextSequence}`;
224
- currentTurn.pendingToolCallDetail = undefined;
239
+ const key = this.extractToolCallKey(update) || `sequence:${nextSequence}`;
240
+ const toolCall = {
241
+ key,
242
+ title,
243
+ messageId: `${currentRunId}-tool-${nextSequence}`,
244
+ sequence: nextSequence,
245
+ emitted: false,
246
+ };
247
+ currentTurn.pendingToolCalls = {
248
+ ...(currentTurn.pendingToolCalls || {}),
249
+ [key]: toolCall,
250
+ };
251
+ currentTurn.pendingToolCallOrder = [
252
+ ...(currentTurn.pendingToolCallOrder || []).filter((item) => item !== key),
253
+ key,
254
+ ];
255
+ currentTurn.activeToolCallKey = key;
256
+ this.syncLegacyPendingToolCall(currentTurn, toolCall);
225
257
  return;
226
258
  }
227
259
  case 'tool_call_update': {
@@ -231,25 +263,41 @@ class LocalCoreAcpTurnCoordinator {
231
263
  if (isSchedulerAddCommand(title) && /Created scheduler job\b/.test(content)) {
232
264
  session.schedulerJobCreatedByRun.set(currentRunId, true);
233
265
  }
234
- const toolName = currentTurn.pendingToolCallTitle?.trim();
235
- const messageId = currentTurn.pendingToolCallId;
236
- const priorDetail = currentTurn.pendingToolCallDetail?.trim();
266
+ const toolCall = this.resolveToolCallForUpdate(currentTurn, update);
267
+ const toolName = toolCall?.title.trim() || currentTurn.pendingToolCallTitle?.trim();
268
+ const messageId = toolCall?.messageId || currentTurn.pendingToolCallId;
269
+ const priorDetail = toolCall ? toolCall.detail?.trim() : currentTurn.pendingToolCallDetail?.trim();
237
270
  if (this.isEmptyRunningToolUpdate(title, status, content)) {
238
- currentTurn.pendingToolCallTitle = undefined;
239
- currentTurn.pendingToolCallId = undefined;
240
- currentTurn.pendingToolCallDetail = undefined;
271
+ if (toolCall) {
272
+ this.deleteToolCall(currentTurn, toolCall.key);
273
+ }
274
+ else {
275
+ currentTurn.pendingToolCallTitle = undefined;
276
+ currentTurn.pendingToolCallId = undefined;
277
+ currentTurn.pendingToolCallDetail = undefined;
278
+ }
279
+ this.syncLegacyPendingToolCall(currentTurn, this.resolveFallbackToolCall(currentTurn));
241
280
  return;
242
281
  }
243
282
  const displayTitle = this.resolveToolUpdateDisplayTitle(title, status, priorDetail);
244
283
  if (!this.isTerminalToolStatus(status) && displayTitle && !/^tool update$/i.test(displayTitle)) {
284
+ if (toolCall) {
285
+ toolCall.detail = displayTitle;
286
+ }
245
287
  currentTurn.pendingToolCallDetail = displayTitle;
246
288
  }
247
289
  if (this.isTerminalToolStatus(status)) {
248
- currentTurn.pendingToolCallTitle = undefined;
249
- currentTurn.pendingToolCallId = undefined;
250
- currentTurn.pendingToolCallDetail = undefined;
290
+ if (toolCall) {
291
+ this.deleteToolCall(currentTurn, toolCall.key);
292
+ }
293
+ else {
294
+ currentTurn.pendingToolCallTitle = undefined;
295
+ currentTurn.pendingToolCallId = undefined;
296
+ currentTurn.pendingToolCallDetail = undefined;
297
+ }
251
298
  }
252
299
  this.emitProgress(session, currentRunId, this.formatToolProgressMessage(toolName, displayTitle, status, content), messageId);
300
+ this.syncLegacyPendingToolCall(currentTurn, this.resolveFallbackToolCall(currentTurn));
253
301
  return;
254
302
  }
255
303
  case 'plan': {
@@ -309,6 +357,9 @@ class LocalCoreAcpTurnCoordinator {
309
357
  if (priorDetail && (this.isTerminalToolStatus(status) || /^tool update$/i.test(title.trim()))) {
310
358
  return priorDetail;
311
359
  }
360
+ if (this.isTerminalToolStatus(status) && /^tool update$/i.test(title.trim())) {
361
+ return '';
362
+ }
312
363
  return title;
313
364
  }
314
365
  isEmptyRunningToolUpdate(title, status, content) {
@@ -319,6 +370,58 @@ class LocalCoreAcpTurnCoordinator {
319
370
  isTerminalToolStatus(status) {
320
371
  return /^(completed|failed|error|cancelled|canceled)$/i.test(status.trim());
321
372
  }
373
+ extractToolCallKey(update) {
374
+ for (const key of ['toolCallId', 'tool_call_id', 'callId', 'call_id', 'invocationId', 'invocation_id', 'id']) {
375
+ const value = update[key];
376
+ if (typeof value === 'string' || typeof value === 'number') {
377
+ const normalized = String(value).trim();
378
+ if (normalized) {
379
+ return normalized;
380
+ }
381
+ }
382
+ }
383
+ return '';
384
+ }
385
+ resolveToolCallForUpdate(currentTurn, update) {
386
+ const explicitKey = this.extractToolCallKey(update);
387
+ if (explicitKey && currentTurn.pendingToolCalls?.[explicitKey]) {
388
+ currentTurn.activeToolCallKey = explicitKey;
389
+ return currentTurn.pendingToolCalls[explicitKey];
390
+ }
391
+ return this.resolveFallbackToolCall(currentTurn);
392
+ }
393
+ resolveFallbackToolCall(currentTurn) {
394
+ const active = currentTurn.activeToolCallKey
395
+ ? currentTurn.pendingToolCalls?.[currentTurn.activeToolCallKey]
396
+ : undefined;
397
+ if (active) {
398
+ return active;
399
+ }
400
+ const ordered = this.getToolCallsInOrder(currentTurn);
401
+ return ordered[ordered.length - 1];
402
+ }
403
+ getToolCallsInOrder(currentTurn) {
404
+ const toolCalls = currentTurn.pendingToolCalls || {};
405
+ const orderedKeys = currentTurn.pendingToolCallOrder || [];
406
+ return orderedKeys
407
+ .map((key) => toolCalls[key])
408
+ .filter((toolCall) => Boolean(toolCall));
409
+ }
410
+ deleteToolCall(currentTurn, key) {
411
+ if (currentTurn.pendingToolCalls) {
412
+ delete currentTurn.pendingToolCalls[key];
413
+ }
414
+ currentTurn.pendingToolCallOrder = (currentTurn.pendingToolCallOrder || []).filter((item) => item !== key);
415
+ if (currentTurn.activeToolCallKey === key) {
416
+ currentTurn.activeToolCallKey = undefined;
417
+ }
418
+ }
419
+ syncLegacyPendingToolCall(currentTurn, toolCall) {
420
+ currentTurn.pendingToolCallTitle = toolCall?.title;
421
+ currentTurn.pendingToolCallId = toolCall?.messageId;
422
+ currentTurn.pendingToolCallDetail = toolCall?.detail;
423
+ currentTurn.activeToolCallKey = toolCall?.key;
424
+ }
322
425
  }
323
426
  exports.LocalCoreAcpTurnCoordinator = LocalCoreAcpTurnCoordinator;
324
427
  function isSchedulerAddCommand(value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kafca/agentdock",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "main": "dist-electron/electron/main.js",
6
6
  "bin": {
@@ -1,2 +0,0 @@
1
- import{u as ze,t as Me,r,j as s,C as ye,I as pe,M as K,B as C,w as ee,R as De,T as Le}from"./index-DbqC4-hV.js";import{M as je}from"./Modal-BfZUw-Vc.js";import{E as U}from"./EmptyState-Blxa5wT6.js";import{C as Ae,S as Be}from"./ChatMarkdown-BJUbKIWx.js";import{l as Ke}from"./projects-CxhcfuFo.js";import{l as Ue,g as $e,s as qe,a as be,r as Fe,d as Oe}from"./sessions-qYxQCCGN.js";import{s as He,a as ve,b as v,L as $,t as Ve}from"./session-utils-DzI7rMtW.js";import{S as We}from"./search-CR2u_AT7.js";import{P as Ge}from"./pencil-CmkSVcVi.js";import{T as Je}from"./trash-2-DwMqg4qR.js";import{B as Qe,U as Xe}from"./user-cFDevW5m.js";import"./index-CTOb2Qbz.js";import"./check-DdHpkvai.js";const Ye=1500,Ze=9e4;function es(a){return String(a||"").startsWith("web:")}function ss(a){return(a||[]).map((c,p)=>({id:`${c.timestamp||p}-${c.role}-${p}`,role:c.role==="user"?"user":"assistant",content:c.content,timestamp:c.timestamp,kind:c.kind}))}function ts(a){return a.map(c=>`${c.role}:${c.kind||"final"}:${c.timestamp||""}:${c.content}`).join(`
2
- `)}function as(a){return a.filter(c=>c.role!=="user").length}function ns(a,c){var p;return(p=a.last_message)!=null&&p.content?a.last_message.content.replace(/\n/g," "):c("sessions.noMessages")}function we(a){return(a instanceof Error?a.message:String(a||"")).trim().toLowerCase().includes("no active session found")}function rs(a,c){return(a instanceof Error?a.message:String(a||"")).trim().toLowerCase()?we(a)?c("sessions.sessionUnavailable"):a instanceof Error?a.message:c("sessions.sendFailed"):c("sessions.sendFailed")}function js(){const{t:a}=ze(),[c,p]=Me(),[se,ke]=r.useState([]),[te,ae]=r.useState({}),[i,G]=r.useState(c.get("project")||""),[j,_]=r.useState([]),[n,h]=r.useState(null),[R,w]=r.useState([]),[J,ne]=r.useState(""),[I,Q]=r.useState(""),[Se,re]=r.useState(!0),[Ne,ie]=r.useState(!1),[Ce,le]=r.useState(!1),[X,oe]=r.useState(!1),[E,P]=r.useState("idle"),[ce,k]=r.useState(""),[T,q]=r.useState(null),[F,Y]=r.useState(""),[z,O]=r.useState(null),[de,H]=r.useState(null),me=r.useRef(null),x=r.useRef({project:"",sessionId:""}),V=r.useRef(null),W=r.useRef(null),b=c.get("project")||"",M=c.get("session")||"",ue=r.useMemo(()=>new Set(Object.values(te)),[te]),S=r.useMemo(()=>{const e=J.trim().toLowerCase();return e?j.filter(t=>He(t,e)):j},[J,j]),D=!!(n&&(n.live||ue.has(n.id))),Ee=!!(i&&D&&I.trim()&&!X&&E!=="sending"&&E!=="activating"&&E!=="polling"),f=r.useCallback((e,t)=>{const l=new URLSearchParams;e&&l.set("project",e),t&&l.set("session",t),p(l,{replace:!0})},[p]),d=r.useCallback((e="idle")=>{V.current&&(window.clearTimeout(V.current),V.current=null),W.current=null,P(e)},[]),xe=r.useCallback(e=>{_(t=>{const l=t.some(o=>o.id===e.id)?t.map(o=>o.id===e.id?{...o,...e}:o):[...t,e];return ve(l)})},[]),fe=r.useCallback(async()=>{re(!0);try{const{projects:e}=await Ke();ke(e||[])}finally{re(!1)}},[]),u=r.useCallback(async e=>{if(!e)return _([]),ae({}),[];ie(!0);try{const{sessions:t,active_keys:l}=await Ue(e),o=ve((t||[]).filter(m=>!es(m.session_key)));return ae(l||{}),x.current.project===e&&_(o),o}finally{ie(!1)}},[]),N=r.useCallback(async(e,t,l)=>{if(!e||!t)return h(null),w([]),null;l!=null&&l.silent||le(!0);try{const o=await $e(e,t,200);return x.current.project!==e||x.current.sessionId!==t||(xe(o),h({id:o.id,project:e,sessionKey:o.session_key,name:o.name||v(o),live:o.live,isDraft:!1,detail:o}),w(ss(o.history)),k("")),o}catch(o){return x.current.project===e&&x.current.sessionId===t&&k(o instanceof Error?o.message:a("sessions.loadFailed")),null}finally{l!=null&&l.silent||le(!1)}},[xe,a]),Z=r.useCallback(e=>{W.current=e,V.current=window.setTimeout(async()=>{const t=W.current;if(!t)return;if(Date.now()-t.startedAt>=Ze){d("timed_out"),k(a("sessions.pollTimeout")),await u(t.project);return}const l=await N(t.project,t.sessionId,{silent:!0});if(!l||!W.current){d(),await u(t.project);return}if(x.current.project!==t.project||x.current.sessionId!==t.sessionId){d();return}const o=ts(l.history),m=as(l.history)>t.assistantCountBefore,g=m&&o===t.lastSignature?t.stableCount+1:0,B={...t,lastSignature:o,stableCount:g};if(m&&g>=2){d(),await u(t.project);return}P("polling"),Z(B)},Ye)},[N,u,d,a]),he=r.useCallback((e,t,l)=>{d(),P("polling"),Z({project:e,sessionId:t,assistantCountBefore:l,stableCount:0,lastSignature:"",startedAt:Date.now()})},[Z,d]),Pe=r.useCallback(async e=>{if(d(),G(e),ne(""),k(""),Q(""),!e){x.current={project:"",sessionId:""},h(null),w([]),_([]),f("");return}x.current={project:e,sessionId:""},h(null),w([]),f(e),await u(e)},[u,d,f]),L=r.useCallback(async e=>{if(e.isDraft||e.live||!e.id)return e;P("activating");try{await qe(e.project,{session_key:e.sessionKey,session_id:e.id}),await u(e.project);const t=await N(e.project,e.id,{silent:!0}),l={...e,live:(t==null?void 0:t.live)??!0,isDraft:!1,detail:t??e.detail,name:(t==null?void 0:t.name)||e.name};return h(l),l}finally{P("idle")}},[N,u]),A=r.useCallback(async(e,t)=>{d(),k(""),x.current={project:e,sessionId:t.id},G(e),f(e,t.id),h({id:t.id,project:e,sessionKey:t.session_key,name:v(t),live:t.live,isDraft:!1,detail:null});const l=await N(e,t.id);l&&!l.live&&await L({id:l.id,project:e,sessionKey:l.session_key,name:l.name||v(l),live:l.live,isDraft:!1,detail:l})},[L,N,d,f]),_e=r.useCallback(async()=>{d(),i&&(await u(i),n!=null&&n.id&&(x.current={project:i,sessionId:n.id},await N(i,n.id)))},[n==null?void 0:n.id,N,u,i,d]),ge=r.useCallback(async()=>{if(!I.trim()||!i)return;if(!D){k(a("sessions.sessionUnavailable"));return}const e=I.trim(),t=`${crypto.randomUUID()}-user`,l={id:t,role:"user",content:e,timestamp:new Date().toISOString()};Q(""),oe(!0),P("sending"),k("");try{const o=n||S[0];if(!o)throw new Error(a("sessions.noAvailableChatTarget"));let m=n&&n.id===o.id?n:{id:o.id,project:i,sessionKey:"session_key"in o?o.session_key:o.sessionKey,name:"session_key"in o?v(o):o.name,live:o.live,isDraft:!1,detail:null};(!n||n.id!==m.id)&&(x.current={project:i,sessionId:m.id},f(i,m.id),h(m)),m=await L(m),w(y=>[...y,l]);try{await be(i,{session_key:m.sessionKey,message:e})}catch(y){if(!we(y)||!m.id)throw y;m=await L({...m,live:!1}),await be(i,{session_key:m.sessionKey,message:e})}const g=m.id;if(!g)throw new Error(a("sessions.createFailed"));const B=R.filter(y=>y.role!=="user").length;x.current={project:i,sessionId:g},h(y=>y&&{...y,id:g,isDraft:!1}),f(i,g),he(i,g,B),await u(i)}catch(o){d(),w(g=>g.filter(B=>B.id!==t));const m=rs(o,a);k(m)}finally{oe(!1)}},[n,D,L,I,S,R,u,i,he,d,a,f]),Re=r.useCallback(async()=>{if(!(!T||!i||!F.trim())){H("rename");try{await Fe(i,T.id,{name:F.trim()});const t=(await u(i)).find(l=>l.id===T.id);t&&(n==null?void 0:n.id)===t.id&&h(l=>l&&{...l,name:v(t)}),q(null),Y("")}finally{H(null)}}},[n==null?void 0:n.id,u,F,T,i]),Ie=r.useCallback(async()=>{if(!(!z||!i)){H("delete");try{await Oe(i,z.id);const e=await u(i);(n==null?void 0:n.id)===z.id&&(d(),x.current={project:i,sessionId:""},h(null),w([]),f(i)),e.length===0&&w([]),O(null)}finally{H(null)}}},[n==null?void 0:n.id,z,u,i,d,f]);r.useEffect(()=>{fe()},[fe]),r.useEffect(()=>{b&&(i&&i===b||G(b))},[b,i]),r.useEffect(()=>{if(!i){_([]);return}x.current.project=i,u(i)},[u,i]),r.useEffect(()=>{!i||M||n!=null&&n.id||S.length===0||A(i,S[0])},[n==null?void 0:n.id,S,A,M,i]),r.useEffect(()=>{if(!b||!M||i!==b)return;const e=j.find(t=>t.id===M);if(!e){j.length>0&&f(b,j[0].id);return}(n==null?void 0:n.id)!==e.id&&A(b,e)},[n==null?void 0:n.id,A,b,M,i,j,f]),r.useEffect(()=>{var e;(e=me.current)==null||e.scrollIntoView({behavior:"smooth"})},[R]),r.useEffect(()=>()=>d(),[d]);const Te=(n==null?void 0:n.name)||a("sessions.activeChat");return s.jsxs("div",{className:"grid min-h-[calc(100vh-8rem)] grid-cols-1 gap-4 xl:grid-cols-[22rem_minmax(0,1fr)] animate-fade-in",children:[s.jsxs(ye,{className:"flex flex-col gap-4 p-4 xl:h-[calc(100vh-8rem)] xl:overflow-hidden",children:[s.jsx("div",{className:"flex items-center gap-3",children:s.jsxs("div",{className:"flex-1",children:[s.jsx("p",{className:"text-xs font-medium uppercase tracking-[0.2em] text-gray-400",children:a("sessions.selectProject")}),s.jsxs("select",{value:i,onChange:e=>void Pe(e.target.value),className:"mt-2 w-full rounded-xl border border-gray-300/90 bg-white/90 px-3 py-2 text-sm text-gray-900 transition-all focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/45 dark:border-white/[0.1] dark:bg-[rgba(0,0,0,0.45)] dark:text-white",children:[s.jsx("option",{value:"",children:a("sessions.allProjects")}),se.map(e=>s.jsx("option",{value:e.name,children:e.name},e.name))]})]})}),s.jsxs("div",{className:"relative",children:[s.jsx(pe,{value:J,onChange:e=>ne(e.target.value),placeholder:a("common.search"),className:"pl-9","aria-label":a("common.search")}),s.jsx(We,{size:16,className:"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"})]}),s.jsxs("div",{className:"flex min-h-0 flex-1 flex-col overflow-hidden",children:[s.jsxs("div",{className:"mb-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400",children:[s.jsx("span",{children:a("sessions.historyTitle")}),s.jsx("span",{children:S.length})]}),s.jsx("div",{className:"min-h-0 flex-1 overflow-y-auto space-y-2 pr-1",children:Se?s.jsx("div",{className:"flex h-32 items-center justify-center text-gray-400",children:s.jsx($,{className:"animate-spin",size:18})}):i?Ne&&j.length===0?s.jsx("div",{className:"flex h-32 items-center justify-center text-gray-400",children:s.jsx($,{className:"animate-spin",size:18})}):j.length===0?s.jsx(U,{message:a("sessions.noSessions"),icon:K}):S.length===0?s.jsx(U,{message:a("sessions.noSessions"),icon:K}):S.map(e=>{const t=e.id===(n==null?void 0:n.id);return s.jsxs("div",{className:ee("rounded-2xl border p-3 transition-all",t?"border-accent/45 bg-accent/10 shadow-[0_0_20px_-12px_rgba(139,92,246,0.55)]":"border-gray-200/80 bg-white/70 hover:border-accent/30 dark:border-white/[0.08] dark:bg-white/[0.03]"),children:[s.jsxs("button",{type:"button",onClick:()=>void A(i,e),className:"w-full text-left","data-testid":"web-chat-session-open",children:[s.jsxs("div",{className:"flex items-start justify-between gap-2",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:"truncate text-sm font-medium text-gray-900 dark:text-white",children:v(e)}),e.live||ue.has(e.id)?s.jsx("span",{className:"rounded-full bg-violet-50 px-2 py-0.5 text-[10px] text-violet-600 dark:bg-violet-950/20 dark:text-violet-300",children:"live"}):s.jsx("span",{className:"rounded-full bg-gray-100 px-2 py-0.5 text-[10px] text-gray-400 dark:bg-white/[0.06] dark:text-gray-500",children:"history"})]}),s.jsx("p",{className:"mt-1 truncate text-xs text-gray-500 dark:text-gray-400",children:Ve(e.updated_at||e.created_at,a("sessions.justNow"))})]}),s.jsx("span",{className:"shrink-0 text-[10px] text-gray-400",children:e.history_count})]}),s.jsx("p",{className:"mt-2 line-clamp-2 text-xs text-gray-500 dark:text-gray-400",children:ns(e,a)})]}),s.jsxs("div",{className:"mt-3 flex items-center justify-end gap-1",children:[s.jsx(C,{size:"sm",variant:"ghost",onClick:()=>{q({id:e.id,name:v(e)}),Y(v(e))},"data-testid":"web-chat-session-rename",children:s.jsx(Ge,{size:14})}),s.jsx(C,{size:"sm",variant:"ghost",onClick:()=>O({id:e.id,name:v(e)}),"data-testid":"web-chat-session-delete",children:s.jsx(Je,{size:14})})]})]},e.id)}):s.jsx(U,{message:a("sessions.projectRequired"),icon:K})})]})]}),s.jsxs(ye,{className:"flex min-h-[32rem] flex-col p-0 xl:h-[calc(100vh-8rem)]",children:[s.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-gray-200/80 px-5 py-4 dark:border-white/[0.08]",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsx("div",{className:"flex items-center gap-2",children:s.jsx("h2",{className:"truncate text-lg font-semibold text-gray-900 dark:text-white",children:Te})}),s.jsx("p",{className:"mt-1 truncate text-sm text-gray-500 dark:text-gray-400",children:n?n.project:a("sessions.sendHint")})]}),s.jsxs(C,{size:"sm",variant:"secondary",onClick:()=>void _e(),"data-testid":"web-chat-refresh",children:[s.jsx(De,{size:14})," ",a("common.refresh")]})]}),s.jsx("div",{className:"flex-1 overflow-y-auto px-5 py-5",children:i?Ce?s.jsx("div",{className:"flex h-full items-center justify-center text-gray-400",children:s.jsx($,{className:"animate-spin",size:22})}):R.length===0?s.jsx("div",{className:"flex h-full items-center justify-center",children:s.jsx(U,{message:a(n?"sessions.noMessages":"sessions.sendHint"),icon:K})}):s.jsxs("div",{className:"space-y-5",children:[R.map(e=>{const t=e.role==="user";return s.jsxs("div",{className:ee("flex gap-3",t?"justify-end":"justify-start"),children:[!t&&s.jsx("div",{className:"mt-1 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-accent/10",children:s.jsx(Qe,{size:16,className:"text-accent"})}),s.jsx("div",{className:ee("max-w-[85%] rounded-2xl px-5 py-3.5 text-sm",t?"bg-accent text-white rounded-br-md":"border border-gray-200 bg-white text-gray-900 shadow-sm dark:border-white/[0.08] dark:bg-[rgba(0,0,0,0.42)] dark:text-gray-100 rounded-bl-md"),children:s.jsx(Ae,{content:e.content,isUser:t})}),t&&s.jsx("div",{className:"mt-1 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-200 dark:bg-white/[0.08]",children:s.jsx(Xe,{size:16,className:"text-gray-500 dark:text-gray-300"})})]},e.id)}),s.jsx("div",{ref:me})]}):s.jsx("div",{className:"flex h-full items-center justify-center",children:s.jsx(U,{message:a("sessions.emptySelection"),icon:K})})}),s.jsxs("div",{className:"border-t border-gray-200/80 px-5 py-4 dark:border-white/[0.08]",children:[ce&&s.jsx("div",{className:"mb-3 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-600 dark:border-red-900/40 dark:bg-red-950/20 dark:text-red-300",children:ce}),E==="polling"&&s.jsxs("div",{className:"mb-3 flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400",children:[s.jsx($,{size:14,className:"animate-spin"}),s.jsx("span",{children:a("sessions.waitingForReply")})]}),E==="activating"&&s.jsxs("div",{className:"mb-3 flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400",children:[s.jsx($,{size:14,className:"animate-spin"}),s.jsx("span",{children:a("sessions.preparingChat")})]}),s.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-end",children:[s.jsx("div",{className:"flex-1",children:s.jsx(Le,{value:I,onChange:e=>Q(e.target.value),onKeyDown:e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),ge())},rows:3,placeholder:a(i?"sessions.messageInput":"sessions.projectRequired"),disabled:!i||!D||X||E==="polling"||E==="activating","data-testid":"web-chat-input"})}),s.jsxs(C,{onClick:()=>void ge(),disabled:!Ee,loading:X,size:"lg",className:"sm:self-stretch","data-testid":"web-chat-send",children:[s.jsx(Be,{size:16})," ",a("sessions.send")]})]}),!D&&n&&s.jsx("div",{className:"mt-3 rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-sm text-gray-500 dark:border-white/[0.08] dark:bg-white/[0.03] dark:text-gray-400",children:a("sessions.notLiveHint")})]})]}),s.jsx(je,{open:!!T,onClose:()=>q(null),title:a("sessions.renameTitle"),children:s.jsxs("div",{className:"space-y-4",children:[s.jsx(pe,{value:F,onChange:e=>Y(e.target.value),placeholder:a("sessions.renamePlaceholder"),"data-testid":"web-chat-rename-input"}),s.jsxs("div",{className:"flex justify-end gap-2",children:[s.jsx(C,{variant:"secondary",onClick:()=>q(null),children:a("common.cancel")}),s.jsx(C,{onClick:()=>void Re(),loading:de==="rename","data-testid":"web-chat-rename-save",children:a("common.save")})]})]})}),s.jsx(je,{open:!!z,onClose:()=>O(null),title:a("sessions.deleteConfirmTitle"),children:s.jsxs("div",{className:"space-y-4",children:[s.jsx("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:a("sessions.deleteConfirmBody")}),s.jsxs("div",{className:"flex justify-end gap-2",children:[s.jsx(C,{variant:"secondary",onClick:()=>O(null),children:a("common.cancel")}),s.jsx(C,{variant:"danger",onClick:()=>void Ie(),loading:de==="delete","data-testid":"web-chat-delete-confirm",children:a("common.delete")})]})]})})]})}export{js as default};
@@ -1 +0,0 @@
1
- import{u as C,z,r,j as e,L as S,B as j,w as g,I as B}from"./index-DbqC4-hV.js";import{B as y}from"./Badge-DXt7cKFc.js";import{g as E,a as I}from"./sessions-qYxQCCGN.js";import{C as L,S as M}from"./ChatMarkdown-BJUbKIWx.js";import{A as R}from"./arrow-left-CHaLGNIO.js";import{C as D}from"./circle-jGjPqcBV.js";import{W as v,R as K}from"./wifi-off-opRy17vp.js";import{B as U,U as W}from"./user-cFDevW5m.js";import"./check-DdHpkvai.js";function G(){var h;const{t:a}=C(),{project:n,id:l}=z(),[s,N]=r.useState(null),[o,m]=r.useState(""),[d,x]=r.useState(!1),[b,f]=r.useState(!0),u=r.useRef(null),c=r.useCallback(async()=>{if(!(!n||!l))try{f(!0);const t=await E(n,l,200);N(t)}finally{f(!1)}},[n,l]);r.useEffect(()=>{c()},[c]),r.useEffect(()=>{var t;(t=u.current)==null||t.scrollIntoView({behavior:"smooth"})},[s==null?void 0:s.history]);const p=async()=>{if(!o.trim()||!n||!s)return;const t=o.trim();m(""),x(!0);try{await I(n,{session_key:s.session_key,message:t}),setTimeout(c,1500)}finally{x(!1)}},w=t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),p())};return b&&!s?e.jsx("div",{className:"flex items-center justify-center h-64 text-muted-foreground animate-pulse",children:"Loading..."}):e.jsxs("div",{className:"flex flex-col h-[calc(100vh-8rem)] animate-fade-in",children:[e.jsxs("div",{className:"flex items-center justify-between pb-4 border-b",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(S,{to:"/sessions",className:"p-2 rounded-md hover:bg-accent/10 transition-colors",children:e.jsx(R,{size:18,className:"text-muted-foreground"})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-lg font-semibold text-foreground",children:(s==null?void 0:s.name)||l}),s!=null&&s.live?e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-primary bg-primary/10 px-1.5 py-0.5 rounded-full",children:[e.jsx(D,{size:5,className:"fill-current"})," live"]}):e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded-full",children:[e.jsx(v,{size:9})," ",a("sessions.offline")]})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-0.5",children:[e.jsx(y,{children:n}),(s==null?void 0:s.platform)&&e.jsx(y,{variant:"info",children:s.platform}),e.jsx("span",{className:"text-xs text-muted-foreground",children:s==null?void 0:s.session_key})]})]})]}),e.jsxs(j,{size:"sm",variant:"ghost",onClick:c,children:[e.jsx(K,{size:14})," ",a("common.refresh")]})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto py-6 space-y-5",children:[(!(s!=null&&s.history)||s.history.length===0)&&e.jsx("p",{className:"text-center text-sm text-muted-foreground py-12",children:a("sessions.noMessages")}),(h=s==null?void 0:s.history)==null?void 0:h.map((t,k)=>{const i=t.role==="user";return e.jsxs("div",{className:g("flex gap-3",i?"justify-end":"justify-start"),children:[!i&&e.jsx("div",{className:"w-8 h-8 rounded-md bg-primary/10 flex items-center justify-center shrink-0 mt-1",children:e.jsx(U,{size:16,className:"text-primary"})}),e.jsx("div",{className:g("rounded-lg px-5 py-3.5 text-sm",i?"max-w-[70%] bg-primary text-primary-foreground rounded-br-md":"max-w-[85%] bg-card border text-card-foreground rounded-bl-md shadow-sm"),children:e.jsx(L,{content:t.content,isUser:i})}),i&&e.jsx("div",{className:"w-8 h-8 rounded-md bg-muted flex items-center justify-center shrink-0 mt-1",children:e.jsx(W,{size:16,className:"text-muted-foreground"})})]},k)}),e.jsx("div",{ref:u})]}),e.jsx("div",{className:"border-t pt-4",children:s!=null&&s.live?e.jsxs("div",{className:"flex gap-3",children:[e.jsx(B,{value:o,onChange:t=>m(t.target.value),onKeyDown:w,placeholder:a("sessions.messageInput"),className:"flex-1",disabled:d}),e.jsx(j,{onClick:p,disabled:d||!o.trim(),size:"icon","aria-label":a("sessions.messageInput"),children:d?e.jsxs("svg",{className:"animate-spin h-4 w-4",viewBox:"0 0 24 24",children:[e.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),e.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]}):e.jsx(M,{size:18})})]}):e.jsxs("div",{className:"flex items-center gap-2 px-4 py-3 text-sm text-muted-foreground bg-muted rounded-lg",children:[e.jsx(v,{size:14}),e.jsx("span",{children:a("sessions.notLiveHint")})]})})]})}export{G as default};