Naz786 commited on
Commit
ff6f573
Β·
verified Β·
1 Parent(s): 6fd750b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -46
app.py CHANGED
@@ -5,7 +5,6 @@ import datetime
5
  import streamlit.components.v1 as components
6
 
7
  # --- CONFIG ---
8
- # Place your API keys here
9
  GROQ_API_KEY = st.secrets.get('GROQ_API_KEY', 'YOUR_GROQ_API_KEY')
10
  BLACKBOX_API_KEY = st.secrets.get('BLACKBOX_API_KEY', 'YOUR_BLACKBOX_API_KEY')
11
 
@@ -22,9 +21,8 @@ EXAMPLE_QUESTIONS = [
22
  "How can I make this code more readable?"
23
  ]
24
 
25
- # --- API STUBS ---
26
  def call_groq_api(prompt, model="llama3-70b-8192"):
27
- # Replace with actual Groq API call
28
  headers = {"Authorization": f"Bearer {GROQ_API_KEY}", "Content-Type": "application/json"}
29
  data = {"model": model, "messages": [{"role": "user", "content": prompt}]}
30
  response = requests.post("https://api.groq.com/openai/v1/chat/completions", json=data, headers=headers)
@@ -47,18 +45,15 @@ def call_blackbox_agent(messages):
47
  if response.status_code == 200:
48
  return response.json()["choices"][0]["message"]["content"]
49
  else:
50
- # fallback to Groq if Blackbox fails
51
  return call_groq_api(messages[-1]["content"])
52
 
53
  # --- UTILS ---
54
  def code_matches_language(code, language):
55
- # Simple heuristic, can be improved
56
  if language.lower() in code.lower():
57
  return True
58
- return True # For demo, always True
59
 
60
  def calculate_code_complexity(code):
61
- # Dummy complexity metric
62
  lines = code.count('\n') + 1
63
  return f"{lines} lines"
64
 
@@ -73,10 +68,6 @@ def get_inline_diff(original, modified):
73
  return '\n'.join(diff)
74
 
75
  def is_coding_question(question):
