agentgui 1.0.755 → 1.0.756
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/lib/db-queries.js +29 -10
- package/package.json +1 -1
- package/server.js +23 -0
- package/static/css/main.css +13 -4
- package/static/js/conversations.js +23 -0
package/lib/db-queries.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createACPQueries } from '../acp-queries.js';
|
|
2
|
-
|
|
3
|
-
export function createQueries(db, prep, generateId) {
|
|
4
|
-
return {
|
|
5
|
-
_db: db,
|
|
2
|
+
|
|
3
|
+
export function createQueries(db, prep, generateId) {
|
|
4
|
+
return {
|
|
5
|
+
_db: db,
|
|
6
6
|
createConversation(agentType, title = null, workingDirectory = null, model = null, subAgent = null) {
|
|
7
7
|
const id = generateId('conv');
|
|
8
8
|
const now = Date.now();
|
|
@@ -36,14 +36,33 @@ export function createQueries(db, prep, generateId) {
|
|
|
36
36
|
|
|
37
37
|
getConversationsList() {
|
|
38
38
|
const stmt = prep(
|
|
39
|
-
'SELECT id, agentId, title, agentType, created_at, updated_at, messageCount, workingDirectory, isStreaming, model, subAgent, pinned FROM conversations WHERE status
|
|
39
|
+
'SELECT id, agentId, title, agentType, created_at, updated_at, messageCount, workingDirectory, isStreaming, model, subAgent, pinned FROM conversations WHERE status NOT IN (?, ?) ORDER BY pinned DESC, updated_at DESC'
|
|
40
40
|
);
|
|
41
|
-
return stmt.all('deleted');
|
|
41
|
+
return stmt.all('deleted', 'archived');
|
|
42
42
|
},
|
|
43
43
|
|
|
44
44
|
getConversations() {
|
|
45
|
-
const stmt = prep('SELECT * FROM conversations WHERE status
|
|
46
|
-
return stmt.all('deleted');
|
|
45
|
+
const stmt = prep('SELECT * FROM conversations WHERE status NOT IN (?, ?) ORDER BY pinned DESC, updated_at DESC');
|
|
46
|
+
return stmt.all('deleted', 'archived');
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
getArchivedConversations() {
|
|
50
|
+
const stmt = prep('SELECT id, agentId, title, agentType, created_at, updated_at, messageCount, workingDirectory, model, subAgent FROM conversations WHERE status = ? ORDER BY updated_at DESC');
|
|
51
|
+
return stmt.all('archived');
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
archiveConversation(id) {
|
|
55
|
+
const conv = this.getConversation(id);
|
|
56
|
+
if (!conv) return null;
|
|
57
|
+
prep('UPDATE conversations SET status = ?, updated_at = ? WHERE id = ?').run('archived', Date.now(), id);
|
|
58
|
+
return this.getConversation(id);
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
restoreConversation(id) {
|
|
62
|
+
const conv = this.getConversation(id);
|
|
63
|
+
if (!conv) return null;
|
|
64
|
+
prep('UPDATE conversations SET status = ?, updated_at = ? WHERE id = ?').run('active', Date.now(), id);
|
|
65
|
+
return this.getConversation(id);
|
|
47
66
|
},
|
|
48
67
|
|
|
49
68
|
updateConversation(id, data) {
|
|
@@ -1336,5 +1355,5 @@ export function createQueries(db, prep, generateId) {
|
|
|
1336
1355
|
|
|
1337
1356
|
// ============ ACP-COMPATIBLE QUERIES ============
|
|
1338
1357
|
...createACPQueries(db, prep)
|
|
1339
|
-
};
|
|
1340
|
-
}
|
|
1358
|
+
};
|
|
1359
|
+
}
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -601,6 +601,29 @@ const server = http.createServer(async (req, res) => {
|
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
+
if (pathOnly === '/api/conversations/archived' && req.method === 'GET') {
|
|
605
|
+
sendJSON(req, res, 200, { conversations: queries.getArchivedConversations() });
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
const archiveMatch = pathOnly.match(/^\/api\/conversations\/([^/]+)\/archive$/);
|
|
610
|
+
if (archiveMatch && req.method === 'POST') {
|
|
611
|
+
const conv = queries.archiveConversation(archiveMatch[1]);
|
|
612
|
+
if (!conv) { sendJSON(req, res, 404, { error: 'Not found' }); return; }
|
|
613
|
+
broadcastSync({ type: 'conversation_deleted', conversationId: archiveMatch[1] });
|
|
614
|
+
sendJSON(req, res, 200, { conversation: conv });
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
const restoreMatch = pathOnly.match(/^\/api\/conversations\/([^/]+)\/restore$/);
|
|
619
|
+
if (restoreMatch && req.method === 'POST') {
|
|
620
|
+
const conv = queries.restoreConversation(restoreMatch[1]);
|
|
621
|
+
if (!conv) { sendJSON(req, res, 404, { error: 'Not found' }); return; }
|
|
622
|
+
broadcastSync({ type: 'conversation_created', conversation: conv });
|
|
623
|
+
sendJSON(req, res, 200, { conversation: conv });
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
|
|
604
627
|
const messagesMatch = pathOnly.match(/^\/api\/conversations\/([^/]+)\/messages$/);
|
|
605
628
|
if (messagesMatch) {
|
|
606
629
|
if (req.method === 'GET') {
|
package/static/css/main.css
CHANGED
|
@@ -275,7 +275,8 @@
|
|
|
275
275
|
overflow: hidden;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
-
.conversation-item-delete
|
|
278
|
+
.conversation-item-delete,
|
|
279
|
+
.conversation-item-archive {
|
|
279
280
|
flex-shrink: 0;
|
|
280
281
|
width: 28px;
|
|
281
282
|
height: 28px;
|
|
@@ -292,7 +293,8 @@
|
|
|
292
293
|
transition: all 0.15s;
|
|
293
294
|
}
|
|
294
295
|
|
|
295
|
-
.conversation-item:hover .conversation-item-delete
|
|
296
|
+
.conversation-item:hover .conversation-item-delete,
|
|
297
|
+
.conversation-item:hover .conversation-item-archive {
|
|
296
298
|
opacity: 1;
|
|
297
299
|
}
|
|
298
300
|
|
|
@@ -301,11 +303,18 @@
|
|
|
301
303
|
color: white;
|
|
302
304
|
}
|
|
303
305
|
|
|
304
|
-
.conversation-item
|
|
306
|
+
.conversation-item-archive:hover {
|
|
307
|
+
background-color: #f59e0b;
|
|
308
|
+
color: white;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.conversation-item.active .conversation-item-delete,
|
|
312
|
+
.conversation-item.active .conversation-item-archive {
|
|
305
313
|
color: rgba(255,255,255,0.8);
|
|
306
314
|
}
|
|
307
315
|
|
|
308
|
-
.conversation-item.active .conversation-item-delete:hover
|
|
316
|
+
.conversation-item.active .conversation-item-delete:hover,
|
|
317
|
+
.conversation-item.active .conversation-item-archive:hover {
|
|
309
318
|
background-color: rgba(255,255,255,0.2);
|
|
310
319
|
color: white;
|
|
311
320
|
}
|
|
@@ -117,6 +117,12 @@ class ConversationManager {
|
|
|
117
117
|
|
|
118
118
|
setupDelegatedListeners() {
|
|
119
119
|
this.listEl.addEventListener('click', (e) => {
|
|
120
|
+
const archiveBtn = e.target.closest('[data-archive-conv]');
|
|
121
|
+
if (archiveBtn) {
|
|
122
|
+
e.stopPropagation();
|
|
123
|
+
this.archiveConversation(archiveBtn.dataset.archiveConv);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
120
126
|
const deleteBtn = e.target.closest('[data-delete-conv]');
|
|
121
127
|
if (deleteBtn) {
|
|
122
128
|
e.stopPropagation();
|
|
@@ -477,6 +483,13 @@ class ConversationManager {
|
|
|
477
483
|
h('div', { class: 'conversation-item-title' }, ...(badge ? [badge, title] : [title])),
|
|
478
484
|
h('div', { class: 'conversation-item-meta' }, metaParts.join(' \u2022 '))
|
|
479
485
|
),
|
|
486
|
+
h('button', { class: 'conversation-item-archive', title: 'Archive conversation', 'data-archive-conv': conv.id },
|
|
487
|
+
h('svg', { width: '14', height: '14', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': '2' },
|
|
488
|
+
h('path', { d: 'M21 8v13H3V8' }),
|
|
489
|
+
h('path', { d: 'M1 3h22v5H1z' }),
|
|
490
|
+
h('path', { d: 'M10 12h4' })
|
|
491
|
+
)
|
|
492
|
+
),
|
|
480
493
|
h('button', { class: 'conversation-item-delete', title: 'Delete conversation', 'data-delete-conv': conv.id },
|
|
481
494
|
h('svg', { width: '14', height: '14', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': '2' },
|
|
482
495
|
h('polyline', { points: '3 6 5 6 21 6' }),
|
|
@@ -584,6 +597,16 @@ class ConversationManager {
|
|
|
584
597
|
this.render();
|
|
585
598
|
}
|
|
586
599
|
|
|
600
|
+
async archiveConversation(convId) {
|
|
601
|
+
try {
|
|
602
|
+
const resp = await fetch(`${window.__BASE_URL || ''}/api/conversations/${convId}/archive`, { method: 'POST' });
|
|
603
|
+
if (!resp.ok) return;
|
|
604
|
+
this.deleteConversation(convId);
|
|
605
|
+
} catch (e) {
|
|
606
|
+
console.error('[archive] Failed:', e.message);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
587
610
|
setupWebSocketListener() {
|
|
588
611
|
window.addEventListener('ws-message', (event) => {
|
|
589
612
|
const msg = event.detail;
|