File size: 6,214 Bytes
e6f643b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import requests
import time
import pandas as pd
from dotenv import load_dotenv
import os
from groq import Groq

# Load env variables
load_dotenv()
HF_API_KEY = st.secrets.get("HUGGINGFACE_API_KEY") or os.getenv("HUGGINGFACE_API_KEY")
GROQ_API_KEY = st.secrets.get("GROQ_API_KEY") or os.getenv("GROQ_API_KEY")

# Initialize Groq client if key exists
groq_client = Groq(api_key=GROQ_API_KEY) if GROQ_API_KEY else None

# Available models
MODELS = {
    "Python/JS Code Gen": {
        "hf": "bigcode/starcoder2-3b",
        "groq": "llama3-8b-8192"
    },
    "Debugging": {
        "hf": "bigcode/starcoder2-3b",
        "groq": "llama3-8b-8192"
    },
    "Explanation": {
        "hf": "mistralai/Mistral-7B-Instruct-v0.2",
        "groq": "llama3-70b-8192"
    }
}

# Hugging Face API
def query_hf(model_id, prompt, max_new_tokens=300):
    url = f"https://api-inference.huggingface.co/models/{model_id}"
    headers = {"Authorization": f"Bearer {HF_API_KEY}"}
    payload = {"inputs": prompt, "parameters": {"max_new_tokens": max_new_tokens}}

    t0 = time.time()
    try:
        response = requests.post(url, headers=headers, json=payload, timeout=60)
        latency = time.time() - t0
        output = response.json()

        if isinstance(output, list) and "generated_text" in output[0]:
            return output[0]["generated_text"], latency, True
        elif isinstance(output, dict) and "error" in output:
            return f"⚠️ HF Error: {output['error']}", latency, False
        else:
            return str(output), latency, False
    except Exception as e:
        latency = time.time() - t0
        return f"⚠️ HF Exception: {e}", latency, False

# Groq API
def query_groq(model_id, prompt, max_tokens=300):
    if not groq_client:
        return "⚠️ Groq API key not set.", 0, False
    t0 = time.time()
    try:
        response = groq_client.chat.completions.create(
            model=model_id,
            messages=[{"role": "user", "content": prompt}],
            max_tokens=max_tokens
        )
        latency = time.time() - t0
        return response.choices[0].message.content, latency, True
    except Exception as e:
        latency = time.time() - t0
        return f"⚠️ Groq Exception: {e}", latency, False

# Prompt builder
def build_prompt(mode, user_input, language="Python"):
    if mode == "Python/JS Code Gen":
        return f"You are a helpful programmer. Write {language} code for:\n{user_input}\nReturn only code."
    elif mode == "Debugging":
        return f"Debug this code and explain briefly:\n{user_input}"
    elif mode == "Explanation":
        return f"Explain this code step by step:\n{user_input}"
    return user_input

# Query with fallback
def run_query(backend, mode, user_input, lang="Python"):
    model_id = MODELS[mode][backend]
    prompt = build_prompt(mode, user_input, lang)

    if backend == "hf":
        output, latency, success = query_hf(model_id, prompt)
        if success:
            return output, latency, "Hugging Face βœ…"
        else:
            # fallback to Groq
            output2, latency2, success2 = query_groq(MODELS[mode]["groq"], prompt)
            return output2, latency + latency2, "Hugging Face ❌ β†’ Groq βœ…"
    elif backend == "groq":
        output, latency, success = query_groq(model_id, prompt)
        if success:
            return output, latency, "Groq βœ…"
        else:
            # fallback to HF
            output2, latency2, success2 = query_hf(MODELS[mode]["hf"], prompt)
            return output2, latency + latency2, "Groq ❌ β†’ Hugging Face βœ…"
    return "⚠️ Invalid backend", 0, "None"

# Streamlit UI
st.set_page_config(page_title="CodeCraft AI", layout="wide")
st.title("πŸ§‘β€πŸ’» CodeCraft AI (with Fallback)")
st.write("Generate, debug, and explain code using Hugging Face & Groq. If one fails, it auto-falls back!")

backend = st.radio("Choose Backend", ["hf", "groq"], format_func=lambda x: "Hugging Face" if x == "hf" else "Groq")

tab1, tab2, tab3, tab4 = st.tabs(["Generate", "Debug", "Explain", "Analytics"])

# Track logs
if "logs" not in st.session_state:
    st.session_state.logs = []

# Tab 1: Generate
with tab1:
    st.subheader("Code Generation")
    lang = st.selectbox("Choose language", ["Python", "JavaScript"])
    problem = st.text_area("Enter your problem statement")
    if st.button("Generate Code", key="gen_btn"):
        if problem.strip():
            output, latency, status = run_query(backend, "Python/JS Code Gen", problem, lang)
            st.code(output, language=lang.lower())
            st.success(f"{status} | Time: {latency:.2f}s")
            st.session_state.logs.append(("Generate", latency, status))
        else:
            st.warning("Please enter a problem.")

# Tab 2: Debug
with tab2:
    st.subheader("Debug Code")
    buggy_code = st.text_area("Paste buggy code here")
    if st.button("Debug Code", key="debug_btn"):
        if buggy_code.strip():
            output, latency, status = run_query(backend, "Debugging", buggy_code)
            st.text_area("AI Fix & Explanation", output, height=300)
            st.success(f"{status} | Time: {latency:.2f}s")
            st.session_state.logs.append(("Debug", latency, status))
        else:
            st.warning("Please paste code.")

# Tab 3: Explain
with tab3:
    st.subheader("Explain Code")
    code_input = st.text_area("Paste code to explain")
    if st.button("Explain Code", key="explain_btn"):
        if code_input.strip():
            output, latency, status = run_query(backend, "Explanation", code_input)
            st.text_area("AI Explanation", output, height=300)
            st.success(f"{status} | Time: {latency:.2f}s")
            st.session_state.logs.append(("Explain", latency, status))
        else:
            st.warning("Please paste code.")

# Tab 4: Analytics
with tab4:
    st.subheader("Usage Analytics")
    if st.session_state.logs:
        df = pd.DataFrame(st.session_state.logs, columns=["Mode", "Latency", "Status"])
        st.write(df)
        st.bar_chart(df.groupby("Mode")["Latency"].mean())
    else:
        st.info("No usage yet. Try generating, debugging, or explaining first!")