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

Update app.py

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