aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-aiassist.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/module-aiassist.js')
-rw-r--r--modules/core/module-aiassist.js74
1 files changed, 73 insertions, 1 deletions
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js
index edc5225..eb41af9 100644
--- a/modules/core/module-aiassist.js
+++ b/modules/core/module-aiassist.js
@@ -384,6 +384,40 @@ RULES:
description: 'Session aggregate stats',
parameters: { type: 'object', properties: {}, required: [] }
}
+ }, {
+ type: 'function',
+ function: {
+ name: 'list_agents',
+ description: 'List registered agent IDs, status, and capabilities',
+ parameters: { type: 'object', properties: {}, required: [] }
+ }
+ }, {
+ type: 'function',
+ function: {
+ name: 'delegate_task',
+ description: '(DESTRUCTIVE) Delegate a task to a worker agent. Auto-spawns if needed.',
+ parameters: {
+ type: 'object',
+ properties: {
+ task: { type: 'string', description: 'The task description to delegate' }
+ },
+ required: ['task']
+ }
+ }
+ }, {
+ type: 'function',
+ function: {
+ name: 'spawn_agent',
+ description: '(DESTRUCTIVE) Spawn a new worker agent with a role and capabilities',
+ parameters: {
+ type: 'object',
+ properties: {
+ role: { type: 'string', description: 'Agent role (e.g. researcher, writer)' },
+ capabilities: { type: 'string', description: 'Comma-separated capabilities (optional)' }
+ },
+ required: ['role']
+ }
+ }
}];
}
getHelpInfo() {
@@ -568,7 +602,14 @@ RULES:
(entry.error ? ' <span class="debug-err">⚠️</span>' : '') +
'</div>';
}
- panel.innerHTML = '<div class="debug-header" style="display:flex;justify-content:space-between;align-items:center;padding:6px 10px;border-bottom:1px solid #333;font-weight:bold;color:var(--success-color);font-size:0.9em;">🔧 Tool Log <span class="debug-count" style="color:var(--text-muted);font-weight:normal;font-size:0.85em;">' + this._toolCallLog.length + ' calls</span><span style="cursor:pointer;color:var(--text-muted);font-size:1.1em;touch-action:manipulation;" onclick="var p=document.getElementById(\'debug-panel\');if(p)p.style.display=\'none\';var a=window.webx11&&webx11.moduleManager&&webx11.moduleManager.modules&&webx11.moduleManager.modules.WebX11AIAssistantModule;if(a)a._debugPanelEnabled=false;">✕</span></div>' + html;
+ panel.innerHTML = '<div class="debug-header" style="display:flex;justify-content:space-between;align-items:center;padding:6px 10px;border-bottom:1px solid #333;font-weight:bold;color:var(--success-color);font-size:0.9em;flex-wrap:wrap;gap:4px;">' +
+ '<span>🔧 Tool Log <span class="debug-count" style="color:var(--text-muted);font-weight:normal;font-size:0.85em;">' + this._toolCallLog.length + ' calls</span></span>' +
+ '<span style="display:flex;gap:4px;">' +
+ '<button onclick="var m=webx11.moduleManager.modules.WebX11AIAssistantModule;if(m){var t=m._toolCallLog.map(function(e){return\'#\'+e.turn+\' \'+e.name+\' (\'+e.duration+\'s)\'+(e.error?\' ⚠️\':\'\')+\'\\n\'+JSON.stringify(e.args).substring(0,80)}).join(\'\\n\\n\');navigator.clipboard.writeText(t).then(function(){m.terminal&&m.terminal.print(\'📋 Debug log copied to clipboard\',\'success\')}).catch(function(){prompt(\'Copy debug log:\',t)})}" style="background:var(--bg-tertiary);border:1px solid var(--border-color);color:var(--text-color);padding:2px 6px;border-radius:3px;cursor:pointer;font-size:0.75em;min-height:24px;">📋</button>' +
+ '<button onclick="var m=webx11.moduleManager.modules.WebX11AIAssistantModule;if(m){var json=JSON.stringify(m._toolCallLog,null,2);var b=new Blob([json],{type:\'application/json\'});var u=URL.createObjectURL(b);var a=document.createElement(\'a\');a.href=u;a.download=\'debug-log-\'+new Date().toISOString().slice(0,19)+\'.json\';document.body.appendChild(a);a.click();setTimeout(function(){document.body.removeChild(a);URL.revokeObjectURL(u)},2000);m.terminal&&m.terminal.print(\'📥 Debug log exported\',\'success\')}" style="background:var(--bg-tertiary);border:1px solid var(--border-color);color:var(--text-color);padding:2px 6px;border-radius:3px;cursor:pointer;font-size:0.75em;min-height:24px;">📥</button>' +
+ '<button onclick="var m=webx11.moduleManager.modules.WebX11AIAssistantModule;if(m){var existing=[];var raw=m.terminal.fs.readFile(\'/debug.log\');if(raw){try{existing=JSON.parse(raw);}catch(e){}}var log=m._toolCallLog;var seen={};existing.forEach(function(e){seen[e.turn]=true;});log.forEach(function(e){if(!seen[e.turn]){existing.push(e);seen[e.turn]=true;}});var json=JSON.stringify(existing,null,2);m.terminal.fs.writeFile(\'/debug.log\',json);m.terminal.print(\'💾 Debug log appended — \'+existing.length+\' entries total\',\'success\')}" style="background:var(--bg-tertiary);border:1px solid var(--border-color);color:var(--text-color);padding:2px 6px;border-radius:3px;cursor:pointer;font-size:0.75em;min-height:24px;">💾</button>' +
+ '<span style="cursor:pointer;color:var(--text-muted);font-size:1.1em;touch-action:manipulation;" onclick="var p=document.getElementById(\'debug-panel\');if(p)p.style.display=\'none\';var a=window.webx11&&webx11.moduleManager&&webx11.moduleManager.modules&&webx11.moduleManager.modules.WebX11AIAssistantModule;if(a)a._debugPanelEnabled=false;">✕</span>' +
+ '</span></div>' + html;
}
_isToolError(result) {
if (!result || typeof result !== 'string') return null;
@@ -1194,6 +1235,37 @@ RULES:
for (const [, meta] of entries) totalTasks += meta.tasks || 0;
return JSON.stringify({ totalSessions: entries.length, totalTasks, dates: entries.map(([d]) => d) });
}
+ case 'list_agents': {
+ const registry = this.terminal.moduleManager.modules['AgentRegistryModule'];
+ if (!registry) return JSON.stringify({ error: 'Agent registry not available' });
+ const agents = this.terminal.fs.ls('/agents/');
+ const results = [];
+ if (agents) {
+ agents.forEach(a => {
+ if (a.type === 'dir' && a.name !== 'configured') {
+ const data = this.terminal.fs.readFile(`/agents/${a.name}/status.json`);
+ if (data) results.push(JSON.parse(data));
+ }
+ });
+ }
+ return JSON.stringify({ agents: results, count: results.length });
+ }
+ case 'delegate_task': {
+ const task = a.task || '';
+ if (!task) return JSON.stringify({ error: 'No task provided' });
+ const orch = this.terminal.moduleManager.modules['OrchestratorModule'];
+ if (!orch) return JSON.stringify({ error: 'Orchestrator not available' });
+ orch.delegateTask(task);
+ return JSON.stringify({ message: `Task delegated: ${task.substring(0, 80)}` });
+ }
+ case 'spawn_agent': {
+ const role = a.role || 'worker';
+ const caps = a.capabilities ? a.capabilities.split(',').map(s => s.trim()) : ['list_files', 'read_file'];
+ const orch = this.terminal.moduleManager.modules['OrchestratorModule'];
+ if (!orch) return JSON.stringify({ error: 'Orchestrator not available' });
+ const agent = orch.spawnAgent(role, caps);
+ return JSON.stringify({ message: `Agent spawned: ${agent.id}`, agent });
+ }
case 'load_skills': {
const query = (a && a.query || '').toLowerCase();
const fs = this.terminal.fs;