Skip to content

fix(meta): batch findings and handle truncated responses - #153

Merged
vineethsai7 merged 4 commits into
mainfrom
codex/fix-137-meta-batching
Aug 3, 2026
Merged

fix(meta): batch findings and handle truncated responses#153
vineethsai7 merged 4 commits into
mainfrom
codex/fix-137-meta-batching

Conversation

@vineethsai7

@vineethsai7 vineethsai7 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • batch meta-analysis findings according to the configured output-token budget while preserving global finding indices
  • detect normalized and provider-native token-limit completion reasons and bisect only the truncated batch
  • remove the fragile partial-JSON repair and full-finding-set follow-up request
  • retain each finding exactly once when a batch is malformed or unavailable
  • expose batch-local degradation through analysis_warnings, meta_analysis_status, and per-finding metadata
  • aggregate token usage from successful and truncated attempts
  • update locked aiohttp to 3.14.3 after CVE-2026-59881 made the security workflow fail

For inputs larger than one batch, correlations and priority rankings are necessarily batch-local and are merged deterministically in batch order. Inputs that fit one batch keep the existing single-call behavior.

Validation

  • focused/API/CLI suite: 100 passed, 1 skipped
  • full suite: 1,582 passed, 5 skipped, 1 xfailed
  • Ruff and formatting checks
  • pre-commit hooks
  • CodeRabbit local review: 0 findings
  • uv run pip-audit (no known vulnerabilities)

Closes #137

Summary by CodeRabbit

  • New Features

    • Large analyses now process findings in manageable batches while preserving their original order and references.
    • Results identify fully validated findings versus degraded findings with associated analysis warnings.
    • Incomplete or malformed batch responses are retained with clear warnings instead of losing results.
  • Bug Fixes

    • Improved handling of truncated responses, token limits, duplicate classifications, and incomplete results.
    • Findings are now consistently normalized and deduplicated.

@vineethsai7
vineethsai7 marked this pull request as ready for review August 3, 2026 20:38
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 20a69978-7156-4863-b3fc-f46f50ab20d9

📥 Commits

Reviewing files that changed from the base of the PR and between a3cfadb and e55989f.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • skill_scanner/core/analyzers/meta_analyzer.py
  • tests/test_meta_analyzer_batching.py

📝 Walkthrough

Walkthrough

Meta-analysis now processes findings in token-budgeted batches. It preserves global indices, handles truncated and malformed responses, merges results deterministically, and reports degraded findings through metadata and analysis_warnings.

Changes

Meta-analysis batching and validation

Layer / File(s) Summary
Analysis status and exceptions
skill_scanner/core/analyzers/meta_analyzer.py
MetaAnalysisResult now includes analysis_warnings. New exceptions identify truncated provider output and invalid JSON. Degraded findings are no longer marked as fully validated.
Batch sizing and response handling
skill_scanner/core/analyzers/meta_analyzer.py
Findings use global indices and token-budgeted batches. Truncated batches are split recursively. Provider token usage is recorded before response handling. Malformed responses produce batch-level degraded results without retries.
Response normalization and degraded merge
skill_scanner/core/analyzers/meta_analyzer.py
Response indices and required fields are validated. Duplicate and out-of-range classifications are removed. Missing findings are restored once. Results retain deterministic ordering and degraded metadata.
Batching and degradation regression coverage
tests/test_meta_analyzer_batching.py
Tests cover bounded batches, malformed responses, truncation splitting, provider-specific token limits, token usage aggregation, and incomplete or duplicate classifications.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MetaAnalyzer
  participant LLMProvider
  participant ResponseParser
  MetaAnalyzer->>LLMProvider: Send indexed finding batch
  LLMProvider-->>MetaAnalyzer: Return response, finish reason, and token usage
  MetaAnalyzer->>ResponseParser: Validate JSON and classification indices
  ResponseParser-->>MetaAnalyzer: Return classifications or parse error
  MetaAnalyzer->>MetaAnalyzer: Split truncated batches or create degraded results
  MetaAnalyzer->>MetaAnalyzer: Normalize and merge all batch results
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR addresses issue #137 by batching findings, detecting truncation, avoiding full-set retries, preserving findings, and exposing degraded analysis.
Out of Scope Changes check ✅ Passed The changes are limited to the meta-analyzer and regression tests that support issue #137 objectives.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: batching findings and handling truncated responses.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-137-meta-batching

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ce7a2323c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread skill_scanner/core/analyzers/meta_analyzer.py Outdated
@vineethsai7

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
tests/test_meta_analyzer_batching.py (1)

190-213: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the two remaining degradation codes.

The suite covers META_BATCH_PARSE_FAILED and META_BATCH_INCOMPLETE. It does not cover META_BATCH_REQUEST_FAILED, which occurs when _make_llm_request raises, or META_BATCH_TRUNCATED, which occurs when a single-finding batch is truncated. Both paths must retain each finding exactly once and mark it degraded.

