#!/usr/bin/env python3 """ Replay-based optimizer for the read tool's config. Inputs (from ~/.omp/stats.db, since --since): * every `read` call's args (selector / offset / limit / bare) * every result's `[Showing lines A-B of N]` footer → actual returned range AND the file's total line count * every result's `[Output truncated` marker → byte cap hit For each (session, file) pair we replay the sequence under a candidate config C = (default_page D, line cap L, byte cap B*) and add up: reads kept * estimated_tokens(range, file) + reads kept * ROUNDTRIP `*` byte cap is modelled as "an explicit range read of size > B/avg_bpl is clipped to floor(B/avg_bpl) lines" so we don't have to know raw bytes. We sweep D and L over a grid, find the (D, L) minimizing simulated total tokens, and verify the simulator reproduces the baseline within ~5% of the actually-observed spend. Output: scripts/session-stats/out/read-config-sweep.png console table with the recommended config + savings """ from __future__ import annotations import argparse import json import math import re import sqlite3 import sys from collections import defaultdict from datetime import datetime, timezone from pathlib import Path from typing import NamedTuple import matplotlib.pyplot as plt import matplotlib.patches as mpatches import numpy as np DB_PATH = Path.home() / ".omp" / "stats.db" OUT_DIR = Path(__file__).resolve().parent / "out" DEFAULT_SINCE = "2026-05-04" # Tool current values (packages/coding-agent/src/session/streaming-output.ts + # tools/read.ts) — used for baseline comparison. CURRENT_DEFAULT = 3000 CURRENT_LINE_CAP = 3000 CURRENT_BYTE_CAP = 50 * 1024 # 50 KB # Average bytes per line — only used to convert byte cap → line cap when the # model didn't pass an explicit limit. Computed at runtime from observed # bytes_per_line per file, with this as a fallback for files we never saw. FALLBACK_BPL = 60.0 FALLBACK_TPL = 12.0 # tokens per line if a file has no observed reads # Cost of an extra tool roundtrip: at minimum the assistant text+thinking # preceding the call (median ~120-250 tokens) + the call envelope + the # result-header overhead. We charge a flat 200 tokens per call kept; the # answer is qualitatively stable across 50-400. ROUNDTRIP_OVERHEAD = 200 # Selector parser (reuses the same rules as analyze_selector_reads.py). _RANGE_RE = re.compile(r"^(\d+)(?:([-+])(\d+))?$") _FOOTER_RE = re.compile( r"\[Showing lines (\d+)-(\d+) of (\d+)\." ) _TRUNCATED_RE = re.compile(r"\[Output truncated") # --------------------------------------------------------------------------- # # Selector → intent class Intent(NamedTuple): kind: str # 'bare' | 'range' | 'raw' | 'conflicts' | 'other' start: int | None # requested start line (1-indexed) — only meaningful for 'range' end: int | None # requested end line (1-indexed, inclusive) — None = open-ended def parse_selector(path: str) -> tuple[str, Intent]: tail_idx = path.rfind("/") tail = path[tail_idx + 1 :] colon = tail.rfind(":") if colon < 0: return path, Intent("bare", None, None) suffix = tail[colon + 1 :] base = (path[: tail_idx + 1] + tail[:colon]) if tail_idx >= 0 else tail[:colon] if suffix == "raw": return base, Intent("raw", None, None) if suffix == "conflicts": return base, Intent("conflicts", None, None) m = _RANGE_RE.match(suffix) if not m: return path, Intent("other", None, None) s = int(m.group(1)) op, nval = m.group(2), m.group(3) if op == "-" and nval is not None: return base, Intent("range", s, int(nval)) if op == "+" and nval is not None: return base, Intent("range", s, s + int(nval) - 1) return base, Intent("range", s, None) # open-ended `:N` def parse_args(arg_json: str | None) -> tuple[str | None, Intent]: if not arg_json: return None, Intent("other", None, None) try: obj = json.loads(arg_json) except json.JSONDecodeError: return None, Intent("other", None, None) path = obj.get("path") if not isinstance(path, str): return None, Intent("other", None, None) base, intent = parse_selector(path) if intent.kind != "bare": return base, intent # Legacy offset/limit treated as an explicit range. offset = obj.get("offset") limit = obj.get("limit") if isinstance(offset, int) and isinstance(limit, int) and offset >= 1 and limit >= 1: return path, Intent("range", offset, offset + limit - 1) if isinstance(offset, int) and offset >= 1: return path, Intent("range", offset, None) return path, Intent("bare", None, None) # --------------------------------------------------------------------------- # # Footer parser → (returned_start, returned_end, file_total_lines) def parse_footer(tail: str | None) -> tuple[int | None, int | None, int | None, bool]: """Returns (returned_a, returned_b, file_total, was_byte_truncated).""" if not tail: return None, None, None, False m = _FOOTER_RE.search(tail) if not m: return None, None, None, bool(_TRUNCATED_RE.search(tail)) return (int(m.group(1)), int(m.group(2)), int(m.group(3)), bool(_TRUNCATED_RE.search(tail))) # --------------------------------------------------------------------------- # # Coverage utilities def merge(ivs: list[tuple[int, int]]) -> list[tuple[int, int]]: if not ivs: return [] ivs = sorted(ivs) out = [ivs[0]] for s, e in ivs[1:]: ls, le = out[-1] if s <= le + 1: out[-1] = (ls, max(le, e)) else: out.append((s, e)) return out def contained(s: int, e: int, ivs: list[tuple[int, int]]) -> bool: for ls, le in ivs: if ls <= s and le >= e: return True return False def subtract(s: int, e: int, ivs: list[tuple[int, int]]) -> list[tuple[int, int]]: """Return [s,e] minus the union of `ivs` as a list of remaining intervals.""" out = [(s, e)] for ls, le in ivs: new = [] for a, b in out: if le < a or ls > b: new.append((a, b)) continue if ls > a: new.append((a, ls - 1)) if le < b: new.append((le + 1, b)) out = new if not out: break return out # --------------------------------------------------------------------------- # # Data model class ReadCall(NamedTuple): seq: int intent: Intent base: str actual_a: int | None # what came back: lines [actual_a, actual_b] actual_b: int | None file_total: int | None # from footer tokens: int # observed result tokens was_truncated: bool # [Output truncated marker present def fetch_reads(conn: sqlite3.Connection, since_ms: int) -> list[tuple[str, ReadCall]]: """Returns list of (session, ReadCall) in (session, seq) order.""" # Pull only the last 320 bytes of result_text — enough for the footer + # truncation marker, keeps the working set small. sql = """ SELECT c.session_file, c.seq, c.arg_json, COALESCE(r.result_tokens, 0) AS tokens, substr(COALESCE(r.result_text, ''), MAX(1, LENGTH(COALESCE(r.result_text, '')) - 320)) AS tail FROM ss_tool_calls c LEFT JOIN ss_tool_results r ON r.session_file = c.session_file AND r.call_id = c.call_id AND r.seq >= c.seq WHERE c.tool_name = 'read' AND c.timestamp >= ? ORDER BY c.session_file, c.seq """ out: list[tuple[str, ReadCall]] = [] for session, seq, arg_json, tokens, tail in conn.execute(sql, (since_ms,)): base, intent = parse_args(arg_json) if not base or base.endswith("/") or "://" in base: continue actual_a, actual_b, file_total, was_trunc = parse_footer(tail) out.append((session, ReadCall(seq, intent, base, actual_a, actual_b, file_total, int(tokens), was_trunc))) return out # --------------------------------------------------------------------------- # # Per-file aggregates class FileStats(NamedTuple): size_lines: int # best-effort estimate tokens_per_line: float bytes_per_line: float # only when we can derive (currently we can't, so fallback) def aggregate_files(reads: list[tuple[str, ReadCall]]) -> dict[str, FileStats]: """Estimate per-file size + tokens/line from observed reads. size_lines: - if any footer reported `of N`, use the max N seen for this file (most reads agree but files grow over time). - else fall back to max(actual_b or intent.end) ever observed. tokens_per_line: - weighted average of (tokens / lines_returned) across reads of this file that have a footer (so we know `lines_returned`). """ by_file_total_lines: dict[str, int] = {} by_file_max_end: dict[str, int] = {} by_file_tok_lines: dict[str, list[tuple[int, int]]] = defaultdict(list) for _session, rc in reads: if rc.file_total: prev = by_file_total_lines.get(rc.base, 0) if rc.file_total > prev: by_file_total_lines[rc.base] = rc.file_total # Track max line ever observed. cands = [v for v in (rc.actual_b, rc.intent.end) if v is not None] if cands: cur = max(cands) prev = by_file_max_end.get(rc.base, 0) if cur > prev: by_file_max_end[rc.base] = cur # tok/line: only when we know how many lines came back AND tokens > 0. if rc.actual_a is not None and rc.actual_b is not None and rc.tokens > 0: n = rc.actual_b - rc.actual_a + 1 if n > 0: by_file_tok_lines[rc.base].append((rc.tokens, n)) out: dict[str, FileStats] = {} files = ( set(by_file_total_lines) | set(by_file_max_end) | set(by_file_tok_lines) ) for f in files: size = by_file_total_lines.get(f) or by_file_max_end.get(f, 1) tok_lines = by_file_tok_lines.get(f, []) if tok_lines: tot_tok = sum(t for t, _ in tok_lines) tot_ln = sum(n for _, n in tok_lines) tpl = tot_tok / max(tot_ln, 1) else: tpl = FALLBACK_TPL out[f] = FileStats(size_lines=size, tokens_per_line=tpl, bytes_per_line=max(8.0, tpl * 4.0)) return out # --------------------------------------------------------------------------- # # Per-pair grouping def group_pairs(reads: list[tuple[str, ReadCall]]) -> dict[tuple[str, str], list[ReadCall]]: by_pair: dict[tuple[str, str], list[ReadCall]] = defaultdict(list) for session, rc in reads: by_pair[(session, rc.base)].append(rc) # Already sorted by session, seq from the SQL. return by_pair # --------------------------------------------------------------------------- # # Simulator class Config(NamedTuple): default_page: int # lines returned for a bare path read line_cap: int # absolute max lines per read byte_cap: int # max bytes per read (modelled as line cap via bytes_per_line) summarize_min: int # min file size (lines) for summarizer to fire on bare reads # (-1 disables summarizer; 0 = always) def effective_returned(rc: ReadCall, fs: FileStats, cfg: Config) -> tuple[int, int] | None: """Range the tool actually returns for one call under cfg. Honours intent (what the agent asked for), then applies (default_page, line_cap, byte_cap, file_size) as bounding constraints. Returns None for intents without line bounds (conflicts/other). The model is one observed call → one simulated call: we do NOT generate synthetic follow-ups when the cap shrinks the response. If the original session needed more lines, those follow-ups will appear as their own observed calls in the same pair. """ intent = rc.intent size = max(fs.size_lines, 1) if intent.kind == "bare": start, end_intent = 1, cfg.default_page elif intent.kind == "range": start = intent.start or 1 end_intent = intent.end if intent.end is not None else (start + cfg.default_page - 1) elif intent.kind == "raw": start, end_intent = 1, size else: return None end = min(end_intent, size, start + cfg.line_cap - 1) if fs.bytes_per_line > 0: end = min(end, start + max(1, int(cfg.byte_cap / fs.bytes_per_line)) - 1) if end < start: end = start return (start, end) def cost_of_chunk(start: int, end: int, fs: FileStats, intent_kind: str, cfg: Config) -> float: """Estimated result tokens for returning [start, end] of this file.""" span = max(end - start + 1, 0) raw = span * fs.tokens_per_line if intent_kind == "bare" and cfg.summarize_min >= 0 and fs.size_lines >= cfg.summarize_min: # Calibrated from observed post-deploy summary-eligible reads: # tokens/line collapses to ~0.35× the verbatim rate. return raw * 0.35 return raw def chunk_range(s: int, e: int, fs: FileStats, cfg: Config) -> list[tuple[int, int]]: """Break [s, e] into chunks no larger than (line_cap, byte_cap).""" max_per_call = cfg.line_cap if fs.bytes_per_line > 0: max_per_call = min(max_per_call, max(1, int(cfg.byte_cap / fs.bytes_per_line))) out: list[tuple[int, int]] = [] cur = s while cur <= e: end = min(cur + max_per_call - 1, e) out.append((cur, end)) cur = end + 1 return out def replay_pair(reads: list[ReadCall], fs: FileStats, cfg: Config) -> tuple[float, int]: """Estimated tokens + calls for one (session, file). Two-phase replay: 1. For every observed call, compute the new returned range under cfg. Drop if fully covered; otherwise charge tokens + roundtrip and fold it into the simulated coverage. 2. Compare simulated coverage against what the agent ACTUALLY received (union of observed returned ranges). Any shortfall is filled by synthetic chunks at (line_cap, byte_cap) granularity, charged at tokens + roundtrip. Phase 2 prevents the simulator from claiming free savings by silently returning fewer lines than the agent demonstrably needed. """ covered: list[tuple[int, int]] = [] observed_needed: list[tuple[int, int]] = [] total = 0.0 kept = 0 for rc in reads: if rc.actual_a is not None and rc.actual_b is not None and rc.actual_b >= rc.actual_a: observed_needed.append((rc.actual_a, rc.actual_b)) ret = effective_returned(rc, fs, cfg) if ret is None: continue s, e = ret if contained(s, e, covered): continue total += cost_of_chunk(s, e, fs, rc.intent.kind, cfg) total += ROUNDTRIP_OVERHEAD kept += 1 covered.append((s, e)) covered = merge(covered) # Shortfall: lines the agent originally read that sim never delivered. observed_needed = merge(observed_needed) gaps: list[tuple[int, int]] = [] for need_s, need_e in observed_needed: gaps.extend(subtract(need_s, need_e, covered)) for gap_s, gap_e in gaps: for cs, ce in chunk_range(gap_s, gap_e, fs, cfg): total += cost_of_chunk(cs, ce, fs, "range", cfg) total += ROUNDTRIP_OVERHEAD kept += 1 covered.append((cs, ce)) covered = merge(covered) return total, kept def simulate(by_pair: dict, files: dict[str, FileStats], cfg: Config) -> tuple[float, int]: grand = 0.0 kept = 0 for (_session, base), reads in by_pair.items(): fs = files.get(base) or FileStats(size_lines=1, tokens_per_line=FALLBACK_TPL, bytes_per_line=FALLBACK_BPL) t, k = replay_pair(reads, fs, cfg) grand += t kept += k return grand, kept def baseline_observed(reads: list[tuple[str, ReadCall]]) -> tuple[int, int]: """Actual observed token spend (sum of result_tokens) and call count.""" tot = sum(rc.tokens for _, rc in reads) return tot, len(reads) # --------------------------------------------------------------------------- # # Sweep + report def sweep(by_pair: dict, files: dict[str, FileStats]) -> dict: defaults = [200, 300, 400, 500, 700, 1000, 1500, 2000, 3000] line_caps = [500, 1000, 1500, 2000, 3000, 5000] summary_thresholds = [-1, 0, 50, 150, 300, 600] # min file size to summarize grid_tokens = np.zeros((len(defaults), len(line_caps))) grid_calls = np.zeros((len(defaults), len(line_caps)), dtype=np.int64) for i, D in enumerate(defaults): for j, L in enumerate(line_caps): cfg = Config(default_page=D, line_cap=L, byte_cap=CURRENT_BYTE_CAP, summarize_min=0) t, k = simulate(by_pair, files, cfg) grid_tokens[i, j] = t grid_calls[i, j] = k # Best (D, L) for fixed summarize_min=0. flat = np.argmin(grid_tokens) i_best, j_best = np.unravel_index(flat, grid_tokens.shape) best_DL = (defaults[i_best], line_caps[j_best]) # Sweep summarize_min at best (D, L). sm_tokens = [] for sm in summary_thresholds: cfg = Config(default_page=best_DL[0], line_cap=best_DL[1], byte_cap=CURRENT_BYTE_CAP, summarize_min=sm) t, k = simulate(by_pair, files, cfg) sm_tokens.append((sm, t, k)) best_sm = min(sm_tokens, key=lambda x: x[1]) # Sweep byte_cap at best (D, L, summarize_min). byte_caps = [16 * 1024, 32 * 1024, 50 * 1024, 75 * 1024, 100 * 1024, 150 * 1024, 200 * 1024] bc_tokens = [] for bc in byte_caps: cfg = Config(default_page=best_DL[0], line_cap=best_DL[1], byte_cap=bc, summarize_min=best_sm[0]) t, k = simulate(by_pair, files, cfg) bc_tokens.append((bc, t, k)) best_bc = min(bc_tokens, key=lambda x: x[1]) # Final combined config (D, L, summarize_min, byte_cap) — should be the # global minimum given the order of dimensions. final_cfg = Config(default_page=best_DL[0], line_cap=best_DL[1], byte_cap=best_bc[0], summarize_min=best_sm[0]) final_tokens, final_calls = simulate(by_pair, files, final_cfg) return { "defaults": defaults, "line_caps": line_caps, "grid_tokens": grid_tokens, "grid_calls": grid_calls, "best_DL": best_DL, "summary_sweep": sm_tokens, "best_summary": best_sm, "byte_cap_sweep": bc_tokens, "best_byte_cap": best_bc, "final_cfg": final_cfg, "final_tokens": final_tokens, "final_calls": final_calls, } # --------------------------------------------------------------------------- # # Plotting def plot(result: dict, baseline_sim: float, observed: int, out_path: Path) -> None: OUT_DIR.mkdir(parents=True, exist_ok=True) plt.rcParams.update({"figure.dpi": 110, "font.size": 10}) fig, axes = plt.subplots(2, 2, figsize=(15, 11)) # Heatmap: relative to baseline (current config). ax = axes[0, 0] grid = result["grid_tokens"] rel = grid / baseline_sim im = ax.imshow(rel, cmap="RdYlGn_r", aspect="auto", origin="lower", vmin=max(0.6, rel.min()), vmax=min(1.4, rel.max() + 0.02)) ax.set_xticks(range(len(result["line_caps"]))) ax.set_xticklabels(result["line_caps"]) ax.set_yticks(range(len(result["defaults"]))) ax.set_yticklabels(result["defaults"]) ax.set_xlabel("line cap (L)") ax.set_ylabel("default page (D)") ax.set_title("simulated read tokens / baseline\n(green = cheaper, red = more)") for i in range(grid.shape[0]): for j in range(grid.shape[1]): ax.text(j, i, f"{rel[i,j]:.2f}", ha="center", va="center", color="black", fontsize=8) fig.colorbar(im, ax=ax, fraction=0.05) # Highlight current and best. cur_i = result["defaults"].index(CURRENT_DEFAULT) if CURRENT_DEFAULT in result["defaults"] else None cur_j = result["line_caps"].index(CURRENT_LINE_CAP) if CURRENT_LINE_CAP in result["line_caps"] else None if cur_i is not None and cur_j is not None: ax.add_patch(mpatches.Rectangle((cur_j - 0.5, cur_i - 0.5), 1, 1, fill=False, edgecolor="#1d4ed8", linewidth=2.4, label="current")) best_i = result["defaults"].index(result["best_DL"][0]) best_j = result["line_caps"].index(result["best_DL"][1]) ax.add_patch(mpatches.Rectangle((best_j - 0.5, best_i - 0.5), 1, 1, fill=False, edgecolor="#000", linewidth=2.4, linestyle="--", label="optimum")) ax.legend(loc="upper right", frameon=True, fontsize=9) # Default-page line (at best line cap). ax = axes[0, 1] best_L = result["best_DL"][1] j = result["line_caps"].index(best_L) col = grid[:, j] / baseline_sim ax.plot(result["defaults"], col, marker="o", linewidth=1.8, color="#0f766e") ax.axhline(1.0, color="#9ca3af", linestyle="--", linewidth=1.0) ax.axvline(CURRENT_DEFAULT, color="#1d4ed8", linestyle=":", linewidth=1.2, label="current default") best_D = result["best_DL"][0] ax.axvline(best_D, color="#000", linestyle="--", linewidth=1.4, label=f"optimum D={best_D}") ax.set_xscale("log") ax.set_xlabel("default page (D) — log scale") ax.set_ylabel("simulated tokens / baseline") ax.set_title(f"sensitivity to default page (line cap fixed at L={best_L})") ax.grid(True, alpha=0.25, linestyle="--") ax.legend(loc="best", frameon=False) # Summarizer threshold sweep. ax = axes[1, 0] sm_data = result["summary_sweep"] xs = [str("off") if sm == -1 else ("always" if sm == 0 else f"≥{sm}") for sm, _, _ in sm_data] ys = [t / baseline_sim for _, t, _ in sm_data] bars = ax.bar(xs, ys, color=["#dc2626" if y > 1 else "#0f766e" for y in ys], edgecolor="#111", linewidth=0.5) for bar, y in zip(bars, ys): ax.text(bar.get_x() + bar.get_width() / 2, y + 0.005, f"{(y - 1) * 100:+.1f}%", ha="center", va="bottom", fontsize=9) ax.axhline(1.0, color="#9ca3af", linestyle="--", linewidth=1.0) ax.set_ylabel("simulated tokens / baseline") ax.set_xlabel("summarize files ≥ N lines") ax.set_title(f"summarizer threshold sweep (D={result['best_DL'][0]}, L={result['best_DL'][1]})") ax.grid(True, axis="y", alpha=0.25, linestyle="--") # Byte cap sweep. ax = axes[1, 1] bc_data = result["byte_cap_sweep"] xs_kb = [bc // 1024 for bc, _, _ in bc_data] ys = [t / baseline_sim for _, t, _ in bc_data] ax.plot(xs_kb, ys, marker="o", linewidth=1.8, color="#7c3aed") ax.axhline(1.0, color="#9ca3af", linestyle="--", linewidth=1.0) ax.axvline(CURRENT_BYTE_CAP / 1024, color="#1d4ed8", linestyle=":", linewidth=1.2, label="current byte cap") best_bc_kb = result["best_byte_cap"][0] // 1024 ax.axvline(best_bc_kb, color="#000", linestyle="--", linewidth=1.4, label=f"optimum {best_bc_kb} KB") ax.set_xlabel("byte cap (KB)") ax.set_ylabel("simulated tokens / baseline") ax.set_title("sensitivity to byte cap") ax.grid(True, alpha=0.25, linestyle="--") ax.legend(loc="best", frameon=False) fig.suptitle( f"read tool config sweep — observed read spend {observed:,}, " f"simulator baseline {baseline_sim:,.0f}", fontsize=12, y=1.02, ) fig.tight_layout() fig.savefig(out_path, bbox_inches="tight") plt.close(fig) # --------------------------------------------------------------------------- # # Report def fmt_pct(x: float) -> str: if x >= 0: return f"+{x*100:.1f}%" return f"{x*100:.1f}%" def report(result: dict, baseline_sim: float, baseline_calls: int, observed: int, observed_calls: int) -> None: defaults = result["defaults"] line_caps = result["line_caps"] grid = result["grid_tokens"] calls = result["grid_calls"] print(f"\nbaseline (current config: D={CURRENT_DEFAULT}, L={CURRENT_LINE_CAP}):") print(f" observed result tokens = {observed:>13,} (truth)") print(f" simulator under baseline = {baseline_sim:>13,.0f} " f"({fmt_pct((baseline_sim - observed) / observed)} vs observed)") print(f" observed read calls = {observed_calls:>13,}") print(f" simulator calls (baseline) = {baseline_calls:>11,}") # Sweep table. print(f"\nsimulated read tokens (× of baseline) by (D, L):") header = " D \\ L " + " ".join(f"{L:>6}" for L in line_caps) print(header) for i, D in enumerate(defaults): row = " ".join(f"{grid[i,j]/baseline_sim:>6.2f}" for j in range(len(line_caps))) print(f" D={D:<6} {row}") print(f"\nbest (D, L) = {result['best_DL']} → " f"{grid[defaults.index(result['best_DL'][0]), line_caps.index(result['best_DL'][1])]:,.0f} tokens" f" ({fmt_pct(grid.min()/baseline_sim - 1)})") # Summarizer threshold sweep at best (D, L). print(f"\nsummarizer threshold sweep at best (D, L) = {result['best_DL']}:") print(f" {'min_file_lines':<16} {'tokens':>12} {'vs baseline':>12}") for sm, t, k in result["summary_sweep"]: label = "off" if sm == -1 else ("always" if sm == 0 else f">={sm}") print(f" {label:<16} {t:>12,.0f} {fmt_pct(t/baseline_sim - 1):>12}") print(f"\nbest summarize_min = {result['best_summary'][0]} → " f"{result['best_summary'][1]:,.0f} tokens " f"({fmt_pct(result['best_summary'][1]/baseline_sim - 1)})") # Byte cap sweep at (best D, L, summarize_min). print(f"\nbyte cap sweep at best (D, L, summarize_min):") print(f" {'byte_cap':<10} {'tokens':>12} {'vs baseline':>12}") for bc, t, k in result["byte_cap_sweep"]: print(f" {bc//1024:>4} KB {t:>12,.0f} {fmt_pct(t/baseline_sim - 1):>12}") print(f"\nbest byte_cap = {result['best_byte_cap'][0]//1024} KB → " f"{result['best_byte_cap'][1]:,.0f} tokens " f"({fmt_pct(result['best_byte_cap'][1]/baseline_sim - 1)})") # Final recommendation. cfg = result["final_cfg"] print("\n" + "=" * 64) print(" RECOMMENDED CONFIG") print("=" * 64) print(f" read.defaultLimit {cfg.default_page} lines (current: {CURRENT_DEFAULT})") print(f" read.lineCap {cfg.line_cap} lines (current: {CURRENT_LINE_CAP})") print(f" read.byteCap {cfg.byte_cap//1024} KB (current: {CURRENT_BYTE_CAP//1024} KB)") sm_label = "off" if cfg.summarize_min == -1 else ( "always" if cfg.summarize_min == 0 else f"only files ≥ {cfg.summarize_min} lines") print(f" read.summarizer {sm_label}") print(f" simulated savings {fmt_pct(result['final_tokens']/baseline_sim - 1)} " f"({baseline_sim - result['final_tokens']:,.0f} fewer tokens / window)") print(f" calls {result['final_calls']:,} " f"(baseline sim: {baseline_calls:,})") # --------------------------------------------------------------------------- # # Entry def main() -> int: ap = argparse.ArgumentParser(description=__doc__.splitlines()[1]) ap.add_argument("--since", default=DEFAULT_SINCE) args = ap.parse_args() since = datetime.strptime(args.since, "%Y-%m-%d").replace(tzinfo=timezone.utc) since_ms = int(since.timestamp() * 1000) if not DB_PATH.exists(): sys.exit(f"db missing: {DB_PATH}") conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True) print(f"loading reads since {args.since}...") reads = fetch_reads(conn, since_ms) conn.close() print(f" {len(reads):,} read calls") # Per-file aggregates. files = aggregate_files(reads) sizes = np.array([f.size_lines for f in files.values()], dtype=np.int64) tpls = np.array([f.tokens_per_line for f in files.values()], dtype=float) print(f" {len(files):,} distinct files") print(f" file size p50={int(np.percentile(sizes,50))} " f"p90={int(np.percentile(sizes,90))} max={int(sizes.max())}") print(f" tokens/line p50={np.percentile(tpls,50):.2f} " f"p90={np.percentile(tpls,90):.2f} max={tpls.max():.2f}") # Per-pair. by_pair = group_pairs(reads) print(f" {len(by_pair):,} (session, file) pairs") # Baseline simulation. print("\nsimulating baseline...") baseline_cfg = Config(default_page=CURRENT_DEFAULT, line_cap=CURRENT_LINE_CAP, byte_cap=CURRENT_BYTE_CAP, summarize_min=0) baseline_sim, baseline_calls = simulate(by_pair, files, baseline_cfg) observed, observed_calls = baseline_observed(reads) print("sweeping (default_page, line_cap, summarize_min)...") result = sweep(by_pair, files) report(result, baseline_sim, baseline_calls, observed, observed_calls) OUT_DIR.mkdir(parents=True, exist_ok=True) out = OUT_DIR / "read-config-sweep.png" plot(result, baseline_sim, observed, out) print(f"\nwrote {out}") return 0 if __name__ == "__main__": sys.exit(main())