agentgui 1.0.419 → 1.0.420
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/lib/ws-handlers-session.js +36 -13
- package/package.json +1 -1
- package/static/index.html +71 -69
- package/static/js/client.js +69 -22
|
@@ -97,19 +97,42 @@ export function register(router, deps) {
|
|
|
97
97
|
return data;
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
router.handle('agent.ls', () => {
|
|
101
|
-
// Get local agents only (avoid external HTTP calls in WebSocket to prevent recursion)
|
|
102
|
-
const localAgents = discoveredAgents.map(agent => ({
|
|
103
|
-
id: agent.id,
|
|
104
|
-
name: agent.name,
|
|
105
|
-
icon: agent.icon,
|
|
106
|
-
path: agent.path,
|
|
107
|
-
protocol: agent.protocol || 'unknown',
|
|
108
|
-
description: agent.description || '',
|
|
109
|
-
status: 'available'
|
|
110
|
-
}));
|
|
111
|
-
|
|
112
|
-
return { agents: localAgents };
|
|
100
|
+
router.handle('agent.ls', () => {
|
|
101
|
+
// Get local agents only (avoid external HTTP calls in WebSocket to prevent recursion)
|
|
102
|
+
const localAgents = discoveredAgents.map(agent => ({
|
|
103
|
+
id: agent.id,
|
|
104
|
+
name: agent.name,
|
|
105
|
+
icon: agent.icon,
|
|
106
|
+
path: agent.path,
|
|
107
|
+
protocol: agent.protocol || 'unknown',
|
|
108
|
+
description: agent.description || '',
|
|
109
|
+
status: 'available'
|
|
110
|
+
}));
|
|
111
|
+
|
|
112
|
+
return { agents: localAgents };
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
router.handle('agent.subagents', async (p) => {
|
|
116
|
+
const agent = discoveredAgents.find(x => x.id === p.id);
|
|
117
|
+
if (!agent) return { subAgents: [] };
|
|
118
|
+
try {
|
|
119
|
+
const port = agent.acpPort || 8080;
|
|
120
|
+
const res = await fetch(`http://localhost:${port}/agents/search`, {
|
|
121
|
+
method: 'POST',
|
|
122
|
+
headers: { 'Content-Type': 'application/json' },
|
|
123
|
+
body: JSON.stringify({}),
|
|
124
|
+
signal: AbortSignal.timeout(3000)
|
|
125
|
+
});
|
|
126
|
+
if (!res.ok) return { subAgents: [] };
|
|
127
|
+
const data = await res.json();
|
|
128
|
+
const subAgents = (data.agents || []).map(a => ({
|
|
129
|
+
id: a.agent_id || a.id,
|
|
130
|
+
name: a.metadata?.ref?.name || a.name || a.agent_id || a.id
|
|
131
|
+
}));
|
|
132
|
+
return { subAgents };
|
|
133
|
+
} catch (_) {
|
|
134
|
+
return { subAgents: [] };
|
|
135
|
+
}
|
|
113
136
|
});
|
|
114
137
|
|
|
115
138
|
router.handle('agent.get', (p) => {
|
package/package.json
CHANGED
package/static/index.html
CHANGED
|
@@ -491,10 +491,10 @@
|
|
|
491
491
|
color: var(--color-text-secondary); user-select: none;
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
-
.terminal-container {
|
|
495
|
-
flex: 1; display: flex; flex-direction: column; overflow: hidden; background: #1e1e1e; min-height: 0;
|
|
496
|
-
}
|
|
497
|
-
.terminal-output { flex: 1; overflow: hidden; position: relative; min-height: 0; }
|
|
494
|
+
.terminal-container {
|
|
495
|
+
flex: 1; display: flex; flex-direction: column; overflow: hidden; background: #1e1e1e; min-height: 0;
|
|
496
|
+
}
|
|
497
|
+
.terminal-output { flex: 1; overflow: hidden; position: relative; min-height: 0; }
|
|
498
498
|
|
|
499
499
|
/* --- View toggle bar --- */
|
|
500
500
|
.view-toggle-bar {
|
|
@@ -804,29 +804,29 @@
|
|
|
804
804
|
align-items: flex-end;
|
|
805
805
|
}
|
|
806
806
|
|
|
807
|
-
.agent-selector {
|
|
808
|
-
padding: 0.5rem;
|
|
809
|
-
border: none;
|
|
810
|
-
border-radius: 0.375rem;
|
|
811
|
-
background-color: var(--color-bg-secondary);
|
|
812
|
-
color: var(--color-text-primary);
|
|
813
|
-
font-size: 0.8rem;
|
|
814
|
-
cursor: pointer;
|
|
815
|
-
flex-shrink: 0;
|
|
816
|
-
width: auto;
|
|
817
|
-
min-width: 80px;
|
|
818
|
-
max-width: 200px;
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
.agent-selector:disabled, .model-selector:disabled {
|
|
826
|
-
opacity: 0.5;
|
|
827
|
-
cursor: not-allowed;
|
|
828
|
-
background-color: var(--color-bg-secondary);
|
|
829
|
-
}
|
|
807
|
+
.agent-selector {
|
|
808
|
+
padding: 0.5rem;
|
|
809
|
+
border: none;
|
|
810
|
+
border-radius: 0.375rem;
|
|
811
|
+
background-color: var(--color-bg-secondary);
|
|
812
|
+
color: var(--color-text-primary);
|
|
813
|
+
font-size: 0.8rem;
|
|
814
|
+
cursor: pointer;
|
|
815
|
+
flex-shrink: 0;
|
|
816
|
+
width: auto;
|
|
817
|
+
min-width: 80px;
|
|
818
|
+
max-width: 200px;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
.agent-selector:disabled, .model-selector:disabled {
|
|
826
|
+
opacity: 0.5;
|
|
827
|
+
cursor: not-allowed;
|
|
828
|
+
background-color: var(--color-bg-secondary);
|
|
829
|
+
}
|
|
830
830
|
|
|
831
831
|
.model-selector {
|
|
832
832
|
padding: 0.5rem;
|
|
@@ -1077,7 +1077,8 @@
|
|
|
1077
1077
|
.message { max-width: 95%; }
|
|
1078
1078
|
.messages-wrapper { padding: 0.375rem 0.5rem; }
|
|
1079
1079
|
.input-section { padding: 0.5rem; padding-bottom: calc(0.5rem + env(safe-area-inset-bottom)); }
|
|
1080
|
-
.
|
|
1080
|
+
.cli-selector { display: none; }
|
|
1081
|
+
.sub-agent-selector { display: none; }
|
|
1081
1082
|
.model-selector { display: none; }
|
|
1082
1083
|
}
|
|
1083
1084
|
|
|
@@ -1328,20 +1329,20 @@
|
|
|
1328
1329
|
.sidebar-list { contain: strict; content-visibility: auto; }
|
|
1329
1330
|
.message { contain: layout style; content-visibility: auto; contain-intrinsic-size: auto 80px; }
|
|
1330
1331
|
|
|
1331
|
-
.voice-block .voice-result-stats {
|
|
1332
|
-
font-size: 0.8rem;
|
|
1333
|
-
color: var(--color-text-secondary);
|
|
1334
|
-
margin-top: 0.5rem;
|
|
1335
|
-
padding-top: 0.5rem;
|
|
1336
|
-
border-top: 1px solid var(--color-border);
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
.voice-block-content {
|
|
1340
|
-
white-space: pre-wrap;
|
|
1341
|
-
display: block;
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
.voice-reread-btn {
|
|
1332
|
+
.voice-block .voice-result-stats {
|
|
1333
|
+
font-size: 0.8rem;
|
|
1334
|
+
color: var(--color-text-secondary);
|
|
1335
|
+
margin-top: 0.5rem;
|
|
1336
|
+
padding-top: 0.5rem;
|
|
1337
|
+
border-top: 1px solid var(--color-border);
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
.voice-block-content {
|
|
1341
|
+
white-space: pre-wrap;
|
|
1342
|
+
display: block;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
.voice-reread-btn {
|
|
1345
1346
|
position: absolute;
|
|
1346
1347
|
top: 0.5rem;
|
|
1347
1348
|
right: 0.5rem;
|
|
@@ -3171,17 +3172,18 @@
|
|
|
3171
3172
|
</div>
|
|
3172
3173
|
|
|
3173
3174
|
<!-- Input area: fixed at bottom -->
|
|
3174
|
-
<div class="input-section">
|
|
3175
|
-
<div class="input-wrapper">
|
|
3176
|
-
<select class="agent-selector" data-
|
|
3177
|
-
<select class="
|
|
3178
|
-
<
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3175
|
+
<div class="input-section">
|
|
3176
|
+
<div class="input-wrapper">
|
|
3177
|
+
<select class="agent-selector cli-selector" data-cli-selector title="Select CLI tool"></select>
|
|
3178
|
+
<select class="agent-selector sub-agent-selector" data-agent-selector title="Select sub-agent" style="display:none"></select>
|
|
3179
|
+
<select class="model-selector" data-model-selector title="Select model" data-empty="true"></select>
|
|
3180
|
+
<textarea
|
|
3181
|
+
class="message-textarea"
|
|
3182
|
+
data-message-input
|
|
3183
|
+
placeholder="Message AgentGUI... (Ctrl+Enter to send)"
|
|
3184
|
+
aria-label="Message input"
|
|
3185
|
+
rows="1"
|
|
3186
|
+
></textarea>
|
|
3185
3187
|
<button class="inject-btn" id="injectBtn" title="Inject instructions into running agent" aria-label="Inject instructions">
|
|
3186
3188
|
<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
|
|
3187
3189
|
<path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/>
|
|
@@ -3226,22 +3228,22 @@
|
|
|
3226
3228
|
window._escHtml = function(t) { return t.replace(_escHtmlRe, function(c) { return _escHtmlMap[c]; }); };
|
|
3227
3229
|
</script>
|
|
3228
3230
|
<script defer src="/gm/js/event-processor.js"></script>
|
|
3229
|
-
<script defer src="/gm/js/streaming-renderer.js"></script>
|
|
3230
|
-
<script defer src="/gm/js/kalman-filter.js"></script>
|
|
3231
|
-
<script defer src="/gm/js/event-consolidator.js"></script>
|
|
3232
|
-
<script defer src="/gm/js/websocket-manager.js"></script>
|
|
3233
|
-
<script defer src="/gm/js/ws-client.js"></script>
|
|
3234
|
-
<script defer src="/gm/js/event-filter.js"></script>
|
|
3235
|
-
<script defer src="/gm/js/syntax-highlighter.js"></script>
|
|
3236
|
-
<script defer src="/gm/js/dialogs.js"></script>
|
|
3237
|
-
<script defer src="/gm/js/ui-components.js"></script>
|
|
3238
|
-
<script defer src="/gm/js/conversations.js"></script>
|
|
3239
|
-
<script defer src="/gm/js/terminal.js"></script>
|
|
3240
|
-
<script defer src="/gm/js/script-runner.js"></script>
|
|
3241
|
-
<script defer src="/gm/js/client.js"></script>
|
|
3242
|
-
<script type="module" src="/gm/js/voice.js"></script>
|
|
3243
|
-
<script defer src="/gm/js/features.js"></script>
|
|
3244
|
-
<script defer src="/gm/js/agent-auth.js"></script>
|
|
3231
|
+
<script defer src="/gm/js/streaming-renderer.js"></script>
|
|
3232
|
+
<script defer src="/gm/js/kalman-filter.js"></script>
|
|
3233
|
+
<script defer src="/gm/js/event-consolidator.js"></script>
|
|
3234
|
+
<script defer src="/gm/js/websocket-manager.js"></script>
|
|
3235
|
+
<script defer src="/gm/js/ws-client.js"></script>
|
|
3236
|
+
<script defer src="/gm/js/event-filter.js"></script>
|
|
3237
|
+
<script defer src="/gm/js/syntax-highlighter.js"></script>
|
|
3238
|
+
<script defer src="/gm/js/dialogs.js"></script>
|
|
3239
|
+
<script defer src="/gm/js/ui-components.js"></script>
|
|
3240
|
+
<script defer src="/gm/js/conversations.js"></script>
|
|
3241
|
+
<script defer src="/gm/js/terminal.js"></script>
|
|
3242
|
+
<script defer src="/gm/js/script-runner.js"></script>
|
|
3243
|
+
<script defer src="/gm/js/client.js"></script>
|
|
3244
|
+
<script type="module" src="/gm/js/voice.js"></script>
|
|
3245
|
+
<script defer src="/gm/js/features.js"></script>
|
|
3246
|
+
<script defer src="/gm/js/agent-auth.js"></script>
|
|
3245
3247
|
|
|
3246
3248
|
<script>
|
|
3247
3249
|
const savedTheme = localStorage.getItem('theme') || 'light';
|
package/static/js/client.js
CHANGED
|
@@ -43,6 +43,7 @@ class AgentGUIClient {
|
|
|
43
43
|
statusIndicator: null,
|
|
44
44
|
messageInput: null,
|
|
45
45
|
sendButton: null,
|
|
46
|
+
cliSelector: null,
|
|
46
47
|
agentSelector: null,
|
|
47
48
|
modelSelector: null
|
|
48
49
|
};
|
|
@@ -354,13 +355,23 @@ class AgentGUIClient {
|
|
|
354
355
|
this.ui.statusIndicator = document.querySelector('[data-status-indicator]');
|
|
355
356
|
this.ui.messageInput = document.querySelector('[data-message-input]');
|
|
356
357
|
this.ui.sendButton = document.querySelector('[data-send-button]');
|
|
358
|
+
this.ui.cliSelector = document.querySelector('[data-cli-selector]');
|
|
357
359
|
this.ui.agentSelector = document.querySelector('[data-agent-selector]');
|
|
358
360
|
this.ui.modelSelector = document.querySelector('[data-model-selector]');
|
|
359
361
|
|
|
362
|
+
if (this.ui.cliSelector) {
|
|
363
|
+
this.ui.cliSelector.addEventListener('change', () => {
|
|
364
|
+
if (!this._agentLocked) {
|
|
365
|
+
this.loadSubAgentsForCli(this.ui.cliSelector.value);
|
|
366
|
+
this.saveAgentAndModelToConversation();
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
360
371
|
if (this.ui.agentSelector) {
|
|
361
372
|
this.ui.agentSelector.addEventListener('change', () => {
|
|
362
373
|
if (!this._agentLocked) {
|
|
363
|
-
this.loadModelsForAgent(this.
|
|
374
|
+
this.loadModelsForAgent(this.getEffectiveAgentId());
|
|
364
375
|
this.saveAgentAndModelToConversation();
|
|
365
376
|
}
|
|
366
377
|
});
|
|
@@ -1822,22 +1833,27 @@ class AgentGUIClient {
|
|
|
1822
1833
|
const { agents } = await window.wsClient.rpc('agent.ls');
|
|
1823
1834
|
this.state.agents = agents;
|
|
1824
1835
|
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1836
|
+
const cliAgents = agents.filter(a => a.protocol === 'cli');
|
|
1837
|
+
const displayAgents = cliAgents.length > 0 ? cliAgents : agents;
|
|
1838
|
+
|
|
1839
|
+
if (this.ui.cliSelector) {
|
|
1840
|
+
if (displayAgents.length > 0) {
|
|
1841
|
+
this.ui.cliSelector.innerHTML = displayAgents
|
|
1842
|
+
.map(a => `<option value="${a.id}">${a.name}</option>`)
|
|
1830
1843
|
.join('');
|
|
1831
|
-
this.ui.
|
|
1844
|
+
this.ui.cliSelector.style.display = 'inline-block';
|
|
1832
1845
|
} else {
|
|
1833
|
-
this.ui.
|
|
1834
|
-
this.ui.
|
|
1846
|
+
this.ui.cliSelector.innerHTML = '';
|
|
1847
|
+
this.ui.cliSelector.style.display = 'none';
|
|
1835
1848
|
}
|
|
1836
1849
|
}
|
|
1837
1850
|
|
|
1838
1851
|
window.dispatchEvent(new CustomEvent('agents-loaded', { detail: { agents } }));
|
|
1839
|
-
|
|
1840
|
-
|
|
1852
|
+
|
|
1853
|
+
if (displayAgents.length > 0 && !this._agentLocked) {
|
|
1854
|
+
const firstId = displayAgents[0].id;
|
|
1855
|
+
await this.loadSubAgentsForCli(firstId);
|
|
1856
|
+
this.loadModelsForAgent(this.getEffectiveAgentId());
|
|
1841
1857
|
}
|
|
1842
1858
|
return agents;
|
|
1843
1859
|
} catch (error) {
|
|
@@ -1847,6 +1863,24 @@ class AgentGUIClient {
|
|
|
1847
1863
|
});
|
|
1848
1864
|
}
|
|
1849
1865
|
|
|
1866
|
+
async loadSubAgentsForCli(cliAgentId) {
|
|
1867
|
+
if (this.ui.agentSelector) {
|
|
1868
|
+
this.ui.agentSelector.innerHTML = '';
|
|
1869
|
+
this.ui.agentSelector.style.display = 'none';
|
|
1870
|
+
}
|
|
1871
|
+
try {
|
|
1872
|
+
const { subAgents } = await window.wsClient.rpc('agent.subagents', { id: cliAgentId });
|
|
1873
|
+
if (subAgents && subAgents.length > 0 && this.ui.agentSelector) {
|
|
1874
|
+
this.ui.agentSelector.innerHTML = subAgents
|
|
1875
|
+
.map(a => `<option value="${a.id}">${a.name}</option>`)
|
|
1876
|
+
.join('');
|
|
1877
|
+
this.ui.agentSelector.style.display = 'inline-block';
|
|
1878
|
+
}
|
|
1879
|
+
} catch (_) {
|
|
1880
|
+
// No sub-agents available for this CLI tool — keep hidden
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1850
1884
|
async checkSpeechStatus() {
|
|
1851
1885
|
try {
|
|
1852
1886
|
const status = await window.wsClient.rpc('speech.status');
|
|
@@ -1899,8 +1933,10 @@ class AgentGUIClient {
|
|
|
1899
1933
|
|
|
1900
1934
|
lockAgentAndModel(agentId, model) {
|
|
1901
1935
|
this._agentLocked = true;
|
|
1936
|
+
if (this.ui.cliSelector) {
|
|
1937
|
+
this.ui.cliSelector.disabled = true;
|
|
1938
|
+
}
|
|
1902
1939
|
if (this.ui.agentSelector) {
|
|
1903
|
-
this.ui.agentSelector.value = agentId;
|
|
1904
1940
|
this.ui.agentSelector.disabled = true;
|
|
1905
1941
|
}
|
|
1906
1942
|
|
|
@@ -1914,9 +1950,11 @@ class AgentGUIClient {
|
|
|
1914
1950
|
|
|
1915
1951
|
unlockAgentAndModel() {
|
|
1916
1952
|
this._agentLocked = false;
|
|
1953
|
+
if (this.ui.cliSelector) {
|
|
1954
|
+
this.ui.cliSelector.disabled = false;
|
|
1955
|
+
}
|
|
1917
1956
|
if (this.ui.agentSelector) {
|
|
1918
1957
|
this.ui.agentSelector.disabled = false;
|
|
1919
|
-
this.ui.agentSelector.style.display = 'inline-block';
|
|
1920
1958
|
}
|
|
1921
1959
|
if (this.ui.modelSelector) {
|
|
1922
1960
|
this.ui.modelSelector.disabled = false;
|
|
@@ -1932,12 +1970,11 @@ class AgentGUIClient {
|
|
|
1932
1970
|
const model = conversation.model || null;
|
|
1933
1971
|
|
|
1934
1972
|
if (hasActivity) {
|
|
1973
|
+
this._setCliSelectorToAgent(agentId);
|
|
1935
1974
|
this.lockAgentAndModel(agentId, model);
|
|
1936
1975
|
} else {
|
|
1937
1976
|
this.unlockAgentAndModel();
|
|
1938
|
-
|
|
1939
|
-
this.ui.agentSelector.value = agentId;
|
|
1940
|
-
}
|
|
1977
|
+
this._setCliSelectorToAgent(agentId);
|
|
1941
1978
|
|
|
1942
1979
|
this.loadModelsForAgent(agentId).then(() => {
|
|
1943
1980
|
if (model && this.ui.modelSelector) {
|
|
@@ -1947,6 +1984,15 @@ class AgentGUIClient {
|
|
|
1947
1984
|
}
|
|
1948
1985
|
}
|
|
1949
1986
|
|
|
1987
|
+
_setCliSelectorToAgent(agentId) {
|
|
1988
|
+
const allAgents = this.state.agents || [];
|
|
1989
|
+
const agent = allAgents.find(a => a.id === agentId);
|
|
1990
|
+
const cliId = (agent?.protocol === 'cli' || !agent) ? agentId : null;
|
|
1991
|
+
if (cliId && this.ui.cliSelector) {
|
|
1992
|
+
this.ui.cliSelector.value = cliId;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1950
1996
|
/**
|
|
1951
1997
|
* Load conversations
|
|
1952
1998
|
*/
|
|
@@ -2510,14 +2556,15 @@ class AgentGUIClient {
|
|
|
2510
2556
|
/**
|
|
2511
2557
|
* Get current selected agent
|
|
2512
2558
|
*/
|
|
2513
|
-
|
|
2514
|
-
if (this.ui.agentSelector?.value) {
|
|
2515
|
-
return this.ui.agentSelector.value;
|
|
2516
|
-
}
|
|
2517
|
-
if (this.ui.agentSelector?.value) {
|
|
2559
|
+
getEffectiveAgentId() {
|
|
2560
|
+
if (this.ui.agentSelector?.value && this.ui.agentSelector.style.display !== 'none') {
|
|
2518
2561
|
return this.ui.agentSelector.value;
|
|
2519
2562
|
}
|
|
2520
|
-
return 'claude-code';
|
|
2563
|
+
return this.ui.cliSelector?.value || 'claude-code';
|
|
2564
|
+
}
|
|
2565
|
+
|
|
2566
|
+
getCurrentAgent() {
|
|
2567
|
+
return this.getEffectiveAgentId();
|
|
2521
2568
|
}
|
|
2522
2569
|
|
|
2523
2570
|
/**
|