agentgui 1.0.414 → 1.0.416
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 +14 -1
- package/package.json +1 -1
- package/server.js +105 -17
- package/static/index.html +34 -30
- package/static/js/client.js +107 -12
|
@@ -97,7 +97,20 @@ export function register(router, deps) {
|
|
|
97
97
|
return data;
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
router.handle('agent.ls', () =>
|
|
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
|
+
});
|
|
101
114
|
|
|
102
115
|
router.handle('agent.get', (p) => {
|
|
103
116
|
const a = discoveredAgents.find(x => x.id === p.id);
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -342,31 +342,96 @@ function findCommand(cmd) {
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
+
async function queryACPServerAgents(baseUrl) {
|
|
346
|
+
try {
|
|
347
|
+
// Ensure correct endpoint format (handle both /api and /api/ cases)
|
|
348
|
+
const endpoint = baseUrl.endsWith('/') ? `${baseUrl}agents/search` : `${baseUrl}/agents/search`;
|
|
349
|
+
const response = await fetch(endpoint, {
|
|
350
|
+
method: 'POST',
|
|
351
|
+
headers: {
|
|
352
|
+
'Content-Type': 'application/json',
|
|
353
|
+
},
|
|
354
|
+
body: JSON.stringify({}),
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
if (!response.ok) {
|
|
358
|
+
console.error(`Failed to query ACP agents from ${baseUrl}: ${response.status}`);
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const data = await response.json();
|
|
363
|
+
if (!data.agents || !Array.isArray(data.agents)) {
|
|
364
|
+
console.error(`Invalid agents response from ${baseUrl}`);
|
|
365
|
+
return [];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Convert ACP agent format to our internal format
|
|
369
|
+
return data.agents.map(agent => ({
|
|
370
|
+
id: agent.agent_id || agent.id,
|
|
371
|
+
name: agent.metadata?.ref?.name || agent.name || 'Unknown Agent',
|
|
372
|
+
icon: agent.metadata?.ref?.name?.charAt(0) || 'A',
|
|
373
|
+
path: baseUrl,
|
|
374
|
+
protocol: 'acp',
|
|
375
|
+
description: agent.metadata?.description || '',
|
|
376
|
+
}));
|
|
377
|
+
} catch (error) {
|
|
378
|
+
console.error(`Error querying ACP server ${baseUrl}:`, error.message);
|
|
379
|
+
return [];
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
345
383
|
function discoverAgents() {
|
|
346
384
|
const agents = [];
|
|
347
385
|
const binaries = [
|
|
348
|
-
{ cmd: 'claude', id: 'claude-code', name: 'Claude Code', icon: 'C' },
|
|
349
|
-
{ cmd: 'opencode', id: 'opencode', name: 'OpenCode', icon: 'O' },
|
|
350
|
-
{ cmd: 'gemini', id: 'gemini', name: 'Gemini CLI', icon: 'G' },
|
|
351
|
-
{ cmd: 'kilo', id: 'kilo', name: 'Kilo Code', icon: 'K' },
|
|
352
|
-
{ cmd: 'goose', id: 'goose', name: 'Goose', icon: 'g' },
|
|
353
|
-
{ cmd: 'openhands', id: 'openhands', name: 'OpenHands', icon: 'H' },
|
|
354
|
-
{ cmd: 'augment', id: 'augment', name: 'Augment Code', icon: 'A' },
|
|
355
|
-
{ cmd: 'cline', id: 'cline', name: 'Cline', icon: 'c' },
|
|
356
|
-
{ cmd: 'kimi', id: 'kimi', name: 'Kimi CLI', icon: 'K' },
|
|
357
|
-
{ cmd: 'qwen-code', id: 'qwen', name: 'Qwen Code', icon: 'Q' },
|
|
358
|
-
{ cmd: 'codex', id: 'codex', name: 'Codex CLI', icon: 'X' },
|
|
359
|
-
{ cmd: 'mistral-vibe', id: 'mistral', name: 'Mistral Vibe', icon: 'M' },
|
|
360
|
-
{ cmd: 'kiro', id: 'kiro', name: 'Kiro CLI', icon: 'k' },
|
|
361
|
-
{ cmd: 'fast-agent', id: 'fast-agent', name: 'fast-agent', icon: 'F' },
|
|
386
|
+
{ cmd: 'claude', id: 'claude-code', name: 'Claude Code', icon: 'C', protocol: 'cli' },
|
|
387
|
+
{ cmd: 'opencode', id: 'opencode', name: 'OpenCode', icon: 'O', protocol: 'acp' },
|
|
388
|
+
{ cmd: 'gemini', id: 'gemini', name: 'Gemini CLI', icon: 'G', protocol: 'acp' },
|
|
389
|
+
{ cmd: 'kilo', id: 'kilo', name: 'Kilo Code', icon: 'K', protocol: 'acp' },
|
|
390
|
+
{ cmd: 'goose', id: 'goose', name: 'Goose', icon: 'g', protocol: 'acp' },
|
|
391
|
+
{ cmd: 'openhands', id: 'openhands', name: 'OpenHands', icon: 'H', protocol: 'acp' },
|
|
392
|
+
{ cmd: 'augment', id: 'augment', name: 'Augment Code', icon: 'A', protocol: 'acp' },
|
|
393
|
+
{ cmd: 'cline', id: 'cline', name: 'Cline', icon: 'c', protocol: 'acp' },
|
|
394
|
+
{ cmd: 'kimi', id: 'kimi', name: 'Kimi CLI', icon: 'K', protocol: 'acp' },
|
|
395
|
+
{ cmd: 'qwen-code', id: 'qwen', name: 'Qwen Code', icon: 'Q', protocol: 'acp' },
|
|
396
|
+
{ cmd: 'codex', id: 'codex', name: 'Codex CLI', icon: 'X', protocol: 'acp' },
|
|
397
|
+
{ cmd: 'mistral-vibe', id: 'mistral', name: 'Mistral Vibe', icon: 'M', protocol: 'acp' },
|
|
398
|
+
{ cmd: 'kiro', id: 'kiro', name: 'Kiro CLI', icon: 'k', protocol: 'acp' },
|
|
399
|
+
{ cmd: 'fast-agent', id: 'fast-agent', name: 'fast-agent', icon: 'F', protocol: 'acp' },
|
|
362
400
|
];
|
|
363
401
|
for (const bin of binaries) {
|
|
364
402
|
const result = findCommand(bin.cmd);
|
|
365
|
-
if (result) agents.push({
|
|
403
|
+
if (result) agents.push({
|
|
404
|
+
id: bin.id,
|
|
405
|
+
name: bin.name,
|
|
406
|
+
icon: bin.icon,
|
|
407
|
+
path: result,
|
|
408
|
+
protocol: bin.protocol
|
|
409
|
+
});
|
|
366
410
|
}
|
|
367
411
|
return agents;
|
|
368
412
|
}
|
|
369
413
|
|
|
414
|
+
// Function to discover agents from external ACP servers
|
|
415
|
+
async function discoverExternalACPServers() {
|
|
416
|
+
// Default ACP servers to query (excluding local server to prevent recursion)
|
|
417
|
+
const acpServers = [
|
|
418
|
+
'http://localhost:8080', // Common default ACP port
|
|
419
|
+
];
|
|
420
|
+
|
|
421
|
+
const externalAgents = [];
|
|
422
|
+
for (const serverUrl of acpServers) {
|
|
423
|
+
try {
|
|
424
|
+
console.log(`Querying ACP agents from: ${serverUrl}`);
|
|
425
|
+
const agents = await queryACPServerAgents(serverUrl);
|
|
426
|
+
externalAgents.push(...agents);
|
|
427
|
+
} catch (error) {
|
|
428
|
+
console.error(`Failed to query ${serverUrl}:`, error.message);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return externalAgents;
|
|
433
|
+
}
|
|
434
|
+
|
|
370
435
|
const discoveredAgents = discoverAgents();
|
|
371
436
|
initializeDescriptors(discoveredAgents);
|
|
372
437
|
|
|
@@ -1947,8 +2012,31 @@ const server = http.createServer(async (req, res) => {
|
|
|
1947
2012
|
|
|
1948
2013
|
if (pathOnly === '/api/agents/search' && req.method === 'POST') {
|
|
1949
2014
|
const body = await parseBody(req);
|
|
1950
|
-
|
|
1951
|
-
|
|
2015
|
+
try {
|
|
2016
|
+
// Get local agents
|
|
2017
|
+
const localResult = queries.searchAgents(discoveredAgents, body);
|
|
2018
|
+
|
|
2019
|
+
// Get external agents from ACP servers
|
|
2020
|
+
const externalAgents = await discoverExternalACPServers();
|
|
2021
|
+
const externalResult = queries.searchAgents(externalAgents, body);
|
|
2022
|
+
|
|
2023
|
+
// Combine results
|
|
2024
|
+
const combinedAgents = [...localResult.agents, ...externalResult.agents];
|
|
2025
|
+
const total = localResult.total + externalResult.total;
|
|
2026
|
+
const hasMore = localResult.hasMore || externalResult.hasMore;
|
|
2027
|
+
|
|
2028
|
+
sendJSON(req, res, 200, {
|
|
2029
|
+
agents: combinedAgents,
|
|
2030
|
+
total,
|
|
2031
|
+
limit: body.limit || 50,
|
|
2032
|
+
offset: body.offset || 0,
|
|
2033
|
+
hasMore,
|
|
2034
|
+
});
|
|
2035
|
+
} catch (error) {
|
|
2036
|
+
console.error('Error searching agents:', error);
|
|
2037
|
+
const result = queries.searchAgents(discoveredAgents, body);
|
|
2038
|
+
sendJSON(req, res, 200, result);
|
|
2039
|
+
}
|
|
1952
2040
|
return;
|
|
1953
2041
|
}
|
|
1954
2042
|
|
package/static/index.html
CHANGED
|
@@ -804,25 +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
|
-
|
|
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
|
+
}
|
|
826
830
|
|
|
827
831
|
.model-selector {
|
|
828
832
|
padding: 0.5rem;
|
|
@@ -3167,17 +3171,17 @@
|
|
|
3167
3171
|
</div>
|
|
3168
3172
|
|
|
3169
3173
|
<!-- Input area: fixed at bottom -->
|
|
3170
|
-
<div class="input-section">
|
|
3171
|
-
<div class="input-wrapper">
|
|
3172
|
-
<select class="agent-selector" data-agent-selector title="Select agent"></select>
|
|
3173
|
-
<select class="model-selector" data-model-selector title="Select model" data-empty="true"></select>
|
|
3174
|
-
<textarea
|
|
3175
|
-
class="message-textarea"
|
|
3176
|
-
data-message-input
|
|
3177
|
-
placeholder="Message AgentGUI... (Ctrl+Enter to send)"
|
|
3178
|
-
aria-label="Message input"
|
|
3179
|
-
rows="1"
|
|
3180
|
-
></textarea>
|
|
3174
|
+
<div class="input-section">
|
|
3175
|
+
<div class="input-wrapper">
|
|
3176
|
+
<select class="agent-selector" data-agent-selector title="Select agent"></select>
|
|
3177
|
+
<select class="model-selector" data-model-selector title="Select model" data-empty="true"></select>
|
|
3178
|
+
<textarea
|
|
3179
|
+
class="message-textarea"
|
|
3180
|
+
data-message-input
|
|
3181
|
+
placeholder="Message AgentGUI... (Ctrl+Enter to send)"
|
|
3182
|
+
aria-label="Message input"
|
|
3183
|
+
rows="1"
|
|
3184
|
+
></textarea>
|
|
3181
3185
|
<button class="inject-btn" id="injectBtn" title="Inject instructions into running agent" aria-label="Inject instructions">
|
|
3182
3186
|
<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
|
|
3183
3187
|
<path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/>
|
package/static/js/client.js
CHANGED
|
@@ -355,6 +355,7 @@ class AgentGUIClient {
|
|
|
355
355
|
this.ui.messageInput = document.querySelector('[data-message-input]');
|
|
356
356
|
this.ui.sendButton = document.querySelector('[data-send-button]');
|
|
357
357
|
this.ui.agentSelector = document.querySelector('[data-agent-selector]');
|
|
358
|
+
this.ui.agentSelector = document.querySelector('[data-agent-selector]');
|
|
358
359
|
this.ui.modelSelector = document.querySelector('[data-model-selector]');
|
|
359
360
|
|
|
360
361
|
if (this.ui.agentSelector) {
|
|
@@ -1248,7 +1249,7 @@ class AgentGUIClient {
|
|
|
1248
1249
|
const prompt = this.ui.messageInput?.value || '';
|
|
1249
1250
|
const conv = this.state.currentConversation;
|
|
1250
1251
|
const isNewConversation = conv && !conv.messageCount && !this.state.streamingConversations.has(conv.id);
|
|
1251
|
-
const agentId = (isNewConversation ? this.
|
|
1252
|
+
const agentId = (isNewConversation ? this.getCurrentAgent() : null) || conv?.agentType || this.getCurrentAgent() || 'claude-code';
|
|
1252
1253
|
const model = this.ui.modelSelector?.value || null;
|
|
1253
1254
|
|
|
1254
1255
|
if (!prompt.trim()) {
|
|
@@ -1822,10 +1823,34 @@ class AgentGUIClient {
|
|
|
1822
1823
|
const { agents } = await window.wsClient.rpc('agent.ls');
|
|
1823
1824
|
this.state.agents = agents;
|
|
1824
1825
|
|
|
1826
|
+
// Split agents by protocol
|
|
1827
|
+
const cliAgents = agents.filter(agent => agent.protocol === 'cli');
|
|
1828
|
+
const acpAgents = agents.filter(agent => agent.protocol === 'acp');
|
|
1829
|
+
|
|
1830
|
+
// Populate CLI agent selector
|
|
1825
1831
|
if (this.ui.agentSelector) {
|
|
1826
|
-
|
|
1827
|
-
.
|
|
1828
|
-
|
|
1832
|
+
if (cliAgents.length > 0) {
|
|
1833
|
+
this.ui.agentSelector.innerHTML = cliAgents
|
|
1834
|
+
.map(agent => `<option value="${agent.id}">${agent.name}</option>`)
|
|
1835
|
+
.join('');
|
|
1836
|
+
this.ui.agentSelector.style.display = 'inline-block';
|
|
1837
|
+
} else {
|
|
1838
|
+
this.ui.agentSelector.innerHTML = '';
|
|
1839
|
+
this.ui.agentSelector.style.display = 'none';
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
// Populate ACP agent selector
|
|
1844
|
+
if (this.ui.agentSelector) {
|
|
1845
|
+
if (acpAgents.length > 0) {
|
|
1846
|
+
this.ui.agentSelector.innerHTML = acpAgents
|
|
1847
|
+
.map(agent => `<option value="${agent.id}">${agent.name}</option>`)
|
|
1848
|
+
.join('');
|
|
1849
|
+
this.ui.agentSelector.style.display = 'inline-block';
|
|
1850
|
+
} else {
|
|
1851
|
+
this.ui.agentSelector.innerHTML = '';
|
|
1852
|
+
this.ui.agentSelector.style.display = 'none';
|
|
1853
|
+
}
|
|
1829
1854
|
}
|
|
1830
1855
|
|
|
1831
1856
|
window.dispatchEvent(new CustomEvent('agents-loaded', { detail: { agents } }));
|
|
@@ -1892,10 +1917,34 @@ class AgentGUIClient {
|
|
|
1892
1917
|
|
|
1893
1918
|
lockAgentAndModel(agentId, model) {
|
|
1894
1919
|
this._agentLocked = true;
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1920
|
+
|
|
1921
|
+
// Find the agent to determine protocol
|
|
1922
|
+
const agent = this.state.agents.find(a => a.id === agentId);
|
|
1923
|
+
|
|
1924
|
+
if (agent) {
|
|
1925
|
+
if (agent.protocol === 'cli') {
|
|
1926
|
+
if (this.ui.agentSelector) {
|
|
1927
|
+
this.ui.agentSelector.value = agentId;
|
|
1928
|
+
this.ui.agentSelector.disabled = true;
|
|
1929
|
+
}
|
|
1930
|
+
if (this.ui.agentSelector) {
|
|
1931
|
+
this.ui.agentSelector.value = '';
|
|
1932
|
+
this.ui.agentSelector.disabled = true;
|
|
1933
|
+
this.ui.agentSelector.style.display = 'none';
|
|
1934
|
+
}
|
|
1935
|
+
} else {
|
|
1936
|
+
if (this.ui.agentSelector) {
|
|
1937
|
+
this.ui.agentSelector.value = agentId;
|
|
1938
|
+
this.ui.agentSelector.disabled = true;
|
|
1939
|
+
}
|
|
1940
|
+
if (this.ui.agentSelector) {
|
|
1941
|
+
this.ui.agentSelector.value = '';
|
|
1942
|
+
this.ui.agentSelector.disabled = true;
|
|
1943
|
+
this.ui.agentSelector.style.display = 'none';
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1898
1946
|
}
|
|
1947
|
+
|
|
1899
1948
|
this.loadModelsForAgent(agentId).then(() => {
|
|
1900
1949
|
if (this.ui.modelSelector && model) {
|
|
1901
1950
|
this.ui.modelSelector.value = model;
|
|
@@ -1908,6 +1957,17 @@ class AgentGUIClient {
|
|
|
1908
1957
|
if (this.ui.agentSelector) {
|
|
1909
1958
|
this.ui.agentSelector.disabled = false;
|
|
1910
1959
|
}
|
|
1960
|
+
if (this.ui.agentSelector) {
|
|
1961
|
+
this.ui.agentSelector.disabled = false;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
// Show both selectors again when unlocking
|
|
1965
|
+
if (this.ui.agentSelector && this.state.agents.some(a => a.protocol === 'cli')) {
|
|
1966
|
+
this.ui.agentSelector.style.display = 'inline-block';
|
|
1967
|
+
}
|
|
1968
|
+
if (this.ui.agentSelector && this.state.agents.some(a => a.protocol === 'acp')) {
|
|
1969
|
+
this.ui.agentSelector.style.display = 'inline-block';
|
|
1970
|
+
}
|
|
1911
1971
|
}
|
|
1912
1972
|
|
|
1913
1973
|
/**
|
|
@@ -1922,9 +1982,31 @@ class AgentGUIClient {
|
|
|
1922
1982
|
this.lockAgentAndModel(agentId, model);
|
|
1923
1983
|
} else {
|
|
1924
1984
|
this.unlockAgentAndModel();
|
|
1925
|
-
|
|
1926
|
-
|
|
1985
|
+
// Find the agent to determine protocol
|
|
1986
|
+
const agent = this.state.agents.find(a => a.id === agentId);
|
|
1987
|
+
|
|
1988
|
+
if (agent) {
|
|
1989
|
+
if (agent.protocol === 'cli') {
|
|
1990
|
+
if (this.ui.agentSelector) {
|
|
1991
|
+
this.ui.agentSelector.value = agentId;
|
|
1992
|
+
this.ui.agentSelector.style.display = 'inline-block';
|
|
1993
|
+
}
|
|
1994
|
+
if (this.ui.agentSelector) {
|
|
1995
|
+
this.ui.agentSelector.value = '';
|
|
1996
|
+
this.ui.agentSelector.style.display = 'none';
|
|
1997
|
+
}
|
|
1998
|
+
} else {
|
|
1999
|
+
if (this.ui.agentSelector) {
|
|
2000
|
+
this.ui.agentSelector.value = agentId;
|
|
2001
|
+
this.ui.agentSelector.style.display = 'inline-block';
|
|
2002
|
+
}
|
|
2003
|
+
if (this.ui.agentSelector) {
|
|
2004
|
+
this.ui.agentSelector.value = '';
|
|
2005
|
+
this.ui.agentSelector.style.display = 'none';
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
1927
2008
|
}
|
|
2009
|
+
|
|
1928
2010
|
this.loadModelsForAgent(agentId).then(() => {
|
|
1929
2011
|
if (model && this.ui.modelSelector) {
|
|
1930
2012
|
this.ui.modelSelector.value = model;
|
|
@@ -2494,10 +2576,23 @@ class AgentGUIClient {
|
|
|
2494
2576
|
}
|
|
2495
2577
|
|
|
2496
2578
|
/**
|
|
2497
|
-
* Get
|
|
2579
|
+
* Get current selected agent
|
|
2580
|
+
*/
|
|
2581
|
+
getCurrentAgent() {
|
|
2582
|
+
if (this.ui.agentSelector?.value) {
|
|
2583
|
+
return this.ui.agentSelector.value;
|
|
2584
|
+
}
|
|
2585
|
+
if (this.ui.agentSelector?.value) {
|
|
2586
|
+
return this.ui.agentSelector.value;
|
|
2587
|
+
}
|
|
2588
|
+
return 'claude-code';
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
/**
|
|
2592
|
+
* Get current selected model
|
|
2498
2593
|
*/
|
|
2499
|
-
|
|
2500
|
-
return
|
|
2594
|
+
getCurrentModel() {
|
|
2595
|
+
return this.ui.modelSelector?.value || null;
|
|
2501
2596
|
}
|
|
2502
2597
|
|
|
2503
2598
|
/**
|