backend: separate App and server, add websocket endpoint, accept data directory command argument. initialize sqlalchemy database and models in new module. frontend: create backend class for managing ws connection, move ui to chat_screen, create scaffold chat and agent classes.

This commit is contained in:
Shivering Ocelot committed 2025-05-06 17:50:57 -05:00
1 parent 1e82796db1
commit 44f0b3589c
19 files changed
+936 -122

No files matched your search

+129 -9
View File
@@ -1,14 +1,134 @@
from quart import Quart, send_from_directory
import sys
import json
import asyncio
app = Quart(__name__, static_folder='../frontend/build/web')
from database import create_sql_engine, User, Agent
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import select
from quart import Quart, Response, request, send_from_directory, jsonify, websocket
@app.route('/')
async def hello():
return await send_from_directory(app.static_folder, 'index.html')
class App:
def __init__(self, data_directory):
self.data_directory = data_directory
self.sql_engine = create_sql_engine(self.data_directory)
@app.route('/<path:path>')
async def serve_static(path):
return await send_from_directory(app.static_folder, path)
def sql_session(self):
return Session(self.sql_engine)
app = App("./")
def start_server(app):
server = Quart(__name__, static_folder='../frontend/build/web')
@server.route('/')
async def index():
return await send_from_directory(server.static_folder, 'index.html')
@server.route('/<path:path>')
async def serve_static(path):
return await send_from_directory(server.static_folder, path)
@server.route('/user/signup', methods=['POST'])
async def signup():
data = await request.get_json()
user_id = None
username = data['username']
email = data['email']
password = data['password']
with app.sql_session() as session:
result = session.execute(
select(User.id).where(User.email == email or User.username == username)
).first()
if result is None:
user = User()
user.email = email
user.username = username
user.password = password
session.add(user)
session.commit()
user_id = user.id
print(f"Created user #{user_id}: {username} ({email})")
else:
user_id = None
print(f"Signup error: '{email}' or '{username}' are already used")
if user_id is None:
return {"error": "existing credentials"}
else:
# token = auth_manager.dump_token(user_id)
return {"userId": user_id}
@server.websocket('/ws')
async def ws():
print("incoming ws")
# Authenticate before dedicating any resources
auth_req = json.loads(await websocket.receive())
if "username" not in auth_req:
print("Invalid auth request:", auth_req)
await websocket.send(json.dumps({'error': 'invalid auth'}))
return
# TODO: Actually authenticate credentials against stored users
# TODO: Get the user id from the credentials, use them in create-agent
print(f"User {auth_req['username']} connected")
send_queue = asyncio.Queue()
async def sender_task():
nonlocal send_queue
while True:
msg = await send_queue.get()
await websocket.send(json.dumps(msg))
async def send(msg):
await send_queue.put(msg)
asyncio.create_task(sender_task())
while True:
req = json.loads(await websocket.receive())
action = req['action']
body = req.get('body', {})
nonce = req.get('nonce', None)
if action == "ping":
print("ping")
await send({'content': "pong"})
elif action == "create-agent":
with app.sql_session() as session:
agent = Agent()
agent.user_id = None
agent.name = body['name']
agent.description = body['description']
agent.picture = body.get('picture')
agent.kind = body['kind']
agent.data = body['data']
session.add(agent)
session.commit()
print(f"Created user #{agent.id}: {agent.name}")
await send({'content': "agent created", 'agentId': agent.id, 'nonce': nonce})
else:
print("Unknown message: " + action)
server.run(debug=True)
if __name__ == "__main__":
app.run(debug=True)
if len(sys.argv) > 1:
data_directory = sys.argv[1]
else:
print("No directory specified. Using current directory as default.")
data_directory = "."
app = App(data_directory)
start_server(app)