I can write both tests if you want.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_meta_analyzer_batching.py` around lines 190 - 213, Add tests
alongside test_incomplete_batch_is_filled_once_without_duplicate_indices
covering META_BATCH_REQUEST_FAILED when _make_llm_request raises and
META_BATCH_TRUNCATED for a truncated single-finding batch. Assert each path
retains every finding exactly once, marks retained findings with
meta_analysis_degraded=True, and emits the corresponding degradation code.
skill_scanner/core/analyzers/meta_analyzer.py (2)

607-613: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Stop calling the provider after a request failure, and narrow the caught exception.

Line 607 converts every exception into a degraded batch. If the failure is permanent, for example an invalid API key or an unknown model, each remaining batch still runs self.max_retries requests. A 257-finding scan then issues many failing calls and reports the configuration error only as META_BATCH_REQUEST_FAILED warnings. Ruff also flags the blind except Exception (BLE001).

Short-circuit the remaining batches after the first request failure, and degrade them locally.

♻️ Proposed short-circuit in `analyze_with_findings`
         batch_size = self._max_findings_per_batch()
         result = MetaAnalysisResult()
+        request_failed = False
 
         for batch_number, start in enumerate(range(0, len(findings), batch_size), start=1):
             indices = list(range(start, min(start + batch_size, len(findings))))
+            if request_failed:
+                self._merge_batch_result(
+                    result,
+                    self._degraded_batch_result(
+                        findings,
+                        indices,
+                        code="META_BATCH_REQUEST_FAILED",
+                        message=(
+                            "Skipped after an earlier meta-analysis request failure; "
+                            "this batch was retained unchanged."
+                        ),
+                    ),
+                )
+                continue
             logger.info(
             batch_result = await self._analyze_batch(
                 skill=skill,
                 findings=findings,
                 indices=indices,
                 skill_context=skill_context,
                 analyzers_used=analyzers_used,
                 start_tag=start_tag,
                 end_tag=end_tag,
             )
+            request_failed = any(
+                warning["code"] == "META_BATCH_REQUEST_FAILED" for warning in batch_result.analysis_warnings
+            )
             self._merge_batch_result(result, batch_result)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill_scanner/core/analyzers/meta_analyzer.py` around lines 607 - 613, Update
analyze_with_findings to stop invoking the provider after the first batch
request failure, locally degrading all remaining batches with the existing
failure result behavior. Narrow the exception handling around the provider
request to the specific request/provider exception types rather than catching
Exception, while preserving the initial batch’s META_BATCH_REQUEST_FAILED
reporting.

Source: Linters/SAST tools


1096-1103: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove or call the fallback path from another caller.

The only _parse_response(...) call passes fallback_on_error=False, so the default fallback_on_error=True branch is unreachable and duplicates _degraded_batch_result.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill_scanner/core/analyzers/meta_analyzer.py` around lines 1096 - 1103,
Update _parse_response and its callers so the unreachable fallback_on_error=True
path is removed, or ensure another caller explicitly uses it if that behavior is
required. Since the existing call passes fallback_on_error=False and duplicates
_degraded_batch_result, eliminate the unused default parameter and fallback
branch while preserving current response parsing and degraded-result behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skill_scanner/core/analyzers/meta_analyzer.py`:
- Around line 1050-1063: Update the finish-reason handling in the
response-processing method around choice and finish_reason to recognize every
provider-specific truncation value used by the configured routes, including
normalized length/max_tokens and retained raw max-token indicators. Keep raising
MetaAnalysisTruncatedError for all such values so the batch orchestrator takes
its bisect path, and document the mapping near the check.

---

Nitpick comments:
In `@skill_scanner/core/analyzers/meta_analyzer.py`:
- Around line 607-613: Update analyze_with_findings to stop invoking the
provider after the first batch request failure, locally degrading all remaining
batches with the existing failure result behavior. Narrow the exception handling
around the provider request to the specific request/provider exception types
rather than catching Exception, while preserving the initial batch’s
META_BATCH_REQUEST_FAILED reporting.
- Around line 1096-1103: Update _parse_response and its callers so the
unreachable fallback_on_error=True path is removed, or ensure another caller
explicitly uses it if that behavior is required. Since the existing call passes
fallback_on_error=False and duplicates _degraded_batch_result, eliminate the
unused default parameter and fallback branch while preserving current response
parsing and degraded-result behavior.

In `@tests/test_meta_analyzer_batching.py`:
- Around line 190-213: Add tests alongside
test_incomplete_batch_is_filled_once_without_duplicate_indices covering
META_BATCH_REQUEST_FAILED when _make_llm_request raises and META_BATCH_TRUNCATED
for a truncated single-finding batch. Assert each path retains every finding
exactly once, marks retained findings with meta_analysis_degraded=True, and
emits the corresponding degradation code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b25d73db-1ee4-4c4a-88c4-7c2e350692d5

📥 Commits

Reviewing files that changed from the base of the PR and between 5dca0c5 and 7ce7a23.

📒 Files selected for processing (2)
  • skill_scanner/core/analyzers/meta_analyzer.py
  • tests/test_meta_analyzer_batching.py

Comment thread skill_scanner/core/analyzers/meta_analyzer.py
@vineethsai7
vineethsai7 force-pushed the codex/fix-137-meta-batching branch from 2ef3430 to e55989f Compare August 3, 2026 20:57
@vineethsai7
vineethsai7 merged commit 8764c3d into main Aug 3, 2026
11 checks passed
@vineethsai7
vineethsai7 deleted the codex/fix-137-meta-batching branch August 3, 2026 21:05
@vineethsai7

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot mentioned this pull request Aug 10, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant