Skip to content

refactor: align python code analysis contracts#398

Merged
jerry609 merged 4 commits intodevfrom
refactor/pr3-python-contract-alignment
Mar 15, 2026
Merged

refactor: align python code analysis contracts#398
jerry609 merged 4 commits intodevfrom
refactor/pr3-python-contract-alignment

Conversation

@jerry609
Copy link
Owner

Summary

  • fill in the missing CodeAnalyzer helpers so structure, dependency, security, and documentation analysis return stable schemas instead of collapsing to empty dicts
  • align CodeAnalysisAgent, QualityAgent, and ScholarWorkflowCoordinator around the actual analysis payloads used in the repo
  • preserve single-repo placeholders, map updated_at / last_commit_date / reproducibility_score into CodeMeta, and remove a stale root-level fallback test that imported a dead module
  • add focused contract tests for analyzer output, code-analysis flattening, quality-agent input handling, and workflow score/code-meta publication

Validation

  • python -m pytest -q tests/unit/test_code_analyzer_contracts.py tests/unit/test_code_analysis_contracts.py tests/unit/test_workflow_coordinator.py

Copilot AI review requested due to automatic review settings March 15, 2026 05:12
@vercel
Copy link

vercel bot commented Mar 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
paper-bot Ready Ready Preview, Comment Mar 15, 2026 6:35am

@coderabbitai
Copy link

coderabbitai bot commented Mar 15, 2026

Warning

Rate limit exceeded

@jerry609 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 57 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bbb56c22-deb8-4af1-b117-eb7eda26c2d3

📥 Commits

Reviewing files that changed from the base of the PR and between 751bcb2 and 728e238.

📒 Files selected for processing (8)
  • src/paperbot/agents/code_analysis/agent.py
  • src/paperbot/agents/quality/agent.py
  • src/paperbot/core/workflow_coordinator.py
  • src/paperbot/utils/analyzer.py
  • tests/test_code_analysis_fallback.py
  • tests/unit/test_code_analysis_contracts.py
  • tests/unit/test_code_analyzer_contracts.py
  • tests/unit/test_workflow_coordinator.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/pr3-python-contract-alignment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the code analysis pipeline to establish clear and stable data contracts between different agents and the workflow coordinator. The changes ensure that analysis results are consistently structured, metadata is accurately mapped, and the quality assessment logic is more robust. This leads to improved reliability and predictability of the code analysis process, making it easier to integrate and extend in the future.

Highlights

  • Code Analysis Contract Alignment: Refactored CodeAnalyzer to ensure all analysis helpers (structure, dependency, security, documentation) return stable and predictable schemas, preventing empty dictionaries and providing consistent data structures.
  • Agent and Workflow Coordination: Aligned CodeAnalysisAgent, QualityAgent, and ScholarWorkflowCoordinator to consistently use the defined analysis payloads, improving data flow and reliability across the system.
  • Metadata Mapping and Enrichment: Enhanced metadata handling by mapping updated_at, last_commit_date, and reproducibility_score into the CodeMeta object, and preserving single-repository placeholders for better context.
  • Expanded Contract Testing: Introduced new, focused contract tests to validate analyzer output, code-analysis flattening, QualityAgent input processing, and the correct publication of workflow scores and CodeMeta.
  • Quality Agent Logic Refinement: Updated the QualityAgent's scoring mechanisms for complexity, maintainability, security, documentation, and test coverage to use more robust calculations and to correctly process both flat and nested analysis results.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/paperbot/agents/code_analysis/agent.py
    • Added logic to return placeholder results directly when in single-repository mode.
    • Updated _flatten_result to prioritize updated_at and include last_commit_date for comprehensive date tracking.
    • Modified _placeholder to include last_commit_date in placeholder responses.
    • Enhanced _extract_repo_meta to capture updated_at from GitHub API and set last_commit_date.
  • src/paperbot/agents/quality/agent.py
    • Removed unused pathlib.Path import.
    • Refactored process method to use new helper functions for input extraction, flat result detection, and repository entry normalization.
    • Improved _process_flat_result to calculate quality_score from reproducibility_score and derive strengths/weaknesses from available metadata.
    • Updated _analyze_complexity, _analyze_maintainability, _analyze_security, _analyze_documentation, and _analyze_test_coverage to use quality analysis metrics if available, or fall back to more detailed calculations.
    • Added new private helper methods: _extract_analysis_input, _is_flat_result, _normalize_repo_entries, _placeholder_quality, _collect_strengths, _collect_weaknesses, and _security_measure_present.
  • src/paperbot/core/workflow_coordinator.py
    • Modified _publish_code_score to use reproducibility_score if present, otherwise fallback to health_score, and normalize the score to a 0-100 range.
    • Updated _run_influence_stage to populate CodeMeta with updated_at, last_commit_date (with fallback), and reproducibility_score, ensuring stars and forks default to 0.
  • src/paperbot/utils/analyzer.py
    • Added new imports for json, shutil, xml.etree.ElementTree, and tomllib (with a fallback for ModuleNotFoundError).
    • Initialized analysis methods (analyze_structure, analyze_security, analyze_quality, analyze_dependencies) with empty, stable schema dictionaries to ensure consistent output.
    • Enhanced analyze_structure to include primary language detection.
    • Refined analyze_quality to calculate maintainability and test coverage scores more accurately and to include file_paths in file statistics.
    • Improved _analyze_documentation to explicitly track has_readme and readme_quality, and to provide detailed api_documentation coverage.
    • Refactored _check_dependency_security for robustness, including checks for requirements.txt, safety tool availability, and improved error handling and reporting.
    • Introduced numerous _empty_* helper methods to provide default, stable schemas for various analysis metrics.
    • Added new parsing and scanning utilities for different dependency types (_parse_python_requirements, _parse_node_dependencies, _parse_rust_dependencies, _parse_maven_dependencies) and security patterns (_scan_security_pattern).
  • tests/test_code_analysis_fallback.py
    • Removed a stale root-level fallback test that imported a dead module.
  • tests/unit/test_code_analysis_contracts.py
    • Added new unit tests to verify single-repository placeholder handling in CodeAnalysisAgent.
    • Included tests for correct mapping of CodeMeta fields during result flattening.
    • Added tests to confirm QualityAgent correctly processes both flat and nested code analysis results.
  • tests/unit/test_code_analyzer_contracts.py
    • Added a comprehensive unit test to ensure CodeAnalyzer returns stable and expected output for structure, security, quality, and dependency analysis.
  • tests/unit/test_workflow_coordinator.py
    • Introduced a _CaptureInfluenceCalculator to inspect CodeMeta passed to the influence stage.
    • Added new tests to confirm the ScholarWorkflowCoordinator uses the reproducibility_score for the code stage and correctly passes aligned CodeMeta to the influence calculator.
