lanna_lalala;- commited on
Commit
fa7a3bc
·
1 Parent(s): 7e2f9b5

init frontend

Browse files
Files changed (3) hide show
  1. phase/Student_view/chatbot.py +43 -41
  2. requirements.txt +5 -0
  3. utils/api.py +5 -1
phase/Student_view/chatbot.py CHANGED
@@ -1,94 +1,97 @@
 
1
  import streamlit as st
2
  import datetime
3
  import os
4
- from openai import OpenAI
5
 
6
  # Read from Space Secrets (Settings → Variables & secrets)
7
- api_key = os.getenv("OPENAI_API_KEY")
8
- if not api_key:
9
- st.error("⚠️ OPENAI_API_KEY is not set. In your Space, add a Secret named OPENAI_API_KEY ")
10
- client = OpenAI(api_key=api_key)
 
 
11
 
12
- # --- Helper to add message ---
13
  def add_message(text: str, sender: str):
14
  st.session_state.messages.append(
15
  {
16
  "id": str(datetime.datetime.now().timestamp()),
17
  "text": text,
18
- "sender": sender,
19
  "timestamp": datetime.datetime.now()
20
  }
21
  )
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def show_page():
24
  st.title("🤖 AI Financial Tutor")
25
  st.caption("Get personalized help with your financial questions")
26
 
27
- # --- Initialize state ---
28
  if "messages" not in st.session_state:
29
- st.session_state.messages = [
30
- {
31
- "id": "1",
32
- "text": "Hi! I'm your AI Financial Tutor. I'm here to help you learn about personal finance, investing, budgeting, and more. What would you like to know?",
33
- "sender": "assistant",
34
- "timestamp": datetime.datetime.now()
35
- }
36
- ]
37
  if "is_typing" not in st.session_state:
38
  st.session_state.is_typing = False
39
 
40
- # --- Chat Container ---
41
  chat_container = st.container()
42
  with chat_container:
43
  for msg in st.session_state.messages:
44
  if msg["sender"] == "assistant":
45
- st.markdown(f"<div style='background-color:#e0e0e0; color:black; padding:10px; border-radius:12px; max-width:70%; margin-bottom:5px;'>{msg['text']}<br><sub>{msg['timestamp'].strftime('%H:%M')}</sub></div>", unsafe_allow_html=True)
 
 
 
46
  else:
47
- st.markdown(f"<div style='background-color:#4CAF50; color:white; padding:10px; border-radius:12px; max-width:70%; margin-left:auto; margin-bottom:5px;'>{msg['text']}<br><sub>{msg['timestamp'].strftime('%H:%M')}</sub></div>", unsafe_allow_html=True)
 
 
 
48
 
49
  if st.session_state.is_typing:
50
  st.markdown("🤖 _FinanceBot is typing..._")
51
 
52
- # --- Quick Questions ---
53
  if len(st.session_state.messages) == 1:
54
  st.markdown("Try asking about:")
55
  cols = st.columns(2)
56
- quick_questions = [
57
  "How does compound interest work?",
58
  "How much should I save for emergencies?",
59
  "What's a good budgeting strategy?",
60
  "How do I start investing?"
61
  ]
62
- for i, q in enumerate(quick_questions):
63
  if cols[i % 2].button(q):
64
- add_message(q, "user")
65
- st.session_state.is_typing = True
66
- st.rerun()
67
 
68
- # --- Input Box ---
69
  user_input = st.chat_input("Ask me anything about personal finance...")
70
  if user_input:
71
  add_message(user_input, "user")
72
  st.session_state.is_typing = True
73
  st.rerun()
74
 
75
- # --- Call OpenAI API directly ---
76
  if st.session_state.is_typing:
77
  try:
78
  with st.spinner("FinanceBot is thinking..."):
79
- messages_payload = [
80
- {"role": m['sender'], "content": m['text']} for m in st.session_state.messages
81
- ]
82
- # Ensure role is either 'user' or 'assistant'
83
- for m in messages_payload:
84
- if m['role'] not in ['user', 'assistant']:
85
- m['role'] = 'user'
86
-
87
- response = client.chat.completions.create(
88
- model="gpt-4o-mini",
89
- messages=messages_payload
90
- )
91
- bot_reply = response.choices[0].message.content
92
  add_message(bot_reply, "assistant")
93
  except Exception as e:
94
  add_message(f"⚠️ Error: {e}", "assistant")
@@ -96,7 +99,6 @@ def show_page():
96
  st.session_state.is_typing = False
97
  st.rerun()
98
 
99
- # --- Navigation Button ---
100
  if st.button("Back to Dashboard", key="ai_tutor_back_btn"):
101
  st.session_state.current_page = "Student Dashboard"
102
  st.rerun()
 
1
+ # phase/Student_view/chatbot.py
2
  import streamlit as st
3
  import datetime
4
  import os
5
+ from huggingface_hub import InferenceClient
6
 
7
  # Read from Space Secrets (Settings → Variables & secrets)
8
+ HF_TOKEN = os.getenv("HF_TOKEN")
9
+ GEN_MODEL = os.getenv("GEN_MODEL", "mistralai/Mistral-7B-Instruct-v0.2")
10
+
11
+ if not HF_TOKEN:
12
+ st.error("⚠️ HF_TOKEN is not set. In your Space, add a Secret named HF_TOKEN.")
13
+ client = InferenceClient(model=GEN_MODEL, token=HF_TOKEN)
14
 
 
15
  def add_message(text: str, sender: str):
