aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-aiassist.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-06-18 06:00:40 +0200
committerAgando <roduccomm@gmail.com>2026-06-18 06:00:40 +0200
commitfba6df22dae297c89fa0df065628dddded66c69c (patch)
treef954a04ee1effe56361282a16444deaa93bd0151 /modules/core/module-aiassist.js
parenta02db2f506dec15c0c89dd4f8f21f975f627e4fe (diff)
auto: 2026-06-18_06:00 changes
Diffstat (limited to 'modules/core/module-aiassist.js')
-rw-r--r--modules/core/module-aiassist.js31
1 files changed, 26 insertions, 5 deletions
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js
index 3cf8b65..ee36789 100644
--- a/modules/core/module-aiassist.js
+++ b/modules/core/module-aiassist.js
@@ -52,9 +52,10 @@ buildSystemPrompt() {
const saved = localStorage.getItem('webx11_ai_system_prompt');
if (saved) {
const now = new Date();
- const dateStr = now.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
+ const dateStr = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0');
+ const dayStr = now.toLocaleDateString('en-US', { weekday: 'long' });
const timeStr = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
- return `Current date: ${dateStr}\nCurrent time: ${timeStr}\n\n${saved}`;
+ return `Current date: ${dateStr} (${dayStr}) ${timeStr}\n\n${saved}`;
}
} catch (e) {}
// Check SmartContextModule for active profile system prompt
@@ -67,6 +68,8 @@ buildSystemPrompt() {
} catch (e) {}
const now = new Date();
const dateStr = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0');
+ const dayStr = now.toLocaleDateString('en-US', { weekday: 'long' });
+ const timeStr = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
const nvfs = this.terminal?.moduleManager?.modules?.NeuralVFSModule;
let nvfsNote = '';
try {
@@ -75,7 +78,7 @@ buildSystemPrompt() {
if (ageMs > 14400000) nvfsNote = ' |nvfs ' + Math.floor(ageMs/3600000) + 'h stale';
}
} catch (e) {}
- let base = 'Current date: ' + dateStr + nvfsNote + '\n'
+ let base = `Current date: ${dateStr} (${dayStr}) ${timeStr}${nvfsNote}\n`
+ 'VFS→Modules→AI. nvfs-index for commands. Tool→Observe→Answer. nvfs-resolve. Destructive cmds need confirm.\n'
+ 'FS: list/read/write/delete | NVFS: nvfs-resolve | Web: search/fetch [POST=method+body] | Mod: view/edit/test/reload | Config | Skills | VaultMind: vaultmind_connect(network) — connect wallet, vaultmind_status — check session, vaultmind_query(ep,msg,agent) — Hyperliquid prices/portfolio/chat | wallet_lookup(address) — read-only portfolio for any wallet\n'
+ 'web_fetch tool: GET for normal pages (returns title+content+word_count), POST for JSON APIs like Hyperliquid /info (pass method="POST" and body as JSON string).\n'
@@ -757,6 +760,7 @@ buildSystemPrompt() {
}
async agenticLoop(messages) {
let toolTurns = 0;
+ const _seenCalls = new Map(); // v4.5.66: loop detection — track repeated tool calls
while (toolTurns < this.MAX_TOOL_TURNS) {
if (this._cancelled) { this.terminal.print('AI loop cancelled', 'warning'); return { finalAnswer: null, toolTurns }; }
toolTurns++;
@@ -778,6 +782,23 @@ buildSystemPrompt() {
return { finalAnswer: text, toolTurns };
}
if (res.tool_calls && res.tool_calls.length > 0) {
+ // v4.5.66: Loop detection — break if AI repeats same tool+args 3+ times
+ let looping = false;
+ for (const tc of res.tool_calls) {
+ const sig = tc.function.name + ':' + (tc.function.arguments || '');
+ const count = (_seenCalls.get(sig) || 0) + 1;
+ _seenCalls.set(sig, count);
+ if (count >= 3) {
+ this.terminal.print(`🔄 Loop detected: ${tc.function.name} called ${count}x with same args — breaking loop`, 'warning');
+ looping = true;
+ break;
+ }
+ }
+ if (looping) {
+ messages.push(res.message);
+ messages.push({ role: 'system', content: 'You are repeating the same tool call with identical arguments. Stop calling tools and provide your final answer based on what you already know.' });
+ continue;
+ }
this.terminal.print(`🔧 AI wants ${res.tool_calls.length} tool(s) — turn ${toolTurns}/${this.MAX_TOOL_TURNS} (${thinkTime}s)`, 'info');
messages.push(res.message);
let pendingText = res.message?.content || null;
@@ -1426,7 +1447,7 @@ buildSystemPrompt() {
'mem-debug','reset-mem']);
return !safeRead.has(cmd);
}
- return ['write_file','delete_file','make_directory','edit_module'].includes(name);
+ return ['write_file','delete_file','make_directory','edit_module','delegate_task','spawn_agent','create_skill','patch_skill','wpm_install','user_set','session_save'].includes(name);
}
async runTool(name, argsStr) {
let a = {};
@@ -2356,7 +2377,7 @@ buildSystemPrompt() {
this.terminal.print(`max-turns: ${this.MAX_TOOL_TURNS} (default: 8)`, '');
this.terminal.print(`max-context: ${this.maxContext} (default: 10)`, '');
this.terminal.print(`max-context-tokens: ${this.maxContextTokens} (default: 2000)`, '');
- this.terminal.print(`trivial-optimization: ${(this.terminal?.ollamaManager?.optimizationEnabled !== false) ? 'on' : 'off'}`, '');
+ this.terminal.print(`trivial-optimization: ${(this.terminal?.ollamaManager?.optimizationEnabled) ? 'on' : 'off (default)'}`, '');
this.terminal.print(`confirm-timeout: ${this._confirmTimeoutMs > 0 ? this._confirmTimeoutMs / 1000 + 's' : 'disabled (no auto-deny)'} (default: 120s)`, '');
this.terminal.print(`chat-lock-timeout: ${this._chatLockTimeoutMs / 1000}s (default: 10s)`, '');
this.terminal.print(`skill-debounce: ${this._skillDebounceMs / 60000}min (default: 30min)`, '');