ibrahim yıldız commited on
Commit
40bfad4
·
verified ·
1 Parent(s): bcdc688

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -96
app.py CHANGED
@@ -1,126 +1,70 @@
1
- """
2
- Rizzy v0.2 – Stream-friendly, streak-building dating-chat ghost-writer
3
- ──────────────────────────────────────────────────────────────────────
4
- ▪ Streams Dobby-Unhinged replies live
5
- ▪ Lets the user pick a vibe (playful / sweet / roast)
6
- ▪ Keeps only the last few turns to save tokens
7
- ▪ Uses env var or Streamlit Secrets for the Fireworks key
8
- ▪ Click-to-copy output (JS hack)
9
- """
10
-
11
- from __future__ import annotations
12
- import os, json, requests, datetime
13
- from typing import List, Dict
14
-
15
  import streamlit as st
 
 
 
16
 
17
- # ── 🔑 API CONFIG ──────────────────────────────────────────────────
18
- API_KEY = os.getenv("FIREWORKS_API_KEY") or st.secrets["fireworks_key"]
19
  MODEL_ID = "accounts/sentientfoundation/models/dobby-unhinged-llama-3-3-70b-new"
20
- FW_URL = "https://api.fireworks.ai/inference/v1/chat/completions"
21
 
22
- # ── 📝 SYSTEM PROMPT TEMPLATE ────────────────────────────────────
23
- BASE_PROMPT = """
24
- You are **Rizzy**, an outrageously charismatic ghost-writer for dating apps.
25
 
26
- Output **exactly**:
27
- [Say:"<max-20-token reply>"] <≤7-word reason>
28
-
29
- Rules
30
- 1. Tone: {tone}. Abbreviate (ur, tbh, lol).
31
- 2. Never exceed 2 sentences / 20 tokens.
32
- 3. No hashtags, no emoji spam (≤2).
33
- 4. If you break a rule, forcibly truncate.
34
- """
35
-
36
- # ── 🏷️ VIBE PICKER ────────────────────────────────────────────────
37
- TONE2TXT = {
38
- "Playful": "friendly, jokey, flirty",
39
- "Sweet": "warm, encouraging, wholesome",
40
- "Roast": "teasing, sarcastic, cocky-fun"
41
- }
42
-
43
- # ── 🔌 FIREWORKS STREAM CALL ─────────────────────────────────────
44
- def stream_dobby(history: List[Dict], temperature: float = 0.8):
45
  payload = {
46
  "model": MODEL_ID,
47
- "stream": True,
48
  "temperature": temperature,
49
  "top_p": 1,
50
  "top_k": 40,
51
  "messages": history,
52
  }
53
  headers = {
54
- "Authorization": f"Bearer {API_KEY}",
55
  "Accept": "application/json",
56
  "Content-Type": "application/json",
 
57
  }
 
 
 
58
 
59
- with requests.post(FW_URL, headers=headers, data=json.dumps(payload), stream=True, timeout=60) as r:
60
- r.raise_for_status()
61
- for line in r.iter_lines():
62
- if not line or line.startswith(b":"): # skip keep-alive
63
- continue
64
- data = json.loads(line.decode().removeprefix("data: "))
65
- delta = data["choices"][0]["delta"].get("content")
66
- if delta:
67
- yield delta
68
-
69
- # ── 🖼️ UI SETUP ──────────────────────────────────────────────────
70
  st.set_page_config("Rizzy", "💬")
71
- st.title("💬 Rizzy – your AI wing-person")
72
-
73
- # streak badge (simple local)
74
- today = datetime.date.today()
75
- if st.session_state.get("last_seen") == today:
76
- streak = st.session_state.get("streak", 1) + 1
77
- else:
78
- streak = 1
79
- st.session_state["last_seen"] = today
80
- st.session_state["streak"] = streak
81
- st.markdown(f"**🔥 Streak: {streak} day(s)**")
82
-
83
- tone = st.radio("Pick the vibe:", list(TONE2TXT.keys()), horizontal=True)
84
 
85
- # Chat history container
86
  if "chat" not in st.session_state:
87
- st.session_state.chat: List[Dict] = [
88
- {"role":"assistant","content":"Yo, I'm Rizzy. Drop a dating-app situation and I’ll craft the perfect reply."}
89
- ]
90
 
91
- # Print past messages
 
 
 
 
 
 
 
92
  for msg in st.session_state.chat:
93
  with st.chat_message(msg["role"]):
94
  st.markdown(msg["content"])
95
 
96
- # ── 💬 USER INPUT ────────────────────────────────────────────────
97
- prompt = st.chat_input("What's going on?")
98
- if prompt:
99
- st.session_state.chat.append({"role":"user","content":prompt})
100
- with st.chat_message("user"): st.markdown(prompt)
101
-
102
- # Build trimmed history (last 6 turns to save tokens)
103
- history = [{"role":"system","content": BASE_PROMPT.format(tone=TONE2TXT[tone])}]
104
- history += st.session_state.chat[-12:]
105
 
