-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
148 lines (124 loc) · 5.05 KB
/
app.py
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import os
import json
import requests
import configparser
import asyncio
from datetime import datetime
from logger import write_chat_log, reset_log, initialize_log_file
app = FastAPI()
templates = Jinja2Templates(directory="templates")
app.mount("/static", StaticFiles(directory="static"), name="static")
config = configparser.ConfigParser()
config.read(os.path.join(os.getcwd(), 'config.ini'))
API_URL = config['api']['url']
MODEL = config['model']['name']
TEMPERATURE = float(config['conversation']['temperature'])
MAX_TOKENS = int(config['conversation']['max_tokens']) if config['conversation']['max_tokens'].isdigit() else None
STREAM = config.getboolean('conversation', 'stream')
WPM = int(config['conversation']['wpm'])
BOT1_NAME = config['personalities']['bot1_name']
BOT2_NAME = config['personalities']['bot2_name']
INITIAL_MESSAGES = [
{"role": config['initial_messages']['message1_role'],
"content": config['initial_messages']['message1_content'].format(bot1_name=BOT1_NAME)},
{"role": config['initial_messages']['message2_role'],
"content": config['initial_messages']['message2_content'].format(bot2_name=BOT2_NAME)}
]
message_history = list(INITIAL_MESSAGES)
current_personality = BOT1_NAME
paused = False
initialize_log_file()
def chat_with_bot(messages):
data = {
"model": MODEL,
"messages": messages,
"temperature": TEMPERATURE,
"max_tokens": MAX_TOKENS if MAX_TOKENS > 0 else 1,
"stream": STREAM,
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "response",
"strict": True,
"schema": {
"type": "object",
"properties": {
"content": {"type": "string"}
},
"required": ["content"]
}
}
}
}
try:
response = requests.post(API_URL, headers={"Content-Type": "application/json"}, data=json.dumps(data))
response.raise_for_status()
response_json = response.json()
if "choices" in response_json and len(response_json["choices"]) > 0:
choice = response_json["choices"][0]
message = choice.get("message", {})
content = message.get("content", "")
if content:
try:
content_json = json.loads(content)
result = content_json.get("content", "Empty content received from API.")
print(f"API Response: {result}")
return result
except json.JSONDecodeError:
print("Error decoding JSON.")
return "Error decoding JSON."
else:
print("Empty content received from API.")
return "Empty content received from API."
else:
print("No choices found in response.")
return "No choices found in response."
except requests.RequestException as e:
print(f"Error: {str(e)}")
return f"Error: {str(e)}"
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.get("/events")
async def events():
async def event_generator():
global message_history, current_personality, paused
while True:
if not paused:
user_message = f"Message from {current_personality}."
message_history.append({"role": "user", "content": user_message, "sender": current_personality})
response = chat_with_bot(message_history)
response_html = response.replace("\n", "<br>")
message_history.append({"role": "assistant", "content": response, "sender": current_personality})
current_personality = BOT2_NAME if current_personality == BOT1_NAME else BOT1_NAME
num_words = len(response.split())
delay = num_words / WPM * 60
write_chat_log(message_history)
yield f"data: {response_html}\n\n"
await asyncio.sleep(delay)
else:
await asyncio.sleep(1)
if paused:
continue
return StreamingResponse(event_generator(), media_type='text/event-stream')
@app.post("/new-chat")
async def new_chat():
global message_history, current_personality, paused
if paused:
return {"status": "paused", "error": "Cannot start a new chat while paused, please press the Resume button and try again."}
reset_log()
initialize_log_file()
message_history = list(INITIAL_MESSAGES)
current_personality = BOT1_NAME
paused = False
print("New chat started")
return {"status": "new chat started"}
@app.post("/pause")
async def pause():
global paused
paused = not paused
return {"paused": paused}