mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-17 05:07:37 +08:00
fix(explore): return a qualified or line-anchored method's body instead of its signature (#2063)
`SQLCompiler.as_sql pre_sql_setup get_select` on django returned get_select and pre_sql_setup in full and SQLCompiler.as_sql -- qualified, step 1 of the Flow, 226 lines -- as one signature line. compiler.py renders as a per-symbol focused view, which picked bodies in source order within a tier, so the unnamed bridge get_qualify_sql and get_select (both above as_sql in the file) took the cap. The follow-ups agents issue (`compiler.py:776`, `compiler.py lines 900-1003`) pinned the file and dropped the line numbers. Every agent run ended in a Read of compiler.py. - query-paths: keep `:776` / `:12-40` / `#L88-L120` suffixes as line anchors and bind prose ranges (`lines 900-1003`, `L900-L1003`, `lines 900 to 1003`) to the nearest single-file path. - EXACT targets: a qualified name resolving to <=3 callables, or the callable enclosing a single-line anchor. Multi-line anchors render as that span. - Focused view: tiers exact > named spine step > unnamed bridge > unique named > family co-named, spine in call order. A tier 0-1 body that does not fit is windowed (head + calls into the question's other symbols) with the explore range that returns each hole, never reduced to a signature. Priced in rendered chars net of the signature lines, so the section keeps its promise. - Cluster path: exact clusters rank first with the spine's bounded overshoot, shrink by exact rendered size, and hold back what lower-ranked exact clusters still owe; files holding one are funded like spine files. - Blast radius leads with exact targets. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,6 +56,57 @@ source.
|
||||
> first, so the budget cap never binds it). OkHttp's interceptors stay a pure
|
||||
> signature skeleton (no named callable in them, don't define a supertype).
|
||||
|
||||
> **Refinement (2026-09-28) — exact targets.** The per-symbol view above still
|
||||
> lost the one method the agent asked for by its qualified name. On a fresh django
|
||||
> index `SQLCompiler.as_sql pre_sql_setup get_select` returned `get_select` and
|
||||
> `pre_sql_setup` in full and `SQLCompiler.as_sql` — step 1 of the rendered Flow,
|
||||
> 226 lines — as its signature line, on main and on every branch since. Bodies
|
||||
> were chosen in SOURCE order within a tier, so the unnamed bridge
|
||||
> `get_qualify_sql` and `get_select` (both above `as_sql` in the file) took the
|
||||
> cap. The agents' follow-ups (`SQLCompiler.as_sql full body compiler.py:776`,
|
||||
> `compiler.py lines 900-1003 as_sql tail`) pinned the file but dropped the line
|
||||
> numbers, returning `SQLInsertCompiler.as_sql` and friends instead; every run
|
||||
> Read compiler.py. The fix:
|
||||
> 1. **Exact targets** — a qualified name that resolves to ≤3 callables
|
||||
> (`SQLCompiler.as_sql`: 1 of 110), or the callable enclosing a line anchor
|
||||
> (`compiler.py:776`). A bare `as_sql` is NOT exact, so the family rules above
|
||||
> still keep the 110 overrides as signatures.
|
||||
> 2. **Tiers in the focused view:** exact → spine step the agent named → unnamed
|
||||
> spine bridge → uniquely-named off-spine → family co-named; the spine in CALL
|
||||
> order within its tier.
|
||||
> 3. **Window, never signature, for tiers 0–1.** A body too big for what is left
|
||||
> is cut to its head plus the lines where it calls the question's other
|
||||
> symbols, and each hole names the explore query that returns it
|
||||
> (`codegraph_explore \`compiler.py:871-1001\``).
|
||||
> 4. **Line anchors** (`query-paths.ts`): `file:line`, `file:a-b`, `#La-Lb`, and
|
||||
> prose `lines a-b` / `L a-L b` next to a path. A range renders as exactly that
|
||||
> span (cluster path, ranked first).
|
||||
> 5. **Priced in rendered chars.** The view counted raw source while it rendered
|
||||
> line numbers and ~20 signature lines; once windows fill the cap the
|
||||
> undercount became a 19% overshoot that zeroed four excalidraw files below it.
|
||||
>
|
||||
> Deterministic replay (54 queries × 8 repos): 43 byte-identical; `as_sql`
|
||||
> complete in all 5 distinct django queries that single it out (was 1, 0, 175,
|
||||
> 0 and 226 of 226 lines), the `lines 900-1003` span 104/104 (was 1); named-body
|
||||
> lines 8,706 → 9,443. The trade: where the file's budget cannot hold everything, a large named
|
||||
> step now wins over several small off-spine bodies (`pb-compiler`: `as_sql` whole,
|
||||
> `execute_sql`/`results_iter` to signatures).
|
||||
>
|
||||
> Agent A/B (`ab-new-vs-baseline.sh`, django, README question pair, Sonnet /
|
||||
> `--effort high`, RUNS=3, baseline `e63fe2ec`): **Read 0 in 3/3 new runs vs a
|
||||
> Read of compiler.py in 2/3 baseline runs** — each right after the agent's own
|
||||
> `SQLCompiler.as_sql … compiler.py:776` explore, the exact follow-up the report
|
||||
> described. Tool calls 3 → 4 median, retrieval residual 19.5K vs 22.9K tokens,
|
||||
> median cost $0.195 vs $0.229 and 30s vs 35s (n=3, the last two within noise).
|
||||
>
|
||||
> Rebased onto #2062 (protected members paid before incidental ones across
|
||||
> clusters), which leaves this gap open — `as_sql` 1/226 on that main. The two
|
||||
> compose: #2062's protected/incidental rule is the cluster path's base, and
|
||||
> exact targets sit on top of it (ranked first, every member priced in rendered
|
||||
> chars, held back for lower exact clusters). Re-measured against that main, 59
|
||||
> queries: 43 byte-identical, named-body lines 9,804 → 10,731, every target span
|
||||
> above complete.
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
@@ -260,8 +311,15 @@ the agent's real query — that mismatch is what this refinement corrects.)
|
||||
`definesPolymorphicSupertype()` (a node HAS ≥3 incoming `implements`/`extends`
|
||||
— i.e. the file is the family base). The skeleton branch:
|
||||
`off-spine && isPolymorphicSibling && !(namedInFile && !definesSupertype)`.
|
||||
`exactNodeIds` / `anchorSpans` (the exact targets) and `bodyFocusLines()`
|
||||
(what a window of an oversize body must reach) are shared by the focused
|
||||
view and the cluster path.
|
||||
- `src/search/query-paths.ts` — `lineAnchors`: `file:line` / range parsing.
|
||||
- `__tests__/adaptive-explore-sizing.test.ts` — 7 cases incl. the named-callable
|
||||
spare (RealCall) and the supertype-family override (compiler.py).
|
||||
- `__tests__/explore-exact-target.test.ts` — the django shape in miniature:
|
||||
qualified body whole, subclass overrides still signatures, blast-radius lead,
|
||||
`file:line` and `lines a-b` anchors, and a windowed body keeping its tail call.
|
||||
|
||||
## Frontier / future work
|
||||
|
||||
|
||||
Reference in New Issue
Block a user