Documentation
¶
Overview ¶
Package readmode implements the smart file-read fidelity tiers used by the `view` tool (lean-ctx context-intelligence Phase 1) plus the helpers for the content-hash unchanged-re-read deduplication (Phase 2).
The modes are strictly additive on top of the tool's existing pagination / line-numbering / streaming behavior: `full` is the default and reproduces the legacy raw window byte-for-byte, while `signatures` / `map` render a compact, line-numbered structural projection of the same window. `auto` deterministically picks a tier from the file path and size. Every compressed render is guarded so it never emits more bytes than the raw window (a parse failure or a render that is not actually smaller falls back to the raw window).
Index ¶
- func DiffWindows(oldContent, newContent string, lineOffset int) string
- func IsCodeLanguage(lang treesitter.Language) bool
- func ParseSymbols(ctx context.Context, path string, content []byte) ([]*treesitter.CodeSymbol, treesitter.Language, bool)
- func RenderMap(symbols []*treesitter.CodeSymbol, lang treesitter.Language, content string, ...) string
- func RenderSignatures(symbols []*treesitter.CodeSymbol, lang treesitter.Language, lineOffset int) string
- type BounceStats
- type BounceTracker
- type Mode
- type ResolveInput
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DiffWindows ¶
DiffWindows renders a compact line diff between two reads of the same window. It trims the common prefix and suffix and reports the changed middle block as removed (-) / added (+) lines, each annotated with its real source line number (lineOffset is the window's 0-based start line). Used by Phase 2 when a re-read of a previously-delivered window has changed.
func IsCodeLanguage ¶
func IsCodeLanguage(lang treesitter.Language) bool
IsCodeLanguage reports whether a tree-sitter language is "code" the auto resolver is willing to compress. Markdown / TOML are structured but excluded from auto compression (their full text is usually what the agent wants).
func ParseSymbols ¶
func ParseSymbols(ctx context.Context, path string, content []byte) ([]*treesitter.CodeSymbol, treesitter.Language, bool)
ParseSymbols parses the given window content with the language inferred from path and returns the extracted symbols. It returns (nil, false) when the file is not a supported source language or parsing/extraction fails — callers must fall back to the raw window in that case.
func RenderMap ¶
func RenderMap(symbols []*treesitter.CodeSymbol, lang treesitter.Language, content string, lineOffset int) string
RenderMap renders a structural outline: an imports line plus top-level signatures only (no nested members). Returns "" when there is nothing to render.
func RenderSignatures ¶
func RenderSignatures(symbols []*treesitter.CodeSymbol, lang treesitter.Language, lineOffset int) string
RenderSignatures renders every symbol's signature, grouped/indented by parent, with the real source line number (window StartLine + lineOffset) so the agent can jump to a full body via offset/limit. Returns "" when there is nothing to render (caller falls back to the raw window).
Types ¶
type BounceStats ¶
type BounceStats struct {
Bounces int `json:"bounces"`
WastedBytes int64 `json:"wasted_bytes"`
HotPaths int `json:"hot_paths"`
HotExts int `json:"hot_exts"`
}
BounceStats is a read-only snapshot of the tracker for reporting.
type BounceTracker ¶
type BounceTracker struct {
// contains filtered or unexported fields
}
BounceTracker makes the `auto` read mode safe to enable by default by learning, within a session, when compression backfires. A "bounce" is a compressed read (signatures/map) of a path followed by a full read of the same path — a strong signal the agent needed the raw bytes anyway. High-bounce paths and extensions get their next `auto` read escalated toward full (signatures → map → full), and the bytes spent on the bounced compressed read are tallied as waste so the Phase-5 savings ledger can subtract them from reported savings.
The tracker is deterministic by default: escalation depends only on the count of observed hard bounces. When learning is enabled (TokenOptimization .ReadModeLearning) a per-extension Beta(α,β) posterior over the bounce rate can add one extra escalation step before enough hard bounces have accumulated.
All methods are safe for concurrent use.
func NewBounceTracker ¶
func NewBounceTracker() *BounceTracker
NewBounceTracker returns an empty tracker.
func (*BounceTracker) RecordCompressed ¶
func (t *BounceTracker) RecordCompressed(path string, mode Mode, compressedBytes int)
RecordCompressed notes that a compressed read (signatures/map) of path was just delivered, of rendered size compressedBytes. It arms a pending bounce for the path and tentatively credits the extension's posterior toward "compression held"; a following full read of the same path reverts that credit into a bounce.
func (*BounceTracker) RecordFull ¶
func (t *BounceTracker) RecordFull(path string) bool
RecordFull notes that a full read of path was just delivered. If a compressed read of the same path was pending it counts as a bounce: per-path and per-extension counters increment, the wasted compressed bytes are tallied, and the extension's posterior shifts toward "bounced". Returns true on a bounce.
func (*BounceTracker) Reset ¶
func (t *BounceTracker) Reset()
Reset clears all tracker state (used when a session cache is cleared).
func (*BounceTracker) Stats ¶
func (t *BounceTracker) Stats() BounceStats
Stats returns a snapshot of the tracker counters.
func (*BounceTracker) Upgrade ¶
func (t *BounceTracker) Upgrade(path string, base Mode, learning bool) Mode
Upgrade returns the mode to actually use for an `auto`-resolved read of path, escalating away from aggressive compression when this path/extension has a bounce history this session. The escalation order is signatures → map → full; each observed bounce (max of path/extension counts) advances one step. When learning is true a high per-extension posterior bounce rate may add one step. base must be a concrete compressed mode (signatures/map); ModeFull/ModeAuto are returned unchanged.
type Mode ¶
type Mode string
Mode is a file-read fidelity tier.
const ( // ModeFull returns the raw paginated window (legacy behavior). ModeFull Mode = "full" // ModeSignatures renders every symbol's signature, grouped by parent. ModeSignatures Mode = "signatures" // ModeMap renders a structural outline: imports plus top-level signatures. ModeMap Mode = "map" // ModeAuto resolves to one of the concrete modes from path + size. ModeAuto Mode = "auto" )
func Normalize ¶
Normalize parses a requested mode string. Unknown/empty values resolve to ModeFull so callers stay byte-identical to the legacy read.
func Resolve ¶
func Resolve(requested Mode, in ResolveInput) Mode
Resolve turns a requested mode into a concrete mode (never ModeAuto). For ModeAuto it mirrors lean-ctx's resolve_inner: instruction files, non-code (config/data/text/markdown) files, small windows and diagnostic-active files stay full; medium code → map; large code → signatures.
type ResolveInput ¶
type ResolveInput struct {
// Path is the file path (absolute or relative) being read.
Path string
// SizeBytes is the size of the window being read (not necessarily the whole file).
SizeBytes int
// DiagnosticsActive indicates the file currently has LSP diagnostics — such
// files are kept at full fidelity so the agent sees the exact offending lines.
DiagnosticsActive bool
}
ResolveInput carries the deterministic signals the auto resolver uses.