Team Ai
Apppublic

kyorlin2001/code-analysis-tool

sourceHugging Faceapache-2.0updated 6mo agoView on Hugging Face
0likes
dependency_agent.py120 linesDownload Raw Back to agents
1from __future__ import annotations2 3from dataclasses import dataclass4from pathlib import Path5from typing import Any6 7from models.analysis_state import AnalysisState8 9 10@dataclass11class DependencyOutput:12    """13    Result of dependency analysis.14    """15 16    imports_by_language: dict[str, int]17    package_manifests: list[str]18    notes: list[str]19    findings: list[dict[str, Any]]20 21 22class DependencyAgent:23    """24    Performs lightweight dependency analysis.25 26    Responsibilities:27    - detect dependency manifest files28    - estimate import/package usage29    - produce early findings for downstream reporting30    """31 32    MANIFEST_FILES = {33        "requirements.txt",34        "pyproject.toml",35        "Pipfile",36        "Pipfile.lock",37        "setup.py",38        "package.json",39        "package-lock.json",40        "pnpm-lock.yaml",41        "yarn.lock",42        "go.mod",43        "Cargo.toml",44        "pom.xml",45        "build.gradle",46        "build.gradle.kts",47        "composer.json",48    }49 50    def run(self, state: AnalysisState) -> DependencyOutput:51        package_manifests = self._find_manifests(state.files)52        imports_by_language = self._estimate_imports(state.files)53 54        findings: list[dict[str, Any]] = []55        notes: list[str] = []56 57        if package_manifests:58            notes.append(f"Found {len(package_manifests)} dependency manifest file(s).")59        else:60            notes.append("No common dependency manifest files were detected.")61 62        if "Python" in imports_by_language:63            findings.append(64                {65                    "severity": "info",66                    "message": "Python source files detected; check for unused or stale dependencies.",67                }68            )69 70        output = DependencyOutput(71            imports_by_language=imports_by_language,72            package_manifests=package_manifests,73            notes=notes,74            findings=findings,75        )76 77        state.summaries["dependencies"] = self._format_summary(output)78        state.agent_outputs["dependencies"] = output79        state.findings.extend(findings)80        return output81 82    def _find_manifests(self, files: list[str]) -> list[str]:83        return [f for f in files if Path(f).name in self.MANIFEST_FILES]84 85    def _estimate_imports(self, files: list[str]) -> dict[str, int]:86        counts: dict[str, int] = {}87 88        for file_path in files:89            suffix = Path(file_path).suffix.lower()90            if suffix == ".py":91                counts["Python"] = counts.get("Python", 0) + 192            elif suffix in {".js", ".jsx"}:93                counts["JavaScript"] = counts.get("JavaScript", 0) + 194            elif suffix in {".ts", ".tsx"}:95                counts["TypeScript"] = counts.get("TypeScript", 0) + 196            elif suffix in {".java", ".kt"}:97                counts["JVM"] = counts.get("JVM", 0) + 198            elif suffix == ".go":99                counts["Go"] = counts.get("Go", 0) + 1100            elif suffix == ".rs":101                counts["Rust"] = counts.get("Rust", 0) + 1102 103        return counts104 105    def _format_summary(self, output: DependencyOutput) -> str:106        lines = ["Dependency analysis:"]107        if output.package_manifests:108            lines.append("Manifests:")109            for manifest in output.package_manifests:110                lines.append(f"- {manifest}")111        else:112            lines.append("No dependency manifests found.")113 114        if output.imports_by_language:115            lines.append("Source file counts by language:")116            for language, count in sorted(output.imports_by_language.items()):117                lines.append(f"- {language}: {count}")118 119        lines.extend(output.notes)120        return "\n".join(lines)