fix(core): require integer ReadFile pagination params (#6381)

This commit is contained in:
VectorPeak 2026-07-06 22:26:51 +08:00 committed by GitHub
parent 5f7b57f933
commit 42921028fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 12 deletions

View file

@ -146,20 +146,52 @@ describe('ReadFileTool', () => {
offset: -1,
};
expect(() => tool.build(params)).toThrow(
'Offset must be a non-negative number',
'Offset must be a non-negative integer',
);
});
it('should throw error if limit is zero or negative', () => {
it('should throw error if offset is fractional', () => {
const params: ReadFileToolParams = {
file_path: path.join(tempRootDir, 'test.txt'),
limit: 0,
offset: 1.5,
};
expect(() => tool.build(params)).toThrow(
'Limit must be a positive number',
);
expect(() => tool.build(params)).toThrow('params/offset must be integer');
});
it('should allow zero offset', () => {
const params: ReadFileToolParams = {
file_path: path.join(tempRootDir, 'test.txt'),
offset: 0,
};
expect(tool.build(params)).toBeDefined();
});
it.each([0, -1])(
'should throw error if limit is not positive (%s)',
(limit) => {
const params: ReadFileToolParams = {
file_path: path.join(tempRootDir, 'test.txt'),
limit,
};
expect(() => tool.build(params)).toThrow(
'Limit must be a positive integer',
);
},
);
it.each([0.5, 1.5])(
'should throw error if limit is fractional (%s)',
(limit) => {
const params: ReadFileToolParams = {
file_path: path.join(tempRootDir, 'test.txt'),
limit,
};
expect(() => tool.build(params)).toThrow(
'params/limit must be integer',
);
},
);
it('should reject offset or limit for notebook files', () => {
const params: ReadFileToolParams = {
file_path: path.join(tempRootDir, 'test.ipynb'),

View file

@ -406,12 +406,12 @@ export class ReadFileTool extends BaseDeclarativeTool<
offset: {
description:
"Optional: For text files, the 0-based line number to start reading from. Requires 'limit' to be set. Use for paginating through large files.",
type: 'number',
type: 'integer',
},
limit: {
description:
"Optional: For text files, maximum number of lines to read. Use with 'offset' to paginate through large files. If omitted, reads the entire file (if feasible, up to a default limit).",
type: 'number',
type: 'integer',
},
pages: {
description:
@ -441,11 +441,17 @@ export class ReadFileTool extends BaseDeclarativeTool<
return `File path must be absolute, but was relative: ${filePath}. You must provide an absolute path.`;
}
if (params.offset !== undefined && params.offset < 0) {
return 'Offset must be a non-negative number';
if (
params.offset !== undefined &&
(!Number.isInteger(params.offset) || params.offset < 0)
) {
return 'Offset must be a non-negative integer';
}
if (params.limit !== undefined && params.limit <= 0) {
return 'Limit must be a positive number';
if (
params.limit !== undefined &&
(!Number.isInteger(params.limit) || params.limit <= 0)
) {
return 'Limit must be a positive integer';
}
if (params.pages !== undefined) {