// 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 — Create a new context profile',
'context-delete': 'context-delete — Delete a context profile',
'context-auto': 'context-auto [on|off] — Toggle auto-routing (detects intent from user input)',
'smart-ask': 'smart-ask — 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-\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['context-auto'] = (args) => this.toggleAutoRouting(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 ", "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 ", "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");
}
}
// ─── Intent Detection Engine ───
_getIntentPatterns() {
return {
'coding': [
/^code\b/i, /\b(edit|fix|write|create|implement|refactor|build)\s+(module|function|class|file|code|script)/i,
/\b(debug|bug|error|fix)\s+(code|module|function|script)/i, /\b(implement|write|create)\s+(a\s+)?(function|class|module|command)/i,
/\b(refactor|rewrite|optimize)\s+(code|module|function)/i, /\b(add\s+)(feature|command|functionality)/i
],
'debug': [
/^debug\b/i, /\b(error|crash|bug|fail|traceback|exception|broken|not working)\b/i,
/\b(why|what happened|diagnose|investigate|find out why)\b/i, /\b(check|inspect|examine)\s+(log|error|issue|problem)/i
],
'research': [
/^research\b/i, /\b(search|find|look up|research|investigate|analyze)\b/i,
/\b(what is|how does|tell me about|explain)\b.*\?$/i, /\b(find|search)\s+(for\s+)?(information|docs|documentation|article)/i
],
'creative': [
/^brainstorm\b/i, /\b(create|design|imagine|generate|compose|draft)\s+(story|poem|art|design|idea|concept|mindmap)/i,
/\b(creative|inspire|innovative|novel)\b/i
],
'system-admin': [
/^(config|setup|install|deploy|backup|restore|security|monitor|maintenance)\b/i,
/\b(configure|setup|install|deploy|backup|restore)\s+(system|server|module|service)/i,
/\b(security|permission|access|block|allow)\b/i
],
'chat': [
/^(hi|hello|hey|how are you|what's up|good morning|good evening)\b/i,
/^.{0,30}\?$/ // short questions
]
};
}
autoDetectIntent(text) {
if (!text || typeof text !== 'string') return { profile: null, confidence: 0 };
const patterns = this._getIntentPatterns();
const scores = {};
const lower = text.toLowerCase();
for (const [profile, regexes] of Object.entries(patterns)) {
let matches = 0;
for (const re of regexes) {
if (re.test(text) || re.test(lower)) matches++;
}
if (matches > 0) scores[profile] = matches;
}
// Code snippet detection (bias toward coding)
if (/[{([\s]*['"`]/.test(text) || /\b(function|class|const|let|var|import|export|=>)\b/.test(text)) {
scores['coding'] = (scores['coding'] || 0) + 2;
}
// Very short text → chat
if (text.length < 15 && !scores['coding'] && !scores['debug']) {
scores['chat'] = (scores['chat'] || 0) + 1;
}
// Find best match
let bestProfile = null;
let bestScore = 0;
let totalScore = 0;
for (const [profile, score] of Object.entries(scores)) {
totalScore += score;
if (score > bestScore) { bestScore = score; bestProfile = profile; }
}
// Calculate confidence (0-100)
const confidence = totalScore > 0 ? Math.round((bestScore / totalScore) * 100) : 0;
return { profile: bestProfile, confidence };
}
autoRouteContext(text) {
if (!text) return { switched: false, from: this.activeProfile, to: this.activeProfile, confidence: 0, reason: 'no input' };
// Check if auto-routing is enabled
const enabled = localStorage.getItem('webx11_context_auto') !== 'off';
if (!enabled) return { switched: false, from: this.activeProfile, to: this.activeProfile, confidence: 0, reason: 'auto-routing disabled' };
const result = this.autoDetectIntent(text);
if (!result.profile || result.confidence < 70) {
return { switched: false, from: this.activeProfile, to: this.activeProfile, confidence: result.confidence, reason: 'confidence too low (<70%)' };
}
// Don't switch if already on the best profile
if (result.profile === this.activeProfile) {
return { switched: false, from: this.activeProfile, to: this.activeProfile, confidence: result.confidence, reason: 'already on best profile' };
}
// Check if the target profile exists
if (!this.contextProfiles[result.profile]) {
return { switched: false, from: this.activeProfile, to: this.activeProfile, confidence: result.confidence, reason: 'profile "' + result.profile + '" not found' };
}
// Switch
const from = this.activeProfile;
this.setContext([result.profile]);
return { switched: true, from: from, to: result.profile, confidence: result.confidence, reason: 'intent detected' };
}
toggleAutoRouting(args) {
const val = args && args[0] ? args[0].toLowerCase() : null;
if (val === 'on' || val === 'true' || val === '1') {
localStorage.setItem('webx11_context_auto', 'on');
this.terminal.print('✅ Auto-routing enabled — context will switch based on intent', 'success');
} else if (val === 'off' || val === 'false' || val === '0') {
localStorage.setItem('webx11_context_auto', 'off');
this.terminal.print('⛔ Auto-routing disabled — use context to switch manually', 'warning');
} else {
const current = localStorage.getItem('webx11_context_auto') !== 'off';
this.terminal.print('Auto-routing: ' + (current ? 'ON' : 'OFF'), 'info');
this.terminal.print('Usage: context-auto on|off', 'info');
}
}
async smartAsk(args) {
if (!args[0]) {
this.terminal.print("Usage: smart-ask ", "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);
}
}
}