diff options
| author | Agando <roduccomm@gmail.com> | 2026-09-29 19:03:27 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-09-29 19:03:27 +0200 |
| commit | 06874424c2bdc1103fa37ea65d87587425c3ceb3 (patch) | |
| tree | ece2807ec211caa8e98c4d7f4f206d7a4fec4b6c /modules/core | |
| parent | 7b9dd97689db400f2408ed50b04857d7d73d83e5 (diff) | |
fix: sequential safe-tool execution — parallel fan-out corrupted print-capture attribution + shadow diff pairing
Diffstat (limited to 'modules/core')
| -rw-r--r-- | modules/core/core-bundle.js | 11 | ||||
| -rw-r--r-- | modules/core/module-aiassist.js | 11 |
2 files changed, 14 insertions, 8 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js index 6127f36..dd86773 100644 --- a/modules/core/core-bundle.js +++ b/modules/core/core-bundle.js @@ -9432,8 +9432,11 @@ buildSystemPrompt() { let pendingText = res.message?.content || null; const destructiveTools = res.tool_calls.filter(tc => this.isDestructive(tc.function.name, tc.function.arguments)); const safeTools = res.tool_calls.filter(tc => !this.isDestructive(tc.function.name, tc.function.arguments)); - // Execute non-destructive tools in parallel (independent read-only operations) - const safeResults = await Promise.all(safeTools.map(async (tc) => { + // Execute non-destructive tools SEQUENTIALLY — parallel fan-out corrupts + // print-capture attribution, shadow-VFS snapshot/diff pairing, and telemetry + // under interleaved awaits. Inference latency dominates anyway. + const safeResults = []; + for (const tc of safeTools) { const fn = tc.function; const t0 = Date.now(); const toolResult = await this.runTool(fn.name, fn.arguments); @@ -9454,8 +9457,8 @@ buildSystemPrompt() { const sm = this.terminal.moduleManager.modules['ServerMonitorModule']; if (sm && sm.logToolCall) sm.logToolCall(fn.name, (t1 * 1000) || 1, this._isToolError(toolResult)); if (this._debugPanelEnabled) this._updateDebugPanel(); - return { fn, toolResult, t1 }; - })); + safeResults.push({ fn, toolResult, t1 }); + } for (const { fn, toolResult, t1 } of safeResults) { this.terminal.print(`🔧 Tool: ${fn.name}(${typeof fn.arguments === 'string' ? fn.arguments : JSON.stringify(fn.arguments)})`, 'info'); // Memory graph: record tool call + file access diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index 9c090ce..193c58d 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -1417,8 +1417,11 @@ buildSystemPrompt() { let pendingText = res.message?.content || null; const destructiveTools = res.tool_calls.filter(tc => this.isDestructive(tc.function.name, tc.function.arguments)); const safeTools = res.tool_calls.filter(tc => !this.isDestructive(tc.function.name, tc.function.arguments)); - // Execute non-destructive tools in parallel (independent read-only operations) - const safeResults = await Promise.all(safeTools.map(async (tc) => { + // Execute non-destructive tools SEQUENTIALLY — parallel fan-out corrupts + // print-capture attribution, shadow-VFS snapshot/diff pairing, and telemetry + // under interleaved awaits. Inference latency dominates anyway. + const safeResults = []; + for (const tc of safeTools) { const fn = tc.function; const t0 = Date.now(); const toolResult = await this.runTool(fn.name, fn.arguments); @@ -1439,8 +1442,8 @@ buildSystemPrompt() { const sm = this.terminal.moduleManager.modules['ServerMonitorModule']; if (sm && sm.logToolCall) sm.logToolCall(fn.name, (t1 * 1000) || 1, this._isToolError(toolResult)); if (this._debugPanelEnabled) this._updateDebugPanel(); - return { fn, toolResult, t1 }; - })); + safeResults.push({ fn, toolResult, t1 }); + } for (const { fn, toolResult, t1 } of safeResults) { this.terminal.print(`🔧 Tool: ${fn.name}(${typeof fn.arguments === 'string' ? fn.arguments : JSON.stringify(fn.arguments)})`, 'info'); // Memory graph: record tool call + file access |