fix: bugs (#885)
* fix: error output truncation (10KB→40KB) and MCP tool bugs - toolErrors.ts: increase error truncation limit from 10KB to 40KB Shell output can be up to 30KB, so 10KB was silently cutting off error logs from systemctl, apt, python, etc. - MCPTool: cache compiled AJV validators (was recompiling every call) - MCPTool: fix validateInput error message showing [object Object] - MCPTool: null-guard mapToolResultToToolResultBlockParam - MCPTool: explicit null check in isResultTruncated - ReadMcpResourceTool: null-guard mapToolResultToToolResultBlockParam Tests (84 passing): - src/utils/toolErrors.test.ts (13 tests) - src/tools/BashTool/commandSemantics.test.ts (24 tests) - src/tools/BashTool/utils.test.ts (32 tests) - src/tools/MCPTool/MCPTool.test.ts (15 tests) * fix: address review blockers from PR #885 Blocker 1: Fix abort path in callMCPTool - Previously returned { content: undefined } on AbortError, which masked the cancellation and caused mapToolResultToToolResultBlockParam to send empty content to the API as if it were a successful result. - Now converts abort errors to our AbortError class and re-throws, so the tool execution framework handles it properly (skips logging, creates is_error: true result with [Request interrupted by user for tool use]). Blocker 2: Fix memory leak in AJV validator cache - Changed compiledValidatorCache from Map to WeakMap so schemas from disconnected/refreshed MCP tools can be garbage collected instead of accumulating strong references indefinitely. Also: null guards now return descriptive indicators instead of empty strings, making it clear when content is unexpectedly missing. --------- Co-authored-by: FluxLuFFy <FluxLuFFy@users.noreply.github.com> Co-authored-by: Fix Bot <fix@openclaw.ai>
This commit is contained in:
@@ -55,6 +55,7 @@ import { type MCPProgress, MCPTool } from '../../tools/MCPTool/MCPTool.js'
|
||||
import { createMcpAuthTool } from '../../tools/McpAuthTool/McpAuthTool.js'
|
||||
import { ReadMcpResourceTool } from '../../tools/ReadMcpResourceTool/ReadMcpResourceTool.js'
|
||||
import { createAbortController } from '../../utils/abortController.js'
|
||||
import { AbortError, isAbortError } from '../../utils/errors.js'
|
||||
import { count } from '../../utils/array.js'
|
||||
import {
|
||||
checkAndRefreshOAuthTokenIfNeeded,
|
||||
@@ -3283,11 +3284,18 @@ async function callMCPTool({
|
||||
}
|
||||
}
|
||||
|
||||
// When the users hits esc, avoid logspew
|
||||
if (!(e instanceof Error) || e.name !== 'AbortError') {
|
||||
throw e
|
||||
// When the user hits esc, convert to our AbortError class so the tool
|
||||
// execution framework handles it properly (skips logging, creates
|
||||
// is_error: true result with [Request interrupted by user for tool use]).
|
||||
// Previously this returned { content: undefined }, which masked the
|
||||
// cancellation and caused mapToolResultToToolResultBlockParam to send
|
||||
// empty/undefined content to the API as if it were a successful result.
|
||||
if (isAbortError(e)) {
|
||||
throw new AbortError(
|
||||
e instanceof Error ? e.message : 'Tool execution cancelled',
|
||||
)
|
||||
}
|
||||
return { content: undefined }
|
||||
throw e
|
||||
} finally {
|
||||
// Always clear intervals
|
||||
if (progressInterval !== undefined) {
|
||||
|
||||
Reference in New Issue
Block a user