agentgui 1.0.659 → 1.0.661
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/ws-handlers-conv.js +3 -1
- package/package.json +1 -1
- package/server.js +6 -4
- package/static/index.html +1 -1
- package/static/js/client.js +13 -0
- package/static/js/conversations.js +20 -4
package/lib/ws-handlers-conv.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import os from 'os';
|
|
2
3
|
|
|
3
4
|
function fail(code, message) { const e = new Error(message); e.code = code; throw e; }
|
|
4
5
|
function notFound(msg = 'Not found') { fail(404, msg); }
|
|
6
|
+
function expandTilde(p) { return p && p.startsWith('~') ? path.join(os.homedir(), p.slice(1)) : p; }
|
|
5
7
|
|
|
6
8
|
export function register(router, deps) {
|
|
7
9
|
const { queries, activeExecutions, messageQueues, rateLimitState,
|
|
@@ -14,7 +16,7 @@ export function register(router, deps) {
|
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
router.handle('conv.new', (p) => {
|
|
17
|
-
const wd = p.workingDirectory ? path.resolve(p.workingDirectory) : null;
|
|
19
|
+
const wd = p.workingDirectory ? path.resolve(expandTilde(p.workingDirectory)) : null;
|
|
18
20
|
const conv = queries.createConversation(p.agentId, p.title, wd, p.model || null, p.subAgent || null);
|
|
19
21
|
queries.createEvent('conversation.created', { agentId: p.agentId, workingDirectory: conv.workingDirectory, model: conv.model, subAgent: conv.subAgent }, conv.id);
|
|
20
22
|
broadcastSync({ type: 'conversation_created', conversation: conv });
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1153,8 +1153,9 @@ const server = http.createServer(async (req, res) => {
|
|
|
1153
1153
|
|
|
1154
1154
|
if (pathOnly === '/api/conversations' && req.method === 'POST') {
|
|
1155
1155
|
const body = await parseBody(req);
|
|
1156
|
-
// Normalize working directory to avoid Windows path issues
|
|
1157
|
-
const
|
|
1156
|
+
// Normalize working directory to avoid Windows path issues; expand ~ to home
|
|
1157
|
+
const expandTilde = p => p && p.startsWith('~') ? path.join(os.homedir(), p.slice(1)) : p;
|
|
1158
|
+
const normalizedWorkingDir = body.workingDirectory ? path.resolve(expandTilde(body.workingDirectory)) : null;
|
|
1158
1159
|
const conversation = queries.createConversation(body.agentId, body.title, normalizedWorkingDir, body.model || null);
|
|
1159
1160
|
queries.createEvent('conversation.created', { agentId: body.agentId, workingDirectory: conversation.workingDirectory, model: conversation.model }, conversation.id);
|
|
1160
1161
|
broadcastSync({ type: 'conversation_created', conversation });
|
|
@@ -1181,9 +1182,10 @@ const server = http.createServer(async (req, res) => {
|
|
|
1181
1182
|
|
|
1182
1183
|
if (req.method === 'POST' || req.method === 'PUT') {
|
|
1183
1184
|
const body = await parseBody(req);
|
|
1184
|
-
// Normalize working directory if present to avoid Windows path issues
|
|
1185
|
+
// Normalize working directory if present to avoid Windows path issues; expand ~ to home
|
|
1185
1186
|
if (body.workingDirectory) {
|
|
1186
|
-
|
|
1187
|
+
const expandTilde = p => p && p.startsWith('~') ? path.join(os.homedir(), p.slice(1)) : p;
|
|
1188
|
+
body.workingDirectory = path.resolve(expandTilde(body.workingDirectory));
|
|
1187
1189
|
}
|
|
1188
1190
|
const conv = queries.updateConversation(convMatch[1], body);
|
|
1189
1191
|
if (!conv) { sendJSON(req, res, 404, { error: 'Conversation not found' }); return; }
|
package/static/index.html
CHANGED
|
@@ -3047,7 +3047,7 @@
|
|
|
3047
3047
|
<button class="clone-cancel-btn" id="cloneCancelBtn" title="Cancel">×</button>
|
|
3048
3048
|
</div>
|
|
3049
3049
|
<ul class="sidebar-list" data-conversation-list>
|
|
3050
|
-
<li class="sidebar-empty" data-conversation-empty>
|
|
3050
|
+
<li class="sidebar-empty" data-conversation-empty>Loading...</li>
|
|
3051
3051
|
</ul>
|
|
3052
3052
|
<!-- PM2 Monitor Panel: hidden until active processes detected -->
|
|
3053
3053
|
<div class="pm2-monitor-panel" id="pm2MonitorPanel" style="display:none">
|
package/static/js/client.js
CHANGED
|
@@ -1140,14 +1140,25 @@ class AgentGUIClient {
|
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
1142
1142
|
const sessionId = data.sessionId || this.state.currentSession?.id;
|
|
1143
|
+
|
|
1144
|
+
// Remove all orphaned streaming indicators (handles case where session never started)
|
|
1145
|
+
const outputEl2 = document.getElementById('output');
|
|
1146
|
+
if (outputEl2) {
|
|
1147
|
+
outputEl2.querySelectorAll('.streaming-indicator').forEach(ind => {
|
|
1148
|
+
ind.innerHTML = `<span style="color:var(--color-error);">Error: ${this.escapeHtml(data.error || 'Unknown error')}</span>`;
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1143
1152
|
const streamingEl = document.getElementById(`streaming-${sessionId}`);
|
|
1144
1153
|
if (streamingEl) {
|
|
1154
|
+
streamingEl.classList.remove('streaming-message');
|
|
1145
1155
|
const indicator = streamingEl.querySelector('.streaming-indicator');
|
|
1146
1156
|
if (indicator) {
|
|
1147
1157
|
indicator.innerHTML = `<span style="color:var(--color-error);">Error: ${this.escapeHtml(data.error || 'Unknown error')}</span>`;
|
|
1148
1158
|
}
|
|
1149
1159
|
}
|
|
1150
1160
|
|
|
1161
|
+
this.unlockAgentAndModel();
|
|
1151
1162
|
this.enableControls();
|
|
1152
1163
|
this.emit('streaming:error', data);
|
|
1153
1164
|
}
|
|
@@ -1306,6 +1317,7 @@ class AgentGUIClient {
|
|
|
1306
1317
|
}
|
|
1307
1318
|
}
|
|
1308
1319
|
|
|
1320
|
+
outputEl.querySelectorAll('p.text-secondary').forEach(p => p.remove());
|
|
1309
1321
|
const messageHtml = `
|
|
1310
1322
|
<div class="message message-${data.message.role}" data-msg-id="${data.message.id}">
|
|
1311
1323
|
<div class="message-role">${data.message.role.charAt(0).toUpperCase() + data.message.role.slice(1)}</div>
|
|
@@ -1723,6 +1735,7 @@ class AgentGUIClient {
|
|
|
1723
1735
|
_showOptimisticMessage(pendingId, content) {
|
|
1724
1736
|
const messagesEl = document.querySelector('.conversation-messages');
|
|
1725
1737
|
if (!messagesEl) return;
|
|
1738
|
+
messagesEl.querySelectorAll('p.text-secondary').forEach(p => p.remove());
|
|
1726
1739
|
const div = document.createElement('div');
|
|
1727
1740
|
div.className = 'message message-user message-sending';
|
|
1728
1741
|
div.id = pendingId;
|
|
@@ -46,13 +46,14 @@ class ConversationManager {
|
|
|
46
46
|
async init() {
|
|
47
47
|
this.newBtn?.addEventListener('click', () => this.openFolderBrowser());
|
|
48
48
|
this.setupDelegatedListeners();
|
|
49
|
-
|
|
50
|
-
this.loadConversations();
|
|
49
|
+
this.showLoading();
|
|
51
50
|
this.setupWebSocketListener();
|
|
52
51
|
this.setupFolderBrowser();
|
|
53
52
|
this.setupCloneUI();
|
|
54
53
|
this.setupDeleteAllButton();
|
|
55
54
|
|
|
55
|
+
await Promise.all([this.loadAgents(), this.loadConversations()]);
|
|
56
|
+
|
|
56
57
|
this._pollInterval = setInterval(() => this.loadConversations(), 30000);
|
|
57
58
|
|
|
58
59
|
window.addEventListener('beforeunload', () => this.destroy());
|
|
@@ -67,7 +68,10 @@ class ConversationManager {
|
|
|
67
68
|
|
|
68
69
|
async loadAgents() {
|
|
69
70
|
try {
|
|
70
|
-
const
|
|
71
|
+
const base = window.__BASE_URL || '/gm';
|
|
72
|
+
const res = await fetch(base + '/api/agents');
|
|
73
|
+
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
74
|
+
const data = await res.json();
|
|
71
75
|
for (const agent of data.agents || []) {
|
|
72
76
|
this.agents.set(agent.id, agent);
|
|
73
77
|
}
|
|
@@ -409,9 +413,21 @@ class ConversationManager {
|
|
|
409
413
|
}
|
|
410
414
|
}
|
|
411
415
|
|
|
416
|
+
showLoading() {
|
|
417
|
+
if (!this.listEl) return;
|
|
418
|
+
this.listEl.innerHTML = '';
|
|
419
|
+
if (this.emptyEl) {
|
|
420
|
+
this.emptyEl.textContent = 'Loading...';
|
|
421
|
+
this.emptyEl.style.display = 'block';
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
412
425
|
async loadConversations() {
|
|
413
426
|
try {
|
|
414
|
-
const
|
|
427
|
+
const base = window.__BASE_URL || '/gm';
|
|
428
|
+
const res = await fetch(base + '/api/conversations');
|
|
429
|
+
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
430
|
+
const data = await res.json();
|
|
415
431
|
const convList = data.conversations || [];
|
|
416
432
|
|
|
417
433
|
this._updateConversations(convList, 'poll');
|