adikwok commited on
Commit
59c2070
Β·
verified Β·
1 Parent(s): 0861547

Update app.py

Browse files

chat. history. journal

Files changed (1) hide show
  1. app.py +259 -129
app.py CHANGED
@@ -9,19 +9,17 @@ from datetime import datetime
9
  API_URL = "https://api.groq.com/openai/v1/chat/completions"
10
  API_KEY = os.getenv("GROQ_API_KEY")
11
 
12
- print(f"πŸ”‘ API Key Found: {'Yes' if API_KEY else 'No'}")
13
-
14
  # In-memory chat history storage
15
  chat_history: List[Dict[str, str]] = []
16
 
17
- def groq_with_memory(message: str, topic: str = "general", summarize: bool = False, max_history: int =10) -> str:
18
- """Groq API call with chat history and optional summarization"""
19
 
20
  if not API_KEY:
21
- return "❌ No API Key found"
22
 
23
  if not message.strip():
24
- return "❌ Empty message"
25
 
26
  try:
27
  headers = {
@@ -29,35 +27,28 @@ def groq_with_memory(message: str, topic: str = "general", summarize: bool = Fal
29
  "Content-Type": "application/json"
30
  }
31
 
32
- # Add current message to history with timestamp and topic
33
  chat_history.append({
34
  "role": "user",
35
  "content": message.strip(),
36
  "topic": topic,
37
- "timestamp": datetime.now().isoformat()
38
  })
39
 
40
- # Limit history to max_history messages
41
- recent_history = chat_history[-max_history:]
42
-
43
- # Prepare messages for API call
44
  messages = [{"role": msg["role"], "content": msg["content"]} for msg in recent_history]
45
 
46
- if summarize:
47
- summary_prompt = f"Summarize this conversation about '{topic}':\n\n"
48
- summary_prompt += "\n".join([f"{msg['role']}: {msg['content']}" for msg in recent_history])
49
- messages.append({"role": "user", "content": summary_prompt})
50
-
51
  payload = {
52
  "model": "gemma2-9b-it",
53
  "messages": messages,
54
- "max_tokens":2000,
55
- "temperature":0.9
56
  }
57
 
58
  response = requests.post(API_URL, headers=headers, json=payload, timeout=30)
59
 
60
- if response.status_code ==200:
61
  result = response.json()
62
  if "choices" in result and result["choices"]:
63
  response_content = result["choices"][0]["message"]["content"]
@@ -65,129 +56,268 @@ def groq_with_memory(message: str, topic: str = "general", summarize: bool = Fal
65
  "role": "assistant",
66
  "content": response_content,
67
  "topic": topic,
68
- "timestamp": datetime.now().isoformat()
69
  })
70
- return response_content
71
- return f"❌ No choices in response: {result}"
72
- return f"❌ HTTP {response.status_code}: {response.text}"
73
 
74
  except Exception as e:
75
- return f"❌ Error: {str(e)}"
76
-
77
- def clear_history():
78
- """Clear the chat history"""
79
- global chat_history
80
- chat_history.clear()
81
- return "βœ… Chat history cleared", ""
82
 
83
- def view_history(topic: str = None):
84
- """View chat history with optional topic filter"""
85
  if not chat_history:
86
- return "❌ No chat history available"
87
 
88
- filtered = [msg for msg in chat_history if topic is None or msg.get("topic") == topic]
89
- return "\n".join(
90
- f"[{msg['timestamp']}] {msg['role'].capitalize()}: {msg['content']}"
91
- for msg in filtered
92
- )
93
-
94
- # Gradio Interface
95
- with gr.Blocks(title="Groq Chat Interface", theme=gr.themes.Soft(), css="""
96
- .gradio-container {
97
- max-width:100% !important;
98
- padding-left:0px !important;
99
- padding-right:0px !important;
100
- }
101
- .main {
102
- max-width:100% !important;
103
- padding:0px !important;
104
- }
105
- .block {
106
- max-width:100% !important;
107
- }
108
- """) as demo:
109
- gr.Markdown("## πŸ’¬ Groq API Chat Interface")
110
-
111
- with gr.Tab("πŸ’¬ Chat"):
112
- # Response area at top
113
- response_output = gr.Textbox(
114
- label="πŸ€– AI Response",
115
- lines=15,
116
- interactive=False,
117
- placeholder="AI responses will appear here...",
118
- show_copy_button=True
119
- )
120
 
121
- gr.Markdown("---")
 
 
122
 
