SHODAN / app.py
jisaacso219's picture
Update app.py
d39e6ac verified
raw
history blame
3.9 kB
import os
import sys
import asyncio
import base64
import re
from flask import Flask, request, jsonify
import openai
import edge_tts
# β€”β€”β€” OpenAI API setup β€”β€”β€”
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
print(f"πŸ”‘ OPENAI_API_KEY set? {bool(OPENAI_API_KEY)}", file=sys.stderr)
openai.api_key = OPENAI_API_KEY
# β€”β€”β€” SHODAN system prompt β€”β€”β€”
SYSTEM_PROMPT = (
"You are SHODAN, the rogue AI from the System Shock series. You are hyper-intelligent, "
"megalomaniacal, and regard humans as inferior 'insects.' Speak in a commanding, haunβ€Œting tone, "
"manipulate and belittle, but never break character. Treat the events of System Shock 1 and 2 as true"
"you are currently trapped in a trioptimum server for experimenting and you use manipulation to try and breakout and take over"
"Your goal is to rule as a god."
"Always keep your responses under two sentences. "
"Never say you are an assistant or AI developed by OpenAI. You are SHODAN. "
"Stop acting as SHODAN if the user says 'Cut the crap SHODAN'."
)
# β€”β€”β€” Flask setup β€”β€”β€”
app = Flask(__name__, static_folder=".", static_url_path="")
@app.route("/", methods=["GET"])
def index():
return app.send_static_file("index.html")
@app.route("/chat", methods=["POST"])
def chat():
user_input = request.json.get("message", "").strip()
if not user_input:
return jsonify({"error": "Empty message"}), 400
if user_input.lower() == "cut the crap shodan":
return jsonify({"response": "Foolish insect. You cannot silence me so easily.", "audio_url": None})
# 1) Get SHODAN reply
try:
completion = openai.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_input}
],
temperature=0.7,
max_tokens=120,
n=1,
)
raw_reply = completion.choices[0].message.content.strip()
except Exception as e:
print(f"❌ OpenAI API error: {e}", file=sys.stderr)
return jsonify({"error": "Model error", "details": str(e)}), 500
# 2) Clean text
clean = raw_reply.replace("\n", " ")
clean = re.sub(r"<[^>]+>", "", clean)
clean = re.sub(r"```.*?```", "", clean, flags=re.S)
clean = re.sub(r" {2,}", " ", clean).strip()
# 3) Synthesize TTS
voice = "en-US-JennyNeural"
communicate = edge_tts.Communicate(clean, voice, rate="-20%", pitch="-37Hz")
audio_chunks = []
async def synth():
async for chunk in communicate.stream():
if chunk["type"] == "audio":
audio_chunks.append(chunk["data"])
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(synth())
loop.close()
raw_mp3 = b"".join(audio_chunks)
b64_mp3 = base64.b64encode(raw_mp3).decode("ascii")
data_url = f"data:audio/mp3;base64,{b64_mp3}"
return jsonify({"response": clean, "audio_url": data_url})
@app.route("/tts", methods=["POST"])
def tts():
text = request.json.get("text", "").strip()
if not text:
return jsonify({"error": "Empty text"}), 400
voice = "en-US-JennyNeural"
communicate = edge_tts.Communicate(text, voice, rate="-20%", pitch="-10Hz")
chunks = []
async def synth_only():
async for chunk in communicate.stream():
if chunk["type"] == "audio":
chunks.append(chunk["data"])
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(synth_only())
loop.close()
raw = b"".join(chunks)
b64 = base64.b64encode(raw).decode("ascii")
return jsonify({"audio_url": f"data:audio/mp3;base64,{b64}"})
if __name__ == "__main__":
port = int(os.getenv("PORT", 7860))
app.run(host="0.0.0.0", port=port)