husseinelsaadi commited on
Commit
89511c3
·
1 Parent(s): ce7ced7

chatbot updated

Browse files
Files changed (3) hide show
  1. app.py +30 -24
  2. backend/templates/base.html +39 -13
  3. requirements.txt +0 -3
app.py CHANGED
@@ -34,13 +34,14 @@ import json
34
  # -----------------------------------------------------------------------------
35
  # Chatbot setup
36
  #
37
- # The chatbot feature uses a local vector database (Chroma) to search the
38
- # ``chatbot/chatbot.txt`` knowledge base and then calls the Groq API via the
39
- # OpenAI client. To avoid the expensive model and database initialisation on
40
- # every request, we lazily load the embeddings and collection the first time
41
- # a chat query is processed. Subsequent requests reuse the same global
42
- # objects. See ``init_chatbot()`` and ``get_chatbot_response()`` below for
43
- # implementation details.
 
44
 
45
  # Paths for the chatbot knowledge base and persistent vector store. We
46
  # compute these relative to the current file so that the app can be deployed
@@ -56,42 +57,47 @@ CHATBOT_DB_DIR = "/tmp/chroma_db"
56
  # -----------------------------------------------------------------------------
57
  # Hugging Face model configuration
58
  #
59
- # The original chatbot implementation sent queries to the Groq API via the
60
- # OpenAI client. To remove that dependency we now load a small conversational
61
- # model from Hugging Face. ``HF_MODEL_NAME`` defines which model to use. The
62
- # default value, ``facebook/blenderbot-400M-distill``, provides a good
63
- # balance between quality and resource consumption and is available on
64
- # Hugging Face without requiring authentication. Should you wish to swap to
65
- # another conversational model (e.g. ``microsoft/DialoGPT-medium``), update
66
- # this constant accordingly. The model and tokenizer are loaded lazily in
67
- # ``init_hf_model()`` to avoid impacting application startup time.
68
- HF_MODEL_NAME = "facebook/blenderbot-400M-distill"
69
 
70
  # Global Hugging Face model and tokenizer. These variables remain ``None``
71
  # until ``init_hf_model()`` is called. They are reused across all chatbot
72
  # requests to prevent repeatedly loading the large model into memory.
73
- _hf_model = None
74
- _hf_tokenizer = None
75
 
76
  def init_hf_model() -> None:
77
- """Initialise the Hugging Face conversational model and tokenizer."""
 
 
 
 
 
 
 
78
  global _hf_model, _hf_tokenizer
79
  if _hf_model is not None and _hf_tokenizer is not None:
80
  return
81
 
82
- from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
83
  import torch
84
 
85
- model_name = "facebook/blenderbot-400M-distill"
86
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
87
 
 
 
 
 
88
  tokenizer = AutoTokenizer.from_pretrained(model_name)
89
  model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device)
90
 
91
  _hf_model = model
92
  _hf_tokenizer = tokenizer
93
-
94
- HF_MODEL_NAME = "facebook/blenderbot-400M-distill"
95
  _chatbot_embedder = None
96
  _chatbot_collection = None
97
 
 
34
  # -----------------------------------------------------------------------------
35
  # Chatbot setup
36
  #
37
+ # The chatbot uses a local vector database (Chroma) to search the
38
+ # ``chatbot/chatbot.txt`` knowledge base. Retrieved passages are fed to
39
+ # a lightweight conversational model from Hugging Face (see
40
+ # ``init_hf_model`` below). To avoid the expensive model and database
41
+ # initialisation on every request, embeddings and the vector collection are
42
+ # loaded lazily the first time a chat query is processed. Subsequent
43
+ # requests reuse the same global objects. See ``init_chatbot`` and
44
+ # ``get_chatbot_response`` for implementation details.
45
 
46
  # Paths for the chatbot knowledge base and persistent vector store. We
47
  # compute these relative to the current file so that the app can be deployed
 
57
  # -----------------------------------------------------------------------------
58
  # Hugging Face model configuration
59
  #
60
+ # The chatbot uses a small conversational model hosted on Hugging Face. To
61
+ # allow easy experimentation, the model name can be overridden via the
62
+ # ``HF_CHATBOT_MODEL`` environment variable. If unset, we fall back to
63
+ # ``facebook/blenderbot-400M-distill`` which provides a good balance of
64
+ # quality and resource usage and is freely available without authentication.
65
+ HF_MODEL_NAME = os.getenv("HF_CHATBOT_MODEL", "facebook/blenderbot-400M-distill")
 
 
 
 
66
 
67
  # Global Hugging Face model and tokenizer. These variables remain ``None``
68
  # until ``init_hf_model()`` is called. They are reused across all chatbot
69
  # requests to prevent repeatedly loading the large model into memory.
70
+ _hf_model: 'AutoModelForSeq2SeqLM | None' = None # type: ignore[type-arg]
71
+ _hf_tokenizer: 'AutoTokenizer | None' = None # type: ignore[type-arg]
72
 
73
  def init_hf_model() -> None:
74
+ """
75
+ Initialise the Hugging Face conversational model and tokenizer.
76
+
77
+ This function loads the specified ``HF_MODEL_NAME`` model and its
78
+ corresponding tokenizer. The model is moved to GPU if available,
79
+ otherwise it runs on CPU. Subsequent calls return immediately if
80
+ the model and tokenizer have already been instantiated.
81
+ """
82
  global _hf_model, _hf_tokenizer
