File size: 4,634 Bytes
53e0bdc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os

from anthropic import Anthropic


def code_analysis_report(code: str) -> str:
    """
    Generate a code analysis report using the Anthropic API.

    Args:
        code (str): The code string to analyze.

    Returns:
        str: A detailed analysis report including top fixes.
    """
    if not code:
        return "Please provide code to analyze."

    try:
        client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

        analysis_prompt = (
            """Analyze the following code for potential issues, including vulnerabilities, style problems, and quality concerns. """.strip()
            + f""" Provide a detailed analysis and list the top 5-10 most critical fixes needed, explaining each one.
```python
{code}
```""".strip()
        )

        # Define a tool to structure the output
        tools = [
            {
                "name": "analysis_report",
                "description": "Return the detailed analysis and a list of top fixes.",
                "input_schema": {
                    "type": "object",
                    "properties": {
                        "detailed_analysis": {
                            "type": "string",
                            "description": "Detailed analysis of the code.",
                        },
                        "top_fixes": {
                            "type": "array",
                            "description": "List of top fixes needed.",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "fix_description": {
                                        "type": "string",
                                        "description": "Description of the fix.",
                                    },
                                    "severity": {
                                        "type": "string",
                                        "description": "Severity of the issue (e.g., Critical, High, Medium, Low).",
                                    },
                                },
                                "required": ["fix_description", "severity"],
                            },
                        },
                    },
                    "required": ["detailed_analysis", "top_fixes"],
                    "additionalProperties": False,
                },
            }
        ]

        resp = client.messages.create(
            model="claude-sonnet-4-20250514",  # Using the model from scoring.py
            messages=[{"role": "user", "content": analysis_prompt.format(code=code)}],
            system="You are a secure-coding assistant that provides detailed analysis and actionable fixes.",
            tools=tools,
            tool_choice={"type": "tool", "name": "analysis_report"},
            max_tokens=1500,  # Increased tokens for detailed output
            temperature=0,
        )

        # Check if the response contains a tool_use block
        tool_call = None
        for content_block in resp.content:
            if content_block.type == "tool_use":
                tool_call = content_block
                break

        if tool_call is None:
            # If no tool_use block is found, return an error with the raw response content
            return f"Error during code analysis: Expected tool_use response, but received: {resp.content}"

        analysis_result = tool_call.input

        report = "Code Analysis Report:\n\n"
        report += "Detailed Analysis:\n"
        report += analysis_result.get("detailed_analysis", "N/A") + "\n\n"

        report += "Top Fixes:\n"
        fixes = analysis_result.get("top_fixes", [])
        if fixes:
            for i, fix in enumerate(fixes):
                report += f"{i + 1}. [Severity: {fix.get('severity', 'N/A')}] {fix.get('fix_description', 'N/A')}\n"
        else:
            report += "No specific fixes identified or issues found."

        return report

    except Exception as exc:
        return f"Error during code analysis: {exc}"


# ------------------------------------------------------------------ #
# Demo / quick test
# ------------------------------------------------------------------ #

if __name__ == "__main__":
    sample_code = """
def calculate_discount(price, discount_rate):
    # Applies a discount to a price
    if discount_rate > 1:
        return price # No discount if rate is invalid
    return price * (1 - discount_rate)
"""

    print("Analyzing sample code...")
    analysis_report = code_analysis_report(sample_code)
    print("\n" + analysis_report)