Skip to content

feat(tools): add maxChars to readFile with default hard cap#142

Merged
remarkablemark merged 1 commit into
masterfrom
feat/tools
Jun 5, 2026
Merged

feat(tools): add maxChars to readFile with default hard cap#142
remarkablemark merged 1 commit into
masterfrom
feat/tools

Conversation

@remarkablemark
Copy link
Copy Markdown
Member

@remarkablemark remarkablemark commented Jun 5, 2026

What is the motivation for this pull request?

Large files returned by read_file with no line range can silently consume a large portion of the model's context window. This adds a default hard cap so unbounded reads are always protected, while also exposing maxChars as a caller-controlled option for intentional bounded reads.

plan.md

What is the current behavior?

readFile returns the full file content with no upper bound when no line range is specified. The model must remember to use startLine/maxLines to avoid large reads.

What is the new behavior?

  • A module-level READ_FILE_MAX_CHARS = 50_000 constant caps all reads by default.
  • An optional maxChars parameter is added to ReadFileOptions and exposed in the read_file tool schema.
  • maxChars is applied after any line-range selection, so it works for both full and partial reads.
  • When truncation occurs, output is suffixed with [file truncated: showing N of M chars].
  • Validation rejects non-integer or < 1 values with a dedicated error message.

Checklist:

Add `maxChars` to `ReadFileOptions` as a caller-controlled char limit, plus a module-level default cap so unbounded full-file reads are always protected, with a truncation notice appended to the content.

Design

- `const READ_FILE_MAX_CHARS = 50_000` — unexported local const in `files.ts`
- `maxChars` defaults to `READ_FILE_MAX_CHARS` when not supplied
- Applied **after** any line-range selection (works for both full and partial reads)
- Truncation appends: `\n[file truncated: showing 50000 of 123456 chars]`
- `maxChars` does **not** trigger `isPartialRead`

Files to change

1. `src/utils/tools/filesystem/files.ts`

- Add `const READ_FILE_MAX_CHARS = 50_000`
- Add `maxChars?: number` to `ReadFileOptions`
- Both the full-read and ranged-read paths produce a final `output` string; after that string is formed, apply `const cap = options.maxChars ?? READ_FILE_MAX_CHARS` and truncate with notice if `output.length > cap` before returning

2. `src/utils/tools/definitions.ts`

- Add `maxChars` param to `TOOL.READ_FILE` schema with description noting the default cap

3. `src/utils/tools/dispatcher.ts`

- Add `'maxChars'` to `numericArgs` validation
- Pass `maxChars` to `readFile(...)` in the switch case

4. `src/utils/tools/filesystem/files.test.ts`

- `maxChars` truncates full reads with notice
- `maxChars` truncates line-range reads with notice
- `maxChars` >= content length is a no-op (no notice)
- Default cap truncates when no `maxChars` is provided and content exceeds `READ_FILE_MAX_CHARS`

5. `src/utils/tools/dispatcher.test.ts`

- Validation rejects non-integer `maxChars`
- Validation rejects `maxChars < 1` with a message that names `maxChars` (separate from the existing `startLine, endLine, and maxLines must be >= 1` message)
- Execution: `read_file` passes `maxChars` through dispatcher and returns truncated content with notice
@remarkablemark remarkablemark self-assigned this Jun 5, 2026
@remarkablemark remarkablemark added the enhancement New feature or request label Jun 5, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
src/utils/tools/definitions.ts 100.00% <ø> (ø)
src/utils/tools/dispatcher.ts 100.00% <100.00%> (ø)
src/utils/tools/filesystem/files.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@remarkablemark remarkablemark enabled auto-merge June 5, 2026 00:15
@remarkablemark remarkablemark merged commit b7f7d38 into master Jun 5, 2026
16 checks passed
@remarkablemark remarkablemark deleted the feat/tools branch June 5, 2026 00:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant