diff options
Diffstat (limited to 'modules/core/terminal.js')
| -rw-r--r-- | modules/core/terminal.js | 130 |
1 files changed, 129 insertions, 1 deletions
diff --git a/modules/core/terminal.js b/modules/core/terminal.js index 1bfc4cd..5e6db6a 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -7,7 +7,7 @@ this.lastRouteTime = 0; this.lastRouteCmd = ''; this.blockedCount = 0; - this.destructiveCmds = new Set(['rm','delete','del','edit','write','save','overwrite','format','kill','stop','shutdown','reboot']); + this.destructiveCmds = new Set(['rm','delete','del','write','save','overwrite','format','kill','stop','shutdown','reboot']); this.systemCmds = new Set(['reboot','shutdown','format','kill','halt','poweroff']); this.suspiciousFlags = new Set(['--dump','--execute','--eval','--exec','--shell','--script']); this.whitelist = new Set(['help','clear','ls','cat','pwd','whoami','df','free','top','ps','echo','date','env','history']); @@ -1143,6 +1143,7 @@ document.getElementById('ollama-endpoint').value = this.ollamaManager.endpoint; this.updateOllamaStatus(); this.renderOllamaModels(); + this.initOllamaUI(); modal.style.display = 'flex'; } closeOllamaManager() { @@ -1392,6 +1393,133 @@ const select = document.getElementById('ollama-current-model'); this.ollamaManager.setModel(select.value); } + toggleOptimization() { + const cb = document.getElementById('ollama-optimization-toggle'); + const label = document.getElementById('ollama-optimization-label'); + const slider = document.getElementById('ollama-optimization-slider'); + const enabled = cb.checked; + this.ollamaManager.setOptimizationEnabled(enabled); + if (label) { + label.textContent = enabled ? 'Enabled' : 'Disabled'; + label.style.color = enabled ? 'var(--success-color)' : 'var(--text-muted)'; + } + if (slider) { + slider.style.background = enabled ? 'var(--accent-color)' : 'var(--bg-tertiary)'; + slider.style.borderColor = enabled ? 'var(--success-color)' : 'var(--border-color)'; + } + this.ollamaManager.saveSettings(); + } + toggleValidator() { + const cb = document.getElementById('ollama-validator-toggle'); + const label = document.getElementById('ollama-validator-label'); + const slider = document.getElementById('ollama-validator-slider'); + const enabled = cb.checked; + this.ollamaManager.validatorEnabled = enabled; + if (label) { + label.textContent = enabled ? 'Enabled' : 'Disabled'; + label.style.color = enabled ? 'var(--success-color)' : 'var(--text-muted)'; + } + if (slider) { + slider.style.background = enabled ? 'var(--info-color)' : 'var(--bg-tertiary)'; + slider.style.borderColor = enabled ? 'var(--info-color)' : 'var(--border-color)'; + } + this.ollamaManager.saveSettings(); + } + saveValidatorConfig() { + const select = document.getElementById('validator-model-select'); + const endpoint = document.getElementById('validator-endpoint-input')?.value?.trim() || 'http://localhost:11434'; + const model = select ? select.value : ''; + localStorage.setItem('webx11_validator_endpoint', endpoint); + this.ollamaManager.validatorEndpoint = endpoint; + this.ollamaManager.setValidatorConfig(this.ollamaManager.validatorEnabled, model); + this.print('Validator config saved. Model: ' + (model || '(none)') + ' at ' + endpoint, 'success'); + } + async connectValidatorEndpoint() { + const endpoint = document.getElementById('validator-endpoint-input')?.value?.trim() || 'http://localhost:11434'; + const statusEl = document.getElementById('validator-connection-status'); + const select = document.getElementById('validator-model-select'); + if (statusEl) statusEl.textContent = '⏳ Connecting to ' + endpoint + '...'; + if (select) { select.disabled = true; select.innerHTML = '<option value="">Connecting...</option>'; } + try { + const resp = await fetch(endpoint + '/api/tags'); + if (!resp.ok) throw new Error('HTTP ' + resp.status); + const data = await resp.json(); + const models = data.models || []; + if (statusEl) statusEl.textContent = '✅ Connected: ' + models.length + ' model(s)'; + // Populate dropdown + if (select) { + select.innerHTML = '<option value="">Select a validator model</option>'; + models.forEach(function(m) { + var opt = document.createElement('option'); + opt.value = m.name; + opt.textContent = m.name; + select.appendChild(opt); + }); + select.disabled = false; + } + // Save endpoint + localStorage.setItem('webx11_validator_endpoint', endpoint); + this.ollamaManager.validatorEndpoint = endpoint; + this.ollamaManager.saveSettings(); + } catch (e) { + if (statusEl) { + statusEl.innerHTML = '❌ Connection failed: ' + e.message + + '<br><span style="font-size:0.85em;color:var(--text-muted);">Make sure Ollama is running and ' + + '<code>OLLAMA_ORIGINS</code> includes this page\'s origin.</span>'; + } + if (select) { select.disabled = true; select.innerHTML = '<option value="">Connection failed — try again</option>'; } + } + } + initOllamaUI() { + // Initialize optimization toggle from stored state + const optCb = document.getElementById('ollama-optimization-toggle'); + const optLabel = document.getElementById('ollama-optimization-label'); + const optSlider = document.getElementById('ollama-optimization-slider'); + if (optCb && this.ollamaManager) { + const enabled = this.ollamaManager.optimizationEnabled !== false; + optCb.checked = enabled; + if (optLabel) { + optLabel.textContent = enabled ? 'Enabled' : 'Disabled'; + optLabel.style.color = enabled ? 'var(--success-color)' : 'var(--text-muted)'; + } + if (optSlider) { + optSlider.style.background = enabled ? 'var(--accent-color)' : 'var(--bg-tertiary)'; + optSlider.style.borderColor = enabled ? 'var(--success-color)' : 'var(--border-color)'; + } + } + // Initialize validator toggle from stored state + const valCb = document.getElementById('ollama-validator-toggle'); + const valLabel = document.getElementById('ollama-validator-label'); + const valSlider = document.getElementById('ollama-validator-slider'); + if (valCb && this.ollamaManager) { + const enabled = this.ollamaManager.validatorEnabled === true; + valCb.checked = enabled; + if (valLabel) { + valLabel.textContent = enabled ? 'Enabled' : 'Disabled'; + valLabel.style.color = enabled ? 'var(--success-color)' : 'var(--text-muted)'; + } + if (valSlider) { + valSlider.style.background = enabled ? 'var(--info-color)' : 'var(--bg-tertiary)'; + valSlider.style.borderColor = enabled ? 'var(--info-color)' : 'var(--border-color)'; + } + } + // Populate validator model dropdown from stored config + const valSelect = document.getElementById('validator-model-select'); + const valEndpoint = document.getElementById('validator-endpoint-input'); + if (valEndpoint && this.ollamaManager) { + valEndpoint.value = this.ollamaManager.validatorEndpoint || 'http://localhost:11434'; + } + if (valSelect && this.ollamaManager) { + const storedModel = this.ollamaManager.validatorModel || ''; + if (storedModel) { + valSelect.innerHTML = '<option value="' + storedModel + '">' + storedModel + '</option><option value="">Disable (use main AI model)</option>'; + valSelect.disabled = false; + } else { + valSelect.innerHTML = '<option value="">Connect to load models</option>'; + valSelect.disabled = true; + } + } + } openStartupModules() { document.getElementById('startup-modules').style.display = 'flex'; this.renderStartupModules(); |