Team Ai
Apppublic

kyorlin2001/code-analysis-tool

sourceHugging Faceapache-2.0updated 6mo agoView on Hugging Face
0likes
app.py236 linesDownload Raw Back to src
1from __future__ import annotations2 3import json4 5import streamlit as st6 7from orchestrator import AnalysisOrchestrator8from tools.github_loader import load_repository_from_github9from tools.repo_loader import load_repository_from_zip10 11 12st.set_page_config(page_title="Agentic Code Analyst", layout="wide")13st.title("Agentic Code Analyst 🤖")14st.write("Analyze a zip archive, or GitHub repository.")15 16 17if "last_result" not in st.session_state:18    st.session_state.last_result = None19if "zip_temp_dir" not in st.session_state:20    st.session_state.zip_temp_dir = None21if "github_temp_dir" not in st.session_state:22    st.session_state.github_temp_dir = None23if "repo_root_path" not in st.session_state:24    st.session_state.repo_root_path = None25 26 27input_mode = st.radio(28    "Choose input type",29    ["Zip file upload", "GitHub repository"],30    horizontal=True,31)32 33repo_path = ""34uploaded_zip = None35github_owner = ""36github_repo = ""37github_branch = "main"38github_token = ""39 40if input_mode == "Local folder path":41    repo_path = st.text_input(42        "Local repository folder path",43        placeholder=r"C:\\path\\to\\your\\repo",44    )45elif input_mode == "Zip file upload":46    uploaded_zip = st.file_uploader(47        "Upload a zip file containing your codebase",48        type=["zip"],49        accept_multiple_files=False,50    )51else:52    github_owner = st.text_input("GitHub owner", placeholder="octocat")53    github_repo = st.text_input("GitHub repo", placeholder="hello-world")54    github_branch = st.text_input("Branch", value="main")55    github_token = st.text_input("GitHub token (optional)", type="password")56 57focus = st.selectbox(58    "Analysis focus",59    ["full", "architecture", "dependencies", "issues"],60    index=0,61)62 63enable_rag = st.checkbox("Enable RAG follow-up questions", value=True)64 65rag_question = ""66if enable_rag:67    rag_question = st.text_area(68        "Optional RAG question",69        placeholder="What should I improve in this repository?",70        height=100,71    )72 73baseline_file = st.file_uploader(74    "Optional baseline findings JSON for regression analysis",75    type=["json"],76    accept_multiple_files=False,77)78 79baseline_findings = []80if baseline_file is not None:81    try:82        baseline_findings = json.loads(baseline_file.getvalue().decode("utf-8"))83        if not isinstance(baseline_findings, list):84            st.warning("Baseline JSON must be a list of finding objects.")85            baseline_findings = []86    except Exception as exc:87        st.warning(f"Could not parse baseline JSON: {exc}")88        baseline_findings = []89 90run_button = st.button("Run analysis")91 92if run_button:93    try:94        with st.spinner("Analyzing repository..."):95            orchestrator = AnalysisOrchestrator(enable_rag=enable_rag)96            repo_data = None97            resolved_repo_path = ""98 99            if input_mode == "Local folder path":100                if not repo_path.strip():101                    st.error("Please enter a folder path.")102                    st.stop()103 104                resolved_repo_path = repo_path.strip()105                result = orchestrator.run_analysis(106                    repo_path=resolved_repo_path,107                    focus=focus,108                    baseline_findings=baseline_findings,109                    rag_question=rag_question.strip() or None,110                )111 112            elif input_mode == "Zip file upload":113                if uploaded_zip is None:114                    st.error("Please upload a zip file.")115                    st.stop()116 117                loaded = load_repository_from_zip(118                    uploaded_zip.getvalue(),119                    uploaded_zip.name,120                )121                st.session_state.zip_temp_dir = loaded.temp_dir122                repo_data = loaded.data123                resolved_repo_path = loaded.data.root_dir or ""124 125                result = orchestrator.run_analysis(126                    repo_path=resolved_repo_path,127                    focus=focus,128                    baseline_findings=baseline_findings,129                    repo_data=repo_data,130                    rag_question=rag_question.strip() or None,131                )132 133            else:134                if not github_owner.strip() or not github_repo.strip():135                    st.error("Please enter both GitHub owner and repo.")136                    st.stop()137 138                loaded = load_repository_from_github(139                    owner=github_owner.strip(),140                    repo=github_repo.strip(),141                    branch=github_branch.strip() or "main",142                    token=github_token.strip() or None,143                )144                st.session_state.github_temp_dir = loaded.temp_dir145                repo_data = loaded.data146                resolved_repo_path = loaded.data.root_dir or ""147 148                result = orchestrator.run_analysis(149                    repo_path=resolved_repo_path,150                    focus=focus,151                    baseline_findings=baseline_findings,152                    repo_data=repo_data,153                    rag_question=rag_question.strip() or None,154                )155 156            st.session_state.last_result = result157            st.session_state.repo_root_path = resolved_repo_path158 159    except Exception as exc:160        st.error(f"Analysis failed: {exc}")161 162 163result = st.session_state.last_result164 165if result:166    st.subheader("Summary")167    st.markdown(result.summary)168 169    st.subheader("Recommendations")170    for rec in result.recommendations:171        st.write(f"- {rec}")172 173    st.subheader("Findings")174    if result.findings:175        for finding in result.findings:176            severity = finding.get("severity", "info")177            message = finding.get("message", "")178            st.write(f"- **[{severity}]** {message}")179    else:180        st.write("No findings reported.")181 182    if result.rag_answer:183        st.divider()184        st.subheader("RAG Answer")185        st.write(result.rag_answer)186 187        if result.rag_suggestions:188            st.subheader("RAG Suggestions")189            for suggestion in result.rag_suggestions:190                st.write(f"- {suggestion}")191 192        if result.rag_citations:193            st.subheader("RAG Citations")194            for citation in result.rag_citations:195                st.write(f"- {citation.get('label', citation)}")196 197        if result.rag_follow_up_questions:198            st.subheader("RAG Follow-up Questions")199            for item in result.rag_follow_up_questions:200                st.write(f"- {item}")201 202        if result.rag_notes:203            st.subheader("RAG Notes")204            for note in result.rag_notes:205                st.write(f"- {note}")206 207        rag_debug = {}208        if isinstance(result.metadata, dict):209            rag_debug = result.metadata.get("rag", {}) or {}210 211        if rag_debug:212            with st.expander("RAG Debug Info"):213                st.json(rag_debug)214 215                prompt_preview = rag_debug.get("prompt_preview")216                if prompt_preview:217                    st.subheader("Prompt Preview")218                    st.text(prompt_preview)219 220                selected_files = rag_debug.get("selected_files", [])221                if selected_files:222                    st.subheader("Selected Files")223                    for file_path in selected_files:224                        st.write(f"- {file_path}")225 226                selected_chunk_previews = rag_debug.get("selected_chunk_previews", [])227                if selected_chunk_previews:228                    st.subheader("Selected Chunk Previews")229                    for i, preview in enumerate(selected_chunk_previews, start=1):230                        st.markdown(f"**Chunk {i}**")231                        st.code(preview)232 233    with st.expander("Raw metadata"):234        st.json(result.metadata)235else:236    st.info("Run an analysis to see results here.")