π File detail
tools/FileReadTool/limits.ts
π― Use case
This module implements the βFileReadToolβ tool (File Read) β something the model can call at runtime alongside other agent tools. On the API surface it exposes DEFAULT_MAX_OUTPUT_TOKENS, FileReadingLimits, and getDefaultFileReadingLimits β mainly types, interfaces, or factory objects. Dependencies touch lodash-es and src. What the file header says: Read tool output limits. Two caps apply to text reads: | limit | default | checks | cost | on overflow | |---------------|---------|---------------------------|---------------|-----------------| | maxSizeBytes | 256 KB | TOTAL FILE SIZE (not out) | 1 stat | throws pre-read | | ma.
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
Read tool output limits. Two caps apply to text reads: | limit | default | checks | cost | on overflow | |---------------|---------|---------------------------|---------------|-----------------| | maxSizeBytes | 256 KB | TOTAL FILE SIZE (not out) | 1 stat | throws pre-read | | maxTokens | 25000 | actual output tokens | API roundtrip | throws post-read| Known mismatch: maxSizeBytes gates on total file size, not the slice. Tested truncating instead of throwing for explicit-limit reads that exceed the byte cap (#21841, Mar 2026). Reverted: tool error rate dropped but mean tokens rose β the throw path yields a ~100-byte error tool-result while truncation yields ~25K tokens of content at the cap.
π€ Exports (heuristic)
DEFAULT_MAX_OUTPUT_TOKENSFileReadingLimitsgetDefaultFileReadingLimits
π External import roots
Package roots from from "β¦" (relative paths omitted).
lodash-essrc
π₯οΈ Source preview
/**
* Read tool output limits. Two caps apply to text reads:
*
* | limit | default | checks | cost | on overflow |
* |---------------|---------|---------------------------|---------------|-----------------|
* | maxSizeBytes | 256 KB | TOTAL FILE SIZE (not out) | 1 stat | throws pre-read |
* | maxTokens | 25000 | actual output tokens | API roundtrip | throws post-read|
*
* Known mismatch: maxSizeBytes gates on total file size, not the slice.
* Tested truncating instead of throwing for explicit-limit reads that
* exceed the byte cap (#21841, Mar 2026). Reverted: tool error rate
* dropped but mean tokens rose β the throw path yields a ~100-byte error
* tool-result while truncation yields ~25K tokens of content at the cap.
*/
import memoize from 'lodash-es/memoize.js'
import { getFeatureValue_CACHED_MAY_BE_STALE } from 'src/services/analytics/growthbook.js'
import { MAX_OUTPUT_SIZE } from 'src/utils/file.js'
export const DEFAULT_MAX_OUTPUT_TOKENS = 25000
/**
* Env var override for max output tokens. Returns undefined when unset/invalid
* so the caller can fall through to the next precedence tier.
*/
function getEnvMaxTokens(): number | undefined {
const override = process.env.CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS
if (override) {
const parsed = parseInt(override, 10)
if (!isNaN(parsed) && parsed > 0) {
return parsed
}
}
return undefined
}
export type FileReadingLimits = {
maxTokens: number
maxSizeBytes: number
includeMaxSizeInPrompt?: boolean
targetedRangeNudge?: boolean
}
/**
* Default limits for Read tool when the ToolUseContext doesn't supply an
* override. Memoized so the GrowthBook value is fixed at first call β avoids
* the cap changing mid-session as the flag refreshes in the background.
*
* Precedence for maxTokens: env var > GrowthBook > DEFAULT_MAX_OUTPUT_TOKENS.
* (Env var is a user-set override, should beat experiment infrastructure.)
*
* Defensive: each field is individually validated; invalid values fall
* through to the hardcoded defaults (no route to cap=0).
*/
export const getDefaultFileReadingLimits = memoize((): FileReadingLimits => {
const override =
getFeatureValue_CACHED_MAY_BE_STALE<Partial<FileReadingLimits> | null>(
'tengu_amber_wren',
{},
)
const maxSizeBytes =
typeof override?.maxSizeBytes === 'number' &&
Number.isFinite(override.maxSizeBytes) &&
override.maxSizeBytes > 0
? override.maxSizeBytes
: MAX_OUTPUT_SIZE
const envMaxTokens = getEnvMaxTokens()
const maxTokens =
envMaxTokens ??
(typeof override?.maxTokens === 'number' &&
Number.isFinite(override.maxTokens) &&
override.maxTokens > 0
? override.maxTokens
: DEFAULT_MAX_OUTPUT_TOKENS)
const includeMaxSizeInPrompt =
typeof override?.includeMaxSizeInPrompt === 'boolean'
? override.includeMaxSizeInPrompt
: undefined
const targetedRangeNudge =
typeof override?.targetedRangeNudge === 'boolean'
? override.targetedRangeNudge
: undefined
return {
maxSizeBytes,
maxTokens,
includeMaxSizeInPrompt,
targetedRangeNudge,
}
})