diff options
| author | Agando <roduccomm@gmail.com> | 2026-06-18 06:00:40 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-06-18 06:00:40 +0200 |
| commit | fba6df22dae297c89fa0df065628dddded66c69c (patch) | |
| tree | f954a04ee1effe56361282a16444deaa93bd0151 /modules/core/module-aiassist.js | |
| parent | a02db2f506dec15c0c89dd4f8f21f975f627e4fe (diff) | |
auto: 2026-06-18_06:00 changes
Diffstat (limited to 'modules/core/module-aiassist.js')
| -rw-r--r-- | modules/core/module-aiassist.js | 31 |
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)`, ''); |