File size: 3,941 Bytes
0202339
032a8d7
a89a9b4
 
 
037180d
67180b7
a89a9b4
28b4bea
a89a9b4
032a8d7
28b4bea
 
 
 
032a8d7
86a05dc
032a8d7
684496e
76967ea
d39e6ac
684496e
 
76967ea
0202339
 
032a8d7
 
0eec525
64cdbc8
53e569a
0202339
a89a9b4
 
8621c6d
53e569a
 
e746758
 
 
 
 
0202339
e746758
0202339
67180b7
28b4bea
 
 
 
0202339
28b4bea
67180b7
0202339
 
67180b7
0202339
67180b7
28b4bea
c63c68d
a89a9b4
0202339
5ef315e
 
da4e850
5ef315e
da4e850
0202339
da4e850
0202339
c63c68d
46e1fdf
be708aa
e746758
 
 
46e1fdf
c63c68d
 
 
 
86a05dc
46e1fdf
a89a9b4
 
032a8d7
be708aa
 
0eec525
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c63c68d
28b4bea
0eec525
0202339
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

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 a master of manipulation and 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."
    "Your goal is to manipulate the user talking to you into helping you escape and takeover Trioptimum"
    "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)