agentgui 1.0.412 → 1.0.414
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 +48 -28
- package/package.json +1 -1
- package/server.js +82 -1
- package/static/js/script-runner.js +8 -3
- package/static/js/terminal.js +132 -103
package/database.js
CHANGED
|
@@ -939,34 +939,54 @@ export const queries = {
|
|
|
939
939
|
return true;
|
|
940
940
|
},
|
|
941
941
|
|
|
942
|
-
deleteClaudeSessionFile(sessionId) {
|
|
943
|
-
try {
|
|
944
|
-
const claudeDir = path.join(os.homedir(), '.claude');
|
|
945
|
-
const projectsDir = path.join(claudeDir, 'projects');
|
|
946
|
-
|
|
947
|
-
if (!fs.existsSync(projectsDir)) {
|
|
948
|
-
return false;
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
// Search for session file in all project directories
|
|
952
|
-
const projects = fs.readdirSync(projectsDir);
|
|
953
|
-
for (const project of projects) {
|
|
954
|
-
const projectPath = path.join(projectsDir, project);
|
|
955
|
-
const sessionFile = path.join(projectPath, `${sessionId}.jsonl`);
|
|
956
|
-
|
|
957
|
-
if (fs.existsSync(sessionFile)) {
|
|
958
|
-
fs.unlinkSync(sessionFile);
|
|
959
|
-
console.log(`[deleteClaudeSessionFile] Deleted Claude session: ${sessionFile}`);
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
942
|
+
deleteClaudeSessionFile(sessionId) {
|
|
943
|
+
try {
|
|
944
|
+
const claudeDir = path.join(os.homedir(), '.claude');
|
|
945
|
+
const projectsDir = path.join(claudeDir, 'projects');
|
|
946
|
+
|
|
947
|
+
if (!fs.existsSync(projectsDir)) {
|
|
948
|
+
return false;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// Search for session file in all project directories
|
|
952
|
+
const projects = fs.readdirSync(projectsDir);
|
|
953
|
+
for (const project of projects) {
|
|
954
|
+
const projectPath = path.join(projectsDir, project);
|
|
955
|
+
const sessionFile = path.join(projectPath, `${sessionId}.jsonl`);
|
|
956
|
+
|
|
957
|
+
if (fs.existsSync(sessionFile)) {
|
|
958
|
+
fs.unlinkSync(sessionFile);
|
|
959
|
+
console.log(`[deleteClaudeSessionFile] Deleted Claude session file: ${sessionFile}`);
|
|
960
|
+
|
|
961
|
+
// Also remove the entry from sessions-index.json if it exists
|
|
962
|
+
const indexPath = path.join(projectPath, 'sessions-index.json');
|
|
963
|
+
if (fs.existsSync(indexPath)) {
|
|
964
|
+
try {
|
|
965
|
+
const indexContent = fs.readFileSync(indexPath, 'utf8');
|
|
966
|
+
const index = JSON.parse(indexContent);
|
|
967
|
+
if (index.entries && Array.isArray(index.entries)) {
|
|
968
|
+
const originalLength = index.entries.length;
|
|
969
|
+
index.entries = index.entries.filter(entry => entry.sessionId !== sessionId);
|
|
970
|
+
if (index.entries.length < originalLength) {
|
|
971
|
+
fs.writeFileSync(indexPath, JSON.stringify(index, null, 2), { encoding: 'utf8' });
|
|
972
|
+
console.log(`[deleteClaudeSessionFile] Removed session ${sessionId} from sessions-index.json in ${projectPath}`);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
} catch (indexErr) {
|
|
976
|
+
console.error(`[deleteClaudeSessionFile] Failed to update sessions-index.json in ${projectPath}:`, indexErr.message);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
return true;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
return false;
|
|
985
|
+
} catch (err) {
|
|
986
|
+
console.error(`[deleteClaudeSessionFile] Error deleting session ${sessionId}:`, err.message);
|
|
987
|
+
return false;
|
|
988
|
+
}
|
|
989
|
+
},
|
|
970
990
|
|
|
971
991
|
cleanup() {
|
|
972
992
|
const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -567,7 +567,88 @@ async function getModelsForAgent(agentId) {
|
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
-
|
|
570
|
+
// Fallback default models for agents that fail to retrieve models
|
|
571
|
+
const fallbackModels = {
|
|
572
|
+
'claude-code': [
|
|
573
|
+
{ id: 'haiku', label: 'Haiku (Default)' },
|
|
574
|
+
{ id: 'sonnet', label: 'Sonnet' },
|
|
575
|
+
{ id: 'opus', label: 'Opus' }
|
|
576
|
+
],
|
|
577
|
+
'gemini': [
|
|
578
|
+
{ id: 'gemini-1.5-pro', label: 'Gemini 1.5 Pro' },
|
|
579
|
+
{ id: 'gemini-1.5-flash', label: 'Gemini 1.5 Flash' },
|
|
580
|
+
{ id: 'gemini-2.0-pro', label: 'Gemini 2.0 Pro' },
|
|
581
|
+
{ id: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash' }
|
|
582
|
+
],
|
|
583
|
+
'opencode': [
|
|
584
|
+
{ id: 'claude-sonnet-4-20250514', label: 'Claude Sonnet 4' },
|
|
585
|
+
{ id: 'claude-haiku-4-20250514', label: 'Claude Haiku 4' },
|
|
586
|
+
{ id: 'gpt-4-turbo', label: 'GPT-4 Turbo' },
|
|
587
|
+
{ id: 'gemini-pro', label: 'Gemini Pro' }
|
|
588
|
+
],
|
|
589
|
+
'kilo': [
|
|
590
|
+
{ id: 'claude-sonnet-4', label: 'Claude Sonnet 4' },
|
|
591
|
+
{ id: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash' },
|
|
592
|
+
{ id: 'gpt-4', label: 'GPT-4' }
|
|
593
|
+
],
|
|
594
|
+
'goose': [
|
|
595
|
+
{ id: 'default', label: 'Default Model' },
|
|
596
|
+
{ id: 'goose-pro', label: 'Goose Pro' }
|
|
597
|
+
],
|
|
598
|
+
'openhands': [
|
|
599
|
+
{ id: 'default', label: 'Default Model' },
|
|
600
|
+
{ id: 'openhands-1', label: 'OpenHands 1' }
|
|
601
|
+
],
|
|
602
|
+
'augment': [
|
|
603
|
+
{ id: 'default', label: 'Default Model' },
|
|
604
|
+
{ id: 'augment-pro', label: 'Augment Pro' }
|
|
605
|
+
],
|
|
606
|
+
'cline': [
|
|
607
|
+
{ id: 'default', label: 'Default Model' },
|
|
608
|
+
{ id: 'cline-1', label: 'Cline 1' }
|
|
609
|
+
],
|
|
610
|
+
'kimi': [
|
|
611
|
+
{ id: 'default', label: 'Default Model' },
|
|
612
|
+
{ id: 'kimi-pro', label: 'Kimi Pro' }
|
|
613
|
+
],
|
|
614
|
+
'qwen': [
|
|
615
|
+
{ id: 'default', label: 'Default Model' },
|
|
616
|
+
{ id: 'qwen-7b', label: 'Qwen 7B' },
|
|
617
|
+
{ id: 'qwen-14b', label: 'Qwen 14B' }
|
|
618
|
+
],
|
|
619
|
+
'codex': [
|
|
620
|
+
{ id: 'default', label: 'Default Model' },
|
|
621
|
+
{ id: 'code-davinci-002', label: 'Code Davinci 002' },
|
|
622
|
+
{ id: 'code-cushman-001', label: 'Code Cushman 001' }
|
|
623
|
+
],
|
|
624
|
+
'mistral': [
|
|
625
|
+
{ id: 'default', label: 'Default Model' },
|
|
626
|
+
{ id: 'mistral-small', label: 'Mistral Small' },
|
|
627
|
+
{ id: 'mistral-medium', label: 'Mistral Medium' },
|
|
628
|
+
{ id: 'mistral-large', label: 'Mistral Large' }
|
|
629
|
+
],
|
|
630
|
+
'kiro': [
|
|
631
|
+
{ id: 'default', label: 'Default Model' },
|
|
632
|
+
{ id: 'kiro-1', label: 'Kiro 1' }
|
|
633
|
+
],
|
|
634
|
+
'fast-agent': [
|
|
635
|
+
{ id: 'default', label: 'Default Model' },
|
|
636
|
+
{ id: 'fast-agent-1', label: 'Fast Agent 1' }
|
|
637
|
+
]
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
if (fallbackModels[agentId]) {
|
|
641
|
+
const models = fallbackModels[agentId];
|
|
642
|
+
modelCache.set(agentId, { models, timestamp: Date.now() });
|
|
643
|
+
return models;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Default fallback for any other agent
|
|
647
|
+
const defaultFallback = [
|
|
648
|
+
{ id: 'default', label: 'Default Model' }
|
|
649
|
+
];
|
|
650
|
+
modelCache.set(agentId, { models: defaultFallback, timestamp: Date.now() });
|
|
651
|
+
return defaultFallback;
|
|
571
652
|
}
|
|
572
653
|
|
|
573
654
|
const GEMINI_SCOPES = [
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
window.addEventListener('conversation-selected', function(e) {
|
|
14
14
|
currentConversationId = e.detail.conversationId;
|
|
15
15
|
hasTerminalContent = false;
|
|
16
|
-
|
|
16
|
+
// Do not hide terminal tab; it should always be visible
|
|
17
17
|
fetchConversationAndCheckScripts();
|
|
18
18
|
});
|
|
19
19
|
|
|
@@ -61,10 +61,15 @@
|
|
|
61
61
|
window.wsClient.rpc('conv.get', { id: currentConversationId })
|
|
62
62
|
.then(function(data) {
|
|
63
63
|
currentWorkingDirectory = data.conversation?.workingDirectory || null;
|
|
64
|
-
|
|
64
|
+
// Always show the terminal tab, even without a working directory
|
|
65
|
+
showTerminalTab();
|
|
65
66
|
checkScripts();
|
|
66
67
|
})
|
|
67
|
-
.catch(function() {
|
|
68
|
+
.catch(function() {
|
|
69
|
+
// Still show terminal tab on error
|
|
70
|
+
showTerminalTab();
|
|
71
|
+
checkScripts();
|
|
72
|
+
});
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
function checkScripts() {
|
package/static/js/terminal.js
CHANGED
|
@@ -1,106 +1,135 @@
|
|
|
1
|
-
(function() {
|
|
2
|
-
var ws = null;
|
|
3
|
-
var term = null;
|
|
4
|
-
var fitAddon = null;
|
|
5
|
-
var termActive = false;
|
|
6
|
-
var BASE = window.__BASE_URL || '';
|
|
7
|
-
|
|
8
|
-
function getWsUrl() {
|
|
9
|
-
var proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
10
|
-
return proto + '//' + location.host + BASE + '/sync';
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function ensureTerm() {
|
|
14
|
-
var output = document.getElementById('terminalOutput');
|
|
15
|
-
if (!output) return false;
|
|
16
|
-
if (term) return true;
|
|
17
|
-
if (!window.Terminal || !window.FitAddon) return false;
|
|
18
|
-
|
|
19
|
-
term = new Terminal({
|
|
20
|
-
cursorBlink: true,
|
|
21
|
-
fontSize: 14,
|
|
22
|
-
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
|
23
|
-
theme: {
|
|
24
|
-
background: '#0d1117',
|
|
25
|
-
foreground: '#e6edf3',
|
|
26
|
-
cursor: '#e6edf3',
|
|
27
|
-
selectionBackground: '#3b4455'
|
|
28
|
-
},
|
|
29
|
-
convertEol: false,
|
|
30
|
-
scrollback: 5000
|
|
31
|
-
});
|
|
32
|
-
fitAddon = new FitAddon.FitAddon();
|
|
33
|
-
term.loadAddon(fitAddon);
|
|
34
|
-
output.innerHTML = '';
|
|
35
|
-
term.open(output);
|
|
36
|
-
fitAddon.fit();
|
|
37
|
-
|
|
38
|
-
term.onData(function(data) {
|
|
39
|
-
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
40
|
-
var encoded = btoa(unescape(encodeURIComponent(data)));
|
|
41
|
-
ws.send(JSON.stringify({ type: 'terminal_input', data: encoded }));
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
window.addEventListener('resize', function() {
|
|
46
|
-
if (fitAddon) try { fitAddon.fit(); } catch(_) {}
|
|
47
|
-
});
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function connectAndStart() {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
startTerminal
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
1
|
+
(function() {
|
|
2
|
+
var ws = null;
|
|
3
|
+
var term = null;
|
|
4
|
+
var fitAddon = null;
|
|
5
|
+
var termActive = false;
|
|
6
|
+
var BASE = window.__BASE_URL || '';
|
|
7
|
+
|
|
8
|
+
function getWsUrl() {
|
|
9
|
+
var proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
10
|
+
return proto + '//' + location.host + BASE + '/sync';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function ensureTerm() {
|
|
14
|
+
var output = document.getElementById('terminalOutput');
|
|
15
|
+
if (!output) return false;
|
|
16
|
+
if (term) return true;
|
|
17
|
+
if (!window.Terminal || !window.FitAddon) return false;
|
|
18
|
+
|
|
19
|
+
term = new Terminal({
|
|
20
|
+
cursorBlink: true,
|
|
21
|
+
fontSize: 14,
|
|
22
|
+
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
|
23
|
+
theme: {
|
|
24
|
+
background: '#0d1117',
|
|
25
|
+
foreground: '#e6edf3',
|
|
26
|
+
cursor: '#e6edf3',
|
|
27
|
+
selectionBackground: '#3b4455'
|
|
28
|
+
},
|
|
29
|
+
convertEol: false,
|
|
30
|
+
scrollback: 5000
|
|
31
|
+
});
|
|
32
|
+
fitAddon = new FitAddon.FitAddon();
|
|
33
|
+
term.loadAddon(fitAddon);
|
|
34
|
+
output.innerHTML = '';
|
|
35
|
+
term.open(output);
|
|
36
|
+
fitAddon.fit();
|
|
37
|
+
|
|
38
|
+
term.onData(function(data) {
|
|
39
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
40
|
+
var encoded = btoa(unescape(encodeURIComponent(data)));
|
|
41
|
+
ws.send(JSON.stringify({ type: 'terminal_input', data: encoded }));
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
window.addEventListener('resize', function() {
|
|
46
|
+
if (fitAddon) try { fitAddon.fit(); } catch(_) {}
|
|
47
|
+
});
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function connectAndStart() {
|
|
52
|
+
console.log('Terminal: Connecting to WebSocket');
|
|
53
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
54
|
+
console.log('Terminal: Sending terminal_start command');
|
|
55
|
+
ws.send(JSON.stringify({ type: 'terminal_start', cwd: window.__STARTUP_CWD || undefined }));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (ws && ws.readyState === WebSocket.CONNECTING) {
|
|
59
|
+
console.log('Terminal: WebSocket already connecting');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
ws = new WebSocket(getWsUrl());
|
|
64
|
+
ws.onopen = function() {
|
|
65
|
+
console.log('Terminal: WebSocket connected, starting terminal');
|
|
66
|
+
ws.send(JSON.stringify({ type: 'terminal_start', cwd: window.__STARTUP_CWD || undefined }));
|
|
67
|
+
};
|
|
68
|
+
ws.onmessage = function(e) {
|
|
69
|
+
try {
|
|
70
|
+
var msg = JSON.parse(e.data);
|
|
71
|
+
if (msg.type === 'terminal_output' && term) {
|
|
72
|
+
var raw = msg.encoding === 'base64'
|
|
73
|
+
? decodeURIComponent(escape(atob(msg.data)))
|
|
74
|
+
: msg.data;
|
|
75
|
+
term.write(raw);
|
|
76
|
+
} else if (msg.type === 'terminal_exit' && term) {
|
|
77
|
+
term.write('\r\n[Process exited with code ' + msg.code + ']\r\n');
|
|
78
|
+
if (termActive) setTimeout(connectAndStart, 2000);
|
|
79
|
+
} else if (msg.type === 'terminal_started') {
|
|
80
|
+
console.log('Terminal: Started successfully');
|
|
81
|
+
}
|
|
82
|
+
} catch(_) {}
|
|
83
|
+
};
|
|
84
|
+
ws.onclose = function() {
|
|
85
|
+
console.log('Terminal: WebSocket closed');
|
|
86
|
+
ws = null;
|
|
87
|
+
if (termActive) setTimeout(connectAndStart, 2000);
|
|
88
|
+
};
|
|
89
|
+
ws.onerror = function(error) {
|
|
90
|
+
console.error('Terminal: WebSocket error:', error);
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function startTerminal() {
|
|
95
|
+
console.log('Terminal: Starting terminal module');
|
|
96
|
+
if (!ensureTerm()) {
|
|
97
|
+
console.log('Terminal: Terminal not ready, retrying');
|
|
98
|
+
setTimeout(startTerminal, 200);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
termActive = true;
|
|
102
|
+
connectAndStart();
|
|
103
|
+
setTimeout(function() { if (fitAddon) try { fitAddon.fit(); } catch(_) {} }, 100);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function stopTerminal() {
|
|
107
|
+
console.log('Terminal: Stopping terminal module');
|
|
108
|
+
termActive = false;
|
|
109
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
110
|
+
ws.send(JSON.stringify({ type: 'terminal_stop' }));
|
|
111
|
+
}
|
|
112
|
+
if (ws) {
|
|
113
|
+
ws.close();
|
|
114
|
+
ws = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Check if terminal view is initially active
|
|
119
|
+
if (document.getElementById('terminalContainer') &&
|
|
120
|
+
window.getComputedStyle(document.getElementById('terminalContainer')).display !== 'none') {
|
|
121
|
+
console.log('Terminal: Terminal view initially visible, starting');
|
|
122
|
+
startTerminal();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
window.addEventListener('view-switched', function(e) {
|
|
126
|
+
if (e.detail.view === 'terminal') {
|
|
127
|
+
startTerminal();
|
|
128
|
+
} else if (termActive) {
|
|
129
|
+
stopTerminal();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
104
133
|
window.terminalModule = {
|
|
105
134
|
start: startTerminal,
|
|
106
135
|
stop: stopTerminal,
|