jisaacso219 commited on
Commit
46e1fdf
Β·
verified Β·
1 Parent(s): 4c9f297

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -35
app.py CHANGED
@@ -1,19 +1,23 @@
 
1
  import os
2
  import sys
3
  import asyncio
4
  import base64
5
  import re
6
- import io
7
 
8
  from flask import Flask, request, jsonify
9
- import openai
10
  import edge_tts
11
- from pydub import AudioSegment
12
 
13
- # β€”β€”β€” OpenAI API 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
  # β€”β€”β€” SHODAN system prompt β€”β€”β€”
19
  SYSTEM_PROMPT = (
@@ -27,6 +31,7 @@ SYSTEM_PROMPT = (
27
  "You will stop acting as SHODAN and return to normal if the user uses the phrase 'Cut the crap SHODAN'."
28
  )
29
 
 
30
  app = Flask(__name__, static_folder=".", static_url_path="")
31
 
32
  @app.route("/")
@@ -46,59 +51,53 @@ def chat():
46
  "audio_url": None
47
  })
48
 
49
- # 1) Generate SHODAN’s reply via OpenAI
 
 
 
 
 
 
 
50
  try:
51
- completion = openai.chat.completions.create(
52
- model="gpt-3.5-turbo",
53
- messages=[
54
- {"role": "system", "content": SYSTEM_PROMPT},
55
- {"role": "user", "content": user_input}
56
- ],
57
  temperature=0.7,
58
- max_tokens=250,
59
  )
60
- raw_reply = completion.choices[0].message.content
61
  except Exception as e:
62
- print(f"❌ OpenAI error: {e}", file=sys.stderr)
63
  return jsonify({"error": "Model error", "details": str(e)}), 500
64
 
65
- # 2) Clean the text (convert newlines to spaces, strip fences/tags)
66
  clean = raw_reply.replace("\n", " ")
67
  clean = re.sub(r"<[^>]+>", "", clean)
68
  clean = re.sub(r"```.*?```", "", clean, flags=re.S)
69
  clean = re.sub(r" {2,}", " ", clean).strip()
70
 
71
- # 3) Synthesize raw TTS audio
72
  voice = "en-US-JennyNeural"
73
  communicate = edge_tts.Communicate(
74
  clean,
75
  voice,
76
- rate="-40%",
77
- pitch="-30Hz"
78
  )
79
  audio_chunks = []
 
80
  async def synth():
81
  async for chunk in communicate.stream():
82
  if chunk["type"] == "audio":
83
  audio_chunks.append(chunk["data"])
 
84
  loop = asyncio.new_event_loop()
85
  asyncio.set_event_loop(loop)
86
  loop.run_until_complete(synth())
87
  loop.close()
88
- raw_mp3 = b"".join(audio_chunks)
89
 
90
- # 4) Apply distortion effect via pydub
91
- audio_seg = AudioSegment.from_file(io.BytesIO(raw_mp3), format="mp3")
92
- # bit-crush: downsample then upsample
93
- crushed = audio_seg.set_frame_rate(int(audio_seg.frame_rate * 0.5))
94
- crushed = crushed.set_frame_rate(audio_seg.frame_rate)
95
- # amplify to create clipping distortion
96
- distorted = crushed + 10 # +10 dB gain
97
- buf = io.BytesIO()
98
- distorted.export(buf, format="mp3")
99
- raw_mp3 = buf.getvalue()
100
-
101
- # 5) Encode to data URL
102
  b64_mp3 = base64.b64encode(raw_mp3).decode("ascii")
103
  data_url = f"data:audio/mp3;base64,{b64_mp3}"
104
 
@@ -107,4 +106,4 @@ def chat():
107
  if __name__ == "__main__":
108
  port = int(os.environ.get("PORT", 7860))
109
  app.run(host="0.0.0.0", port=port)
110
-
 
1
+ ```python
2
  import os
3
  import sys
4
  import asyncio
5
  import base64
6
  import re
 
7
 
8
  from flask import Flask, request, jsonify
9
+ from llama_cpp import Llama
10
  import edge_tts
 
11
 
12
+ # β€”β€”β€” Load local quantized model via llama-cpp-python β€”β€”β€”
13
+ MODEL_PATH = "models/mistral-7b-instruct-q4_k_m.gguf"
14
+ print(f"βš™οΈ Loading local model from {MODEL_PATH}", file=sys.stderr)
15
+ llm = Llama(
16
+ model_path=MODEL_PATH,
17
+ n_ctx=2048,
18
+ n_threads=int(os.getenv("THREADS", 4)),
19
+ verbose=False
20
+ )
21
 
22
  # β€”β€”β€” SHODAN system prompt β€”β€”β€”
23
  SYSTEM_PROMPT = (
 
31
  "You will stop acting as SHODAN and return to normal if the user uses the phrase 'Cut the crap SHODAN'."
32
  )
33
 
34
+ # β€”β€”β€” Flask app, serving static files β€”β€”β€”
35
  app = Flask(__name__, static_folder=".", static_url_path="")
36
 
37
  @app.route("/")
 
51
  "audio_url": None
52
  })
53
 
54
+ # Build prompt
55
+ prompt = (
56
+ SYSTEM_PROMPT
57
+ + "\n\nHuman: " + user_input
58
+ + "\nSHODAN:"
59
+ )
60
+
61
+ # 1) Generate reply locally
62
  try:
63
+ out = llm(
64
+ prompt,
65
+ max_tokens=256,
 
 
 
66
  temperature=0.7,
67
+ stop=["Human:", "SHODAN:"]
68
  )
69
+ raw_reply = out["choices"][0]["text"]
70
  except Exception as e:
71
+ print(f"❌ Local model error: {e}", file=sys.stderr)
72
  return jsonify({"error": "Model error", "details": str(e)}), 500
73
 
74
+ # 2) Clean text (convert newlines to spaces, strip fences/tags)
75
  clean = raw_reply.replace("\n", " ")
76
  clean = re.sub(r"<[^>]+>", "", clean)
77
  clean = re.sub(r"```.*?```", "", clean, flags=re.S)
78
  clean = re.sub(r" {2,}", " ", clean).strip()
79
 
80
+ # 3) Synthesize using edge-tts
81
  voice = "en-US-JennyNeural"
82
  communicate = edge_tts.Communicate(
83
  clean,
84
  voice,
85
+ rate="-20%",
86
+ pitch="-10Hz"
87
  )
88
  audio_chunks = []
89
+
90
  async def synth():
91
  async for chunk in communicate.stream():
92
  if chunk["type"] == "audio":
93
  audio_chunks.append(chunk["data"])
94
+
95
  loop = asyncio.new_event_loop()
96
  asyncio.set_event_loop(loop)
97
  loop.run_until_complete(synth())
98
  loop.close()
 
99
 
100
+ raw_mp3 = b"".join(audio_chunks)
 
 
 
 
 
 
 
 
 
 
 
101
  b64_mp3 = base64.b64encode(raw_mp3).decode("ascii")
102
  data_url = f"data:audio/mp3;base64,{b64_mp3}"
103
 
 
106
  if __name__ == "__main__":
107
  port = int(os.environ.get("PORT", 7860))
108
  app.run(host="0.0.0.0", port=port)
109
+ ```