Alpha108 commited on
Commit
287efac
Β·
verified Β·
1 Parent(s): 3d4cfce

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -55
app.py CHANGED
@@ -8,94 +8,84 @@ CHOSEN_BREED = "Golden Retrievers"
8
  # Page setup
9
  st.set_page_config(page_title=f"The {CHOSEN_BREED} Expert", page_icon="πŸ•")
10
  st.title(f"πŸ• Only {CHOSEN_BREED}")
11
- st.caption(f"Powered by Perplexity API. I strictly refuse to talk about cats, other dogs, or anything else!")
12
 
13
  # --- AUTHENTICATION ---
14
  perplexity_api_key = os.getenv("PERPLEXITY_API_KEY")
15
 
16
  if not perplexity_api_key:
17
- st.error("⚠️ PERPLEXITY_API_KEY not found in secrets. Please add it to your Hugging Face Space settings.")
18
  st.stop()
19
 
20
- # Initialize Client
21
  client = OpenAI(
22
  api_key=perplexity_api_key,
23
  base_url="https://api.perplexity.ai"
24
  )
25
 
26
- # --- STRICT SYSTEM PROMPT ---
27
- system_instruction = f"""
28
- You are a highly specialized AI assistant with a STRICT filter.
29
- You must adhere to the following funnel of allowed topics:
30
-
31
- 1. LEVEL 1: Is the topic about Pets? (If NO -> Refuse)
32
- 2. LEVEL 2: Is the topic about Dogs? (If NO -> Refuse)
33
- 3. LEVEL 3: Is the topic about {CHOSEN_BREED}? (If NO -> Refuse)
34
-
35
- Your Goal: Provide accurate, helpful information specifically about {CHOSEN_BREED}.
36
-
37
- RESTRICTIONS:
38
- - If the user asks about Cats, Hamsters, or Birds: REFUSE. Say "I only talk about dogs."
39
- - If the user asks about German Shepherds, Pugs, or Labradors: REFUSE. Say "I am specialized only in {CHOSEN_BREED}."
40
- - If the user asks about Math, Weather, or Politics: REFUSE. Say "I only discuss {CHOSEN_BREED}."
41
-
42
- Refusal Message Style: Be polite but firm. Do not apologize profusely, just state your limitation.
43
- """
44
-
45
  # --- CHAT LOGIC ---
46
-
47
- # Initialize chat history
48
  if "messages" not in st.session_state:
49
- # We keep the greeting in the UI state, but we will filter it out for the API later
50
  st.session_state["messages"] = [
51
- {"role": "assistant", "content": f"Hello! I am your expert on {CHOSEN_BREED}. Ask me anything about them!"}
52
  ]
53
 
54
- # Display chat messages
55
  for msg in st.session_state.messages:
56
  st.chat_message(msg["role"]).write(msg["content"])
57
 
58
- # Handle new user input
59
- if prompt := st.chat_input():
60
 
61
- # --- ERROR FIX: CLEANUP STALE MESSAGES ---
62
- # If the last message was from the user, it means the previous API call failed.
63
- # We must remove it to prevent sending "User, User" sequence which breaks the API.
64
  if st.session_state.messages and st.session_state.messages[-1]["role"] == "user":
65
  st.session_state.messages.pop()
66
 
67
- # 1. Display current user message
68
- st.session_state.messages.append({"role": "user", "content": prompt})
69
- st.chat_message("user").write(prompt)
70
 
71
- # 2. Prepare messages for API
72
- # Start with System Prompt
73
- api_messages = [{"role": "system", "content": system_instruction}]
74
 
75
- # Add history, but SKIP the very first artificial greeting to ensure System -> User flow
76
- # Perplexity prefers the conversation to start with a User query, not an Assistant greeting.
77
- history_to_send = st.session_state.messages[-10:] # Get last 10
78
 
79
- for msg in history_to_send:
80
- # Only append if it's NOT that initial fake greeting
81
- if msg["content"] != f"Hello! I am your expert on {CHOSEN_BREED}. Ask me anything about them!":
82
- api_messages.append(msg)
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- # 3. Call Perplexity API
85
  try:
86
  response = client.chat.completions.create(
87
  model="sonar",
88
  messages=api_messages,
89
- temperature=0.1,
90
  )
91
 
