diff options
| -rw-r--r-- | main.html | 70 | ||||
| -rw-r--r-- | modules/core/module-aiassist.js | 106 | ||||
| -rw-r--r-- | modules/core/ollama-manager.js | 25 | ||||
| -rw-r--r-- | modules/core/terminal.js | 130 | ||||
| -rw-r--r-- | skills/agent-optimization-framework.md | 31 | ||||
| -rw-r--r-- | skills/index.json | 134 | ||||
| -rw-r--r-- | skills/macro-engine-debug.md | 10 | ||||
| -rw-r--r-- | skills/macro-engine-onboarding.md | 10 | ||||
| -rw-r--r-- | skills/project-profile-manager.md | 25 |
9 files changed, 404 insertions, 137 deletions
@@ -315,6 +315,26 @@ } .ollama-status.connected { background: rgba(0, 255, 0, 0.1); border: 1px solid var(--success-color); } .ollama-status.disconnected { background: rgba(255, 85, 85, 0.1); border: 1px solid var(--error-color); } + /* Toggle slider styles */ + #ollama-optimization-slider::before, #ollama-validator-slider::before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 2px; + bottom: 2px; + background: var(--text-color); + border-radius: 50%; + transition: 0.3s; + } + #ollama-optimization-toggle:checked + #ollama-optimization-slider::before, + #ollama-validator-toggle:checked + #ollama-validator-slider::before { + transform: translateX(22px); + } + #ollama-optimization-toggle:checked + #ollama-optimization-slider, + #ollama-validator-toggle:checked + #ollama-validator-slider { + border-color: var(--success-color); + } .copy-btn { position: absolute; top: 5px; @@ -635,6 +655,56 @@ </select> <button class="btn" onclick="webx11.setOllamaModel()" style="width: 100%;">Set Model</button> </div> + <hr style="border-color:var(--border-color); margin: 15px 0;"> + <h4 style="color: var(--accent-color); margin-bottom: 10px;">⚡ AI Agent Optimization</h4> + <div style="display:flex; align-items:center; gap:10px; margin-bottom: 12px;"> + <span style="color:var(--text-muted); font-size:0.85em;">Agent Loop Optimizations:</span> + <label style="position:relative; display:inline-block; width:48px; height:26px;"> + <input type="checkbox" id="ollama-optimization-toggle" onchange="webx11.toggleOptimization()" style="opacity:0; width:0; height:0;"> + <span id="ollama-optimization-slider" style="position:absolute; cursor:pointer; inset:0; background:var(--bg-tertiary); border:1px solid var(--border-color); border-radius:26px; transition:0.3s;"></span> + </label> + <span id="ollama-optimization-label" style="font-size:0.85em; color:var(--success-color);">Enabled</span> + </div> + <div style="font-size:0.8em; color:var(--text-muted); margin-bottom: 10px;"> + ⚡ Tool def caching, trivial query skip, parallel safe tools, debounced reflection<br> + <span style="color:var(--warning-color);">Disable for debugging or if model behaves unexpectedly. Reload after toggle.</span> + </div> + <hr style="border-color:var(--border-color); margin: 15px 0;"> + <h4 style="color: var(--info-color); margin-bottom: 10px;">🔍 Validator Agent (Future)</h4> + <div style="font-size:0.85em; color:var(--text-muted); margin-bottom: 10px;"> + A separate lightweight AI that validates the main agent's tool results. Has its own + endpoint and model — independent from your active AI model. + </div> + <div style="display:flex; align-items:center; gap:10px; margin-bottom: 10px;"> + <span style="color:var(--text-muted); font-size:0.85em;">Enable Validator:</span> + <label style="position:relative; display:inline-block; width:48px; height:26px;"> + <input type="checkbox" id="ollama-validator-toggle" onchange="webx11.toggleValidator()" style="opacity:0; width:0; height:0;"> + <span id="ollama-validator-slider" style="position:absolute; cursor:pointer; inset:0; background:var(--bg-tertiary); border:1px solid var(--border-color); border-radius:26px; transition:0.3s;"></span> + </label> + <span id="ollama-validator-label" style="font-size:0.85em; color:var(--text-muted);">Disabled</span> + </div> + <div style="margin-bottom: 8px;"> + <label style="display: block; margin-bottom: 3px; color: var(--text-muted); font-size:0.85em;">Validator Endpoint:</label> + <input type="text" id="validator-endpoint-input" class="module-url-input" value="http://localhost:11434" placeholder="http://localhost:11434" style="margin-bottom:6px;"> + <button class="btn" onclick="webx11.connectValidatorEndpoint()" style="width:100%; border-color:var(--info-color); color:var(--info-color);">🔌 Connect & Load Models</button> + <div id="validator-connection-status" style="font-size:0.8em; margin-top:4px;"></div> + </div> + <div style="margin-bottom: 10px;"> + <label style="display: block; margin-bottom: 3px; color: var(--text-muted); font-size:0.85em;">Validator Model:</label> + <select id="validator-model-select" class="module-url-input" style="margin-bottom:6px;" disabled> + <option value="">Connect to load models</option> + </select> + <button class="btn" onclick="webx11.saveValidatorConfig()" style="width:100%; border-color:var(--info-color); color:var(--info-color);">Save Validator Config</button> + </div> + <div style="font-size:0.8em; color:var(--warning-color); border:1px solid var(--border-color); border-radius:4px; padding:10px; margin-top:10px;"> + <strong>⚠️ Connection Notes</strong><br> + • Cloud models (deepseek-v4*, gemma4:*b-cloud) via Ollama proxy often <strong>ignore tool calls</strong> + and answer from training data instead. Use local models for tool calling.<br> + • To connect to local Ollama from a web page: set <code>OLLAMA_ORIGINS</code> on the server: + <code>export OLLAMA_ORIGINS="https://webx11.duckdns.org"</code> then restart Ollama.<br> + • Test local connection: open a terminal and run <code>curl http://localhost:11434/api/tags</code><br> + • If you see <strong>403</strong> errors in console: the <code>OLLAMA_ORIGINS</code> env var isn't matching your page URL. + </div> </div> <div class="modal-footer"> <button class="btn" onclick="webx11.closeOllamaManager()">Close</button> diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index 70882a9..602ae3e 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -35,7 +35,10 @@ const now = new Date(); const dateStr = now.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); const timeStr = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }); - return `Current date: ${dateStr}\nCurrent time: ${timeStr}\n\nYou are WebX11AI, the AI assistant embedded in the WebX11 browser terminal. You have direct access to read/write files, search the web, install packages, edit modules, and run terminal commands — all via tool calls. Use tools proactively. Keep responses concise.\n\n== TOOL REFERENCE == + const optimizationActive = this.terminal?.ollamaManager?.optimizationEnabled !== false; + const CR = String.fromCharCode(10); + const optNote = CR + CR + '== TOOL EXECUTION RULES (STRICT) ==' + CR + 'STRICT RULE 1: NEVER describe what the filesystem looks like from your training data. ALWAYS call list_files() or read_file() first, then report the ACTUAL result.' + CR + 'STRICT RULE 2: If you return text without calling any tool, you have failed. Use tools for every factual question.' + CR + 'STRICT RULE 3: A response like "/bin/, /etc/, /home/" without calling list_files is ILLEGAL. Call the tool.' + CR + 'STRICT RULE 4: When calling a tool, base your answer ENTIRELY on the tool result. If result is empty, say "empty".' + CR + CR; + return `Current date: ${dateStr}\nCurrent time: ${timeStr}\n\nYou are WebX11AI, the AI assistant embedded in the WebX11 browser terminal. You have direct access to read/write files, search the web, install packages, edit modules, and run terminal commands — all via tool calls. Use tools proactively. Keep responses concise.${optNote}== TOOL REFERENCE == You have these tools available. Use them WITHOUT asking permission unless the tool description says (DESTRUCTIVE): FILESYSTEM: @@ -436,7 +439,8 @@ RULES: } // Auto-load skills relevant to the user's query (awaited, not fire-and-forget) // Skip skill loading for trivial queries (< 10 chars, no actionable keywords) - const isTrivial = userMessage.length < 10 && !/\b(search|write|install|edit|create|make|find|delete|remove|change|update|improve|add|fix|build|set|load|save|help)\b/i.test(userMessage); + const optEnabled = this.terminal?.ollamaManager?.optimizationEnabled !== false; + const isTrivial = optEnabled && userMessage.length < 10 && !/\b(search|write|install|edit|create|make|find|delete|remove|change|update|improve|add|fix|build|set|load|save|help)\b/i.test(userMessage); if (!isTrivial) { try { const skillRes = await this.runTool('load_skills', { query: userMessage }); @@ -539,6 +543,42 @@ RULES: } return null; } + _parseToolBlocksFromText(text) { + if (!text) return []; + const toolCalls = []; + // Match ```tool name(args) or ```tool\nname(args) blocks + const blockRegex = /```tool(?:\s*\n)?\s*(\w+)\s*({[^}]*})?\s*```/gi; + let match; + while ((match = blockRegex.exec(text)) !== null) { + const name = match[1]; + let args = {}; + try { + if (match[2]) args = JSON.parse(match[2]); + } catch (e) { + // If JSON parse fails, treat as raw string + args = match[2] ? { path: match[2].replace(/[{}]/g,'').trim() } : {}; + } + toolCalls.push({ + id: 'text_' + Date.now() + '_' + toolCalls.length, + type: 'function', + function: { name, arguments: args } + }); + } + // Also handle single-line format: ```tool get_status{} + const simpleRegex = /```tool\s+(\w+)\s*\{([^}]*)\}\s*```/gi; + while ((match = simpleRegex.exec(text)) !== null) { + // Avoid duplicates — skip if already caught by blockRegex + const name = match[1]; + if (!toolCalls.find(tc => tc.function.name === name)) { + toolCalls.push({ + id: 'text_' + Date.now() + '_' + toolCalls.length, + type: 'function', + function: { name, arguments: {} } + }); + } + } + return toolCalls; + } _trackToolFailure(toolName, error) { try { const key = 'webx11_tool_failures'; @@ -571,7 +611,67 @@ RULES: if (this._cancelled) return { finalAnswer: null, toolTurns }; if (res.error) { this.terminal.print(`⚠️ AI model error (${thinkTime}s): ${res.error}`, 'error'); return { finalAnswer: null, toolTurns }; } if (res.message && !res.tool_calls) { - const text = res.message.content || ''; + let text = res.message.content || ''; + // Fallback: parse ```tool blocks from text when model writes them instead of native tool_calls + let parsedToolCalls = this._parseToolBlocksFromText(text); + if (parsedToolCalls.length > 0) { + this.terminal.print(`🔧 Parsed ${parsedToolCalls.length} tool call(s) from text block — turn ${toolTurns}/${this.MAX_TOOL_TURNS} (${thinkTime}s)`, 'info'); + // Extract any non-tool text as pending assistant content + const cleanText = text.replace(/```tool[\s\S]*?```/g, '').trim(); + if (cleanText) messages.push({ role: 'assistant', content: cleanText }); + messages.push({ role: 'assistant', content: '(calling tool via text block)' }); + let pendingText = cleanText || null; + const destructiveTools = parsedToolCalls.filter(tc => this.isDestructive(tc.function.name)); + const safeTools = parsedToolCalls.filter(tc => !this.isDestructive(tc.function.name)); + const safeResults = await Promise.all(safeTools.map(async (tc) => { + const fn = tc.function; + const t0 = Date.now(); + const toolResult = await this.runTool(fn.name, fn.arguments); + const t1 = Math.round((Date.now() - t0) / 1000); + return { fn, toolResult, t1 }; + })); + for (const { fn, toolResult, t1 } of safeResults) { + this.terminal.print(`🔧 Tool: ${fn.name}(${typeof fn.arguments === 'string' ? fn.arguments : JSON.stringify(fn.arguments)})`, 'info'); + const obs = this._summarizeObservation(toolResult, 150); + const err = this._isToolError(toolResult); + if (err) { + this.terminal.log('WARN', 'AI', `Tool ${fn.name} failed: ${err} (${t1}s)`); + this._trackToolFailure(fn.name, err); + this.terminal.print(`📊 Result (${t1}s): ⚠️ Error: ${err}`, 'warning'); + } else { + this.terminal.log('INFO', 'AI', `Tool ${fn.name} ok (${t1}s)`); + this.terminal.print(`📊 Result (${t1}s): ${obs}`, 'info'); + } + messages.push({ role: 'tool', content: toolResult }); + } + if (destructiveTools.length > 0) { + const approved = await this.confirmActionMulti(destructiveTools); + if (approved) { + for (const tc of destructiveTools) { + const fn = tc.function; + const t0 = Date.now(); + this.terminal.print(`🔧 Tool: ${fn.name}(${typeof fn.arguments === 'string' ? fn.arguments : JSON.stringify(fn.arguments)})`, 'info'); + const toolResult = await this.runTool(fn.name, fn.arguments); + const t1 = Math.round((Date.now() - t0) / 1000); + const dObs = this._summarizeObservation(toolResult, 150); + const dErr = this._isToolError(toolResult); + if (dErr) { + this.terminal.log('WARN', 'AI', `Tool ${fn.name} failed: ${dErr} (${t1}s)`); + this._trackToolFailure(fn.name, dErr); + this.terminal.print(`📊 Result (${t1}s): ⚠️ Error: ${dErr}`, 'warning'); + } else { + this.terminal.log('INFO', 'AI', `Tool ${fn.name} ok (${t1}s)`); + this.terminal.print(`📊 Result (${t1}s): ${dObs}`, 'info'); + } + messages.push({ role: 'tool', content: toolResult }); + } + } else { + messages.push({ role: 'tool', content: `Destructive actions (${destructiveTools.map(tc => tc.function.name).join(', ')}) denied.` }); + } + } + if (pendingText) messages.push({ role: 'assistant', content: pendingText }); + continue; + } this.terminal.printAIResponse(text || '(no response)'); if (text) this.terminal.ollamaManager.fireResponseHooks(text); this.terminal.print(`💬 AI answered (turn ${toolTurns}/${this.MAX_TOOL_TURNS}, ${thinkTime}s)`, 'info'); diff --git a/modules/core/ollama-manager.js b/modules/core/ollama-manager.js index 3f46b13..34ece29 100644 --- a/modules/core/ollama-manager.js +++ b/modules/core/ollama-manager.js @@ -11,6 +11,12 @@ class OllamaManager { this.currentModel = localStorage.getItem('webx11_ollama_model') || 'gemma4:31b-cloud'; this.responseHooks = []; this._abortController = null; + // --- AI Agent Loop Optimization Toggle --- + this.optimizationEnabled = localStorage.getItem('webx11_optimization_enabled') !== 'false'; + // --- Validator Agent Config (future) --- + this.validatorEnabled = localStorage.getItem('webx11_validator_enabled') === 'true'; + this.validatorModel = localStorage.getItem('webx11_validator_model') || ''; + this.validatorEndpoint = localStorage.getItem('webx11_validator_endpoint') || ''; // Build fallback endpoints this.fallbackEndpoints = []; const origin = typeof window !== 'undefined' ? window.location.origin : ''; @@ -900,6 +906,25 @@ class OllamaManager { saveSettings() { localStorage.setItem('webx11_ollama_endpoint', this.endpoint); localStorage.setItem('webx11_ollama_model', this.currentModel); + localStorage.setItem('webx11_optimization_enabled', this.optimizationEnabled ? 'true' : 'false'); + localStorage.setItem('webx11_validator_enabled', this.validatorEnabled ? 'true' : 'false'); + localStorage.setItem('webx11_validator_model', this.validatorModel); + localStorage.setItem('webx11_validator_endpoint', this.validatorEndpoint || ''); + } + + setOptimizationEnabled(val) { + this.optimizationEnabled = !!val; + this.terminal?.print(`Agent optimization ${this.optimizationEnabled ? 'enabled' : 'disabled'}. Reload to apply.`, 'info'); + this.saveSettings(); + } + + setValidatorConfig(enabled, model) { + this.validatorEnabled = !!enabled; + if (model !== undefined) { + this.validatorModel = model; + localStorage.setItem('webx11_validator_model', model); + } + this.saveSettings(); } getModels() { return this.models; } 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(); diff --git a/skills/agent-optimization-framework.md b/skills/agent-optimization-framework.md new file mode 100644 index 0000000..78a143d --- /dev/null +++ b/skills/agent-optimization-framework.md @@ -0,0 +1,31 @@ +--- +name: agent-optimization-framework +description: System for reducing tool-call latency and increasing agentic precision through programmatic workflows. +tags: [optimization, agentic-workflow, efficiency, tool-calls] +--- + +# Agent Optimization Framework + +## 🎯 Objective +Transition from manual prompt-based reasoning to a programmatic "Compiler" approach to reduce turns and eliminate hallucinations. + +## 🛠️ Optimization Protocols + +### 1. VFS Cache & Batching (Latency Reduction) +- **Batching:** If a task requires information from multiple files, call `read_file` for all relevant paths in a single turn rather than sequentially. +- **Contextual Caching:** Store the result of `list_files` in temporary memory to avoid redundant calls to the same directory within the same task. + +### 2. Speculative Tool-Calling (Turn Reduction) +- **Anticipation:** Predict the next 2-3 logical steps. If they are independent (e.g., `web_search` followed by `get_status`), execute them in parallel. +- **Pre-fetching:** When a user asks about a module, call `get_module_status` AND `view_module` immediately instead of waiting for the user's second prompt. + +### 3. Strict Validation Loop (Precision) +- **Cross-Reference:** Compare tool output against the `get_help` command reference to ensure parameters are used correctly. +- **Auto-Fallback:** If a `read_file` returns empty, immediately try `list_files` to verify the path before reporting a failure to the user. + +## 🔄 Implementation Workflow +1. **REASON:** Identify the target goal and all required dependencies. +2. **BATCH:** Group all independent data-gathering tool calls. +3. **EXECUTE:** Run the batch. +4. **VALIDATE:** Verify the output against the expected schema. +5. **REFINE:** If the result is missing or incorrect, trigger the auto-fallback protocol. diff --git a/skills/index.json b/skills/index.json index 373efdf..6d57936 100644 --- a/skills/index.json +++ b/skills/index.json @@ -1,133 +1 @@ -{ - "web-search-and-fetch": { - "name": "web-search-and-fetch", - "description": "How to search the web and fetch URL content using the WebX11 proxy API", - "category": "research", - "tags": [ - "search", - "fetch", - "web", - "proxy", - "api" - ] - }, - "webdav-sync": { - "name": "webdav-sync", - "description": "Sync, backup, and restore VFS via WebDAV in WebX11. CRITICAL: Only use verified commands.", - "category": "system", - "tags": [ - "webdav", - "sync", - "backup", - "cloud", - "vfs" - ] - }, - "test": { - "name": "test", - "description": "No description", - "category": "general", - "tags": [] - }, - "module-management": { - "name": "module-management", - "description": "How to view, edit, test, reload modules and manage startup configuration", - "category": "dev", - "tags": [ - "modules", - "editing", - "code", - "self-improvement" - ] - }, - "backup-and-restore": { - "name": "backup-and-restore", - "description": "How to backup, restore, and export WebX11 data", - "category": "system", - "tags": [ - "backup", - "restore", - "export", - "import", - "persistence" - ] - }, - "navigating-the-terminal": { - "name": "navigating-the-terminal", - "description": "How to explore the WebX11 terminal, find commands, check status, and navigate the filesystem", - "category": "system", - "tags": [ - "terminal", - "navigation", - "help", - "filesystem" - ] - }, - "system-maintenance": { - "name": "system-maintenance", - "description": "How to reset, troubleshoot, and maintain the WebX11 terminal", - "category": "system", - "tags": [ - "system", - "maintenance", - "reset", - "troubleshoot", - "config" - ] - }, - "mindmap-workflow": { - "name": "mindmap-workflow", - "description": "How to create, view, edit, and manage brainstorming mindmaps", - "category": "productivity", - "tags": [ - "mindmap", - "brainstorming", - "planning", - "organization" - ] - }, - "webx11-dev-cycle": { - "name": "webx11-dev-cycle", - "description": "Professional workflow for analyzing, prototyping, and implementing new features in WebX11.", - "category": "general", - "tags": [] - }, - "mindmap-user-guide": { - "name": "mindmap-user-guide", - "description": "How to create, view, and manage brainstorming mindmaps using the mindmap terminal module", - "category": "productivity", - "tags": [ - "mindmap", - "brainstorming", - "organization", - "planning" - ] - }, - "memory-and-profile": { - "name": "memory-and-profile", - "description": "How to use the user profile system, session memory, and pattern tracking for persistent context", - "category": "system", - "tags": [ - "memory", - "profile", - "session", - "persistence" - ] - }, - "memory-map": { - "name": "memory-map", - "description": "Maintain and query the persistent memory map at /memory/map.json for Agando/DarkMoto Systems.", - "category": "system", - "tags": [] - }, - "skills-system-guide": { - "name": "skills-system-guide", - "description": "How to use the skills system: load, create, patch, list, and audit skills for persistent procedural memory", - "category": "system", - "tags": [ - "skills", - "system", - "meta" - ] - } -}
\ No newline at end of file +{"navigating-the-terminal":{"name":"navigating-the-terminal","description":"How to explore the WebX11 terminal, find commands, check status, and navigate the filesystem","tags":["terminal","navigation","help","filesystem"],"category":"system","created":"2026-05-28T15:39:51.676Z","updated":"2026-05-28T15:39:51.676Z"},"memory-and-profile":{"name":"memory-and-profile","description":"How to use the user profile system, session memory, and pattern tracking for persistent context","tags":["memory","profile","session","persistence"],"category":"system","created":"2026-05-28T15:39:51.676Z","updated":"2026-05-28T15:39:51.676Z"},"web-search-and-fetch":{"name":"web-search-and-fetch","description":"How to search the web and fetch URL content using the WebX11 proxy API","tags":["search","fetch","web","proxy","api"],"category":"research","created":"2026-05-28T15:39:51.676Z","updated":"2026-05-28T15:39:51.676Z"},"module-management":{"name":"module-management","description":"How to view, edit, test, reload modules and manage startup configuration","tags":["modules","editing","code","self-improvement"],"category":"dev","created":"2026-05-28T15:39:51.676Z","updated":"2026-05-28T15:39:51.676Z"},"system-maintenance":{"name":"system-maintenance","description":"How to reset, troubleshoot, and maintain the WebX11 terminal","tags":["system","maintenance","reset","troubleshoot","config"],"category":"system","created":"2026-05-28T15:39:51.676Z","updated":"2026-05-28T15:39:51.676Z"},"backup-and-restore":{"name":"backup-and-restore","description":"How to backup, restore, and export WebX11 data","tags":["backup","restore","export","import","persistence"],"category":"system","created":"2026-05-28T15:39:51.676Z","updated":"2026-05-28T15:39:51.676Z"},"mindmap-workflow":{"name":"mindmap-workflow","description":"How to create, view, edit, and manage brainstorming mindmaps","tags":["mindmap","brainstorming","planning","organization"],"category":"productivity","created":"2026-05-28T15:39:51.677Z","updated":"2026-05-28T15:39:51.677Z"},"skills-system-guide":{"name":"skills-system-guide","description":"How to use the skills system: load, create, patch, list, and audit skills for persistent procedural memory","tags":["skills","system","meta"],"category":"system","created":"2026-05-28T15:39:51.677Z","updated":"2026-05-28T15:39:51.677Z"},"mindmap-user-guide":{"name":"mindmap-user-guide","description":"How to create, view, and manage brainstorming mindmaps using the mindmap terminal module","tags":["mindmap","brainstorming","organization","planning"],"category":"productivity","created":"2026-05-28T15:40:02.250Z","updated":"2026-05-28T15:40:02.250Z"},"webx11-task-manager":{"name":"webx11-task-manager","description":"","tags":["task-management","productivity","vfs","organization"],"category":"system","created":"2026-05-28T16:32:01.429Z","updated":"2026-05-28T16:32:01.430Z"},"mindmap-architect-3d":{"name":"mindmap-architect-3d","description":"","tags":["visual","map","3d","mermaid","ui"],"category":"dev","created":"2026-05-29T00:10:49.903Z","updated":"2026-05-29T00:10:49.903Z"},"mindmap-navigation-pro":{"name":"mindmap-navigation-pro","description":"","tags":["ui","mobile","js","mindmap"],"category":"ui-dev","created":"2026-05-29T00:22:20.790Z","updated":"2026-05-29T00:22:20.790Z"},"agent-optimization-framework":{"name":"agent-optimization-framework","description":"","tags":["optimization","agentic-workflow","efficiency","tool-calls"],"category":"system","created":"2026-05-29T14:52:23.451Z","updated":"2026-05-29T14:52:23.451Z"},"macro-engine-debug":{"name":"macro-engine-debug","description":"","tags":["debug","a-repair","macro"],"category":"system","created":"2026-05-29T15:06:24.057Z","updated":"2026-05-29T15:06:24.057Z"},"macro-engine-onboarding":{"name":"macro-engine-onboarding","description":"","tags":["onboarding","context","macro"],"category":"system","created":"2026-05-29T15:06:24.064Z","updated":"2026-05-29T15:06:24.064Z"},"project-profile-manager":{"name":"project-profile-manager","description":"","tags":["context","memory","workspace"],"category":"system","created":"2026-05-29T15:08:44.897Z","updated":"2026-05-29T15:08:44.897Z"}}
\ No newline at end of file diff --git a/skills/macro-engine-debug.md b/skills/macro-engine-debug.md new file mode 100644 index 0000000..cd43a29 --- /dev/null +++ b/skills/macro-engine-debug.md @@ -0,0 +1,10 @@ +--- +name: macro-engine-debug +description: A compound operation to audit, view, and test a module in one logical flow. +steps: + 1. Call get_module_status to identify if the module is loaded/modified. + 2. Call view_module(name) to analyze the source. + 3. Call run_command('test-module <name>') or similar health checks. + 4. Synthesize a health report. +tags: [debug, a-repair, macro] +--- diff --git a/skills/macro-engine-onboarding.md b/skills/macro-engine-onboarding.md new file mode 100644 index 0000000..46c2677 --- /dev/null +++ b/skills/macro-engine-onboarding.md @@ -0,0 +1,10 @@ +--- +name: macro-engine-onboarding +description: A rapid context-recovery sequence to understand current session state. +steps: + 1. Call session_recent(3) to see previous work. + 2. Call list_files('') to see current root state. + 3. Call load_skills('current-task') to find relevant procedures. + 4. Call user_list to check for project-specific flags. +tags: [onboarding, context, macro] +--- diff --git a/skills/project-profile-manager.md b/skills/project-profile-manager.md new file mode 100644 index 0000000..03eead8 --- /dev/null +++ b/skills/project-profile-manager.md @@ -0,0 +1,25 @@ +--- +name: project-profile-manager +description: Handles saving and loading of project-specific context bundles. +tags: [context, memory, workspace] +--- + +# Project Profile Manager + +## Profile Structure +Profiles are stored in `/profiles/<name>.json` containing: +- `preferences`: Key-value pairs for `user_set` +- `required_skills`: List of skills to be loaded via `load_skills` +- `working_dir`: The primary VFS path for the project +- `session_anchor`: Last known session date/ID + +## Workflow: Save +1. Capture current working directory using `get_current_dir`. +2. Retrieve relevant `user_list` keys. +3. Save as JSON to `/profiles/`. + +## Workflow: Load +1. Read `/profiles/<name>.json`. +2. Apply `user_set` for all stored preferences. +3. Call `load_skills` for all registered project skills. +4. Navigate to `working_dir`. |