83
  if _hf_model is not None and _hf_tokenizer is not None:
84
  return
85
 
86
+ from transformers import AutoModelForSeq2SeqLM, AutoTokenizer # type: ignore
87
  import torch
88
 
89
+ model_name = HF_MODEL_NAME
90
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
91
 
92
+ # Load tokenizer and model from Hugging Face. We deliberately avoid
93
+ # specifying ``use_auth_token`` here since the default models are
94
+ # publicly accessible. Should you wish to use a private model, set
95
+ # HF_HOME/HF_TOKEN environment variables accordingly.
96
  tokenizer = AutoTokenizer.from_pretrained(model_name)
97
  model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device)
98
 
99
  _hf_model = model
100
  _hf_tokenizer = tokenizer
 
 
101
  _chatbot_embedder = None
102
  _chatbot_collection = None
103
 
backend/templates/base.html CHANGED
@@ -778,7 +778,13 @@
778
 
779
  #CHATBOT START
780
  <!-- Chatbot Toggle Button -->
781
- <div id="chatbot-toggle" onclick="toggleChatbot()">💬 Chat</div>
 
 
 
 
 
 
782
 
783
  <!-- Chatbox Popup -->
784
  <div id="chatbot-box">
@@ -790,29 +796,41 @@
790
  <style>
791
  #chatbot-toggle {
792
  position: fixed;
793
- bottom: 20px;
794
- right: 20px;
795
  background-color: #4caf50;
796
  color: white;
797
- padding: 12px 15px;
798
  border-radius: 30px;
799
  cursor: pointer;
800
  z-index: 1000;
 
 
 
 
 
 
 
 
 
 
 
801
  }
802
 
803
  #chatbot-box {
804
  position: fixed;
805
- bottom: 80px;
806
- right: 20px;
807
  /* Default dimensions for larger screens */
808
- width: 300px;
809
- height: 400px;
810
  background: white;
811
  border: 2px solid #ccc;
812
  border-radius: 10px;
813
  display: none;
814
  flex-direction: column;
815
  z-index: 1000;
 
816
  }
817
 
818
  #chat-header {
@@ -835,18 +853,26 @@
835
  #chatbot-box {
836
  width: 90vw;
837
  height: 60vh;
838
- bottom: 70px;
839
  right: 5vw;
840
  }
841
  #chat-messages {
842
- max-height: calc(60vh - 100px);
 
 
 
 
 
 
843
  }
844
  }
 
845
  @media (max-width: 400px) {
846
  #chatbot-toggle {
847
- bottom: 10px;
848
- right: 10px;
849
- padding: 10px 12px;
 
850
  }
851
  }
852
 
 
778
 
779
  #CHATBOT START
780
  <!-- Chatbot Toggle Button -->
781
+ <!--
782
+ The floating chat button toggles the visibility of the chat window.
783
+ We use a flex container here to ensure the emoji and text remain
784
+ centred on all screen sizes. Additional media queries adjust the
785
+ button's position and padding for very small viewports.
786
+ -->
787
+ <div id="chatbot-toggle" onclick="toggleChatbot()">💬 Chat</div>
788
 
789
  <!-- Chatbox Popup -->
790
  <div id="chatbot-box">
 
796
  <style>
797
  #chatbot-toggle {
798
  position: fixed;
799
+ bottom: 1rem;
800
+ right: 1rem;
801
  background-color: #4caf50;
802
  color: white;
803
+ padding: 0.75rem 1rem;
804
  border-radius: 30px;
805
  cursor: pointer;
806
  z-index: 1000;
807
+ display: flex;
808
+ align-items: center;
809
+ justify-content: center;
810
+ font-size: 1rem;
811
+ line-height: 1;
812
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
813
+ transition: background-color 0.2s ease;
814
+ }
815
+
816
+ #chatbot-toggle:hover {
817
+ background-color: #43a047; /* slightly darker green on hover */
818
  }
819
 
820
  #chatbot-box {
821
  position: fixed;
822
+ bottom: calc(1rem + 3.5rem); /* sit above the toggle on desktop */
823
+ right: 1rem;
824
  /* Default dimensions for larger screens */
825
+ width: 20rem;
826
+ height: 25rem;
827
  background: white;
828
  border: 2px solid #ccc;
829
  border-radius: 10px;
830
  display: none;
831
  flex-direction: column;
832
  z-index: 1000;
833
+ box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
834
  }
835
 
836
  #chat-header {
 
853
  #chatbot-box {
854
  width: 90vw;
855
  height: 60vh;
856
+ bottom: calc(1rem + 3rem);
857
  right: 5vw;
858
  }
859
  #chat-messages {
860
+ max-height: calc(60vh - 5.5rem);
861
+ }
862
+ #chatbot-toggle {
863
+ bottom: 1rem;
864
+ right: 1rem;
865
+ padding: 0.65rem 0.9rem;
866
+ font-size: 0.9rem;
867
  }
868
  }
869
+
870
  @media (max-width: 400px) {
871
  #chatbot-toggle {
872
+ bottom: 0.75rem;
873
+ right: 0.75rem;
874
+ padding: 0.6rem 0.8rem;
875
+ font-size: 0.85rem;
876
  }
877
  }
878
 
requirements.txt CHANGED
@@ -1,6 +1,3 @@
1
-
2
-
3
-
4
  flask
5
  flask_login
6
  flask_sqlalchemy
 
 
 
 
1
  flask
2
  flask_login
3
  flask_sqlalchemy