16
  st.session_state.messages.append(
17
  {
18
  "id": str(datetime.datetime.now().timestamp()),
19
  "text": text,
20
+ "sender": sender, # "user" or "assistant"
21
  "timestamp": datetime.datetime.now()
22
  }
23
  )
24
 
25
+ def _reply_with_hf():
26
+ # Convert chat history into a simple prompt
27
+ system = "You are a kind Jamaican primary-school finance tutor. Keep answers short, friendly, and age-appropriate."
28
+ convo = []
29
+ for m in st.session_state.messages:
30
+ role = "USER" if m["sender"] != "assistant" else "ASSISTANT"
31
+ convo.append(f"{role}: {m['text']}")
32
+ prompt = (system + "\n\n" + "\n".join(convo) + "\nASSISTANT:").strip()
33
+
34
+ return client.text_generation(
35
+ prompt,
36
+ max_new_tokens=220,
37
+ temperature=0.2,
38
+ stream=False
39
+ )
40
+
41
  def show_page():
42
  st.title("🤖 AI Financial Tutor")
43
  st.caption("Get personalized help with your financial questions")
44
 
 
45
  if "messages" not in st.session_state:
46
+ st.session_state.messages = [{
47
+ "id": "1",
48
+ "text": "Hi! I'm your AI Financial Tutor. What would you like to learn today?",
49
+ "sender": "assistant",
50
+ "timestamp": datetime.datetime.now()
51
+ }]
 
 
52
  if "is_typing" not in st.session_state:
53
  st.session_state.is_typing = False
54
 
 
55
  chat_container = st.container()
56
  with chat_container:
57
  for msg in st.session_state.messages:
58
  if msg["sender"] == "assistant":
59
+ st.markdown(
60
+ f"<div style='background-color:#e0e0e0; color:black; padding:10px; border-radius:12px; max-width:70%; margin-bottom:5px;'>{msg['text']}<br><sub>{msg['timestamp'].strftime('%H:%M')}</sub></div>",
61
+ unsafe_allow_html=True
62
+ )
63
  else:
64
+ st.markdown(
65
+ f"<div style='background-color:#4CAF50; color:white; padding:10px; border-radius:12px; max-width:70%; margin-left:auto; margin-bottom:5px;'>{msg['text']}<br><sub>{msg['timestamp'].strftime('%H:%M')}</sub></div>",
66
+ unsafe_allow_html=True
67
+ )
68
 
69
  if st.session_state.is_typing:
70
  st.markdown("🤖 _FinanceBot is typing..._")
71
 
 
72
  if len(st.session_state.messages) == 1:
73
  st.markdown("Try asking about:")
74
  cols = st.columns(2)
75
+ quick = [
76
  "How does compound interest work?",
77
  "How much should I save for emergencies?",
78
  "What's a good budgeting strategy?",
79
  "How do I start investing?"
80
  ]
81
+ for i, q in enumerate(quick):
82
  if cols[i % 2].button(q):
83
+ add_message(q, "user"); st.session_state.is_typing = True; st.rerun()
 
 
84
 
 
85
  user_input = st.chat_input("Ask me anything about personal finance...")
86
  if user_input:
87
  add_message(user_input, "user")
88
  st.session_state.is_typing = True
89
  st.rerun()
90
 
 
91
  if st.session_state.is_typing:
92
  try:
93
  with st.spinner("FinanceBot is thinking..."):
94
+ bot_reply = _reply_with_hf()
 
 
 
 
 
 
 
 
 
 
 
 
95
  add_message(bot_reply, "assistant")
96
  except Exception as e:
97
  add_message(f"⚠️ Error: {e}", "assistant")
 
99
  st.session_state.is_typing = False
100
  st.rerun()
101
 
 
102
  if st.button("Back to Dashboard", key="ai_tutor_back_btn"):
103
  st.session_state.current_page = "Student Dashboard"
104
  st.rerun()
requirements.txt CHANGED
@@ -31,3 +31,8 @@ markdownify>=0.12.1
31
  duckduckgo-search==6.3.5
32
  bcrypt
33
  plotly
 
 
 
 
 
 
31
  duckduckgo-search==6.3.5
32
  bcrypt
33
  plotly
34
+
35
+
36
+ python-dotenv==1.0.1
37
+ requests>=2.32
38
+ huggingface_hub==0.24.5
utils/api.py CHANGED
@@ -1,6 +1,10 @@
 
1
  import os, requests
2
 
3
- BACKEND = os.getenv("BACKEND_URL").rstrip("/")
 
 
 
4
 
5
  def start_agent(student_id:int, lesson_id:int, level_slug:str):
6
  r = requests.post(f"{BACKEND}/agent/start", json={"student_id":student_id,"lesson_id":lesson_id,"level_slug":level_slug})
 
1
+ # utils/api.py
2
  import os, requests
3
 
4
+ BACKEND = (os.getenv("BACKEND_URL") or "").strip()
5
+ if not BACKEND:
6
+ raise RuntimeError("BACKEND_URL is not set in Space secrets.")
7
+ BACKEND = BACKEND.rstrip("/")
8
 
9
  def start_agent(student_id:int, lesson_id:int, level_slug:str):
10
  r = requests.post(f"{BACKEND}/agent/start", json={"student_id":student_id,"lesson_id":lesson_id,"level_slug":level_slug})