76
- """
77
- Uses Blackbox AI agent to check if the question is about programming/code.
78
- Returns True if yes, False otherwise.
79
- """
80
  messages = [
81
  {"role": "system", "content": "You are a helpful coding assistant."},
82
  {"role": "user", "content": f"Is the following question about programming or code? Answer only 'yes' or 'no'. Question: {question}"}
@@ -127,7 +118,6 @@ elif page == "AI Workflow":
127
  st.error(f"Language mismatch. Please check your code and language selection.")
128
  else:
129
  with st.spinner("Running AI Workflow..."):
130
- # Simulate workflow steps
131
  steps = [
132
  ("Explain", call_groq_api(f"Explain this {programming_language} code for a {skill_level} {user_role} in {explanation_language}:\n{code_input}")),
133
  ("Refactor", call_blackbox_agent([
@@ -145,11 +135,9 @@ elif page == "AI Workflow":
145
  for t in timeline:
146
  st.subheader(t["step"])
147
  st.write(t["output"])
148
- # Show code diff (Original vs Refactored)
149
  st.subheader("Code Diff (Original vs Refactored)")
150
- refactored_code = steps[1][1] # Blackbox agent output
151
  st.code(get_inline_diff(code_input, refactored_code), language=programming_language.lower())
152
- # Download report
153
  report = f"AI Workflow Report\nGenerated on: {datetime.datetime.now()}\nLanguage: {programming_language}\nSkill Level: {skill_level}\nRole: {user_role}\n\n"
154
  for t in timeline:
155
  report += f"## {t['step']}\n{t['output']}\n\n---\n\n"
@@ -175,72 +163,99 @@ elif page == "Semantic Search":
175
  st.caption("Example questions:")
176
  st.write(", ".join(EXAMPLE_QUESTIONS))
177
 
178
- # Session state for question and trigger
179
  if 'voice_question' not in st.session_state:
180
  st.session_state['voice_question'] = ''
181
  if 'run_semantic_search' not in st.session_state:
182
  st.session_state['run_semantic_search'] = False
183
 
184
- # Voice input widget (Web Speech API)
185
- components.html('''
186
- <button id="voice-btn" style="margin-bottom:8px;">🎀 Speak your question</button>
187
- <span id="voice-status" style="margin-left:8px;"></span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  <script>
189
- const btn = document.getElementById('voice-btn');
190
- const status = document.getElementById('voice-status');
191
  let recognition;
192
  if ('webkitSpeechRecognition' in window) {
193
  recognition = new webkitSpeechRecognition();
194
  recognition.lang = 'en-US';
195
  recognition.continuous = false;
196
  recognition.interimResults = false;
197
- btn.onclick = function() {
 
198
  recognition.start();
199
- status.textContent = 'Listening...';
200
  };
201
  recognition.onresult = function(event) {
202
  const transcript = event.results[0][0].transcript;
 
203
  window.parent.postMessage({isStreamlitMessage: true, type: 'streamlit:setComponentValue', value: transcript}, '*');
204
- status.textContent = 'Heard: ' + transcript;
205
  };
206
  recognition.onerror = function() {
207
- status.textContent = 'Voice error';
208
  };
209
  recognition.onend = function() {
210
- if (status.textContent === 'Listening...') status.textContent = '';
211
  };
212
  } else {
213
- btn.disabled = true;
214
- status.textContent = 'Voice not supported';
 
 
 
 
215
  }
216
  </script>
217
- ''', height=60)
218
 
219
- # --- Main question input ---
220
- question = st.text_input("Ask a question about your code", value=st.session_state.get('voice_question', ''), key="sem_question")
221
 
222
- # If voice input is received, validate and set question
223
- # NOTE: Streamlit's JS->Python communication for custom components is limited.
224
- # For a production app, use a robust Streamlit component for voice input.
225
- # Here, we simulate the process using session_state for demonstration.
226
- # You may need to use streamlit_js_eval or a similar package for real-time JS->Python value passing.
227
 
228
- # Simulate voice input: check if the question was updated by voice
229
- if st.session_state.get('voice_question', '') and not st.session_state.get('run_semantic_search', False):
230
- voice_input = st.session_state['voice_question']
231
- if is_coding_question(voice_input):
232
  st.session_state['run_semantic_search'] = True
233
- st.success(f"Question recognized: {voice_input}")
234
  else:
235
  st.warning("Please ask a relevant question.")
236
- st.session_state['voice_question'] = '' # reset
237
 
238
- # Run Semantic Search button
239
  run_btn = st.button("Run Semantic Search")
240
- # If triggered by voice or button
241
  run_search = run_btn or st.session_state.get('run_semantic_search', False)
242
  if run_search:
243
- st.session_state['run_semantic_search'] = False # reset trigger
244
  if not code_input.strip() or not question.strip():
245
  st.error("Both code and question are required.")
246
  elif not code_matches_language(code_input, programming_language):
 
5
  import streamlit.components.v1 as components
6
 
7
  # --- CONFIG ---
 
8
  GROQ_API_KEY = st.secrets.get('GROQ_API_KEY', 'YOUR_GROQ_API_KEY')
9
  BLACKBOX_API_KEY = st.secrets.get('BLACKBOX_API_KEY', 'YOUR_BLACKBOX_API_KEY')
10
 
 
21
  "How can I make this code more readable?"
22
  ]
23
 
24
+ # --- API CALLS ---
25
  def call_groq_api(prompt, model="llama3-70b-8192"):
 
26
  headers = {"Authorization": f"Bearer {GROQ_API_KEY}", "Content-Type": "application/json"}
27
  data = {"model": model, "messages": [{"role": "user", "content": prompt}]}
28
  response = requests.post("https://api.groq.com/openai/v1/chat/completions", json=data, headers=headers)
 
45
  if response.status_code == 200:
46
  return response.json()["choices"][0]["message"]["content"]
47
  else:
 
48
  return call_groq_api(messages[-1]["content"])
49
 
50
  # --- UTILS ---
51
  def code_matches_language(code, language):
 
52
  if language.lower() in code.lower():
53
  return True
54
+ return True
55
 
56
  def calculate_code_complexity(code):
 
57
  lines = code.count('\n') + 1
58
  return f"{lines} lines"
59
 
 
68
  return '\n'.join(diff)
69
 
70
  def is_coding_question(question):
 
 
 
 
71
  messages = [
72
  {"role": "system", "content": "You are a helpful coding assistant."},
73
  {"role": "user", "content": f"Is the following question about programming or code? Answer only 'yes' or 'no'. Question: {question}"}
 
118
  st.error(f"Language mismatch. Please check your code and language selection.")
119
  else:
120
  with st.spinner("Running AI Workflow..."):
 
121
  steps = [
122
  ("Explain", call_groq_api(f"Explain this {programming_language} code for a {skill_level} {user_role} in {explanation_language}:\n{code_input}")),
123
  ("Refactor", call_blackbox_agent([
 
135
  for t in timeline:
136
  st.subheader(t["step"])
137
  st.write(t["output"])
 
138
  st.subheader("Code Diff (Original vs Refactored)")
139
+ refactored_code = steps[1][1]
140
  st.code(get_inline_diff(code_input, refactored_code), language=programming_language.lower())
 
141
  report = f"AI Workflow Report\nGenerated on: {datetime.datetime.now()}\nLanguage: {programming_language}\nSkill Level: {skill_level}\nRole: {user_role}\n\n"
142
  for t in timeline:
143
  report += f"## {t['step']}\n{t['output']}\n\n---\n\n"
 
163
  st.caption("Example questions:")
164
  st.write(", ".join(EXAMPLE_QUESTIONS))
165
 
 
166
  if 'voice_question' not in st.session_state:
167
  st.session_state['voice_question'] = ''
168
  if 'run_semantic_search' not in st.session_state:
169
  st.session_state['run_semantic_search'] = False
170
 
171
+ # Custom input with mic button (HTML/JS)
172
+ question_html = """
173
+ <style>
174
+ .input-mic-container {
175
+ position: relative;
176
+ width: 100%;
177
+ max-width: 500px;
178
+ }
179
+ .input-mic {
180
+ width: 100%;
181
+ padding-right: 40px;
182
+ height: 38px;
183
+ font-size: 16px;
184
+ box-sizing: border-box;
185
+ }
186
+ .mic-btn {
187
+ position: absolute;
188
+ right: 5px;
189
+ top: 4px;
190
+ border: none;
191
+ background: none;
192
+ font-size: 22px;
193
+ cursor: pointer;
194
+ outline: none;
195
+ }
196
+ </style>
197
+ <div class="input-mic-container">
198
+ <input id="questionInput" class="input-mic" type="text" placeholder="Ask a question about your code" value="{value}" />
199
+ <button class="mic-btn" id="micBtn" title="Speak your question">🎀</button>
200
+ </div>
201
  <script>
202
+ const input = document.getElementById('questionInput');
203
+ const micBtn = document.getElementById('micBtn');
204
  let recognition;
205
  if ('webkitSpeechRecognition' in window) {
206
  recognition = new webkitSpeechRecognition();
207
  recognition.lang = 'en-US';
208
  recognition.continuous = false;
209
  recognition.interimResults = false;
210
+ micBtn.onclick = function(e) {
211
+ e.preventDefault();
212
  recognition.start();
213
+ micBtn.textContent = 'πŸŽ™οΈ';
214
  };
215
  recognition.onresult = function(event) {
216
  const transcript = event.results[0][0].transcript;
217
+ input.value = transcript;
218
  window.parent.postMessage({isStreamlitMessage: true, type: 'streamlit:setComponentValue', value: transcript}, '*');
219
+ micBtn.textContent = '🎀';
220
  };
221
  recognition.onerror = function() {
222
+ micBtn.textContent = '🎀';
223
  };
224
  recognition.onend = function() {
225
+ micBtn.textContent = '🎀';
226
  };
227
  } else {
228
+ micBtn.disabled = true;
229
+ micBtn.title = 'Voice not supported';
230
+ }
231
+ // Send value on input change
232
+ input.onchange = function() {
233
+ window.parent.postMessage({isStreamlitMessage: true, type: 'streamlit:setComponentValue', value: input.value}, '*');
234
  }
235
  </script>
236
+ """.replace("{value}", st.session_state.get('voice_question', ''))
237
 
238
+ # Render the custom input+mic
239
+ question_value = components.html(question_html, height=60)
240
 
241
+ # Fallback for Streamlit's JS->Python communication
242
+ # For demo, use a text_input to allow manual typing as well
243
+ question = st.text_input("Ask a question about your code", value=st.session_state.get('voice_question', ''), key="sem_question")
 
 
244
 
245
+ # If the value is updated, validate and set
246
+ if question and question != st.session_state.get('voice_question', ''):
247
+ if is_coding_question(question):
248
+ st.session_state['voice_question'] = question
249
  st.session_state['run_semantic_search'] = True
250
+ st.success(f"Question recognized: {question}")
251
  else:
252
  st.warning("Please ask a relevant question.")
253
+ st.session_state['voice_question'] = ''
254
 
 
255
  run_btn = st.button("Run Semantic Search")
 
256
  run_search = run_btn or st.session_state.get('run_semantic_search', False)
257
  if run_search:
258
+ st.session_state['run_semantic_search'] = False
259
  if not code_input.strip() or not question.strip():
260
  st.error("Both code and question are required.")
261
  elif not code_matches_language(code_input, programming_language):