File size: 7,085 Bytes
52a22ac
6600546
 
 
 
 
 
 
 
 
312326d
 
6600546
 
 
 
e718ad1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52a22ac
e718ad1
 
 
 
 
52a22ac
e718ad1
52a22ac
e718ad1
 
 
 
 
 
 
 
 
 
52a22ac
e718ad1
 
52a22ac
e718ad1
312326d
 
e718ad1
 
52a22ac
e718ad1
 
52a22ac
e718ad1
 
 
52a22ac
e718ad1
 
52a22ac
f004bde
312326d
 
 
 
 
52a22ac
312326d
 
e718ad1
 
 
 
 
 
 
 
 
 
bf9eab2
e718ad1
 
bf9eab2
e718ad1
 
 
bf9eab2
e718ad1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312326d
6600546
70ffab8
6600546
e718ad1
312326d
e718ad1
 
 
 
 
 
 
6600546
 
 
 
e718ad1
 
 
52a22ac
 
 
 
 
 
 
 
 
 
 
6600546
e718ad1
 
 
 
 
 
 
 
 
 
 
6600546
52a22ac
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

import streamlit as st
import requests
from fpdf import FPDF
import os
import time
from datetime import datetime
import groq

# API keys (replace with your keys or use environment variables)
mistral_api_key = os.getenv("MISTRAL_API_KEY", "gz6lDXokxgR6cLY72oomALWcm7vhjRzQ")
groq_api_key = os.getenv("GROQ_API_KEY", "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")

# Initialize Groq client
groq_client = groq.Client(api_key=groq_api_key)

# Function to call Mistral API
def call_mistral_api(prompt):
    url = "https://api.mistral.ai/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {mistral_api_key}",
        "Content-Type": "application/json"
    }
    payload = {
        "model": "mistral-medium",
        "messages": [
            {"role": "user", "content": prompt}
        ]
    }
    try:
        response = requests.post(url, headers=headers, json=payload)
        response.raise_for_status()  # Raise an error for bad status codes
        return response.json()['choices'][0]['message']['content']
    except requests.exceptions.HTTPError as err:
        if response.status_code == 429:  # Rate limit exceeded
            st.warning("Rate limit exceeded. Please wait a few seconds and try again.")
            time.sleep(5)  # Wait for 5 seconds before retrying
            return call_mistral_api(prompt)  # Retry the request
        return f"HTTP Error: {err}"
    except Exception as err:
        return f"Error: {err}"

# Function to call Groq API
def call_groq_api(prompt):
    try:
        response = groq_client.chat.completions.create(
            model="llama-3.3-70b-versatile",  # Correct model name
            messages=[
                {"role": "user", "content": prompt}
            ]
        )
        return response.choices[0].message.content
    except Exception as err:
        st.error(f"Error: {err}")
        return f"Error: {err}"

# Function to analyze a single requirement using both models
def analyze_requirement(requirement):
    # Use Mistral for classification and domain identification
    type_prompt = f"Classify the following requirement as Functional or Non-Functional in one word:\n\n{requirement}\n\nType:"
    req_type = call_mistral_api(type_prompt).strip()

    domain_prompt = f"Classify the domain for the following requirement in one word (e.g., E-commerce, Education, etc.):\n\n{requirement}\n\nDomain:"
    domain = call_mistral_api(domain_prompt).strip()

    # Use Groq for defect analysis and rewriting
    defects_prompt = f"""List ONLY the major defects in the following requirement (e.g., Ambiguity, Incompleteness, etc.) in 1-2 words each:\n\n{requirement}\n\nDefects:"""
    defects = call_groq_api(defects_prompt).strip()

    rewritten_prompt = f"""Rewrite the following requirement in 1-2 sentences to address the defects:\n\n{requirement}\n\nRewritten:"""
    rewritten = call_groq_api(rewritten_prompt).strip()

    return {
        "Requirement": requirement,
        "Type": req_type,
        "Domain": domain,
        "Defects": defects,
        "Rewritten": rewritten
    }