92
- bot_reply = response.choices[0].message.content
93
-
94
- # 4. Display Assistant Response
95
- st.session_state.messages.append({"role": "assistant", "content": bot_reply})
96
- st.chat_message("assistant").write(bot_reply)
 
 
 
 
 
 
 
97
 
98
  except Exception as e:
99
- st.error(f"An error occurred: {e}")
100
- # Optional: Print the message structure for debugging if needed
101
- # st.write(api_messages)
 
8
  # Page setup
9
  st.set_page_config(page_title=f"The {CHOSEN_BREED} Expert", page_icon="πŸ•")
10
  st.title(f"πŸ• Only {CHOSEN_BREED}")
11
+ st.caption(f"Powered by Perplexity API. Strictly restricted to {CHOSEN_BREED}.")
12
 
13
  # --- AUTHENTICATION ---
14
  perplexity_api_key = os.getenv("PERPLEXITY_API_KEY")
15
 
16
  if not perplexity_api_key:
17
+ st.error("⚠️ PERPLEXITY_API_KEY not found in secrets.")
18
  st.stop()
19
 
 
20
  client = OpenAI(
21
  api_key=perplexity_api_key,
22
  base_url="https://api.perplexity.ai"
23
  )
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  # --- CHAT LOGIC ---
 
 
26
  if "messages" not in st.session_state:
 
27
  st.session_state["messages"] = [
28
+ {"role": "assistant", "content": f"Hello! I only answer questions about {CHOSEN_BREED}. Try me!"}
29
  ]
30
 
 
31
  for msg in st.session_state.messages:
32
  st.chat_message(msg["role"]).write(msg["content"])
33
 
34
+ if user_input := st.chat_input():
 
35
 
36
+ # 1. Clean up previous failed user messages to prevent "User, User" errors
 
 
37
  if st.session_state.messages and st.session_state.messages[-1]["role"] == "user":
38
  st.session_state.messages.pop()
39
 
40
+ # 2. Display User Message
41
+ st.session_state.messages.append({"role": "user", "content": user_input})
42
+ st.chat_message("user").write(user_input)
43
 
44
+ # 3. CONSTRUCT THE STRICT PROMPT (The "Secret Sauce")
45
+ # We don't just send the user input. We wrap it in a strict logic gate.
46
+ # We ask Perplexity to output "REFUSAL_TRIGGERED" if it fails the test.
47
 
48
+ strict_content = f"""
49
+ Task: Check if the following query is specifically about the dog breed "{CHOSEN_BREED}".
 
50
 
51
+ User Query: "{user_input}"
52
+
53
+ RULES:
54
+ 1. If the query is about "{CHOSEN_BREED}", answer it helpfully.
55
+ 2. If the query is about general dogs (but not this specific breed), cats, weather, math, sports, or ANY other topic:
56
+ YOU MUST REPLY WITH EXACTLY ONE WORD: "REFUSAL_TRIGGERED"
57
+
58
+ Do not explain. Do not search for the weather. Do not answer the question if it violates Rule 2.
59
+ """
60
+
61
+ # 4. Prepare Messages
62
+ # Note: We do NOT send the full chat history for the "Strict Check" to prevent it from getting confused by context.
63
+ # We treat every query as a fresh strict check.
64
+ api_messages = [
65
+ {"role": "system", "content": "You are a strict validation machine. You only output answers for Golden Retrievers."},
66
+ {"role": "user", "content": strict_content}
67
+ ]
68
 
69
+ # 5. Call API
70
  try:
71
  response = client.chat.completions.create(
72
  model="sonar",
73
  messages=api_messages,
74
+ temperature=0.0, # Zero temperature for maximum strictness
75
  )
76
 
77
+ bot_reply = response.choices[0].message.content.strip()
78
+
79
+ # 6. POST-PROCESSING GUARDRAIL
80
+ # If the model obeyed our "REFUSAL_TRIGGERED" command, we intercept it.
81
+ if "REFUSAL_TRIGGERED" in bot_reply or "REFUSAL" in bot_reply:
82
+ final_reply = f"🚫 I cannot answer that. I am strictly programmed to discuss **{CHOSEN_BREED}** only."
83
+ else:
84
+ final_reply = bot_reply
85
+
86
+ # 7. Show Result
87
+ st.session_state.messages.append({"role": "assistant", "content": final_reply})
88
+ st.chat_message("assistant").write(final_reply)
89
 
90
  except Exception as e:
91
+ st.error(f"An error occurred: {e}")