charesz commited on
Commit
40bd192
·
verified ·
1 Parent(s): 5576c67

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +21 -0
  2. app.py +201 -0
  3. requirements (1).txt +9 -0
README.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: ChatModelApp
3
+ emoji: ⚡
4
+ colorFrom: gray
5
+ colorTo: red
6
+ sdk: streamlit
7
+ sdk_version: 1.30.0
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ # ChatModelApp
13
+
14
+ Multi-provider chat app using **Google Gemini (PaLM API)** and **Hugging Face** models, built with Streamlit.
15
+
16
+ ## Usage
17
+
18
+ 1. Set Secrets in Hugging Face Spaces:
19
+ - `GEN_API_KEY` → Gemini API key
20
+ - `HUGGINGFACE_HUB_TOKEN` → Hugging Face token
21
+ 2. The app file is `app.py`. It will run automatically.
app.py ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from huggingface_hub import InferenceClient
3
+ import google.generativeai as genai
4
+ import time
5
+ import json # Import json for better handling of HF client response
6
+
7
+ # -------------------
8
+ # API Keys Setup
9
+ # -------------------
10
+ # Use Streamlit's built-in secrets handling
11
+ huggingface_token = st.secrets.get("HUGGINGFACE_HUB_TOKEN", "")
12
+ gemini_api_key = st.secrets.get("GEN_API_KEY", "")
13
+
14
+ # -------------------
15
+ # Configuration
16
+ # -------------------
17
+ st.set_page_config(page_title="Multi-Provider Chat", layout="wide")
18
+ st.title("⚡ Multi-Provider Chat App")
19
+
20
+ # List of recommended Hugging Face models that work well for chat via InferenceClient
21
+ # All instruction-tuned models (Mistral, Zephyr, Gemma) are failing due to server
22
+ # restrictions requiring the 'conversational' task or brittle templating.
23
+ # Switching to small, reliable base models guaranteed to support 'text-generation'.
24
+ HF_RECOMMENDED_MODELS = [
25
+ "gpt2", # New primary fallback: Very stable base model
26
+ "bigscience/bloom-560m", # Kept as secondary base model
27
+ ]
28
+
29
+ # -------------------
30
+ # Sidebar Settings
31
+ # -------------------
32
+ st.sidebar.title("⚙️ Settings")
33
+ provider = st.sidebar.selectbox("Provider", ["Hugging Face", "Gemini"])
34
+
35
+ # -------------------
36
+ # Provider Setup
37
+ # -------------------
38
+ client = None
39
+ model = None
40
+
41
+ if provider == "Hugging Face":
42
+ if not huggingface_token:
43
+ st.error("⚠️ Please set your 'HUGGINGFACE_HUB_TOKEN' in Streamlit secrets.")
44
+ st.stop()
45
+
46
+ # Initialize the client
47
+ client = InferenceClient(token=huggingface_token)
48
+
49
+ selected_models = st.sidebar.multiselect(
50
+ "Choose HF models",
51
+ HF_RECOMMENDED_MODELS,
52
+ default=[HF_RECOMMENDED_MODELS[0]]
53
+ )
54
+ if not selected_models:
55
+ st.warning("⚠️ Please select at least one Hugging Face model.")
56
+ st.stop()
57
+
58
+ elif provider == "Gemini":
59
+ if not gemini_api_key:
60
+ st.error("⚠️ Please set your 'GEN_API_KEY' in Streamlit secrets.")
61
+ st.stop()
62
+
63
+ genai.configure(api_key=gemini_api_key)
64
+
65
+ # Fetch available models that support the generateContent method
66
+ available_models = [
67
+ m.name for m in genai.list_models() if "generateContent" in m.supported_generation_methods
68
+ ]
69
+
70
+ if not available_models:
71
+ st.error("⚠️ No Gemini models available for your API key.")
72
+ st.stop()
73
+
74
+ model = st.sidebar.selectbox("Model", available_models)
75
+
76
+ # Initialize Gemini chat if model changes or if not initialized
77
+ if "gemini_chat" not in st.session_state or st.session_state.get("model") != model:
78
+ st.session_state.model = model
79
+ try:
80
+ gemini_model = genai.GenerativeModel(model)
81
+ st.session_state.gemini_chat = gemini_model.start_chat(history=[])
82
+ except Exception as e:
83
+ st.error(f"⚠️ Could not initialize Gemini model: {e}")
84
+ st.stop()
85
+
86
+ # -------------------
87
+ # System Prompt
88
+ # -------------------
89
+ system_prompt = st.sidebar.text_area(
90
+ "System Prompt",
91
+ "You are a helpful AI assistant. Provide concise and accurate answers."
92
+ )
93
+
94
+ # -------------------
95
+ # Chat History State
96
+ # -------------------
97
+ if "messages" not in st.session_state:
98
+ st.session_state.messages = []
99
+
100
+ # Reset conversation button
101
+ if st.sidebar.button("Reset Conversation"):
102
+ st.session_state.messages = []
103
+ # Also reset the Gemini chat history if using Gemini
104
+ if provider == "Gemini" and model:
105
+ gemini_model = genai.GenerativeModel(model)
106
+ st.session_state.gemini_chat = gemini_model.start_chat(history=[])
107
+ st.rerun() # Rerun to clear messages immediately
108
+
109
+ # -------------------
110
+ # Display Chat Messages
111
+ # -------------------
112
+ for msg in st.session_state.messages:
113
+ with st.chat_message(msg["role"]):
114
+ st.markdown(msg["content"])
115
+
116
+ # -------------------
117
+ # User Input
118
+ # -------------------
119
+ if user_input := st.chat_input("Type your message..."):
120
+ # 1. Display and save user message immediately
121
+ st.chat_message("user").markdown(user_input)
122
+ st.session_state.messages.append({"role": "user", "content": user_input})
123
+
124
+ # -------------------
125
+ # Hugging Face Logic
126
+ # -------------------
127
+ if provider == "Hugging Face":
128
+ for m in selected_models:
129
+ # Display a temporary "generating" message
130
+ with st.chat_message("assistant"):
131
+ message_placeholder = st.empty()
132
+ message_placeholder.markdown(f"**{m}** is generating...")
133
+
134
+ try:
135
+ bot_text = ""
136
+ # Use simple stop sequences for chat formatting, including "assistant:" itself
137
+ stop_sequences = ["assistant:", "user:"]
138
+ prompt_text = ""
139
+
140
+ # --- Generic Chat Template (Most reliable for text-generation endpoint) ---
141
+ # This uses the simple "role: content" format which is often robust.
142
+ conv = "\n".join([f"{msg['role']}: {msg['content']}" for msg in st.session_state.messages])
143
+ prompt_text = f"{system_prompt}\n\n{conv}\nassistant:"
144
+
145
+ # 2. Generate response using text_generation
146
+ resp = client.text_generation(
147
+ model=m,
148
+ prompt=prompt_text,
149
+ max_new_tokens=256,
150
+ temperature=0.7,
151
+ stop_sequences=stop_sequences
152
+ )
153
+
154
+ # 3. Unified parsing
155
+ if isinstance(resp, str):
156
+ bot_text = resp
157
+ elif isinstance(resp, dict) and "generated_text" in resp:
158
+ bot_text = resp["generated_text"]
159
+ elif isinstance(resp, list) and resp and "generated_text" in resp[0]:
160
+ bot_text = resp[0]["generated_text"]
161
+
162
+ # Clean up prompt from response if model echoes it (common behavior for text_generation)
163
+ if bot_text.startswith(prompt_text):
164
+ bot_text = bot_text[len(prompt_text):].strip()
165
+
166
+ except Exception as e:
167
+ # Catching connection errors or specific API deployment issues
168
+ bot_text = f"⚠️ Error with **{m}**: Model could not generate a response. ({type(e).__name__}: {e})"
169
+
170
+ # 4. Display and save final response (common logic for all models)
171
+ final_response = f"**{m}**\n\n{bot_text}"
172
+
173
+ # Update the temporary placeholder with the final response
174
+ message_placeholder.markdown(final_response)
175
+
176
+ # Save the final response to chat history
177
+ st.session_state.messages.append({"role": "assistant", "content": final_response})
178
+ st.rerun() # Rerun to update the display properly after generation
179
+
180
+ # -------------------
181
+ # Gemini Logic
182
+ # -------------------
183
+ elif provider == "Gemini":
184
+ try:
185
+ if user_input.strip():
186
+ with st.spinner("Gemini is thinking..."):
187
+ resp = st.session_state.gemini_chat.send_message(user_input)
188
+
189
+ bot_text = resp.text
190
+ else:
191
+ bot_text = "⚠️ Please enter a message before sending."
192
+
193
+ except Exception as e:
194
+ bot_text = f"⚠️ Gemini could not respond right now. Please try again. ({e})"
195
+
196
+ # Display and save assistant response
197
+ with st.chat_message("assistant"):
198
+ st.markdown(bot_text)
199
+
200
+ st.session_state.messages.append({"role": "assistant", "content": bot_text})
201
+ st.rerun()
requirements (1).txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit==1.30.0
2
+ streamlit-chat
3
+ huggingface-hub>=0.21,<1.0.0
4
+ google-generativeai==0.3.0
5
+ datasets
6
+ protobuf<4
7
+ pydantic>=2.0,<3.0
8
+
9
+