Activity
  • The pull request includes a detailed summary of changes in the description.
  • Validation steps are provided, instructing to run specific pytest commands for unit tests related to code analyzer contracts, code analysis contracts, and workflow coordinator.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

github-actions bot commented Mar 15, 2026

Vercel Preview

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a significant and well-executed refactoring that aligns the data contracts across the code analysis components. The introduction of stable schemas for analysis results, especially in failure cases, greatly improves the robustness of the pipeline. The expanded analysis capabilities in CodeAnalyzer and the improved logic in QualityAgent are excellent additions. The new contract tests provide good coverage for these critical changes.

I have one suggestion regarding a potential circular dependency in the fallback logic for calculating the maintainability score in QualityAgent, which could lead to incorrect scoring.

Comment on lines +176 to 181
overall = float(quality_metrics.get('overall_score', 0.0) or 0.0)
documentation = float(quality_metrics.get('documentation_score', 0.0) or 0.0)
complexity = float(quality_metrics.get('complexity_score', 0.0) or 0.0)
has_readme = 1.0 if quality_metrics.get('has_readme') else 0.0
score = (overall * 0.5) + (documentation * 0.2) + (complexity * 0.2) + (has_readme * 0.1)
return min(1.0, max(0.0, score))

Choose a reason for hiding this comment

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

high

The fallback calculation for the maintainability score appears to have a circular dependency. It uses overall_score from quality_analysis to compute a maintainability_score. However, the overall_score from the CodeAnalyzer is a composite score that already includes a maintainability_score component. This circular logic can lead to incorrect and unpredictable scoring.

The fallback should be based on more fundamental metrics. A better approach would be to use other pre-calculated scores like complexity_score and documentation_score, but without using overall_score.

Suggested change
overall = float(quality_metrics.get('overall_score', 0.0) or 0.0)
documentation = float(quality_metrics.get('documentation_score', 0.0) or 0.0)
complexity = float(quality_metrics.get('complexity_score', 0.0) or 0.0)
has_readme = 1.0 if quality_metrics.get('has_readme') else 0.0
score = (overall * 0.5) + (documentation * 0.2) + (complexity * 0.2) + (has_readme * 0.1)
return min(1.0, max(0.0, score))
complexity_score = float(quality_metrics.get('complexity_score', 0.0) or 0.0)
documentation_score = float(quality_metrics.get('documentation_score', 0.0) or 0.0)
has_readme = 1.0 if quality_metrics.get('has_readme') else 0.0
# Re-weighted score based on available metrics, avoiding circular dependency on overall_score.
score = (complexity_score * 0.6) + (documentation_score * 0.2) + (has_readme * 0.2)
return min(1.0, max(0.0, score))

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR tightens the “code analysis → workflow scoring → influence” data contract by standardizing fields like reproducibility_score, updated_at, and last_commit_date, and adding unit tests to enforce these expectations across the analyzer, agents, and coordinator.

