agentgui 1.0.743 → 1.0.744
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 +8 -5
- package/package.json +1 -1
- package/server.js +9 -0
- package/static/js/client.js +12 -0
- package/static/theme.js +7 -4
package/database.js
CHANGED
|
@@ -421,7 +421,8 @@ try {
|
|
|
421
421
|
claudeSessionId: 'TEXT',
|
|
422
422
|
isStreaming: 'INTEGER DEFAULT 0',
|
|
423
423
|
model: 'TEXT',
|
|
424
|
-
subAgent: 'TEXT'
|
|
424
|
+
subAgent: 'TEXT',
|
|
425
|
+
pinned: 'INTEGER DEFAULT 0'
|
|
425
426
|
};
|
|
426
427
|
|
|
427
428
|
let addedColumns = false;
|
|
@@ -644,13 +645,13 @@ export const queries = {
|
|
|
644
645
|
|
|
645
646
|
getConversationsList() {
|
|
646
647
|
const stmt = prep(
|
|
647
|
-
'SELECT id, agentId, title, agentType, created_at, updated_at, messageCount, workingDirectory, isStreaming, model, subAgent FROM conversations WHERE status != ? ORDER BY updated_at DESC'
|
|
648
|
+
'SELECT id, agentId, title, agentType, created_at, updated_at, messageCount, workingDirectory, isStreaming, model, subAgent, pinned FROM conversations WHERE status != ? ORDER BY pinned DESC, updated_at DESC'
|
|
648
649
|
);
|
|
649
650
|
return stmt.all('deleted');
|
|
650
651
|
},
|
|
651
652
|
|
|
652
653
|
getConversations() {
|
|
653
|
-
const stmt = prep('SELECT * FROM conversations WHERE status != ? ORDER BY updated_at DESC');
|
|
654
|
+
const stmt = prep('SELECT * FROM conversations WHERE status != ? ORDER BY pinned DESC, updated_at DESC');
|
|
654
655
|
return stmt.all('deleted');
|
|
655
656
|
},
|
|
656
657
|
|
|
@@ -665,11 +666,12 @@ export const queries = {
|
|
|
665
666
|
const agentType = data.agentType !== undefined ? data.agentType : conv.agentType;
|
|
666
667
|
const model = data.model !== undefined ? data.model : conv.model;
|
|
667
668
|
const subAgent = data.subAgent !== undefined ? data.subAgent : conv.subAgent;
|
|
669
|
+
const pinned = data.pinned !== undefined ? (data.pinned ? 1 : 0) : (conv.pinned || 0);
|
|
668
670
|
|
|
669
671
|
const stmt = prep(
|
|
670
|
-
`UPDATE conversations SET title = ?, status = ?, agentId = ?, agentType = ?, model = ?, subAgent = ?, updated_at = ? WHERE id = ?`
|
|
672
|
+
`UPDATE conversations SET title = ?, status = ?, agentId = ?, agentType = ?, model = ?, subAgent = ?, pinned = ?, updated_at = ? WHERE id = ?`
|
|
671
673
|
);
|
|
672
|
-
stmt.run(title, status, agentId, agentType, model, subAgent, now, id);
|
|
674
|
+
stmt.run(title, status, agentId, agentType, model, subAgent, pinned, now, id);
|
|
673
675
|
|
|
674
676
|
return {
|
|
675
677
|
...conv,
|
|
@@ -679,6 +681,7 @@ export const queries = {
|
|
|
679
681
|
agentType,
|
|
680
682
|
model,
|
|
681
683
|
subAgent,
|
|
684
|
+
pinned,
|
|
682
685
|
updated_at: now
|
|
683
686
|
};
|
|
684
687
|
},
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -2107,6 +2107,15 @@ const server = http.createServer(async (req, res) => {
|
|
|
2107
2107
|
return;
|
|
2108
2108
|
}
|
|
2109
2109
|
|
|
2110
|
+
if (pathOnly === '/api/backup' && req.method === 'GET') {
|
|
2111
|
+
const dbPath = path.join(os.homedir(), '.gmgui', 'data.db');
|
|
2112
|
+
if (!fs.existsSync(dbPath)) { sendJSON(req, res, 404, { error: 'Database not found' }); return; }
|
|
2113
|
+
const stat = fs.statSync(dbPath);
|
|
2114
|
+
res.writeHead(200, { 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="agentgui-backup.db"', 'Content-Length': stat.size });
|
|
2115
|
+
fs.createReadStream(dbPath).pipe(res);
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2110
2119
|
if (pathOnly === '/api/debug/machines' && req.method === 'GET' && process.env.DEBUG) {
|
|
2111
2120
|
const toolSnap = {};
|
|
2112
2121
|
for (const [id, actor] of toolInstallMachine.getMachineActors()) {
|
package/static/js/client.js
CHANGED
|
@@ -914,6 +914,16 @@ class AgentGUIClient {
|
|
|
914
914
|
this.scrollToBottom(true);
|
|
915
915
|
}
|
|
916
916
|
|
|
917
|
+
this._streamStartedAt = Date.now();
|
|
918
|
+
if (this._elapsedTimer) clearInterval(this._elapsedTimer);
|
|
919
|
+
this._elapsedTimer = setInterval(() => {
|
|
920
|
+
const label = streamingDiv?.querySelector('.streaming-indicator-label');
|
|
921
|
+
if (label) {
|
|
922
|
+
const sec = ((Date.now() - this._streamStartedAt) / 1000) | 0;
|
|
923
|
+
label.textContent = sec < 60 ? sec + 's' : Math.floor(sec / 60) + 'm ' + (sec % 60) + 's';
|
|
924
|
+
}
|
|
925
|
+
}, 1000);
|
|
926
|
+
|
|
917
927
|
// Reset rendered block seq tracker for this session
|
|
918
928
|
this._renderedSeqs[data.sessionId] = new Set();
|
|
919
929
|
|
|
@@ -1116,6 +1126,7 @@ class AgentGUIClient {
|
|
|
1116
1126
|
console.error('Streaming error:', data);
|
|
1117
1127
|
if (window.promptMachineAPI) window.promptMachineAPI.send({ type: 'READY' });
|
|
1118
1128
|
this._clearThinkingCountdown();
|
|
1129
|
+
if (this._elapsedTimer) { clearInterval(this._elapsedTimer); this._elapsedTimer = null; }
|
|
1119
1130
|
|
|
1120
1131
|
// Hide stop and inject buttons on error
|
|
1121
1132
|
if (this.ui.stopButton) this.ui.stopButton.classList.remove('visible');
|
|
@@ -1194,6 +1205,7 @@ class AgentGUIClient {
|
|
|
1194
1205
|
this._dbg('Streaming completed:', data);
|
|
1195
1206
|
if (window.promptMachineAPI) window.promptMachineAPI.send({ type: 'READY' });
|
|
1196
1207
|
this._clearThinkingCountdown();
|
|
1208
|
+
if (this._elapsedTimer) { clearInterval(this._elapsedTimer); this._elapsedTimer = null; }
|
|
1197
1209
|
|
|
1198
1210
|
const conversationId = data.conversationId || this.state.currentSession?.conversationId;
|
|
1199
1211
|
if (conversationId) this.invalidateCache(conversationId);
|
package/static/theme.js
CHANGED
|
@@ -53,15 +53,18 @@ class ThemeManager {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
toggleTheme() {
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
this.setTheme(
|
|
56
|
+
const saved = localStorage.getItem(this.THEME_KEY);
|
|
57
|
+
const current = document.documentElement.getAttribute('data-theme') || 'light';
|
|
58
|
+
if (saved === 'dark') { this.setTheme('light'); }
|
|
59
|
+
else if (saved === 'light') { localStorage.removeItem(this.THEME_KEY); this.setTheme(this.SYSTEM_DARK_MODE.matches ? 'dark' : 'light'); this.updateThemeIcon('auto'); return; }
|
|
60
|
+
else { this.setTheme('dark'); }
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
updateThemeIcon(theme) {
|
|
62
64
|
const icon = document.querySelector('.theme-icon');
|
|
63
65
|
if (icon) {
|
|
64
|
-
icon.textContent = theme === 'dark' ? '☀️' : '🌙';
|
|
66
|
+
icon.textContent = theme === 'auto' ? '⚙️' : theme === 'dark' ? '☀️' : '🌙';
|
|
67
|
+
icon.title = theme === 'auto' ? 'Theme: Auto (follows OS)' : theme === 'dark' ? 'Theme: Dark' : 'Theme: Light';
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
|