agentgui 1.0.725 → 1.0.726
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 +18 -0
- package/static/js/client.js +55 -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
|
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,27 @@ class AgentGUIClient {
|
|
|
2741
2740
|
}
|
|
2742
2741
|
return;
|
|
2743
2742
|
}
|
|
2744
|
-
|
|
2743
|
+
try {
|
|
2744
|
+
const [convRes, chunksRes, msgsRes] = await Promise.all([
|
|
2745
|
+
fetch(`/gm/api/conversations/${conversationId}`),
|
|
2746
|
+
fetch(`/gm/api/conversations/${conversationId}/chunks`),
|
|
2747
|
+
fetch(`/gm/api/conversations/${conversationId}/messages?limit=500`)
|
|
2748
|
+
]);
|
|
2749
|
+
const convData = await convRes.json();
|
|
2750
|
+
const chunksData = await chunksRes.json();
|
|
2751
|
+
const msgsData = await msgsRes.json();
|
|
2752
|
+
fullData = {
|
|
2753
|
+
conversation: convData.conversation,
|
|
2754
|
+
isActivelyStreaming: false,
|
|
2755
|
+
latestSession: null,
|
|
2756
|
+
chunks: chunksData.chunks || [],
|
|
2757
|
+
totalChunks: (chunksData.chunks || []).length,
|
|
2758
|
+
messages: msgsData.messages || []
|
|
2759
|
+
};
|
|
2760
|
+
if (convSignal.aborted) return;
|
|
2761
|
+
} catch (restErr) {
|
|
2762
|
+
throw wsErr;
|
|
2763
|
+
}
|
|
2745
2764
|
}
|
|
2746
2765
|
if (convSignal.aborted) return;
|
|
2747
2766
|
const { conversation, isActivelyStreaming, latestSession, chunks: rawChunks, totalChunks, messages: allMessages } = fullData;
|
|
@@ -2813,7 +2832,16 @@ class AgentGUIClient {
|
|
|
2813
2832
|
loadMoreBtn.disabled = true;
|
|
2814
2833
|
loadMoreBtn.textContent = 'Loading...';
|
|
2815
2834
|
try {
|
|
2816
|
-
|
|
2835
|
+
try {
|
|
2836
|
+
await window.wsClient.rpc('conv.full', { id: conversationId, allChunks: true });
|
|
2837
|
+
} catch (wsErr) {
|
|
2838
|
+
const [chunksRes, msgsRes] = await Promise.all([
|
|
2839
|
+
fetch(`/gm/api/conversations/${conversationId}/chunks`),
|
|
2840
|
+
fetch(`/gm/api/conversations/${conversationId}/messages?limit=500`)
|
|
2841
|
+
]);
|
|
2842
|
+
const chunksData = await chunksRes.json();
|
|
2843
|
+
const msgsData = await msgsRes.json();
|
|
2844
|
+
}
|
|
2817
2845
|
this.invalidateCache(conversationId);
|
|
2818
2846
|
await this.loadConversationMessages(conversationId);
|
|
2819
2847
|
} catch (e) {
|
|
@@ -3076,17 +3104,29 @@ class AgentGUIClient {
|
|
|
3076
3104
|
|
|
3077
3105
|
let result;
|
|
3078
3106
|
if (detectionState.oldestMessageId) {
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3107
|
+
try {
|
|
3108
|
+
result = await window.wsClient.rpc('msg.ls.earlier', {
|
|
3109
|
+
id: conversationId,
|
|
3110
|
+
before: detectionState.oldestMessageId,
|
|
3111
|
+
limit: 50
|
|
3112
|
+
});
|
|
3113
|
+
} catch (e) {
|
|
3114
|
+
const r = await fetch(`/gm/api/conversations/${conversationId}/messages?limit=50`);
|
|
3115
|
+
const d = await r.json();
|
|
3116
|
+
result = { messages: d.messages || [] };
|
|
3117
|
+
}
|
|
3084
3118
|
} else if (detectionState.oldestTimestamp > 0) {
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3119
|
+
try {
|
|
3120
|
+
result = await window.wsClient.rpc('conv.chunks.earlier', {
|
|
3121
|
+
id: conversationId,
|
|
3122
|
+
before: detectionState.oldestTimestamp,
|
|
3123
|
+
limit: 500
|
|
3124
|
+
});
|
|
3125
|
+
} catch (e) {
|
|
3126
|
+
const r = await fetch(`/gm/api/conversations/${conversationId}/chunks`);
|
|
3127
|
+
const d = await r.json();
|
|
3128
|
+
result = { chunks: d.chunks || [] };
|
|
3129
|
+
}
|
|
3090
3130
|
}
|
|
3091
3131
|
|
|
3092
3132
|
if (result && ((result.messages && result.messages.length > 0) || (result.chunks && result.chunks.length > 0))) {
|