fix(deep): chunk crux calls for symbol-dense files (#260) - #274
Frankie-Xu wants to merge 2 commits into
Conversation
🌱 graft blast radius1 area changed → 2 areas can be affected. 4 dependent symbols, depth 2. flowchart TB
A0(("Graph Enrichment<br/>3 symbols"))
A1(("Crux Summarization<br/>1 symbol"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0,A1 reached;
Who knows this code — 2 people across 3 areas
Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no All 4 dependent symbols, grouped by areaGraph Enrichment — 3 symbols in 1 file
Crux Summarization — 1 symbol in 1 file
Test signal per changed area — 1 ✓Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.
5 test suites also reference this code10 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.
Open the interactive graph → — click an area to see its dependent symbols at file:line. |
e426307 to
0d8a1af
Compare
0d8a1af to
f7e24a3
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Rebased onto current main. CI is green. Ready for review. |
|
Chunking is the right call over raising The chunk loop spreads the file's source unchanged into every chunk: for (const nodes of chunkCruxTargets(input.nodes)) {
const { parsed, res } = await this.describeChunk({ ...input, nodes });
The output-budget problem is genuinely fixed by this PR. What's left is that the binding The fix composes with what's already here — window the source alongside the targets. Split Measured on a synthetic 500 KB / 8,000-line / 200-symbol file with a stub model: That last line is the assertion worth adding to On a real 14-file / 1,447-symbol directory, source-span windowing took coverage 6% → 96%, and |
|
Thanks @SeatownSin — you are right. Chunking fixed the output-budget miss, but each chunk still sent the whole Pushed
Did not take a pasted patch. Did not touch |
Summary
maxTokens: 8192around ~125 symbols. The OpenAI adapter'sJSON.parseof the truncated tool arguments fails,parseResultsreturns[], and the whole file is dropped. Re-running--deephits the same ceiling, so those files stay failed forever.CRUX_CHUNK_SIZE = 80(pinned by test; ~90 completion tokens/entry stays under 8192). Dense files take several sequential calls; results are merged. Small files still cost one call.finish_reason=lengthis logged instead of swallowed. Empty chunks staypendingand are not cached asready(fix(deep): retry pending nodes — don't cache empty meaning summaries (#172) #177).maxTokensand retry once onfinish_reason=length. Rejected:public/js/app.jshas 698 targets (~65k completion tokens); there is no ceiling that covers that in one call.Orthogonal to the #254 circuit breaker (quality misses vs quota) and Draft #270 (echoed TARGET-line ids). Does not touch
--only-dir(#262),recover-tool(#269), or the echo peel.Closes #260
Rebase vs Draft #270
Both PRs edit
src/ai/crux.ts. This one only changes packing (describeFilesplits + merges;parseResultsuntouched). #270 peels echoed ids insideparseResults. They compose: chunk, then peel per chunk.Suggested order: land this, rebase #270 onto it (conflict should be
describeFilevsparseResults, not overlapping hunks). If #270 lands first, rebase this onto it — thedescribeFilerewrite is the larger hunk.Test plan
model.createfinish_reason=lengthwith empty{}tool args logstruncated/finish_reason=length(the silent-drop shape)pending, not cachedready(fix(deep): retry pending nodes — don't cache empty meaning summaries (#172) #177)pendingnode --import tsx --test test/crux-chunk.test.ts test/llm-ops.test.ts test/graph-enrich-pending.test.ts test/graph-enrich-quality.test.ts test/graph-enrich-failures.test.tsnpm run buildMade with Cursor