Remove unnecessary FileErrorType. (#6697)
This commit is contained in:
parent
6eb6560d42
commit
0193ce77dd
|
@ -219,7 +219,7 @@ describe('ReadFileTool', () => {
|
||||||
returnDisplay: 'Path is a directory.',
|
returnDisplay: 'Path is a directory.',
|
||||||
error: {
|
error: {
|
||||||
message: `Path is a directory, not a file: ${dirPath}`,
|
message: `Path is a directory, not a file: ${dirPath}`,
|
||||||
type: ToolErrorType.INVALID_TOOL_PARAMS,
|
type: ToolErrorType.TARGET_IS_DIRECTORY,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
ToolLocation,
|
ToolLocation,
|
||||||
ToolResult,
|
ToolResult,
|
||||||
} from './tools.js';
|
} from './tools.js';
|
||||||
import { ToolErrorType } from './tool-error.js';
|
|
||||||
import { PartUnion } from '@google/genai';
|
import { PartUnion } from '@google/genai';
|
||||||
import {
|
import {
|
||||||
processSingleFileContent,
|
processSingleFileContent,
|
||||||
|
@ -79,44 +79,12 @@ class ReadFileToolInvocation extends BaseToolInvocation<
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
// Map error messages to ToolErrorType
|
|
||||||
let errorType: ToolErrorType;
|
|
||||||
let llmContent: string;
|
|
||||||
|
|
||||||
// Check error message patterns to determine error type
|
|
||||||
if (
|
|
||||||
result.error.includes('File not found') ||
|
|
||||||
result.error.includes('does not exist') ||
|
|
||||||
result.error.includes('ENOENT')
|
|
||||||
) {
|
|
||||||
errorType = ToolErrorType.FILE_NOT_FOUND;
|
|
||||||
llmContent =
|
|
||||||
'Could not read file because no file was found at the specified path.';
|
|
||||||
} else if (
|
|
||||||
result.error.includes('is a directory') ||
|
|
||||||
result.error.includes('EISDIR')
|
|
||||||
) {
|
|
||||||
errorType = ToolErrorType.INVALID_TOOL_PARAMS;
|
|
||||||
llmContent =
|
|
||||||
'Could not read file because the provided path is a directory, not a file.';
|
|
||||||
} else if (
|
|
||||||
result.error.includes('too large') ||
|
|
||||||
result.error.includes('File size exceeds')
|
|
||||||
) {
|
|
||||||
errorType = ToolErrorType.FILE_TOO_LARGE;
|
|
||||||
llmContent = `Could not read file. ${result.error}`;
|
|
||||||
} else {
|
|
||||||
// Other read errors map to READ_CONTENT_FAILURE
|
|
||||||
errorType = ToolErrorType.READ_CONTENT_FAILURE;
|
|
||||||
llmContent = `Could not read file. ${result.error}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
llmContent,
|
llmContent: result.llmContent,
|
||||||
returnDisplay: result.returnDisplay || 'Error reading file',
|
returnDisplay: result.returnDisplay || 'Error reading file',
|
||||||
error: {
|
error: {
|
||||||
message: result.error,
|
message: result.error,
|
||||||
type: errorType,
|
type: result.errorType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
processSingleFileContent,
|
processSingleFileContent,
|
||||||
DEFAULT_ENCODING,
|
DEFAULT_ENCODING,
|
||||||
getSpecificMimeType,
|
getSpecificMimeType,
|
||||||
|
ProcessedFileReadResult,
|
||||||
} from '../utils/fileUtils.js';
|
} from '../utils/fileUtils.js';
|
||||||
import { PartListUnion } from '@google/genai';
|
import { PartListUnion } from '@google/genai';
|
||||||
import { Config, DEFAULT_FILE_FILTERING_OPTIONS } from '../config/config.js';
|
import { Config, DEFAULT_FILE_FILTERING_OPTIONS } from '../config/config.js';
|
||||||
|
@ -84,9 +85,7 @@ type FileProcessingResult =
|
||||||
success: true;
|
success: true;
|
||||||
filePath: string;
|
filePath: string;
|
||||||
relativePathForDisplay: string;
|
relativePathForDisplay: string;
|
||||||
fileReadResult: NonNullable<
|
fileReadResult: ProcessedFileReadResult;
|
||||||
Awaited<ReturnType<typeof processSingleFileContent>>
|
|
||||||
>;
|
|
||||||
reason?: undefined;
|
reason?: undefined;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import path from 'node:path';
|
||||||
import { PartUnion } from '@google/genai';
|
import { PartUnion } from '@google/genai';
|
||||||
import mime from 'mime-types';
|
import mime from 'mime-types';
|
||||||
import { FileSystemService } from '../services/fileSystemService.js';
|
import { FileSystemService } from '../services/fileSystemService.js';
|
||||||
|
import { ToolErrorType } from '../tools/tool-error.js';
|
||||||
|
|
||||||
// Constants for text file processing
|
// Constants for text file processing
|
||||||
const DEFAULT_MAX_LINES_TEXT_FILE = 2000;
|
const DEFAULT_MAX_LINES_TEXT_FILE = 2000;
|
||||||
|
@ -196,18 +197,11 @@ export async function detectFileType(
|
||||||
return 'text';
|
return 'text';
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum FileErrorType {
|
|
||||||
FILE_NOT_FOUND = 'FILE_NOT_FOUND',
|
|
||||||
IS_DIRECTORY = 'IS_DIRECTORY',
|
|
||||||
FILE_TOO_LARGE = 'FILE_TOO_LARGE',
|
|
||||||
READ_ERROR = 'READ_ERROR',
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ProcessedFileReadResult {
|
export interface ProcessedFileReadResult {
|
||||||
llmContent: PartUnion; // string for text, Part for image/pdf/unreadable binary
|
llmContent: PartUnion; // string for text, Part for image/pdf/unreadable binary
|
||||||
returnDisplay: string;
|
returnDisplay: string;
|
||||||
error?: string; // Optional error message for the LLM if file processing failed
|
error?: string; // Optional error message for the LLM if file processing failed
|
||||||
errorType?: FileErrorType; // Structured error type using enum
|
errorType?: ToolErrorType; // Structured error type
|
||||||
isTruncated?: boolean; // For text files, indicates if content was truncated
|
isTruncated?: boolean; // For text files, indicates if content was truncated
|
||||||
originalLineCount?: number; // For text files
|
originalLineCount?: number; // For text files
|
||||||
linesShown?: [number, number]; // For text files [startLine, endLine] (1-based for display)
|
linesShown?: [number, number]; // For text files [startLine, endLine] (1-based for display)
|
||||||
|
@ -232,33 +226,32 @@ export async function processSingleFileContent(
|
||||||
if (!fs.existsSync(filePath)) {
|
if (!fs.existsSync(filePath)) {
|
||||||
// Sync check is acceptable before async read
|
// Sync check is acceptable before async read
|
||||||
return {
|
return {
|
||||||
llmContent: '',
|
llmContent:
|
||||||
|
'Could not read file because no file was found at the specified path.',
|
||||||
returnDisplay: 'File not found.',
|
returnDisplay: 'File not found.',
|
||||||
error: `File not found: ${filePath}`,
|
error: `File not found: ${filePath}`,
|
||||||
errorType: FileErrorType.FILE_NOT_FOUND,
|
errorType: ToolErrorType.FILE_NOT_FOUND,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const stats = await fs.promises.stat(filePath);
|
const stats = await fs.promises.stat(filePath);
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
return {
|
return {
|
||||||
llmContent: '',
|
llmContent:
|
||||||
|
'Could not read file because the provided path is a directory, not a file.',
|
||||||
returnDisplay: 'Path is a directory.',
|
returnDisplay: 'Path is a directory.',
|
||||||
error: `Path is a directory, not a file: ${filePath}`,
|
error: `Path is a directory, not a file: ${filePath}`,
|
||||||
errorType: FileErrorType.IS_DIRECTORY,
|
errorType: ToolErrorType.TARGET_IS_DIRECTORY,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileSizeInBytes = stats.size;
|
const fileSizeInMB = stats.size / (1024 * 1024);
|
||||||
// 20MB limit
|
if (fileSizeInMB > 20) {
|
||||||
const maxFileSize = 20 * 1024 * 1024;
|
return {
|
||||||
|
llmContent: 'File size exceeds the 20MB limit.',
|
||||||
if (fileSizeInBytes > maxFileSize) {
|
returnDisplay: 'File size exceeds the 20MB limit.',
|
||||||
throw new Error(
|
error: `File size exceeds the 20MB limit: ${filePath} (${fileSizeInMB.toFixed(2)}MB)`,
|
||||||
`File size exceeds the 20MB limit: ${filePath} (${(
|
errorType: ToolErrorType.FILE_TOO_LARGE,
|
||||||
fileSizeInBytes /
|
};
|
||||||
(1024 * 1024)
|
|
||||||
).toFixed(2)}MB)`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileType = await detectFileType(filePath);
|
const fileType = await detectFileType(filePath);
|
||||||
|
@ -373,6 +366,7 @@ export async function processSingleFileContent(
|
||||||
llmContent: `Error reading file ${displayPath}: ${errorMessage}`,
|
llmContent: `Error reading file ${displayPath}: ${errorMessage}`,
|
||||||
returnDisplay: `Error reading file ${displayPath}: ${errorMessage}`,
|
returnDisplay: `Error reading file ${displayPath}: ${errorMessage}`,
|
||||||
error: `Error reading file ${filePath}: ${errorMessage}`,
|
error: `Error reading file ${filePath}: ${errorMessage}`,
|
||||||
|
errorType: ToolErrorType.READ_CONTENT_FAILURE,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue