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 | 61d98053cbd4541fec4265095b47fa1fed066fba (patch) | |
| tree | 2fe281ed9dd0b2f7fc46c3490831ed91e83d2106 /modules/core/terminal.js | |
| parent | 588339dd1cca9d9f7874196b7635baba61454b12 (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/terminal.js')
| -rw-r--r-- | modules/core/terminal.js | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/modules/core/terminal.js b/modules/core/terminal.js index b058346..5c7a8fb 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -15,6 +15,9 @@ this.systemCmds = new Set(this._baseSystem); this.suspiciousFlags = new Set(this._baseSuspiciousFlags); this.whitelist = new Set(this._baseWhitelist); + // AI loop-guard: depth counter (reentrant, race-safe vs parallel tool calls) + this._aiToolDepth = 0; + this._lastUnknownCmd = null; // Load persisted user deltas (add/remove) so hardcoded defaults can be demoted. this._loadSecurityDeltas(); this._registerBuiltIn(); @@ -168,6 +171,7 @@ return { cmd, args, known, destructive, system, unknown, hasSuspicious }; } async checkAndRun(rawInput) { + this._lastUnknownCmd = null; const { cmd, args, known, destructive, system, unknown, hasSuspicious } = this._classify(rawInput); // Level 3 Audit: just log and allow if (this.level === 3) { @@ -191,13 +195,14 @@ return; } // Level 1: typo of a safe whitelisted command → one-tap clickable fix, no AI call burned - if (sug && sug.dist <= 1 && this.whitelist.has(sug.cmd) && this.terminal.showSuggestionBar && !this._aiToolCall) { + if (sug && sug.dist <= 1 && this.whitelist.has(sug.cmd) && this.terminal.showSuggestionBar && !(this._aiToolDepth > 0)) { this.terminal.print(`Unknown command "${cmd}" — did you mean:`, 'warning'); this.terminal.showSuggestionBar(sug.cmd, args); return; } // AI-invoked commands must not route back to AI (infinite loop) — return structured error - if (this._aiToolCall) { + if (this._aiToolDepth > 0) { + this._lastUnknownCmd = cmd; this.terminal.print(`Command not found: ${cmd}${sug ? `. Did you mean: ${sug.cmd}?` : ''}`, 'error'); return; } |