1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
// Extracted from newOS4 index.html — OllamaModelsModule
class OllamaModelsModule {
constructor() { this.commands = {}; this.terminal = null; }
getHelpInfo() {
return {
'models': 'models — List all available Ollama models',
'model-info': 'model-info <model-name> — Show details about a specific model',
'model-pull': 'model-pull <model-name> — Pull a model from Ollama registry',
'model-delete': 'model-delete <model-name> — Delete a model from local storage',
'model-run': 'model-run <model-name> [prompt] — Run inference with a model'
};
}
registerCommands() {
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 <model>' first.", "warning"); return;
}
this.terminal.print("=== Available Ollama Models ===", "info");
this.terminal.printHTML(`<table style="width: 100%; border-collapse: collapse; margin: 10px 0;">
<tr style="border-bottom: 1px solid #005500;">
<th style="text-align: left; padding: 5px;">Name</th>
<th style="text-align: left; padding: 5px;">Size</th>
<th style="text-align: left; padding: 5px;">Family</th>
</tr>`);
models.forEach(m => {
const sizeGB = (m.size / 1e9).toFixed(2);
this.terminal.printHTML(`<tr style="border-bottom: 1px solid #111;">
<td style="padding: 5px; color: #00ff00;">${m.name}</td>
<td style="padding: 5px; color: #888888;">${sizeGB} GB</td>
<td style="padding: 5px; color: #00aaff;">${m.details?.family || 'N/A'}</td>
</tr>`);
});
this.terminal.printHTML(`</table>`);
} catch (e) {
this.terminal.print(`Failed to fetch models: ${e.message}`, "error");
}
}
async modelInfo(args) {
if (!args[0]) {
this.terminal.print("Usage: model-info <model-name>", "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] || '<model-name>'}`, "info");
}
deleteModel(args) {
this.terminal.print("⚠️ Model deletion must be done via Ollama CLI", "warning");
this.terminal.print(`Run: ollama rm ${args[0] || '<model-name>'}`, "info");
}
async runModel(args) {
if (!args[0]) {
this.terminal.print("Usage: model-run <model-name> [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);
}
}
|