// Extracted from newOS4 index.html — OllamaModule (merged with OllamaModelsModule) // Commands: ollama, ollamaconnect, ollamadisconnect, ollamamodels, ollamasetmodel, ollamasetproxy, models, model-info, model-pull, model-delete, model-run, ai, ask class OllamaModule { constructor() { this.commands = {}; this.terminal = null; } getHelpInfo() { return { 'ollama': 'ollama — Open the Ollama model manager UI', 'ollamaconnect': 'ollamaconnect — Connect to the Ollama server', 'ollamadisconnect': 'ollamadisconnect — Disconnect from the Ollama server', 'ollamamodels': 'ollamamodels — List all available models from Ollama', 'models': 'models — List all available Ollama models (table format)', 'model-info': 'model-info — Show details about a specific model', 'model-pull': 'model-pull — Pull a model from Ollama registry', 'model-delete': 'model-delete — Delete a model from local storage', 'model-run': 'model-run [prompt] — Run inference with a model', 'ollamasetmodel': 'ollamasetmodel — Set the active Ollama model', 'ollamasetproxy': 'ollamasetproxy [endpoint] — View or change the Ollama endpoint URL', }; } registerCommands() { this.commands['ollama'] = () => { this.terminal.openOllamaManager(); }; this.commands['ollamaconnect'] = async () => { await this.terminal.ollamaManager.connect(); this.terminal.updateOllamaStatus(); }; this.commands['ollamadisconnect'] = () => { this.terminal.ollamaManager.connected = false; this.terminal.ollamaManager.models = []; this.terminal.print('Ollama disconnected', 'info'); this.terminal.updateOllamaStatus(); }; this.commands['ollamamodels'] = () => { const models = this.terminal.ollamaManager.getModels(); if(models.length === 0) return this.terminal.print("No models found. Connect first."); models.forEach(m => this.terminal.print(`${m.name} (${(m.size/1e9).toFixed(1)}GB)`)); }; this.commands['ollamasetmodel'] = (args) => { if(!args[0]) return this.terminal.print("Usage: ollamasetmodel ", 'warning'); this.terminal.ollamaManager.setModel(args[0]); }; this.commands['ollamasetproxy'] = (args) => { if(!args[0]) { const ep = this.terminal.ollamaManager.endpoint; return this.terminal.print(`Current Ollama endpoint: ${ep}`, 'info'); } this.terminal.ollamaManager.setEndpoint(args[0]); this.terminal.print(`Ollama endpoint set to: ${args[0]}`, 'success'); }; this.commands['ai'] = async (args) => { if(!args[0]) return this.terminal.print("Usage: ai ", 'warning'); await this.terminal.ollamaManager.chat(args.join(' ')); }; this.commands['ask'] = async (args) => { if(!args[0]) return this.terminal.print("Usage: ask ", 'warning'); await this.terminal.ollamaManager.chat(args.join(' ')); }; // Merged from OllamaModelsModule this.commands['models'] = () => this.listModels(); this.commands['model-info'] = (args) => this.modelInfo(args); this.commands['model-pull'] = (args) => this.pullModel(args); this.commands['model-delete'] = (args) => this.deleteModel(args); this.commands['model-run'] = (args) => this.runModel(args); } async listModels() { const endpoint = localStorage.getItem('webx11_ollama_endpoint') || 'http://localhost:11434'; try { const response = await fetch(`${endpoint}/api/tags`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); const models = data.models || []; if (models.length === 0) { this.terminal.print("No models found. Run 'ollama pull ' first.", "warning"); return; } this.terminal.print("=== Available Ollama Models ===", "info"); this.terminal.printHTML(``); models.forEach(m => { const sizeGB = (m.size / 1e9).toFixed(2); this.terminal.printHTML(``); }); this.terminal.printHTML(`
Name Size Family
${m.name} ${sizeGB} GB ${m.details?.family || 'N/A'}
`); } catch (e) { this.terminal.print(`Failed to fetch models: ${e.message}`, "error"); } } async modelInfo(args) { if (!args[0]) { this.terminal.print("Usage: model-info ", "warning"); return; } const endpoint = localStorage.getItem('webx11_ollama_endpoint') || 'http://localhost:11434'; try { const response = await fetch(`${endpoint}/api/show`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: args[0] }) }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); this.terminal.print(`=== ${args[0]} ===`, "info"); this.terminal.print(`License: ${data.license || 'N/A'}`); this.terminal.print(`Parameters: ${data.details?.parameter_size || 'N/A'}`); this.terminal.print(`Family: ${data.details?.family || 'N/A'}`); } catch (e) { this.terminal.print(`Failed to get model info: ${e.message}`, "error"); } } pullModel(args) { this.terminal.print("⚠️ Model pulling must be done via Ollama CLI", "warning"); this.terminal.print(`Run: ollama pull ${args[0] || ''}`, "info"); } deleteModel(args) { this.terminal.print("⚠️ Model deletion must be done via Ollama CLI", "warning"); this.terminal.print(`Run: ollama rm ${args[0] || ''}`, "info"); } async runModel(args) { if (!args[0]) { this.terminal.print("Usage: model-run [prompt]", "warning"); return; } const model = args[0]; const prompt = args.slice(1).join(' ') || 'Hello!'; this.terminal.print(`Running ${model}...`, "info"); await this.terminal.ollamaManager.chat(prompt, model); } }