Changes:

  • Update ScholarWorkflowCoordinator to prefer reproducibility_score for the code-stage score and pass richer CodeMeta into influence calculation.
  • Expand CodeAnalyzer output contracts (structure/security/quality/dependencies) and improve fallback defaults for error cases.
  • Refactor QualityAgent input handling to support both nested analysis results and flat workflow code_analysis_result, with new contract tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/unit/test_workflow_coordinator.py Adds regression tests ensuring code-stage uses reproducibility score and influence receives aligned CodeMeta.
tests/unit/test_code_analyzer_contracts.py New contract test for CodeAnalyzer outputs across structure/security/quality/dependencies.
tests/unit/test_code_analysis_contracts.py New contract tests for CodeAnalysisAgent flattening/placeholder behavior and QualityAgent input compatibility.
tests/test_code_analysis_fallback.py Removes outdated fallback tests (superseded by new unit contract tests).
src/paperbot/utils/analyzer.py Adds stable “empty” contracts, primary language detection, richer documentation/dependency parsing, and dependency security reporting.
src/paperbot/core/workflow_coordinator.py Uses reproducibility_score for code-stage scoring when available; passes updated_at/last_commit_date/reproducibility_score into CodeMeta.
src/paperbot/agents/quality/agent.py Refactors process() to normalize inputs and support flat/nested code analysis contracts.
src/paperbot/agents/code_analysis/agent.py Preserves placeholder results in single-repo mode and aligns flattened metadata fields (updated_at, last_commit_date).
Comments suppressed due to low confidence (1)

src/paperbot/utils/analyzer.py:26

  • radon / ComplexityVisitor are imported (and assigned None on ImportError) but no longer referenced anywhere in this module. Removing these unused imports/variables will reduce confusion and avoid future lint failures if strict linting is enabled.
try:
    import radon.complexity as radon
    from radon.visitors import ComplexityVisitor
except ImportError:
    radon = None
    ComplexityVisitor = None

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 107 to +115
# 计算总体质量分数
overall_score = 0.0
recommendations = []

# 复杂度评分 (0-1)
total_complexity = complexity.get('overall_complexity', 0)
if total_complexity > 0:
complexity_score = max(0, 1 - (total_complexity / 100))
else:
complexity_score = 1.0
file_count = max(1, len(complexity.get('file_complexity', {})))
average_complexity = total_complexity / file_count
complexity_score = max(0.0, 1.0 - (average_complexity / 20.0))
@sonarqubecloud
Copy link

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the “code analysis → workflow scoring → influence” contract by standardizing flattened code-analysis fields (reproducibility score + repo metadata) and adding tests to lock the behavior down across agents and the workflow coordinator.

Changes:

  • Update workflow coordinator to publish the code-stage score from reproducibility_score (fallback to health_score) and pass aligned CodeMeta into influence calculations.
  • Expand CodeAnalyzer outputs (stable empty contracts, primary language detection, dependency parsing, richer documentation metrics, and dependency security reporting).
  • Add/replace unit tests covering analyzer/agent contracts and workflow integration; remove legacy root-import test.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/unit/test_workflow_coordinator.py Adds regression tests ensuring code-stage score uses reproducibility and influence receives aligned CodeMeta.
tests/unit/test_code_analyzer_contracts.py New contract tests for CodeAnalyzer structure/security/quality/dependency outputs and requirements parsing.
tests/unit/test_code_analysis_contracts.py New contract tests for CodeAnalysisAgent flattening/placeholder behavior and QualityAgent input compatibility.
tests/test_code_analysis_fallback.py Removes legacy root-import tests.
src/paperbot/utils/analyzer.py Enhances analyzer output stability, dependency parsing, doc metrics, and dependency security scanning behavior.
src/paperbot/core/workflow_coordinator.py Uses reproducibility_score for code-stage scoring and builds richer CodeMeta for influence stage.
src/paperbot/agents/quality/agent.py Refactors input normalization; supports flat code-analysis results and computes overall quality score aggregation.
src/paperbot/agents/code_analysis/agent.py Preserves placeholders in single-repo mode and aligns flattened metadata fields (updated_at, last_commit_date).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 107 to 116
# 计算总体质量分数
overall_score = 0.0
recommendations = []

# 复杂度评分 (0-1)
total_complexity = complexity.get('overall_complexity', 0)
if total_complexity > 0:
complexity_score = max(0, 1 - (total_complexity / 100))
else:
complexity_score = 1.0
file_count = max(1, len(complexity.get('file_complexity', {})))
average_complexity = total_complexity / file_count
complexity_score = max(0.0, 1.0 - (average_complexity / 20.0))
overall_score += complexity_score * self.quality_weights['complexity']
Comment on lines +377 to +380
report['vulnerable_dependencies'] = vulnerabilities
report['total_vulnerabilities'] = len(vulnerabilities)
report['status'] = 'issues_found' if vulnerabilities else 'clean'
return report
@jerry609 jerry609 merged commit 8e49999 into dev Mar 15, 2026
14 checks passed
@jerry609 jerry609 deleted the refactor/pr3-python-contract-alignment branch March 15, 2026 06:36
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.

2 participants