# Function to generate a PDF report
def generate_pdf_report(results):
    pdf = FPDF()
    pdf.add_page()
    pdf.set_font("Arial", size=12)

    # Add watermark
    pdf.set_font("Arial", 'B', 50)
    pdf.set_text_color(230, 230, 230)  # Light gray color for watermark
    pdf.rotate(45)  # Rotate the text for watermark effect
    pdf.text(60, 150, "MSSE31 Student's Project")
    pdf.rotate(0)  # Reset rotation


    # Add title and date/time
    pdf.set_font("Arial", 'B', 16)
    pdf.set_text_color(0, 0, 0)  # Black color for title
    pdf.cell(200, 10, txt="AI-Based Requirement Defect Detection Using Large Language Models (LLMs)s", ln=True, align='C')
    pdf.set_font("Arial", size=12)
    pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
    pdf.ln(10)  # Add some space

    # Add requirements analysis
    pdf.set_font("Arial", size=12)
    for i, result in enumerate(results, start=1):
        if pdf.get_y() > 250:  # If the content is near the bottom of the page
            pdf.add_page()  # Add a new page
            pdf.set_font("Arial", 'B', 16)
            pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection", ln=True, align='C')
            pdf.set_font("Arial", size=12)
            pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
            pdf.ln(10)  # Add some space

        # Add requirement details
        pdf.set_font("Arial", 'B', 14)
        pdf.multi_cell(200, 10, txt=f"Requirement R{i}: {result['Requirement']}", align='L')
        pdf.set_font("Arial", size=12)
        pdf.multi_cell(200, 10, txt=f"Type: {result['Type']}", align='L')
        pdf.multi_cell(200, 10, txt=f"Domain: {result['Domain']}", align='L')
        pdf.multi_cell(200, 10, txt=f"Defects: {result['Defects']}", align='L')
        pdf.multi_cell(200, 10, txt=f"Rewritten: {result['Rewritten']}", align='L')
        pdf.multi_cell(200, 10, txt="-" * 50, align='L')
        pdf.ln(5)  # Add some space between requirements

    pdf_output = "requirements_report.pdf"
    pdf.output(pdf_output)
    return pdf_output

# Streamlit app
def main():
    st.title("AI-Based Requirement Defect Detection Using Large Language Models (LLMs)")
    st.markdown("**Team Name:** Sadia, Areeba, Rabbia, Tesmia")
    st.markdown("**Models:** Mistral (Classification & Domain) + Groq (Defects & Rewriting)")

    # Input requirements manually
    input_text = st.text_area("Enter your requirements (one per line or separated by periods):")
    requirements = []
    if input_text:
        requirements = [req.strip() for req in input_text.replace("\n", ".").split(".") if req.strip()]

    # Analyze requirements
    if st.button("Analyze Requirements"):
        if not requirements:
            st.warning("Please enter requirements.")
        else:
            results = []
            for req in requirements:
                if req.strip():  # Ignore empty lines
                    results.append(analyze_requirement(req.strip()))

            # Display results
            st.subheader("Analysis Results")
            for i, result in enumerate(results, start=1):
                st.write(f"### Requirement R{i}: {result['Requirement']}")
                st.write(f"**Type:** {result['Type']}")
                st.write(f"**Domain:** {result['Domain']}")
                st.write(f"**Defects:** {result['Defects']}")
                st.write(f"**Rewritten:** {result['Rewritten']}")
                st.write("---")

            # Generate and download PDF report
            pdf_report = generate_pdf_report(results)
            with open(pdf_report, "rb") as f:
                st.download_button(
                    label="Download PDF Report",
                    data=f,
                    file_name="requirements_report.pdf",
                    mime="application/pdf"
                )

# Run the app
if __name__ == "__main__":
    main()