123
- # Input area at bottom
124
- with gr.Row():
125
- with gr.Column(scale=4):
126
- msg_input = gr.Textbox(
127
- label="✍️ Your Message",
128
- placeholder="Type your message here...",
129
- lines=3,
130
- max_lines=10
131
- )
132
-
133
- with gr.Column(scale=1):
134
- topic_input = gr.Textbox(
135
- label="🏷️ Topic",
136
- value="general",
137
- placeholder="conversation topic"
138
- )
139
- summarize_cb = gr.Checkbox(
140
- label="πŸ“‹ Summarize conversation",
141
- value=False
142
- )
143
- send_btn = gr.Button("πŸ“€ Send Message", variant="primary")
 
 
 
 
144
 
145
- with gr.Row():
146
- clear_btn = gr.Button("πŸ—‘οΈ Clear Response", variant="secondary")
147
- history_btn = gr.Button("πŸ“š View History", variant="secondary")
148
- history_output = gr.Textbox(
149
- label="πŸ“š Chat History",
150
- lines=15,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  interactive=False,
152
- placeholder="Chat history will appear here..."
 
 
153
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
- # Event handlers - Fixed indentation
156
- send_btn.click(
157
- lambda message, topic, summarize: groq_with_memory(message, topic, summarize),
158
- inputs=[msg_input, topic_input, summarize_cb],
159
- outputs=[response_output]
160
- )
161
-
162
- msg_input.submit(
163
- lambda message, topic, summarize: groq_with_memory(message, topic, summarize),
164
- inputs=[msg_input, topic_input, summarize_cb],
165
- outputs=[response_output]
166
- )
167
-
168
- clear_btn.click(
169
- lambda: ("", ""),
170
- outputs=[response_output, msg_input]
171
- )
172
-
173
- history_btn.click(
174
- lambda topic: view_history(topic),
175
- inputs=[topic_input],
176
- outputs=[history_output]
177
- )
178
-
179
-
180
- # Launch message
181
- print("πŸš€ Starting Groq Chat Interface...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  print(f"🌐 Access at: http://localhost:7860")
183
- if API_KEY:
184
- print("βœ… API Key detected - Ready to chat!")
185
- else:
186
- print("⚠️ No API Key found - Please set GROQ_API_KEY environment variable")
187
 
188
  if __name__ == "__main__":
189
  demo.launch(
190
- server_name="0.0.0.0",
191
  server_port=7860,
192
- show_error=True
193
- )
 
 
9
  API_URL = "https://api.groq.com/openai/v1/chat/completions"
10
  API_KEY = os.getenv("GROQ_API_KEY")
11
 
 
 
12
  # In-memory chat history storage
13
  chat_history: List[Dict[str, str]] = []
14
 
15
+ def groq_with_memory(message: str, topic: str = "general") -> tuple:
16
+ """Groq API call with chat history"""
17
 
18
  if not API_KEY:
19
+ return "❌ No API Key found", ""
20
 
21
  if not message.strip():
22
+ return "❌ Empty message", ""
23
 
24
  try:
25
  headers = {
 
27
  "Content-Type": "application/json"
28
  }
29
 
30
+ # Add current message to history
31
  chat_history.append({
32
  "role": "user",
33
  "content": message.strip(),
34
  "topic": topic,
35
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M")
36
  })
37
 
38
+ # Prepare messages for API call (last 10 messages)
39
+ recent_history = chat_history[-10:]
 
 
40
  messages = [{"role": msg["role"], "content": msg["content"]} for msg in recent_history]
41
 
 
 
 
 
 
42
  payload = {
43
  "model": "gemma2-9b-it",
44
  "messages": messages,
45
+ "max_tokens": 2000,
46
+ "temperature": 0.7
47
  }
48
 
49
  response = requests.post(API_URL, headers=headers, json=payload, timeout=30)
50
 
51
+ if response.status_code == 200:
52
  result = response.json()
53
  if "choices" in result and result["choices"]:
54
  response_content = result["choices"][0]["message"]["content"]
 
56
  "role": "assistant",
57
  "content": response_content,
58
  "topic": topic,
59
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M")
60
  })
61
+ return response_content, "" # Clear input after send
62
+ return f"❌ No response: {result}", ""
63
+ return f"❌ HTTP {response.status_code}: {response.text}", ""
64
 
65
  except Exception as e:
66
+ return f"❌ Error: {str(e)}", ""
 
 
 
 
 
 
67
 
68
+ def get_chat_summary(topic_filter: str = None) -> str:
69
+ """Generate conversation summary"""
70
  if not chat_history:
71
+ return "❌ No chat history to summarize"
72
 
