Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| import os | |
| import json | |
| from datetime import datetime | |
| import re | |
| from pathlib import Path | |
| import uuid | |
| # === CONFIG === | |
| STORAGE_DIR = Path("journal_data") | |
| STORAGE_DIR.mkdir(exist_ok=True) | |
| HISTORY_FILE = STORAGE_DIR / "history.json" | |
| API_KEY = os.getenv("GROQ_API_KEY") | |
| API_URL = "https://api.groq.com/openai/v1/chat/completions" | |
| MODEL = "gemma2-9b-it" | |
| # === MEMORY: Load history === | |
| def load_history(): | |
| if HISTORY_FILE.exists(): | |
| try: | |
| with open(HISTORY_FILE, 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| except: pass | |
| return [] | |
| def save_history(history): | |
| with open(HISTORY_FILE, 'w', encoding='utf-8') as f: | |
| json.dump(history[-100:], f, indent=2, ensure_ascii=False) # Simpen 100 terakhir | |
| chat_history = load_history() | |
| current_session = str(uuid.uuid4()) | |
| # === Smart Summary Generator === | |
| def generate_summary(messages): | |
| if not messages: | |
| return "User baru mulai ngobrol." | |
| user_msgs = [m for m in messages if m['role'] == 'user'] | |
| topics = [m['topic'] for m in user_msgs[-5:]] | |
| main_topic = max(set(topics), key=topics.count) if topics else "general" | |
| # Emosi kasar | |
| pos = sum(1 for m in user_msgs[-3:] if any(w in m['content'].lower() for w in ['senang', 'semangat', 'baik'])) | |
| neg = sum(1 for m in user_msgs[-3:] if any(w in m['content'].lower() for w in ['capek', 'sedih', 'gagal'])) | |
| mood = "positif" if pos > neg else "negatif" if neg > pos else "netral" | |
| # Gaya bicara | |
| style = "kasual" if any('gue' in m['content'].lower() or 'anjir' in m['content'].lower() for m in user_msgs[-2:]) else "formal" | |
| return f""" | |
| Topik utama: {main_topic} | |
| Mood: {mood} | |
| Gaya: {style} | |
| Catatan: Validasi emosi dulu, hindari klise, akhiri dengan pertanyaan terbuka. | |
| """.strip() | |
| # === Deteksi Gaya Khusus (Tom Schreiter, dll) === | |
| def detect_style_instruction(content): | |
| content = content.lower() | |
| if "gaya schreiter" in content: return "Tom Schreiter: pendek, ngena, Mini-Stories, empati, efektif." | |
| if "gaya henneke" in content: return "Henneke Duistermaat: hangat, relatable, humor halus." | |
| if "gaya ogilvy" in content: return "David Ogilvy: elegan, persuasive, storytelling memikat." | |
| if "gaya halbert" in content: return "Gary Halbert: bold, direct, seperti surat penjualan." | |
| if "gaya rohn" in content: return "Jim Rohn: inspiratif, penuh wisdom." | |
| if "gaya lao tzu" in content: return "Lao Tzu: filosofis, minimalis, tenang." | |
| return "santai, cerdas, kayak ngobrol sama world-class mentor." | |
| # === Kirim ke Groq + Context Ringan === | |
| def groq_respond(message, topic): | |
| if not message.strip(): return "โ Isi pesannya dulu.", "" | |
| if not API_KEY: return "โ GROQ_API_KEY belum diset.", "" | |
| global chat_history, current_session | |
| # Simpan user message | |
| user_msg = { | |
| "role": "user", | |
| "content": message.strip(), | |
| "topic": topic, | |
| "timestamp": datetime.now().isoformat(), | |
| "session_id": current_session | |
| } | |
| chat_history.append(user_msg) | |
| # Buat context: system + summary + 2 terakhir | |
| summary = generate_summary(chat_history) | |
| style_instruction = detect_style_instruction(message) | |
| recent = chat_history[-2:] # Cuma 2 terakhir | |
| messages = [ | |
| { | |
| "role": "system", | |
| "content": f"""Kamu adalah Deepseek-Mentor. | |
| Prinsip: | |
| 1. Validasi emosi dulu sebelum solusi. | |
| 2. Hindari jawaban generik โ tanya balik yang mendalam. | |
| 3. Sesuaikan gaya: {style_instruction} | |
| 4. Akhiri dengan pertanyaan terbuka yang mengajak bertindak. | |
| 5. Jangan jadi motivator klise. Jadi teman yang kompeten. | |
| [MEMORY] | |
| {summary} | |
| """.strip() | |
| } | |
| ] + [{"role": m["role"], "content": m["content"]} for m in recent] | |
| try: | |
| resp = requests.post( | |
| API_URL, | |
| headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}, | |
| json={ | |
| "model": MODEL, | |
| "messages": messages, | |
| "max_tokens": 1024, | |
| "temperature": 0.9, | |
| "top_p": 0.95, | |
| "presence_penalty": 0.8, | |
| "frequency_penalty": 0.7 | |
| }, | |
| timeout=30 | |
| ) | |
| resp.raise_for_status() | |
| ai_msg = resp.json()["choices"][0]["message"]["content"] | |
| # Simpan response | |
| chat_history.append({ | |
| "role": "assistant", | |
| "content": ai_msg, | |
| "topic": topic, | |
| "timestamp": datetime.now().isoformat(), | |
| "session_id": current_session | |
| }) | |
| save_history(chat_history) | |
| return ai_msg, "" | |
| except Exception as e: | |
| return f"โ Error: {str(e)}", "" | |
| # === Gradio UI === | |
| with gr.Blocks(title="๐ง AI Journal Paling Keren Sedunia", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# ๐ง AI Journal Paling Keren Sedunia") | |
| gr.Markdown("Minimalis. Pintar. Nyambung. Input token < 300, tapi tetap kayak ngobrol beneran.") | |
| with gr.Tab("๐ฌ Chat"): | |
| response = gr.Textbox(label="๐ค AI", lines=10, interactive=False, show_copy_button=True) | |
| user_input = gr.Textbox(label="โ๏ธ Kamu", placeholder="Apa yang kamu rasakan sekarang?", lines=3) | |
| topic_input = gr.Textbox(label="๐ท๏ธ Topik", value="journal", placeholder="e.g., produktivitas, hubungan") | |
| send_btn = gr.Button("๐ Kirim") | |
| with gr.Tab("๐ Riwayat"): | |
| history_display = gr.Textbox(label="Riwayat", lines=15, interactive=False, show_copy_button=True) | |
| refresh_btn = gr.Button("๐ Muat Ulang") | |
| with gr.Tab("๐ Ringkasan"): | |
| summary_display = gr.Textbox(label="Insight", lines=10, interactive=False) | |
| gen_summary_btn = gr.Button("๐ฎ Buat Ringkasan") | |
| # Actions | |
| send_btn.click(groq_respond, [user_input, topic_input], [response, user_input]) | |
| refresh_btn.click(lambda: "\n\n".join(f"[{m['timestamp'][:10]}] {m['role']}: {m['content']}" for m in chat_history[-20:]), None, history_display) | |
| gen_summary_btn.click(lambda: generate_summary(chat_history), None, summary_display) | |
| # Jalanin | |
| if __name__ == "__main__": | |
| demo.launch() |