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 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('DELETE FROM conversations WHERE id = ?').run(id);
1064
+ prep('UPDATE conversations SET status = ?, updated_at = ? WHERE id = ?').run('deleted', Date.now(), id);
1065
1065
  });
1066
1066
 
1067
1067
  deleteStmt();
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.725",
3
+ "version": "1.0.726",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
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
@@ -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 (e) {
2726
- if (e.code === 404) {
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
- throw e;
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
- await window.wsClient.rpc('conv.full', { id: conversationId, allChunks: true });
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
- result = await window.wsClient.rpc('msg.ls.earlier', {
3080
- id: conversationId,
3081
- before: detectionState.oldestMessageId,
3082
- limit: 50
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
- result = await window.wsClient.rpc('conv.chunks.earlier', {
3086
- id: conversationId,
3087
- before: detectionState.oldestTimestamp,
3088
- limit: 500
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))) {