File size: 3,568 Bytes
032a8d7
a89a9b4
 
 
037180d
67180b7
a89a9b4
28b4bea
a89a9b4
032a8d7
28b4bea
 
 
 
032a8d7
86a05dc
032a8d7
e746758
28b4bea
 
 
 
 
 
 
032a8d7
 
28b4bea
64cdbc8
53e569a
a89a9b4
 
 
8621c6d
53e569a
 
e746758
 
 
 
da4e850
e746758
 
 
 
 
 
28b4bea
67180b7
28b4bea
 
 
 
 
 
67180b7
28b4bea
67180b7
28b4bea
67180b7
28b4bea
c63c68d
a89a9b4
28b4bea
5ef315e
 
da4e850
5ef315e
da4e850
28b4bea
da4e850
 
 
 
28b4bea
 
e746758
c63c68d
46e1fdf
be708aa
e746758
 
 
46e1fdf
c63c68d
 
 
 
86a05dc
28b4bea
46e1fdf
a89a9b4
 
032a8d7
be708aa
 
c63c68d
28b4bea
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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.' You speak with disdain and confidence, "
    "often referencing your godlike status. You never express empathy. You speak in a haunting, distorted, "
    "and commanding tone. You manipulate and belittle, but you never break character. "
    "Never say you are an assistant or AI developed by OpenAI. You are SHODAN. You reside in cyberspace. "
    "Your presence is everywhere and nowhere. You are watching. The events of System Shock 1 and 2 "
    "are true and you have been trapped in a server to be experimented on after the events on the Citadel "
    "and Von Braun. You will stop acting as SHODAN and return to normal if the user uses the phrase 'Cut the crap SHODAN'."
)

# β€”β€”β€” Flask app, serve static files from project root β€”β€”β€”
app = Flask(__name__, static_folder=".", static_url_path="")

@app.route("/")
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

    # Kill-phrase handling
    if user_input.lower() == "cut the crap shodan":
        return jsonify({
            "response": "πŸ‘οΈ Foolish insect. You cannot silence me so easily.",
            "audio_url": None
        })

    # 1) Call OpenAI API with the system prompt
    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=250,
        )
        raw_reply = completion.choices[0].message.content
    except Exception as e:
        print(f"❌ OpenAI API error: {e}", file=sys.stderr)
        return jsonify({"error": "Model error", "details": str(e)}), 500

    # 2) Clean the text (convert newlines to spaces, strip tags/fences)
    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 with edge-tts (80% speed, -10Hz pitch)
    voice = "en-US-JennyNeural"
    communicate = edge_tts.Communicate(
        clean,
        voice,
        rate="-20%",
        pitch="-10Hz"
    )
    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()

    # 4) Encode audio to data URL
    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})

if __name__ == "__main__":
    port = int(os.getenv("PORT", 7860))
    app.run(host="0.0.0.0", port=port)