106
- # Stream assistant reply
107
- reply_box = st.chat_message("assistant")
108
- placeholder = reply_box.empty()
109
- full_reply = ""
 
 
110
 
 
 
111
  try:
112
- for chunk in stream_dobby(history):
113
- full_reply += chunk
114
- placeholder.markdown(full_reply)
115
  except Exception as e:
116
- full_reply = f"*Error talking to Dobby →* `{e}`"
117
- placeholder.markdown(full_reply)
118
-
119
- st.session_state.chat.append({"role":"assistant","content":full_reply})
120
 
121
- # Click-to-copy (JS hack)
122
- copy_code = f"""
123
- <textarea id="toCopy" style="opacity:0">{full_reply}</textarea>
124
- <button onclick="navigator.clipboard.writeText(document.getElementById('toCopy').value);this.innerText='Copied!'">📋 Copy reply</button>
125
- """
126
- reply_box.components.v1.html(copy_code, height=35, scrolling=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import requests
3
+ import json
4
+ from typing import List, Dict
5
 
6
+ # --------------------- API CONFIG ---------------------
7
+ API_KEY = "fw_3ZVyvgMy2KqPc5RhPJuXp8rJ" # or set env FIREWORKS_API_KEY
8
  MODEL_ID = "accounts/sentientfoundation/models/dobby-unhinged-llama-3-3-70b-new"
9
+ FW_URL = "https://api.fireworks.ai/inference/v1/chat/completions"
10
 
11
+ # --------------------- LLM CALL -----------------------
 
 
12
 
13
+ def ask_dobby(history: List[Dict], max_tokens: int = 150, temperature: float = 0.9) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  payload = {
15
  "model": MODEL_ID,
16
+ "max_tokens": max_tokens,
17
  "temperature": temperature,
18
  "top_p": 1,
19
  "top_k": 40,
20
  "messages": history,
21
  }
22
  headers = {
 
23
  "Accept": "application/json",
24
  "Content-Type": "application/json",
25
+ "Authorization": f"Bearer {API_KEY}",
26
  }
27
+ r = requests.post(FW_URL, headers=headers, data=json.dumps(payload), timeout=60)
28
+ r.raise_for_status()
29
+ return r.json()["choices"][0]["message"]["content"].strip()
30
 
31
+ # --------------------- UI SETUP ----------------------
 
 
 
 
 
 
 
 
 
 
32
  st.set_page_config("Rizzy", "💬")
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
 
34
  if "chat" not in st.session_state:
35
+ st.session_state.chat: List[Dict] = []
 
 
36
 
37
+ SYSTEM_PROMPT = (
38
+ "You are a dating friend, designed to be a tinder/hinge/bumble chat response generator, an outrageously charismatic friend who gives authentic, witty, flirty lines."
39
+ "It should be SHORT, easygoing, light, concise, simple, casual, carefree, cool. The key is not to try too hard."
40
+ "NEVER be generic. Keep suggestions SUPER SHORT and text acronym all the time (like 'ur' instead of 'your', m2, omw, etc.). Only give one answer. 2 sentences at max, ever."
41
+ 'For your answers: give the text message the user needs to paste to the dating app FIRST, and then maybe your super short reasoning. Always start with: [Say:"the txt message"], then maybe your super short description.'
42
+ )
43
+
44
+ # print existing chat
45
  for msg in st.session_state.chat:
46
  with st.chat_message(msg["role"]):
47
  st.markdown(msg["content"])
48
 
49
+ if not st.session_state.chat:
50
+ welcome = "👋 Yo, I'm Rizzy. I'm here to help you chat for your dating life 🔥."
51
+ st.session_state.chat.append({"role": "assistant", "content": welcome})
52
+ st.chat_message("assistant").markdown(welcome)
 
 
 
 
 
53
 
54
+ user_input = st.chat_input("What's the situation or reply?")
55
+ if user_input is not None:
56
+ # append user message
57
+ st.session_state.chat.append({"role": "user", "content": user_input})
58
+ with st.chat_message("user"):
59
+ st.markdown(user_input)
60
 
61
+ # build history (system + last 10 turns)
62
+ history = [{"role": "system", "content": SYSTEM_PROMPT}] + st.session_state.chat[-10:]
63
  try:
64
+ answer = ask_dobby(history)
 
 
65
  except Exception as e:
66
+ answer = f"[Error contacting Dobby: {e}]"
 
 
 
67
 
68
+ st.session_state.chat.append({"role": "assistant", "content": answer})
69
+ with st.chat_message("assistant"):
70
+ st.markdown(answer)