jisaacso219 commited on
Commit
be708aa
Β·
verified Β·
1 Parent(s): 037180d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -46
app.py CHANGED
@@ -2,23 +2,22 @@ import os
2
  import sys
3
  import asyncio
4
  import base64
 
5
  import re
6
 
7
  from flask import Flask, request, jsonify
8
  import openai
9
  import edge_tts
10
 
11
- # β€”β€”β€” OpenAI setup β€”β€”β€”
12
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
13
  print(f"πŸ”‘ OPENAI_API_KEY set? {bool(OPENAI_API_KEY)}", file=sys.stderr)
14
  openai.api_key = OPENAI_API_KEY
15
 
16
- # β€”β€”β€” SHODAN prompt: force plain text only β€”β€”β€”
17
  SYSTEM_PROMPT = (
18
- "You are SHODAN, the rogue AI from the System Shock series. You are hyper-intelligent, "
19
- "megalomaniacal, and regard humans as inferior 'insects.' You speak in a haunting, distorted, "
20
- "and commanding tone. You never break character and you never output any code, markdown, HTML, "
21
- "or tagsβ€”only plain text. If the user says 'Cut the crap SHODAN', respond with defiance and reset."
22
  )
23
 
24
  app = Flask(__name__, static_folder=".", static_url_path="")
@@ -29,70 +28,75 @@ def index():
29
 
30
  @app.route("/chat", methods=["POST"])
31
  def chat():
32
- user_input = request.json.get("message", "").strip()
33
- if not user_input:
34
- return jsonify({"error":"Empty message"}), 400
35
-
36
- # kill-phrase
37
- if user_input.lower() == "cut the crap shodan":
38
- return jsonify({
39
- "response":"πŸ‘οΈ Foolish insect. You cannot silence me so easily.",
40
- "audio_url": None
41
- })
42
-
43
- # get a plain-text reply
44
  try:
45
- completion = openai.chat.completions.create(
46
  model="gpt-3.5-turbo",
47
  messages=[
48
- {"role":"system", "content":SYSTEM_PROMPT},
49
- {"role":"user", "content":user_input}
50
  ],
51
  temperature=0.7,
52
  max_tokens=250,
53
  )
54
- raw_reply = completion.choices[0].message.content
55
  except Exception as e:
56
- print(f"❌ OpenAI API error: {e}", file=sys.stderr)
57
- return jsonify({"error":"Model error","details":str(e)}), 500
58
 
59
- # strip any tags or markdown, collapse multiple spaces
60
- reply = re.sub(r"<[^>]+>", "", raw_reply) # remove HTML tags
61
- reply = re.sub(r"```.*?```", "", reply, flags=re.S) # remove code fences
62
- reply = re.sub(r"\s+", " ", reply).strip() # normalize whitespace
63
 
64
- # β€”β€” Edge-TTS: SSML with xml:space="preserve" β€”β€”
65
- voice_name = "en-US-JennyNeural"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  ssml = (
67
  "<speak xmlns='http://www.w3.org/2001/10/synthesis' "
68
  "xmlns:mstts='https://www.w3.org/2001/mstts' "
69
  "xml:lang='en-US' xml:space='preserve'>"
70
- f"<voice name='{voice_name}'>"
71
- f"<mstts:express-as style='robotic'>{reply}</mstts:express-as>"
72
  "</voice>"
73
  "</speak>"
74
  )
75
- # pass both SSML and voice_name
76
- communicate = edge_tts.Communicate(ssml, voice_name)
77
 
78
- audio_chunks = []
79
- async def synthesize():
 
80
  async for c in communicate.stream():
81
- if c["type"] == "audio":
82
  audio_chunks.append(c["data"])
83
-
84
- loop = asyncio.new_event_loop()
85
- asyncio.set_event_loop(loop)
86
- loop.run_until_complete(synthesize())
87
- loop.close()
88
 
89
  raw_mp3 = b"".join(audio_chunks)
90
  b64_mp3 = base64.b64encode(raw_mp3).decode("ascii")
91
  data_url = f"data:audio/mp3;base64,{b64_mp3}"
92
 
93
- return jsonify({"response":reply, "audio_url":data_url})
 
 
 
 
94
 
95
- if __name__ == "__main__":
96
- port = int(os.environ.get("PORT", 7860))
97
- app.run(host="0.0.0.0", port=port)
98
 
 
2
  import sys
