agentgui 1.0.546 → 1.0.547
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/package.json +1 -1
- package/static/js/client.js +90 -6
package/package.json
CHANGED
package/static/js/client.js
CHANGED
|
@@ -35,6 +35,16 @@ class AgentGUIClient {
|
|
|
35
35
|
this.conversationCache = new Map();
|
|
36
36
|
this.MAX_CACHE_SIZE = 10;
|
|
37
37
|
|
|
38
|
+
// Conversation list cache with TTL
|
|
39
|
+
this.conversationListCache = {
|
|
40
|
+
data: [],
|
|
41
|
+
timestamp: 0,
|
|
42
|
+
ttl: 30000 // 30 seconds
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Draft prompts per conversation
|
|
46
|
+
this.draftPrompts = new Map();
|
|
47
|
+
|
|
38
48
|
// Event handlers
|
|
39
49
|
this.eventHandlers = {};
|
|
40
50
|
|
|
@@ -155,12 +165,14 @@ class AgentGUIClient {
|
|
|
155
165
|
this.updateConnectionStatus('connected');
|
|
156
166
|
this._subscribeToConversationUpdates();
|
|
157
167
|
this._recoverMissedChunks();
|
|
168
|
+
this.updateSendButtonState();
|
|
158
169
|
this.emit('ws:connected');
|
|
159
170
|
});
|
|
160
171
|
|
|
161
172
|
this.wsManager.on('disconnected', () => {
|
|
162
173
|
console.log('WebSocket disconnected');
|
|
163
174
|
this.updateConnectionStatus('disconnected');
|
|
175
|
+
this.updateSendButtonState();
|
|
164
176
|
this.emit('ws:disconnected');
|
|
165
177
|
});
|
|
166
178
|
|
|
@@ -194,10 +206,16 @@ class AgentGUIClient {
|
|
|
194
206
|
// Switch to idle view when selecting non-streaming conversation
|
|
195
207
|
window.addEventListener('conversation-selected', (e) => {
|
|
196
208
|
const convId = e.detail.conversationId;
|
|
209
|
+
// Save draft from previous conversation before switching
|
|
210
|
+
this.saveDraftPrompt();
|
|
211
|
+
|
|
197
212
|
const isStreaming = convId && this.state.streamingConversations.has(convId);
|
|
198
213
|
if (!isStreaming && window.switchView) {
|
|
199
214
|
window.switchView('chat');
|
|
200
215
|
}
|
|
216
|
+
|
|
217
|
+
// Restore draft for new conversation after a tick
|
|
218
|
+
setTimeout(() => this.restoreDraftPrompt(convId), 0);
|
|
201
219
|
});
|
|
202
220
|
|
|
203
221
|
// Preserve controls state across tab switches
|
|
@@ -392,6 +410,19 @@ class AgentGUIClient {
|
|
|
392
410
|
this.ui.agentSelector = document.querySelector('[data-agent-selector]');
|
|
393
411
|
this.ui.modelSelector = document.querySelector('[data-model-selector]');
|
|
394
412
|
|
|
413
|
+
// Auto-save drafts on input
|
|
414
|
+
if (this.ui.messageInput) {
|
|
415
|
+
this.ui.messageInput.addEventListener('input', () => {
|
|
416
|
+
this.saveDraftPrompt();
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
// Restore draft when conversation loads
|
|
420
|
+
const currentConvId = this.state.currentConversation?.id;
|
|
421
|
+
if (currentConvId) {
|
|
422
|
+
this.restoreDraftPrompt(currentConvId);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
395
426
|
if (this.ui.cliSelector) {
|
|
396
427
|
this.ui.cliSelector.addEventListener('change', () => {
|
|
397
428
|
if (!this._agentLocked) {
|
|
@@ -2140,10 +2171,21 @@ class AgentGUIClient {
|
|
|
2140
2171
|
* Load conversations
|
|
2141
2172
|
*/
|
|
2142
2173
|
async loadConversations() {
|
|
2174
|
+
// Return cached conversations if still fresh
|
|
2175
|
+
const now = Date.now();
|
|
2176
|
+
if (this.conversationListCache.data.length > 0 &&
|
|
2177
|
+
(now - this.conversationListCache.timestamp) < this.conversationListCache.ttl) {
|
|
2178
|
+
this.state.conversations = this.conversationListCache.data;
|
|
2179
|
+
return this.conversationListCache.data;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2143
2182
|
return this._dedupedFetch('loadConversations', async () => {
|
|
2144
2183
|
try {
|
|
2145
2184
|
const { conversations } = await window.wsClient.rpc('conv.ls');
|
|
2146
2185
|
this.state.conversations = conversations;
|
|
2186
|
+
// Update cache
|
|
2187
|
+
this.conversationListCache.data = conversations;
|
|
2188
|
+
this.conversationListCache.timestamp = Date.now();
|
|
2147
2189
|
return conversations;
|
|
2148
2190
|
} catch (error) {
|
|
2149
2191
|
console.error('Failed to load conversations:', error);
|
|
@@ -2289,9 +2331,7 @@ class AgentGUIClient {
|
|
|
2289
2331
|
if (this.ui.messageInput) {
|
|
2290
2332
|
this.ui.messageInput.disabled = true;
|
|
2291
2333
|
}
|
|
2292
|
-
|
|
2293
|
-
this.ui.sendButton.disabled = true;
|
|
2294
|
-
}
|
|
2334
|
+
// Send button state managed by WebSocket connection, not streaming state
|
|
2295
2335
|
const injectBtn = document.getElementById('injectBtn');
|
|
2296
2336
|
const stopBtn = document.getElementById('stopBtn');
|
|
2297
2337
|
if (injectBtn) injectBtn.disabled = true;
|
|
@@ -2305,9 +2345,7 @@ class AgentGUIClient {
|
|
|
2305
2345
|
if (this.ui.messageInput) {
|
|
2306
2346
|
this.ui.messageInput.disabled = false;
|
|
2307
2347
|
}
|
|
2308
|
-
|
|
2309
|
-
this.ui.sendButton.disabled = false;
|
|
2310
|
-
}
|
|
2348
|
+
// Send button state managed by WebSocket connection, not streaming state
|
|
2311
2349
|
const injectBtn = document.getElementById('injectBtn');
|
|
2312
2350
|
const stopBtn = document.getElementById('stopBtn');
|
|
2313
2351
|
if (injectBtn) injectBtn.disabled = false;
|
|
@@ -2874,6 +2912,52 @@ class AgentGUIClient {
|
|
|
2874
2912
|
};
|
|
2875
2913
|
}
|
|
2876
2914
|
|
|
2915
|
+
/**
|
|
2916
|
+
* Save draft prompt for current conversation
|
|
2917
|
+
*/
|
|
2918
|
+
saveDraftPrompt() {
|
|
2919
|
+
const convId = this.state.currentConversation?.id;
|
|
2920
|
+
if (convId && this.ui.messageInput) {
|
|
2921
|
+
const draft = this.ui.messageInput.value;
|
|
2922
|
+
this.draftPrompts.set(convId, draft);
|
|
2923
|
+
if (draft) {
|
|
2924
|
+
localStorage.setItem(`draft-${convId}`, draft);
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2929
|
+
/**
|
|
2930
|
+
* Restore draft prompt for conversation
|
|
2931
|
+
*/
|
|
2932
|
+
restoreDraftPrompt(conversationId) {
|
|
2933
|
+
if (!this.ui.messageInput) return;
|
|
2934
|
+
|
|
2935
|
+
let draft = this.draftPrompts.get(conversationId) || '';
|
|
2936
|
+
if (!draft) {
|
|
2937
|
+
draft = localStorage.getItem(`draft-${conversationId}`) || '';
|
|
2938
|
+
if (draft) this.draftPrompts.set(conversationId, draft);
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
this.ui.messageInput.value = draft;
|
|
2942
|
+
}
|
|
2943
|
+
|
|
2944
|
+
/**
|
|
2945
|
+
* Clear draft for conversation
|
|
2946
|
+
*/
|
|
2947
|
+
clearDraft(conversationId) {
|
|
2948
|
+
this.draftPrompts.delete(conversationId);
|
|
2949
|
+
localStorage.removeItem(`draft-${conversationId}`);
|
|
2950
|
+
}
|
|
2951
|
+
|
|
2952
|
+
/**
|
|
2953
|
+
* Update send button state based on WebSocket connection
|
|
2954
|
+
*/
|
|
2955
|
+
updateSendButtonState() {
|
|
2956
|
+
if (this.ui.sendButton) {
|
|
2957
|
+
this.ui.sendButton.disabled = !this.wsManager.isConnected;
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2877
2961
|
/**
|
|
2878
2962
|
* Cleanup resources
|
|
2879
2963
|
*/
|