diff options
| author | Agando <roduccomm@gmail.com> | 2026-09-29 13:48:35 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-09-29 13:48:35 +0200 |
| commit | dd50ae715f3a648aeb42fb524fe1b106a0c084c7 (patch) | |
| tree | a199c1a6dab4d30d3e54a745e5eb05b9ccd575a1 /modules/core/module-aiassist.js | |
| parent | 78059a20c9c6fef43da99e81ff847928a33b989c (diff) | |
newOS4 v4.6.14: race-safe AI loop guard (depth counter), cover _capture* entry points, structured JSON tool error
Diffstat (limited to 'modules/core/module-aiassist.js')
| -rw-r--r-- | modules/core/module-aiassist.js | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index e134d69..85aae46 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -948,8 +948,10 @@ buildSystemPrompt() { const originalPrint = this.terminal.print.bind(this.terminal); let output = ''; this.terminal.print = (text, type) => { output += text + '\n'; }; + // Loop guard: AI-initiated commands must not route back to AI on unknown command + this.terminal.security._aiToolDepth++; try { await this.terminal.security.checkAndRun(cmd); } - finally { this.terminal.print = originalPrint; } + finally { this.terminal.security._aiToolDepth--; this.terminal.print = originalPrint; } return output.trim(); } async _captureShellCommand(cmd) { @@ -957,8 +959,10 @@ buildSystemPrompt() { const originalPrint = this.terminal.print.bind(this.terminal); let output = ''; this.terminal.print = (text, type) => { output += text + '\n'; }; + // Loop guard: AI-initiated commands must not route back to AI on unknown command + this.terminal.security._aiToolDepth++; try { await this.terminal.executeCommand(cmd); } - finally { this.terminal.print = originalPrint; } + finally { this.terminal.security._aiToolDepth--; this.terminal.print = originalPrint; } return output.trim(); } async _captureConsoleErrors(durationMs) { @@ -2259,10 +2263,15 @@ buildSystemPrompt() { const originalPrint = this.terminal.print.bind(this.terminal); let output = ''; this.terminal.print = (text, type) => { output += text + '\n'; }; - // Flag security so unknown commands return an error instead of routing back to AI (loop guard) - const prevAiFlag = this.terminal.security._aiToolCall; - this.terminal.security._aiToolCall = true; - try { await this.terminal.security.checkAndRun(cmd); } finally { this.terminal.security._aiToolCall = prevAiFlag; this.terminal.print = originalPrint; } + // Loop guard (depth counter — race-safe under Promise.all tool fan-out): + // unknown commands return an error instead of routing back to AI + this.terminal.security._aiToolDepth++; + try { await this.terminal.security.checkAndRun(cmd); } finally { this.terminal.security._aiToolDepth--; this.terminal.print = originalPrint; } + const unknownCmd = this.terminal.security._lastUnknownCmd; + if (unknownCmd) { + const sug = this.terminal.security.suggest(unknownCmd); + return JSON.stringify({ error: `Command not found: ${unknownCmd}`, suggestion: sug ? sug.cmd : null }); + } // 📸 Diff and append shadow report const shadowDiff = this._diffShadowVFS(); if (shadowDiff && shadowDiff.length > 0) { |