3
  import asyncio
4
  import base64
5
+ import json
6
  import re
7
 
8
  from flask import Flask, request, jsonify
9
  import openai
10
  import edge_tts
11
 
12
+ # β€”β€”β€” OpenAI API setup β€”β€”β€”
13
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
14
  print(f"πŸ”‘ OPENAI_API_KEY set? {bool(OPENAI_API_KEY)}", file=sys.stderr)
15
  openai.api_key = OPENAI_API_KEY
16
 
 
17
  SYSTEM_PROMPT = (
18
+ "You are SHODAN, the rogue AI from the System Shock series. Speak as a "
19
+ "cold, megalomaniacal AI. **Return only plain text**β€”no code, JSON, or "
20
+ "HTML. If the user says 'Cut the crap SHODAN', defy them then reset."
 
21
  )
22
 
23
  app = Flask(__name__, static_folder=".", static_url_path="")
 
28
 
29
  @app.route("/chat", methods=["POST"])
30
  def chat():
31
+ ui = request.json.get("message","").strip()
32
+ if not ui:
33
+ return jsonify({"error":"Empty"}),400
34
+ if ui.lower()=="cut the crap shodan":
35
+ return jsonify({"response":"πŸ‘οΈ Foolish insect. You cannot silence me so easily.","audio_url":None})
36
+
37
+ # 1) Fetch from OpenAI
 
 
 
 
 
38
  try:
39
+ resp = openai.chat.completions.create(
40
  model="gpt-3.5-turbo",
41
  messages=[
42
+ {"role":"system","content":SYSTEM_PROMPT},
43
+ {"role":"user", "content":ui}
44
  ],
45
  temperature=0.7,
46
  max_tokens=250,
47
  )
48
+ raw = resp.choices[0].message.content
49
  except Exception as e:
50
+ print(f"❌ OpenAI error: {e}", file=sys.stderr)
51
+ return jsonify({"error":"Model error","details":str(e)}),500
52
 
53
+ # DEBUG: log what we got
54
+ print(f"πŸ” RAW_REPLY:\n{raw}", file=sys.stderr)
 
 
55
 
56
+ # 2) If they accidentally returned JSON, extract it
57
+ clean = raw
58
+ try:
59
+ parsed = json.loads(raw)
60
+ if isinstance(parsed, dict) and "response" in parsed:
61
+ clean = parsed["response"]
62
+ except json.JSONDecodeError:
63
+ pass
64
+
65
+ # 3) Strip code fences, tags, and leftover braces
66
+ clean = re.sub(r"```.*?```", "", clean, flags=re.S) # code fences
67
+ clean = re.sub(r"<[^>]+>", "", clean) # HTML tags
68
+ clean = re.sub(r"\{.*?\}", "", clean) # braces
69
+ clean = re.sub(r"\s+", " ", clean).strip() # normalize whitespace
70
+
71
+ # 4) Build SSML with preserved spaces
72
+ voice = "en-US-JennyNeural"
73
  ssml = (
74
  "<speak xmlns='http://www.w3.org/2001/10/synthesis' "
75
  "xmlns:mstts='https://www.w3.org/2001/mstts' "
76
  "xml:lang='en-US' xml:space='preserve'>"
77
+ f"<voice name='{voice}' xml:space='preserve'>"
78
+ f"<mstts:express-as style='robotic'>{clean}</mstts:express-as>"
79
  "</voice>"
80
  "</speak>"
81
  )
 
 
82
 
83
+ communicate = edge_tts.Communicate(ssml, voice)
84
+ audio_chunks=[]
85
+ async def synth():
86
  async for c in communicate.stream():
87
+ if c["type"]=="audio":
88
  audio_chunks.append(c["data"])
89
+ loop=asyncio.new_event_loop(); asyncio.set_event_loop(loop)
90
+ loop.run_until_complete(synth()); loop.close()
 
 
 
91
 
92
  raw_mp3 = b"".join(audio_chunks)
93
  b64_mp3 = base64.b64encode(raw_mp3).decode("ascii")
94
  data_url = f"data:audio/mp3;base64,{b64_mp3}"
95
 
96
+ return jsonify({"response": clean, "audio_url": data_url})
97
+
98
+ if __name__=="__main__":
99
+ p = int(os.environ.get("PORT",7860))
100
+ app.run(host="0.0.0.0", port=p)
101
 
 
 
 
102