ginipick commited on
Commit
77b173a
ยท
verified ยท
1 Parent(s): ad366bb

Delete app- backup.py

Browse files
Files changed (1) hide show
  1. app- backup.py +0 -509
app- backup.py DELETED
@@ -1,509 +0,0 @@
1
- import streamlit as st
2
- import os
3
- import json
4
- from datetime import datetime, timedelta
5
- import base64
6
- import pandas as pd
7
- import pydeck as pdk
8
- from paper import (
9
- literature_research_task, outline_task, draft_writing_task,
10
- citation_task, editing_task, chatbot_task,
11
- run_task
12
- )
13
-
14
- # st.set_page_config()๋Š” ๋‹ค๋ฅธ Streamlit ํ•จ์ˆ˜๋ณด๋‹ค ๊ฐ€์žฅ ๋จผ์ € ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
15
- st.set_page_config(
16
- page_title="Your AI Agent for Academic Research",
17
- page_icon="๐Ÿ“š",
18
- layout="wide",
19
- initial_sidebar_state="expanded"
20
- )
21
-
22
- # ------------------------------------------
23
- # ๋‹ค๊ตญ์–ด ์ง€์› (์˜์–ด/ํ•œ๊ตญ์–ด ์˜ˆ์‹œ)
24
- # ------------------------------------------
25
- translations = {
26
- "en": {
27
- "page_title": "Your AI Agent for Academic Research",
28
- "header": "Your AI Agent for Academic Research",
29
- "create_itinerary": "Generate Your Research Paper",
30
- "trip_details": "Research Details",
31
- "origin": "Research Topic",
32
- "destination": "Paper Title",
33
- "travel_dates": "Due Date",
34
- "duration": "Paper Length (pages)",
35
- "preferences": "Keywords/Focus",
36
- "special_requirements": "Additional Instructions",
37
- "submit": "๐Ÿš€ Generate My Research Paper",
38
- "request_details": "Your Research Request",
39
- "from": "Topic",
40
- "when": "Due Date",
41
- "budget": "Paper Type",
42
- "travel_style": "Writing Style",
43
- "live_agent_outputs": "Live Agent Outputs",
44
- "full_itinerary": "Full Paper",
45
- "details": "Details",
46
- "download_share": "Download & Share",
47
- "save_itinerary": "Save Your Paper",
48
- "plan_another_trip": "๐Ÿ”„ Generate Another Paper",
49
- "about": "About",
50
- "how_it_works": "How it works",
51
- "travel_agents": "Research Agents",
52
- "share_itinerary": "Share Your Paper",
53
- "save_for_mobile": "Save for Mobile",
54
- "built_with": "Built with โค๏ธ for you",
55
- "itinerary_ready": "Your Research Paper is Ready! ๐ŸŽ‰",
56
- "personalized_experience": "We've created a personalized academic paper based on your inputs. Explore your paper below.",
57
- "agent_activity": "Agent Activity",
58
- "error_origin_destination": "Please enter both the research topic and paper title.",
59
- "your_itinerary_file": "Your Paper File",
60
- "text_format": "Text format - Can be opened in any text editor"
61
- },
62
- "ko": {
63
- "page_title": "๋‹น์‹ ์˜ ํ•™์ˆ  ์—ฐ๊ตฌ AI ์—์ด์ „ํŠธ",
64
- "header": "๋‹น์‹ ์˜ ํ•™์ˆ  ์—ฐ๊ตฌ AI ์—์ด์ „ํŠธ",
65
- "create_itinerary": "๋…ผ๋ฌธ ์ƒ์„ฑ",
66
- "trip_details": "์—ฐ๊ตฌ ์„ธ๋ถ€์‚ฌํ•ญ",
67
- "origin": "์—ฐ๊ตฌ ์ฃผ์ œ",
68
- "destination": "๋…ผ๋ฌธ ์ œ๋ชฉ",
69
- "travel_dates": "์ œ์ถœ ๊ธฐํ•œ",
70
- "duration": "๋…ผ๋ฌธ ๋ถ„๋Ÿ‰ (ํŽ˜์ด์ง€)",
71
- "preferences": "ํ‚ค์›Œ๋“œ/์ฃผ์š” ์ดˆ์ ",
72
- "special_requirements": "์ถ”๊ฐ€ ์ง€์‹œ์‚ฌํ•ญ",
73
- "submit": "๐Ÿš€ ๋‚˜์˜ ๋…ผ๋ฌธ ์ƒ์„ฑ",
74
- "request_details": "์—ฐ๊ตฌ ์š”์ฒญ ์ •๋ณด",
75
- "from": "์ฃผ์ œ",
76
- "when": "์ œ์ถœ ๊ธฐํ•œ",
77
- "budget": "๋…ผ๋ฌธ ์ข…๋ฅ˜",
78
- "travel_style": "์ž‘์„ฑ ์Šคํƒ€์ผ",
79
- "live_agent_outputs": "์‹ค์‹œ๊ฐ„ ์—์ด์ „ํŠธ ๊ฒฐ๊ณผ",
80
- "full_itinerary": "์ „์ฒด ๋…ผ๋ฌธ",
81
- "details": "์„ธ๋ถ€์‚ฌํ•ญ",
82
- "download_share": "๋‹ค์šด๋กœ๋“œ ๋ฐ ๊ณต์œ ",
83
- "save_itinerary": "๋…ผ๋ฌธ ์ €์žฅ",
84
- "plan_another_trip": "๐Ÿ”„ ๋‹ค๋ฅธ ๋…ผ๋ฌธ ์ƒ์„ฑ",
85
- "about": "์†Œ๊ฐœ",
86
- "how_it_works": "์ž‘๋™ ๋ฐฉ์‹",
87
- "travel_agents": "์—ฐ๊ตฌ ์—์ด์ „ํŠธ",
88
- "share_itinerary": "๋…ผ๋ฌธ ๊ณต์œ ",
89
- "save_for_mobile": "๋ชจ๋ฐ”์ผ ์ €์žฅ",
90
- "built_with": "๋‹น์‹ ์„ ์œ„ํ•ด โค๏ธ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค",
91
- "itinerary_ready": "๋…ผ๋ฌธ์ด ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๐ŸŽ‰",
92
- "personalized_experience": "์ž…๋ ฅํ•˜์‹  ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋งž์ถคํ˜• ๋…ผ๋ฌธ์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์—์„œ ๋…ผ๋ฌธ์„ ํ™•์ธํ•˜์„ธ์š”.",
93
- "agent_activity": "์—์ด์ „ํŠธ ํ™œ๋™",
94
- "error_origin_destination": "์—ฐ๊ตฌ ์ฃผ์ œ์™€ ๋…ผ๋ฌธ ์ œ๋ชฉ์„ ๋ชจ๋‘ ์ž…๋ ฅํ•˜์„ธ์š”.",
95
- "your_itinerary_file": "๋…ผ๋ฌธ ํŒŒ์ผ",
96
- "text_format": "ํ…์ŠคํŠธ ํ˜•์‹ - ๋ชจ๋“  ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ์—์„œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."
97
- }
98
- }
99
-
100
- def t(key):
101
- lang = st.session_state.get("selected_language", "en")
102
- return translations[lang].get(key, key)
103
-
104
- # ---------------------------
105
- # ์„ธ์…˜ ์ดˆ๊ธฐํ™”
106
- # ---------------------------
107
- if 'selected_language' not in st.session_state:
108
- st.session_state.selected_language = "en"
109
-
110
- # ------------------------------------------
111
- # ์‚ฌ์ด๋“œ๋ฐ”์— ์–ธ์–ด ์„ ํƒ ์œ„์ ฏ ์ถ”๊ฐ€
112
- # ------------------------------------------
113
- with st.sidebar:
114
- language = st.selectbox(
115
- "Language / ์–ธ์–ด",
116
- ["English", "ํ•œ๊ตญ์–ด"]
117
- )
118
- lang_map = {
119
- "English": "en",
120
- "ํ•œ๊ตญ์–ด": "ko"
121
- }
122
- st.session_state.selected_language = lang_map.get(language, "en")
123
-
124
- # ------------------------------------------
125
- # UI ์‹œ์ž‘
126
- # ------------------------------------------
127
- st.markdown("""
128
- <style>
129
- :root {
130
- --primary: #3a86ff;
131
- --primary-light: #4895ef;
132
- --primary-dark: #2667ff;
133
- --background: #f8f9fa;
134
- --card-bg: #ffffff;
135
- --text: #212529;
136
- --border: #e9ecef;
137
- }
138
- .main-header {
139
- font-size: 2.5rem;
140
- color: var(--primary-dark);
141
- text-align: center;
142
- margin-bottom: 0.8rem;
143
- font-weight: 700;
144
- }
145
- .modern-card {
146
- background-color: var(--card-bg);
147
- border-radius: 10px;
148
- padding: 1.2rem;
149
- margin-bottom: 1.2rem;
150
- box-shadow: 0 2px 10px rgba(0,0,0,0.05);
151
- border: 1px solid var(--border);
152
- }
153
- </style>
154
- """, unsafe_allow_html=True)
155
-
156
- def get_download_link(text_content, filename):
157
- b64 = base64.b64encode(text_content.encode()).decode()
158
- href = f'<a class="download-link" href="data:text/plain;base64,{b64}" download="{filename}"><i>๐Ÿ“ฅ</i> {t("save_itinerary")}</a>'
159
- return href
160
-
161
- def display_modern_progress(current_step, total_steps=5):
162
- if 'progress_steps' not in st.session_state:
163
- st.session_state.progress_steps = {
164
- 0: {'status': 'pending', 'name': t("trip_details")},
165
- 1: {'status': 'pending', 'name': t("about")},
166
- 2: {'status': 'pending', 'name': t("live_agent_outputs")},
167
- 3: {'status': 'pending', 'name': t("download_share")},
168
- 4: {'status': 'pending', 'name': t("full_itinerary")}
169
- }
170
- for i in range(total_steps):
171
- if i < current_step:
172
- st.session_state.progress_steps[i]['status'] = 'complete'
173
- elif i == current_step:
174
- st.session_state.progress_steps[i]['status'] = 'active'
175
- else:
176
- st.session_state.progress_steps[i]['status'] = 'pending'
177
- progress_percentage = (current_step / total_steps) * 100
178
- st.progress(progress_percentage / 100)
179
- st.markdown("<div>Progress: " + str(progress_percentage) + "% completed.</div>")
180
- return progress_percentage
181
-
182
- def update_step_status(step_index, status):
183
- if 'progress_steps' in st.session_state and step_index in st.session_state.progress_steps:
184
- st.session_state.progress_steps[step_index]['status'] = status
185
-
186
- def run_task_with_logs(task, input_text, log_container, output_container, results_key=None):
187
- log_message = f"๐Ÿค– Starting {task.agent.role}..."
188
- st.session_state.log_messages.append(log_message)
189
- with log_container:
190
- st.markdown("### " + t("agent_activity"))
191
- for msg in st.session_state.log_messages:
192
- st.markdown(msg)
193
- result = run_task(task, input_text)
194
- if results_key:
195
- st.session_state.results[results_key] = result
196
- log_message = f"โœ… {task.agent.role} completed!"
197
- st.session_state.log_messages.append(log_message)
198
- with log_container:
199
- st.markdown("### " + t("agent_activity"))
200
- for msg in st.session_state.log_messages:
201
- st.markdown(msg)
202
- with output_container:
203
- st.markdown(f"### {task.agent.role} Output")
204
- st.markdown("<div class='agent-output'>" + result + "</div>", unsafe_allow_html=True)
205
- return result
206
-
207
- if 'generated_itinerary' not in st.session_state:
208
- st.session_state.generated_itinerary = None
209
- if 'generation_complete' not in st.session_state:
210
- st.session_state.generation_complete = False
211
- if 'current_step' not in st.session_state:
212
- st.session_state.current_step = 0
213
- if 'results' not in st.session_state:
214
- st.session_state.results = {
215
- "literature_review": "",
216
- "outline": "",
217
- "draft": "",
218
- "citations": "",
219
- "edited": ""
220
- }
221
- if 'log_messages' not in st.session_state:
222
- st.session_state.log_messages = []
223
- if 'form_submitted' not in st.session_state:
224
- st.session_state.form_submitted = False
225
-
226
- st.markdown(f"""
227
- <div style="text-align: center;">
228
- <img src="https://img.icons8.com/fluency/96/book.png" width="90">
229
- <h1 class="main-header">{t("header")}</h1>
230
- <p>Generate your personalized research paper with AI-powered academic agents.</p>
231
- </div>
232
- """, unsafe_allow_html=True)
233
- st.markdown('<hr>', unsafe_allow_html=True)
234
-
235
- with st.sidebar:
236
- st.markdown("""
237
- <div style="text-align: center;">
238
- <img src="https://img.icons8.com/fluency/96/book.png" width="80">
239
- <h3>Your AI Academic Research Assistant</h3>
240
- <p>AI-Powered Paper Generation</p>
241
- </div>
242
- """, unsafe_allow_html=True)
243
- st.markdown('<div class="modern-card">', unsafe_allow_html=True)
244
- st.markdown("### " + t("about"))
245
- st.info("This tool generates a personalized academic research paper based on your inputs. Fill in the form and let our specialized agents craft your paper!")
246
- st.markdown('</div>', unsafe_allow_html=True)
247
- st.markdown('<div class="modern-card">', unsafe_allow_html=True)
248
- st.markdown("### " + t("how_it_works"))
249
- st.markdown("""
250
- <ol>
251
- <li>Enter your research details</li>
252
- <li>AI conducts literature research</li>
253
- <li>Generate a paper outline</li>
254
- <li>Draft and edit your paper</li>
255
- <li>Download your final paper</li>
256
- </ol>
257
- """, unsafe_allow_html=True)
258
- st.markdown('</div>', unsafe_allow_html=True)
259
-
260
- if not st.session_state.generation_complete:
261
- st.markdown('<div class="modern-card">', unsafe_allow_html=True)
262
- st.markdown("<h3>" + t("create_itinerary") + "</h3>", unsafe_allow_html=True)
263
- st.markdown("<p>Fill in the details below to generate your research paper.</p>", unsafe_allow_html=True)
264
-
265
- with st.form("research_form"):
266
- col1, col2 = st.columns(2)
267
- with col1:
268
- research_topic = st.text_input(t("origin"), placeholder="e.g., Deep Learning in Healthcare")
269
- paper_title = st.text_input(t("destination"), placeholder="e.g., Advances in Deep Learning for Medical Diagnosis")
270
- due_date = st.date_input(t("travel_dates"), min_value=datetime.now())
271
- with col2:
272
- paper_length = st.slider(t("duration"), min_value=5, max_value=50, value=10)
273
- paper_type_options = ["Journal", "Conference", "Thesis", "Review"]
274
- paper_type = st.selectbox(t("budget"), paper_type_options, help="Select the type of paper")
275
- writing_style = st.multiselect(t("travel_style"), options=["Formal", "Technical", "Creative"], default=["Formal"])
276
- additional_instructions = st.text_area(t("special_requirements"), placeholder="Any additional instructions or requirements...")
277
- keywords = st.text_area(t("preferences"), placeholder="Enter keywords or focus areas, separated by commas")
278
- submit_button = st.form_submit_button(t("submit"))
279
- st.markdown('</div>', unsafe_allow_html=True)
280
-
281
- if submit_button:
282
- if not research_topic or not paper_title:
283
- st.error(t("error_origin_destination"))
284
- else:
285
- st.session_state.form_submitted = True
286
- st.session_state.research_topic = research_topic
287
- user_input = {
288
- "research_topic": research_topic,
289
- "paper_title": paper_title,
290
- "due_date": due_date.strftime("%Y-%m-%d"),
291
- "paper_length": str(paper_length),
292
- "paper_type": paper_type,
293
- "writing_style": ", ".join(writing_style),
294
- "keywords": keywords,
295
- "additional_instructions": additional_instructions
296
- }
297
- st.session_state.user_input = user_input
298
- input_context = f"""Research Request Details:
299
- Research Topic: {user_input['research_topic']}
300
- Paper Title: {user_input['paper_title']}
301
- Due Date: {user_input['due_date']}
302
- Paper Length: {user_input['paper_length']} pages
303
- Paper Type: {user_input['paper_type']}
304
- Writing Style: {user_input['writing_style']}
305
- Keywords/Focus: {user_input['keywords']}
306
- Additional Instructions: {user_input['additional_instructions']}
307
- """
308
- llm_language_instructions = {
309
- "en": "Please output the response in English.",
310
- "ko": "ํ•œ๊ตญ์–ด๋กœ ์ถœ๋ ฅํ•ด ์ฃผ์„ธ์š”."
311
- }
312
- selected_lang = st.session_state.get("selected_language", "en")
313
- language_instruction = llm_language_instructions.get(selected_lang, "Please output the response in English.")
314
- modified_input_context = language_instruction + "\n" + input_context
315
-
316
- st.markdown("<div>Processing your request...</div>", unsafe_allow_html=True)
317
- st.session_state.current_step = 0
318
- update_step_status(0, 'active')
319
- progress_placeholder = st.empty()
320
- with progress_placeholder.container():
321
- display_modern_progress(st.session_state.current_step)
322
- log_container = st.container()
323
- st.session_state.log_messages = []
324
- output_container = st.container()
325
- st.session_state.results = {}
326
-
327
- # Step 1: Literature Research
328
- literature_review = run_task_with_logs(
329
- literature_research_task,
330
- modified_input_context.format(topic=user_input['research_topic'], keywords=user_input['keywords']),
331
- log_container,
332
- output_container,
333
- "literature_review"
334
- )
335
- update_step_status(0, 'complete')
336
- st.session_state.current_step = 1
337
- update_step_status(1, 'active')
338
- with progress_placeholder.container():
339
- display_modern_progress(st.session_state.current_step)
340
-
341
- # Step 2: Generate Outline
342
- outline = run_task_with_logs(
343
- outline_task,
344
- modified_input_context.format(topic=user_input['research_topic']),
345
- log_container,
346
- output_container,
347
- "outline"
348
- )
349
- update_step_status(1, 'complete')
350
- st.session_state.current_step = 2
351
- update_step_status(2, 'active')
352
- with progress_placeholder.container():
353
- display_modern_progress(st.session_state.current_step)
354
-
355
- # Step 3: Draft Writing
356
- draft = run_task_with_logs(
357
- draft_writing_task,
358
- modified_input_context.format(topic=user_input['research_topic']),
359
- log_container,
360
- output_container,
361
- "draft"
362
- )
363
- update_step_status(2, 'complete')
364
- st.session_state.current_step = 3
365
- update_step_status(3, 'active')
366
- with progress_placeholder.container():
367
- display_modern_progress(st.session_state.current_step)
368
-
369
- # Step 4: Citation Generation
370
- citations = run_task_with_logs(
371
- citation_task,
372
- modified_input_context.format(topic=user_input['research_topic']),
373
- log_container,
374
- output_container,
375
- "citations"
376
- )
377
- update_step_status(3, 'complete')
378
- st.session_state.current_step = 4
379
- update_step_status(4, 'active')
380
- with progress_placeholder.container():
381
- display_modern_progress(st.session_state.current_step)
382
-
383
- # Step 5: Editing and Polishing
384
- edited = run_task_with_logs(
385
- editing_task,
386
- modified_input_context.format(topic=user_input['research_topic']),
387
- log_container,
388
- output_container,
389
- "edited"
390
- )
391
- update_step_status(4, 'complete')
392
- st.session_state.current_step = 5
393
- with progress_placeholder.container():
394
- display_modern_progress(st.session_state.current_step)
395
-
396
- full_paper = f"""Research Paper:
397
- {input_context}
398
-
399
- Literature Review:
400
- {literature_review}
401
-
402
- Outline:
403
- {outline}
404
-
405
- Draft:
406
- {draft}
407
-
408
- Citations:
409
- {citations}
410
-
411
- Edited Version:
412
- {edited}
413
- """
414
- st.session_state.generated_itinerary = full_paper
415
- st.session_state.generation_complete = True
416
- date_str = datetime.now().strftime("%Y-%m-%d")
417
- st.session_state.filename = f"{user_input['paper_title'].replace(' ', '_')}_{date_str}_paper.txt"
418
-
419
- if st.session_state.generation_complete:
420
- st.markdown(f"""
421
- <div class="modern-card">
422
- <div style="text-align: center;">
423
- <h2>{t("itinerary_ready")}</h2>
424
- <p>{t("personalized_experience")}</p>
425
- </div>
426
- </div>
427
- """, unsafe_allow_html=True)
428
-
429
- # ํƒญ ์ƒ์„ฑ (์ „์ฒด ๋…ผ๋ฌธ, ์„ธ๋ถ€ ์ •๋ณด, ๋‹ค์šด๋กœ๋“œ/๊ณต์œ , ์‹œ๊ฐํ™”, ์ฑ—๋ด‡)
430
- full_paper_tab, details_tab, download_tab, visualization_tab, chatbot_tab = st.tabs([
431
- "๐Ÿ—’๏ธ " + t("full_itinerary"),
432
- "๐Ÿ’ผ " + t("details"),
433
- "๐Ÿ’พ " + t("download_share"),
434
- "๐Ÿ“Š Visualization",
435
- "๐Ÿค– ์ฑ—๋ด‡ ์ธํ„ฐํŽ˜์ด์Šค"
436
- ])
437
-
438
- with full_paper_tab:
439
- st.text_area("Your Research Paper", st.session_state.generated_itinerary, height=600)
440
-
441
- with details_tab:
442
- agent_tabs = st.tabs(["๐Ÿ“š Literature Review", "๐Ÿ“ Outline", "โœ๏ธ Draft", "๐Ÿ”— Citations", "๐Ÿ–‹๏ธ Edited Version"])
443
- with agent_tabs[0]:
444
- st.markdown("### Literature Review")
445
- st.markdown(st.session_state.results.get("literature_review", ""))
446
- with agent_tabs[1]:
447
- st.markdown("### Outline")
448
- st.markdown(st.session_state.results.get("outline", ""))
449
- with agent_tabs[2]:
450
- st.markdown("### Draft")
451
- st.markdown(st.session_state.results.get("draft", ""))
452
- with agent_tabs[3]:
453
- st.markdown("### Citations")
454
- st.markdown(st.session_state.results.get("citations", ""))
455
- with agent_tabs[4]:
456
- st.markdown("### Edited Version")
457
- st.markdown(st.session_state.results.get("edited", ""))
458
-
459
- with download_tab:
460
- col1, col2 = st.columns([2, 1])
461
- with col1:
462
- st.markdown("### " + t("save_itinerary"))
463
- st.markdown("Download your research paper to access it offline or share with your colleagues.")
464
- st.markdown(f"""
465
- <div style="background-color: #f8f9fa; padding: 15px; border-radius: 10px; margin-top: 20px;">
466
- <h4>{t("your_itinerary_file")}</h4>
467
- <p style="font-size: 0.9rem; color: #6c757d;">{t("text_format")}</p>
468
- </div>
469
- """, unsafe_allow_html=True)
470
- st.markdown("<div>" + get_download_link(st.session_state.generated_itinerary, st.session_state.filename) + "</div>", unsafe_allow_html=True)
471
- st.markdown("### " + t("share_itinerary"))
472
- st.markdown("*Coming soon: Email your paper or share via social media.*")
473
- with col2:
474
- st.markdown("### " + t("save_for_mobile"))
475
- st.markdown("*Coming soon: QR code for easy access on your phone*")
476
-
477
- with visualization_tab:
478
- st.markdown("### Visualization")
479
- st.markdown("A conceptual diagram or visualization related to your research paper can be displayed here. (Feature under development)")
480
-
481
- with chatbot_tab:
482
- st.markdown("### AI ์ฑ—๋ด‡ ์ธํ„ฐํŽ˜์ด์Šค")
483
- if "chat_history" not in st.session_state:
484
- st.session_state.chat_history = []
485
- user_message = st.text_input("๋ฉ”์‹œ์ง€๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”:", key="chat_input")
486
- if st.button("์ „์†ก", key="send_button"):
487
- if user_message:
488
- response = run_task(chatbot_task, user_message)
489
- st.session_state.chat_history.append({
490
- "speaker": "์‚ฌ์šฉ์ž",
491
- "message": user_message,
492
- "time": datetime.now()
493
- })
494
- st.session_state.chat_history.append({
495
- "speaker": "AI",
496
- "message": response,
497
- "time": datetime.now()
498
- })
499
- st.markdown("<div style='max-height:400px; overflow-y:auto; padding:10px; border:1px solid #eaeaea; border-radius:6px;'>", unsafe_allow_html=True)
500
- for chat in st.session_state.chat_history:
501
- time_str = chat["time"].strftime("%H:%M:%S")
502
- st.markdown(f"**{chat['speaker']}** ({time_str}): {chat['message']}")
503
- st.markdown("</div>", unsafe_allow_html=True)
504
-
505
- st.markdown("""
506
- <div style="text-align: center; padding: 20px; color: #6c757d; font-size: 0.8rem;">
507
- <p>""" + t("built_with") + """</p>
508
- </div>
509
- """, unsafe_allow_html=True)