73
+ filtered = [msg for msg in chat_history if not topic_filter or msg.get("topic") == topic_filter]
74
+
75
+ if not filtered:
76
+ return f"❌ No messages found for topic: {topic_filter}"
77
+
78
+ # Group by topic
79
+ topics = {}
80
+ for msg in filtered:
81
+ topic = msg.get("topic", "general")
82
+ if topic not in topics:
83
+ topics[topic] = []
84
+ topics[topic].append(msg)
85
+
86
+ summary = "πŸ“‹ **Chat Summary**\n\n"
87
+ for topic, messages in topics.items():
88
+ user_msgs = [m for m in messages if m["role"] == "user"]
89
+ ai_msgs = [m for m in messages if m["role"] == "assistant"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
+ summary += f"**🏷️ Topic: {topic}**\n"
92
+ summary += f"- Messages: {len(user_msgs)} user, {len(ai_msgs)} AI\n"
93
+ summary += f"- Time span: {messages[0]['timestamp']} - {messages[-1]['timestamp']}\n"
94
 
95
+ if user_msgs:
96
+ summary += f"- Key topics discussed: {', '.join(msg['content'][:50] + '...' for msg in user_msgs[:3])}\n"
97
+ summary += "\n"
98
+
99
+ return summary
100
+
101
+ def get_full_history(topic_filter: str = None) -> str:
102
+ """Get full chat history with optional topic filter"""
103
+ if not chat_history:
104
+ return "❌ No chat history available"
105
+
106
+ filtered = [msg for msg in chat_history if not topic_filter or msg.get("topic") == topic_filter]
107
+
108
+ if not filtered:
109
+ return f"❌ No messages found for topic: {topic_filter}"
110
+
111
+ history_text = f"πŸ“š **Chat History** ({len(filtered)} messages)\n\n"
112
+
113
+ current_topic = None
114
+ for msg in filtered:
115
+ # Add topic header when topic changes
116
+ if msg.get("topic") != current_topic:
117
+ current_topic = msg.get("topic")
118
+ history_text += f"\n**🏷️ Topic: {current_topic}**\n"
119
+ history_text += "---\n"
120
 
121
+ role_icon = "πŸ‘€" if msg["role"] == "user" else "πŸ€–"
122
+ history_text += f"{role_icon} **{msg['timestamp']}**\n"
123
+ history_text += f"{msg['content']}\n\n"
124
+
125
+ return history_text
126
+
127
+ def clear_all_history():
128
+ """Clear all chat history"""
129
+ global chat_history
130
+ chat_history.clear()
131
+ return "βœ… All chat history cleared", "", ""
132
+
133
+ def get_topics_list() -> List[str]:
134
+ """Get list of unique topics"""
135
+ topics = list(set(msg.get("topic", "general") for msg in chat_history))
136
+ return ["All Topics"] + sorted(topics)
137
+
138
+ # Custom CSS for better UI
139
+ custom_css = """
140
+ .gradio-container {
141
+ max-width: 1200px !important;
142
+ margin: 0 auto !important;
143
+ }
144
+
145
+ .main-chat {
146
+ border: 1px solid #e0e0e0;
147
+ border-radius: 12px;
148
+ padding: 20px;
149
+ background: #fafafa;
150
+ }
151
+
152
+ .input-area {
153
+ background: white;
154
+ border-radius: 8px;
155
+ padding: 15px;
156
+ margin-top: 10px;
157
+ }
158
+
159
+ .history-area {
160
+ background: white;
161
+ border-radius: 8px;
162
+ padding: 15px;
163
+ margin-top: 10px;
164
+ }
165
+
166
+ .tab-nav {
167
+ background: #f5f5f5;
168
+ border-radius: 8px 8px 0 0;
169
+ }
170
+
171
+ /* Copy button styling */
172
+ .copy-button {
173
+ background: #4CAF50 !important;
174
+ color: white !important;
175
+ border-radius: 4px !important;
176
+ }
177
+ """
178
+
179
+ # Main Gradio Interface
180
+ with gr.Blocks(
181
+ title="πŸ€– AI Journal Chat",
182
+ theme=gr.themes.Soft(),
183
+ css=custom_css
184
+ ) as demo:
185
+
186
+ gr.Markdown("# πŸ“ AI Journal Chat Interface")
187
+ gr.Markdown("*Write, chat, and keep track of your thoughts with AI assistance*")
188
+
189
+ with gr.Tabs() as tabs:
190
+ # MAIN CHAT TAB
191
+ with gr.Tab("πŸ’¬ Chat", elem_classes="main-chat"):
192
+ # AI Response Area (Top)
193
+ ai_response = gr.Textbox(
194
+ label="πŸ€– AI Response",
195
+ lines=12,
196
+ max_lines=20,
197
  interactive=False,
198
+ placeholder="AI responses will appear here...",
199
+ show_copy_button=True,
200
+ elem_classes="response-area"
201
  )
202
+
203
+ # Input Area (Bottom)
204
+ with gr.Group(elem_classes="input-area"):
205
+ with gr.Row():
206
+ user_input = gr.Textbox(
207
+ label="✍️ Your Message",
208
+ placeholder="Type your thoughts, questions, or journal entry here...",
209
+ lines=4,
210
+ max_lines=10,
211
+ scale=3
212
+ )
213
+ with gr.Column(scale=1):
214
+ topic_input = gr.Textbox(
215
+ label="🏷️ Topic",
216
+ value="journal",
217
+ placeholder="e.g., work, personal, ideas"
218
+ )
219
+ send_btn = gr.Button("πŸ“€ Send", variant="primary", size="lg")
220
+
221
+ with gr.Row():
222
+ clear_response_btn = gr.Button("πŸ—‘οΈ Clear Response", variant="secondary")
223
+ new_topic_btn = gr.Button("πŸ†• New Topic", variant="secondary")
224
 
225
+ # HISTORY TAB
226
+ with gr.Tab("πŸ“š Chat History"):
227
+ with gr.Group(elem_classes="history-area"):
228
+ with gr.Row():
229
+ topic_filter = gr.Dropdown(
230
+ label="πŸ” Filter by Topic",
231
+ choices=["All Topics"],
232
+ value="All Topics",
233
+ interactive=True
234
+ )
235
+ refresh_topics_btn = gr.Button("πŸ”„ Refresh Topics", variant="secondary")
236
+
237
+ with gr.Row():
238
+ show_history_btn = gr.Button("πŸ“– Show Full History", variant="primary")
239
+ show_summary_btn = gr.Button("πŸ“‹ Show Summary", variant="secondary")
240
+ clear_history_btn = gr.Button("πŸ—‘οΈ Clear All History", variant="stop")
241
+
242
+ history_display = gr.Textbox(
243
+ label="πŸ“š History & Summary",
244
+ lines=20,
245
+ max_lines=30,
246
+ interactive=False,
247
+ show_copy_button=True,
248
+ placeholder="Chat history and summaries will appear here..."
249
+ )
250
+
251
+ # Event Handlers
252
+ def send_message(message, topic):
253
+ response, cleared_input = groq_with_memory(message, topic)
254
+ return response, cleared_input
255
+
256
+ def refresh_topic_choices():
257
+ return gr.Dropdown(choices=get_topics_list())
258
+
259
+ def filter_and_show_history(topic_filter):
260
+ filter_topic = None if topic_filter == "All Topics" else topic_filter
261
+ return get_full_history(filter_topic)
262
+
263
+ def filter_and_show_summary(topic_filter):
264
+ filter_topic = None if topic_filter == "All Topics" else topic_filter
265
+ return get_chat_summary(filter_topic)
266
+
267
+ # Button Events
268
+ send_btn.click(
269
+ send_message,
270
+ inputs=[user_input, topic_input],
271
+ outputs=[ai_response, user_input]
272
+ )
273
+
274
+ user_input.submit(
275
+ send_message,
276
+ inputs=[user_input, topic_input],
277
+ outputs=[ai_response, user_input]
278
+ )
279
+
280
+ clear_response_btn.click(
281
+ lambda: "",
282
+ outputs=[ai_response]
283
+ )
284
+
285
+ new_topic_btn.click(
286
+ lambda: "",
287
+ outputs=[topic_input]
288
+ )
289
+
290
+ refresh_topics_btn.click(
291
+ refresh_topic_choices,
292
+ outputs=[topic_filter]
293
+ )
294
+
295
+ show_history_btn.click(
296
+ filter_and_show_history,
297
+ inputs=[topic_filter],
298
+ outputs=[history_display]
299
+ )
300
+
301
+ show_summary_btn.click(
302
+ filter_and_show_summary,
303
+ inputs=[topic_filter],
304
+ outputs=[history_display]
305
+ )
306
+
307
+ clear_history_btn.click(
308
+ clear_all_history,
309
+ outputs=[ai_response, user_input, history_display]
310
+ )
311
+
312
+ # Launch configuration
313
+ print("πŸš€ Starting AI Journal Chat Interface...")
314
  print(f"🌐 Access at: http://localhost:7860")
315
+ print(f"πŸ”‘ API Key: {'βœ… Found' if API_KEY else '❌ Missing'}")
 
 
 
316
 
317
  if __name__ == "__main__":
318
  demo.launch(
319
+ server_name="0.0.0.0",
320
  server_port=7860,
321
+ show_error=True,
322
+ share=False
323
+ )