agentgui 1.0.725 → 1.0.727
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/database.js +1 -1
- package/lib/jsonl-watcher.js +2 -0
- package/package.json +1 -1
- package/server.js +19 -1
- package/static/js/client.js +51 -15
package/database.js
CHANGED
|
@@ -1061,7 +1061,7 @@ export const queries = {
|
|
|
1061
1061
|
}
|
|
1062
1062
|
prep('DELETE FROM sessions WHERE conversationId = ?').run(id);
|
|
1063
1063
|
prep('DELETE FROM messages WHERE conversationId = ?').run(id);
|
|
1064
|
-
prep('
|
|
1064
|
+
prep('UPDATE conversations SET status = ?, updated_at = ? WHERE id = ?').run('deleted', Date.now(), id);
|
|
1065
1065
|
});
|
|
1066
1066
|
|
|
1067
1067
|
deleteStmt();
|
package/lib/jsonl-watcher.js
CHANGED
|
@@ -23,6 +23,8 @@ export class JsonlWatcher {
|
|
|
23
23
|
start() {
|
|
24
24
|
if (!fs.existsSync(PROJECTS_DIR)) return;
|
|
25
25
|
this._scanDir(PROJECTS_DIR, 0);
|
|
26
|
+
for (const [fp, t] of this._timers.entries()) { clearTimeout(t); this._timers.delete(fp); this._read(fp); }
|
|
27
|
+
for (const sid of [...this._streaming]) this._endStreaming(this._convMap.get(sid), sid);
|
|
26
28
|
try {
|
|
27
29
|
this._watcher = fs.watch(PROJECTS_DIR, { recursive: true }, (_, f) => {
|
|
28
30
|
if (f && f.endsWith('.jsonl')) this._debounce(path.join(PROJECTS_DIR, f));
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1370,6 +1370,24 @@ const server = http.createServer(async (req, res) => {
|
|
|
1370
1370
|
if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; }
|
|
1371
1371
|
if (req.headers.upgrade && req.headers.upgrade.toLowerCase() === 'websocket') return;
|
|
1372
1372
|
|
|
1373
|
+
const _pwd = process.env.PASSWORD;
|
|
1374
|
+
if (_pwd) {
|
|
1375
|
+
const _auth = req.headers['authorization'] || '';
|
|
1376
|
+
let _ok = false;
|
|
1377
|
+
if (_auth.startsWith('Basic ')) {
|
|
1378
|
+
try {
|
|
1379
|
+
const _decoded = Buffer.from(_auth.slice(6), 'base64').toString('utf8');
|
|
1380
|
+
const _ci = _decoded.indexOf(':');
|
|
1381
|
+
if (_ci !== -1) _ok = _decoded.slice(_ci + 1) === _pwd;
|
|
1382
|
+
} catch (_) {}
|
|
1383
|
+
}
|
|
1384
|
+
if (!_ok) {
|
|
1385
|
+
res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="agentgui"' });
|
|
1386
|
+
res.end('Unauthorized');
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1373
1391
|
const pathOnly = req.url.split('?')[0];
|
|
1374
1392
|
|
|
1375
1393
|
// Route file upload and fsbrowse requests through Express sub-app
|
|
@@ -1488,7 +1506,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
1488
1506
|
if (messagesMatch) {
|
|
1489
1507
|
if (req.method === 'GET') {
|
|
1490
1508
|
const url = new URL(req.url, 'http://localhost');
|
|
1491
|
-
const limit = Math.min(parseInt(url.searchParams.get('limit') || '50'),
|
|
1509
|
+
const limit = Math.min(parseInt(url.searchParams.get('limit') || '50'), 500);
|
|
1492
1510
|
const offset = Math.max(parseInt(url.searchParams.get('offset') || '0'), 0);
|
|
1493
1511
|
const result = queries.getPaginatedMessages(messagesMatch[1], limit, offset);
|
|
1494
1512
|
sendJSON(req, res, 200, result);
|
package/static/js/client.js
CHANGED
|
@@ -2722,13 +2722,12 @@ class AgentGUIClient {
|
|
|
2722
2722
|
try {
|
|
2723
2723
|
fullData = await window.wsClient.rpc('conv.full', { id: conversationId, chunkLimit: 50 });
|
|
2724
2724
|
if (convSignal.aborted) return;
|
|
2725
|
-
} catch (
|
|
2726
|
-
if (
|
|
2725
|
+
} catch (wsErr) {
|
|
2726
|
+
if (wsErr.code === 404) {
|
|
2727
2727
|
console.warn('Conversation no longer exists:', conversationId);
|
|
2728
2728
|
window.ConversationState?.clear('conversation_not_found');
|
|
2729
2729
|
this.state.currentConversation = null;
|
|
2730
2730
|
if (window.conversationManager) window.conversationManager.loadConversations();
|
|
2731
|
-
// Resume from last successful conversation if available, or fall back to any available conversation
|
|
2732
2731
|
const fallbackConv = prevConversationId ? prevConversationId : availableFallback?.id;
|
|
2733
2732
|
if (fallbackConv && fallbackConv !== conversationId) {
|
|
2734
2733
|
console.log('Resuming from fallback conversation:', fallbackConv);
|
|
@@ -2741,7 +2740,28 @@ class AgentGUIClient {
|
|
|
2741
2740
|
}
|
|
2742
2741
|
return;
|
|
2743
2742
|
}
|
|
2744
|
-
|
|
2743
|
+
try {
|
|
2744
|
+
const base = window.__BASE_URL || '';
|
|
2745
|
+
const [convRes, chunksRes, msgsRes] = await Promise.all([
|
|
2746
|
+
fetch(`${base}/api/conversations/${conversationId}`),
|
|
2747
|
+
fetch(`${base}/api/conversations/${conversationId}/chunks`),
|
|
2748
|
+
fetch(`${base}/api/conversations/${conversationId}/messages?limit=500`)
|
|
2749
|
+
]);
|
|
2750
|
+
const convData = await convRes.json();
|
|
2751
|
+
const chunksData = await chunksRes.json();
|
|
2752
|
+
const msgsData = await msgsRes.json();
|
|
2753
|
+
fullData = {
|
|
2754
|
+
conversation: convData.conversation,
|
|
2755
|
+
isActivelyStreaming: false,
|
|
2756
|
+
latestSession: null,
|
|
2757
|
+
chunks: chunksData.chunks || [],
|
|
2758
|
+
totalChunks: (chunksData.chunks || []).length,
|
|
2759
|
+
messages: msgsData.messages || []
|
|
2760
|
+
};
|
|
2761
|
+
if (convSignal.aborted) return;
|
|
2762
|
+
} catch (restErr) {
|
|
2763
|
+
throw wsErr;
|
|
2764
|
+
}
|
|
2745
2765
|
}
|
|
2746
2766
|
if (convSignal.aborted) return;
|
|
2747
2767
|
const { conversation, isActivelyStreaming, latestSession, chunks: rawChunks, totalChunks, messages: allMessages } = fullData;
|
|
@@ -2813,7 +2833,9 @@ class AgentGUIClient {
|
|
|
2813
2833
|
loadMoreBtn.disabled = true;
|
|
2814
2834
|
loadMoreBtn.textContent = 'Loading...';
|
|
2815
2835
|
try {
|
|
2816
|
-
|
|
2836
|
+
try {
|
|
2837
|
+
await window.wsClient.rpc('conv.full', { id: conversationId, allChunks: true });
|
|
2838
|
+
} catch (wsErr) {}
|
|
2817
2839
|
this.invalidateCache(conversationId);
|
|
2818
2840
|
await this.loadConversationMessages(conversationId);
|
|
2819
2841
|
} catch (e) {
|
|
@@ -3076,17 +3098,31 @@ class AgentGUIClient {
|
|
|
3076
3098
|
|
|
3077
3099
|
let result;
|
|
3078
3100
|
if (detectionState.oldestMessageId) {
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3101
|
+
try {
|
|
3102
|
+
result = await window.wsClient.rpc('msg.ls.earlier', {
|
|
3103
|
+
id: conversationId,
|
|
3104
|
+
before: detectionState.oldestMessageId,
|
|
3105
|
+
limit: 50
|
|
3106
|
+
});
|
|
3107
|
+
} catch (e) {
|
|
3108
|
+
const base = window.__BASE_URL || '';
|
|
3109
|
+
const r = await fetch(`${base}/api/conversations/${conversationId}/messages?limit=50`);
|
|
3110
|
+
const d = await r.json();
|
|
3111
|
+
result = { messages: d.messages || [] };
|
|
3112
|
+
}
|
|
3084
3113
|
} else if (detectionState.oldestTimestamp > 0) {
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3114
|
+
try {
|
|
3115
|
+
result = await window.wsClient.rpc('conv.chunks.earlier', {
|
|
3116
|
+
id: conversationId,
|
|
3117
|
+
before: detectionState.oldestTimestamp,
|
|
3118
|
+
limit: 500
|
|
3119
|
+
});
|
|
3120
|
+
} catch (e) {
|
|
3121
|
+
const base = window.__BASE_URL || '';
|
|
3122
|
+
const r = await fetch(`${base}/api/conversations/${conversationId}/chunks`);
|
|
3123
|
+
const d = await r.json();
|
|
3124
|
+
result = { chunks: d.chunks || [] };
|
|
3125
|
+
}
|
|
3090
3126
|
}
|
|
3091
3127
|
|
|
3092
3128
|
if (result && ((result.messages && result.messages.length > 0) || (result.chunks && result.chunks.length > 0))) {
|