Skip to content

fix(ingest): per-LLM-call timeout + leaf-section cap (un-stick big PDFs)#27

Merged
hallelx2 merged 1 commit into
mainfrom
feat/ingest-timeout
May 28, 2026
Merged

fix(ingest): per-LLM-call timeout + leaf-section cap (un-stick big PDFs)#27
hallelx2 merged 1 commit into
mainfrom
feat/ingest-timeout

Conversation

@hallelx2
Copy link
Copy Markdown
Owner

Summary

Two ingest bugs that blocked FinanceBench from completing and are real defects on any large filing.

1. No per-LLM-call timeout → infinite ingest hangs

A single hung summarize / HyDE / multi-axis / TOC-build call blocked the stage's errgroup Wait() forever. A doc was observed stuck in summarizing for 13+ hours. Fix: completeWithTimeout wraps every individual LLM.Complete in a context.WithTimeout (default 90s, tunable via ingest.llm_call_timeout_seconds / VLE_INGEST_LLM_CALL_TIMEOUT_SECONDS). On timeout the call is logged and skipped; the document still reaches ready.

2. Leaf-section explosion → ~1500 sections per 10-K

chunkOversizedLeaves splits any leaf >2400 chars into ~900-char pieces, so a 45K-char "Notes to Financial Statements" section shattered into ~50 chunks. A 92-page 10-K produced ~1500 leaves, each costing a summarize + HyDE + multi-axis LLM call — the root of the slow/stalled ingest. Fix: capLeafSections enforces a ceiling (default 400, ingest.max_sections / VLE_INGEST_MAX_SECTIONS) by merging the smallest adjacent leaf siblings under a shared parent until within budget. Content preserved (blank-line joined), page ranges unioned, table sections never merged. Applied in both the heuristic and outline parse paths.

Reachability

The 400-leaf cap is active on the deployed binary today via the existing RegistryFromTableOpts → NewPDFWithTables path (MaxSections:0 resolves to the default). Making ingest.max_sections operator-tunable end-to-end is a 2-line follow-up in the cmd/ binaries (left out here to avoid colliding with the in-flight cmd/server consolidation PR).

Test plan

  • go build ./..., go vet ./..., go test ./... all green
  • Hung-call mock: pipeline still completes, other sections summarize, total time bounded by the timeout
  • Cap tests: merge-down to budget, smallest-pair-first ordering, content preservation (within separator slack), disabled (<=0) escape hatch

Expected impact

A 92-page 10-K should now cap at ~400 leaves (down from ~1500), cutting ingest LLM calls ~3-4x, and no single hung call can freeze a document.

Two ingest bugs that froze FinanceBench ingests and are real product
defects on any large filing:

1. No per-LLM-call timeout. A single hung summarize / HyDE / multi-axis
   / TOC-build call blocked the stage's errgroup Wait() forever — a doc
   was observed stuck in `summarizing` for 13+ hours. Fix:
   completeWithTimeout wraps every individual LLM.Complete in a
   context.WithTimeout (default 90s, ingest.llm_call_timeout_seconds /
   VLE_INGEST_LLM_CALL_TIMEOUT_SECONDS). On timeout the call is logged
   and skipped — the section keeps its existing/empty summary and the
   document still reaches `ready`. One bad call can no longer freeze a
   whole document.

2. Leaf-section explosion. chunkOversizedLeaves splits any leaf over
   2400 chars into ~900-char pieces, so a 45K-char "Notes to Financial
   Statements" section shattered into ~50 chunks; a 92-page 10-K
   produced ~1500 leaves, each costing a summarize+HyDE+multi-axis LLM
   call → the slow/stalled ingest. Fix: capLeafSections enforces a
   ceiling (default 400, ingest.max_sections / VLE_INGEST_MAX_SECTIONS)
   by merging the smallest adjacent leaf siblings under a shared parent
   until the count is within budget. Content is preserved (blank-line
   joined), page ranges unioned, and table sections — attached after
   this pass — are never merged. Applied in both the heuristic and
   outline parse paths.

The cap runs at its default (400) through the existing
RegistryFromTableOpts → NewPDFWithTables path, so the fix is active on
the deployed binary without a cmd wiring change. ingest.max_sections
becoming operator-tunable end-to-end is a small follow-up in the cmd
binaries.

Tests: a hung-call mock proves the pipeline still completes and other
sections summarize; cap tests prove merge-down to budget, smallest-pair
ordering, content preservation, and the disabled (<=0) escape hatch.
go build/vet/test all green.
Copilot AI review requested due to automatic review settings May 28, 2026 14:33
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @hallelx2, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Warning

Review limit reached

@hallelx2, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 58 minutes and 44 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2c75c56b-3276-492d-98fc-ebe1d31f25c7

📥 Commits

Reviewing files that changed from the base of the PR and between e183ca7 and 9f9e087.

📒 Files selected for processing (8)
  • pkg/config/config.go
  • pkg/ingest/hyde.go
  • pkg/ingest/hyde_test.go
  • pkg/ingest/ingest.go
  • pkg/ingest/summary_axes.go
  • pkg/ingest/toc_builder.go
  • pkg/parser/cap_test.go
  • pkg/parser/pdf.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ingest-timeout

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hallelx2 hallelx2 merged commit e2de03d into main May 28, 2026
3 of 9 checks passed
@hallelx2 hallelx2 deleted the feat/ingest-timeout branch May 28, 2026 14:34
@hallelx2 hallelx2 review requested due to automatic review settings May 28, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant