aboutsummaryrefslogtreecommitdiff
path: root/modules/core/terminal.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/terminal.js')
-rw-r--r--modules/core/terminal.js130
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();