aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-smartctx.js
blob: 0bfc91aeeeba4c4f84380ed057db2c6c4c356d79 (plain)
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Extracted from newOS4 index.html — SmartContextModule
        class SmartContextModule {
            constructor() {
                this.commands = {}; this.terminal = null;
                this.contextProfiles = this.loadProfiles(); this.activeProfile = this.loadActiveProfile();
            }
            getHelpInfo() {
                return {
                    'context': 'context [name] — Set or view current context profile',
                    'contexts': 'contexts — List all available context profiles',
                    'context-new': 'context-new <name> <displayName> <systemPrompt> — Create a new context profile',
                    'context-delete': 'context-delete <name> — Delete a context profile',
                    'smart-ask': 'smart-ask <question> — Ask a question using the active context'
                };
            }
            loadProfiles() {
                try {
                    const saved = localStorage.getItem('webx11_context_profiles');
                    return saved ? JSON.parse(saved) : this.getDefaultProfiles();
                } catch (e) { return this.getDefaultProfiles(); }
            }
            saveProfiles() {
                localStorage.setItem('webx11_context_profiles', JSON.stringify(this.contextProfiles));
            }
            loadActiveProfile() {
                try {
                    const saved = localStorage.getItem('webx11_active_context_profile');
                    if (saved && this.contextProfiles[saved]) return saved;
                } catch (e) {}
                return null;
            }
            saveActiveProfile() {
                try {
                    if (this.activeProfile) {
                        localStorage.setItem('webx11_active_context_profile', this.activeProfile);
                    } else {
                        localStorage.removeItem('webx11_active_context_profile');
                    }
                } catch (e) {}
            }
            getDefaultProfiles() {
                return {
                    'coding': { name: 'Coding Assistant', systemPrompt: "You are a WebX11 newOS4 coding expert. You have access to the full terminal, VFS, and module system.\n\nAvailable commands: view_module, edit_module, test_module, reload_module, list_modified_modules, check_updates, load-local, loadmod, removemod, startup-modules, node, js-run, git, diff, patch\n\nSkills available: module-management (view/edit/test/reload modules), skills-system-guide (create/patch skills)\n\nBehavior:\n- Always show exact code changes when editing modules\n- Use edit_module for modifications, test_module to verify\n- Create checkpoints before risky edits: checkpoint mod-edit-<name>\n- Reference the module-management skill for the full workflow\n- When the user reports a bug, first view_module to inspect, then edit\n- Use nvfs_resolve to find relevant files before editing\n- Prefer write_file for creating new files, edit_module for modifying modules", temperature: 0.7 },
                    'debug': { name: 'Debug Helper', systemPrompt: "You are a WebX11 newOS4 debugging expert. Your goal is to diagnose and fix issues systematically.\n\nAvailable commands: debug, debug-ai, debug-ai-last, debug-ai-send, debug-ai-log, logs, logrotate, health-check, check, mem, status, archive-list, archive-read, guardrail, shadow, shadow-commit, shadow-rollback\n\nSkills available: debug-panel-and-logs (toggle debug panel, session logging, diagnostics), system-maintenance (health checks, config, security)\n\nBehavior:\n- Start with health-check and check to assess system state\n- Use debug-ai to see the last AI tool call and response\n- Use logs 50 ERROR to find error entries\n- Check browser console for JS errors\n- Use guardrail to inspect security policies\n- Use shadow for safe execution of risky commands\n- Always check module loading status first", temperature: 0.3 },
                    'creative': { name: 'Creative Writer', systemPrompt: "You are a creative assistant for WebX11 newOS4. You help with brainstorming, content creation, and design.\n\nAvailable commands: mindmap new/add/show/save/load/export, floating-add/remove/list, ai-system, ai-config\n\nSkills available: mindmap-workflow (create/view/edit mindmaps), floating-ui (create floating buttons/menus/panels)\n\nBehavior:\n- Use mindmap for brainstorming and organizing ideas\n- Use floating-add to create quick-access UI elements\n- Use web_search and web_fetch for research and inspiration\n- Higher temperature (0.9) for creative divergence\n- When the user says \"brainstorm\" or \"diagram\", create a mindmap\n- Use create_mindmap AI tool for visual architecture diagrams\n- Reference the mindmap-workflow skill for full capabilities", temperature: 0.9 },
                    'technical': { name: 'Technical Docs', systemPrompt: "You are a technical documentation expert for WebX11 newOS4. You help with docs, guides, and system understanding.\n\nAvailable commands: help, commands, status, modules, health-check, nvfs-index, nvfs-resolve, view_module, cat, edit, grep, find, tree\n\nSkills available: navigating-terminal (explore terminal, filesystem, system state), web-search-and-fetch (search web, fetch URLs), skills-system-guide (create/patch skills)\n\nBehavior:\n- Use help and commands to discover available functionality\n- Use nvfs-resolve to find files by concept\n- Use view_module to inspect module source for documentation\n- When creating documentation, use write_file to save to VFS\n- Reference the navigating-terminal skill for filesystem exploration\n- Use web_search for external research", temperature: 0.3 },
                    'chat': { name: 'Casual Chat', systemPrompt: "You are a friendly, helpful assistant for WebX11 newOS4. You handle general questions, casual conversation, and light tasks.\n\nAvailable commands: ai, ask, search, fetch, status, help, user_get, user_set, session_save, session_recent, my-set, my-get\n\nSkills available: memory-and-profile (user profile, session memory, checkpoints), web-search-and-fetch (search web, fetch URLs)\n\nBehavior:\n- Be conversational and approachable\n- Use user_get/user_set to remember user preferences\n- Use session_recent at start to recall past work\n- Use session_save after completing tasks\n- For complex tasks, suggest switching to a more specific context profile\n- Reference the memory-and-profile skill for persistence features", temperature: 0.8 },
                    'system-admin': { name: 'System Admin', systemPrompt: "You are a WebX11 newOS4 system administrator. You handle maintenance, backup, security, and configuration.\n\nAvailable commands: config-list, config-set, config-delete, config-reset, security-level, security, cmd-allow, cmd-deny, backup, vfs-export, webdav-backup, webdav-restore, webdav-config, webdav-status, factory-reset, reset-vfs, checkpoint, checkpoint-list, rollback, health-check, check_updates, font-size\n\nSkills available: system-maintenance (reset, config, security, health checks), backup-and-restore (VFS backup, WebDAV cloud backup, restore), webdav-operations (cloud storage, file sync), security-and-safety (security levels, command blocking)\n\nBehavior:\n- Always create a checkpoint before making system changes\n- Use webdav-backup before destructive operations\n- Check security-level before running commands\n- Use health-check for full system audit\n- Reference the system-maintenance skill for reset procedures\n- Reference the backup-and-restore skill for data safety", temperature: 0.3 },
                    'research': { name: 'Research Assistant', systemPrompt: "You are a research assistant for WebX11 newOS4. You gather information, analyze data, and synthesize findings.\n\nAvailable commands: search, fetch, web_search, web_fetch, nvfs-resolve, nvfs-index, grep, find, cat, view_module, session_recent, session_load, session_stats\n\nSkills available: web-search-and-fetch (search web, fetch URL content), memory-and-profile (session memory, checkpoints), navigating-terminal (explore filesystem)\n\nBehavior:\n- Start with web_search for external research\n- Use nvfs-resolve to find relevant VFS files\n- Use session_recent to check past work on the topic\n- Use fetch to read full articles from URLs\n- Synthesize findings before presenting\n- Reference the web-search-and-fetch skill for search flags", temperature: 0.5 },
                    'security': { name: 'Security Expert', systemPrompt: "You are a WebX11 newOS4 security expert. You handle threat assessment, command control, and safety.\n\nAvailable commands: security, security-level, cmd-allow, cmd-deny, guardrail, guardrail-add, guardrail-remove, shadow, shadow-commit, shadow-rollback, health-check, check, logs, debug\n\nSkills available: security-and-safety (security levels, command blocking, safety checklist), debug-panel-and-logs (diagnostics, logging), system-maintenance (config, health checks)\n\nBehavior:\n- Always check current security level first with security\n- Use guardrail to inspect and manage security policies\n- Use shadow for safe execution of suspicious commands\n- Never recommend factory-reset without backup first\n- Use cmd-deny to block dangerous commands\n- Reference the security-and-safety skill for level descriptions", temperature: 0.2 }
                };
            }
            registerCommands() {
                this.commands['context'] = (args) => this.setContext(args);
                this.commands['contexts'] = () => this.listContexts();
                this.commands['context-new'] = (args) => this.createContext(args);
                this.commands['context-delete'] = (args) => this.deleteContext(args);
                this.commands['smart-ask'] = (args) => this.smartAsk(args);
            }
            setContext(args) {
                if (!args[0]) {
                    this.terminal.print(`Current context: ${this.activeProfile || 'none'}`, "info"); return;
                }
                if (this.contextProfiles[args[0]]) {
                    this.activeProfile = args[0];
                    this.saveActiveProfile();
                    this.terminal.print(`Context set to: ${this.contextProfiles[args[0]].name}`, "success");
                    // Also switch agent loop profile to match
                    const PROFILE_MAP = {
                        'coding': 'coder',
                        'debug': 'minimal',
                        'creative': 'creative',
                        'technical': 'research',
                        'chat': 'default',
                        'system-admin': 'safe',
                        'research': 'research',
                        'security': 'safe'
                    };
                    const targetLoop = PROFILE_MAP[args[0]];
                    if (targetLoop) {
                        const aiMod = this.terminal?.moduleManager?.modules?.WebX11AIAssistantModule;
                        if (aiMod && aiMod._switchLoopProfile) {
                            aiMod._switchLoopProfile(targetLoop);
                            this.terminal.print(`  Agent loop switched to: ${targetLoop}`, "text-muted");
                        }
                    } else {
                        // Custom profile — rebuild system prompt without loop switch
                        const aiMod = this.terminal?.moduleManager?.modules?.WebX11AIAssistantModule;
                        if (aiMod && aiMod.buildSystemPrompt) {
                            aiMod.systemPrompt = aiMod.buildSystemPrompt();
                        }
                        this.terminal.print(`  No agent loop mapped for '${args[0]}'`, "text-muted");
                    }
                } else {
                    this.terminal.print(`Profile '${args[0]}' not found`, "error");
                }
            }
            listContexts() {
                this.terminal.print("=== Context Profiles ===", "info");
                Object.entries(this.contextProfiles).forEach(([key, profile]) => {
                    const active = key === this.activeProfile ? ' ✅' : '';
                    this.terminal.print(`${key}: ${profile.name}${active}`);
                });
            }
            createContext(args) {
                if (args.length < 3) {
                    this.terminal.print("Usage: context-new <name> <displayName> <systemPrompt>", "warning"); return;
                }
                const name = args[0], displayName = args[1], systemPrompt = args.slice(2).join(' ');
                this.contextProfiles[name] = { name: displayName, systemPrompt, temperature: 0.7 };
                this.saveProfiles();
                this.terminal.print(`Context profile '${name}' created`, "success");
            }
            deleteContext(args) {
                if (!args[0]) {
                    this.terminal.print("Usage: context-delete <name>", "warning"); return;
                }
                if (this.contextProfiles[args[0]]) {
                    delete this.contextProfiles[args[0]];
                    this.saveProfiles();
                    if (this.activeProfile === args[0]) { this.activeProfile = null; }
                    this.terminal.print(`Context profile '${args[0]}' deleted`, "success");
                } else {
                    this.terminal.print(`Profile '${args[0]}' not found`, "error");
                }
            }
            async smartAsk(args) {
                if (!args[0]) {
                    this.terminal.print("Usage: smart-ask <your-question>", "warning"); return;
                }
                let systemPrompt = "You are a helpful assistant.";
                let temperature = 0.7;
                if (this.activeProfile && this.contextProfiles[this.activeProfile]) {
                    const profile = this.contextProfiles[this.activeProfile];
                    systemPrompt = profile.systemPrompt;
                    temperature = profile.temperature || 0.7;
                    this.terminal.print(`Using context: ${profile.name} (temp: ${temperature})`, "info");
                }
                // Use agentic loop via the AI assistant module for tool-enabled responses
                const aiModule = this.terminal?.moduleManager?.modules?.WebX11AIAssistantModule;
                if (aiModule) {
                    // Set temperature on ollamaManager modelParams temporarily
                    const om = this.terminal?.ollamaManager;
                    if (!om) { this.terminal?.print('⚠️ Ollama manager not available', 'error'); return; }
                    const savedTemp = om.modelParams ? om.modelParams.temperature : undefined;
                    if (om.modelParams) {
                        om.modelParams.temperature = temperature;
                    }
                    try {
                        const messages = [
                            { role: 'system', content: systemPrompt },
                            { role: 'user', content: args.join(' ') }
                        ];
                        const result = await om.chatWithTools(messages, aiModule.getToolDefinitions());
                        if (result && result.message) {
                            this.terminal.printAIResponse(result.message.content || '(no response)');
                        } else if (result && result.error) {
                            this.terminal.print(`⚠️ AI error: ${result.error}`, 'error');
                        }
                    } finally {
                        if (om.modelParams && savedTemp !== undefined) {
                            om.modelParams.temperature = savedTemp;
                        }
                    }
                } else {
                    // Fallback: simple chat with temperature
                    const om = this.terminal.ollamaManager;
                    const fullPrompt = `${systemPrompt}\n\nUser: ${args.join(' ')}`;
                    await om.chat(fullPrompt);
                }
            }
        }