├── .env.example ├── services ├── uniqueIdentifier.js └── chatService.js ├── middleware ├── passport-local.js └── auth.js ├── Dockerfile ├── routes ├── chat.js ├── auth.js ├── user.js ├── agent.js └── conversation.js ├── config └── database.js ├── models ├── user.js ├── conversation.js ├── agent.js └── response.js ├── controllers ├── chatController.js ├── authController.js ├── userController.js ├── agentController.js └── conversationController.js ├── package.json ├── app.js ├── .gitignore ├── README.md └── spec └── openapi.yml /.env.example: -------------------------------------------------------------------------------- 1 | MONGO_URI = "" 2 | OPENAI_API_KEY = "" 3 | PORT = "" 4 | HOST = "" -------------------------------------------------------------------------------- /services/uniqueIdentifier.js: -------------------------------------------------------------------------------- 1 | const { v4: uuidv4 } = require("uuid"); 2 | const crypto = require("crypto"); 3 | 4 | function generateUniqueId() { 5 | return uuidv4(); 6 | } 7 | 8 | function generateSecretKey(length) { 9 | return crypto.randomBytes(length).toString("hex"); 10 | } 11 | 12 | module.exports = { 13 | generateUniqueId, 14 | generateSecretKey, 15 | }; 16 | -------------------------------------------------------------------------------- /middleware/passport-local.js: -------------------------------------------------------------------------------- 1 | const passport = require("passport"); 2 | const LocalStrategy = require("passport-local").Strategy; 3 | const User = require("../models/user"); 4 | 5 | passport.use( 6 | new LocalStrategy({ usernameField: "username" }, User.authenticate()) 7 | ); 8 | passport.serializeUser(User.serializeUser()); 9 | passport.deserializeUser(User.deserializeUser()); 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Node.js runtime as the base image 2 | FROM node:14 3 | 4 | # Set the working directory in the container 5 | WORKDIR / 6 | 7 | # Copy package.json and package-lock.json to the container 8 | COPY package*.json ./ 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Copy the rest of your application code to the container 14 | COPY . . 15 | 16 | # Expose a port (if your app listens on a specific port) 17 | EXPOSE 80 18 | 19 | # Define the command to run your application 20 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /routes/chat.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const chatController = require("../controllers/chatController"); 4 | const { ensureAuthenticated, checkRole } = require("../middleware/auth"); 5 | 6 | // POST /v1/chat/completion 7 | router.post( 8 | "/completion", 9 | ensureAuthenticated, 10 | checkRole(["user", "developer", "admin"]), 11 | chatController.generateChatResponse 12 | ); 13 | 14 | // Add more routes as needed for chat-related operations 15 | 16 | module.exports = router; 17 | -------------------------------------------------------------------------------- /config/database.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | require("dotenv").config(); 3 | 4 | // Get the MongoDB connection string from environment variables 5 | const mongoURI = process.env.MONGO_URI; 6 | 7 | // Set up options for the mongoose connection 8 | const options = { 9 | useNewUrlParser: true, 10 | useUnifiedTopology: true, 11 | }; 12 | 13 | // Connect to MongoDB 14 | mongoose 15 | .connect(mongoURI, options) 16 | .then(() => { 17 | console.log("Connected to MongoDB"); 18 | }) 19 | .catch((err) => { 20 | console.error("MongoDB connection error:", err); 21 | }); 22 | 23 | module.exports = mongoose; 24 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("../config/database"); 2 | const passportLocalMongoose = require("passport-local-mongoose"); 3 | 4 | const userSchema = new mongoose.Schema({ 5 | username: { 6 | type: String, 7 | required: true, 8 | unique: true, 9 | }, 10 | password: { 11 | type: String, 12 | required: true, 13 | }, 14 | display_name: { 15 | type: String, 16 | required: true, 17 | }, 18 | role: { 19 | type: String, 20 | enum: ["user", "developer", "admin"], 21 | default: "user", 22 | }, 23 | }); 24 | 25 | userSchema.plugin(passportLocalMongoose); 26 | 27 | const User = mongoose.model("User", userSchema); 28 | 29 | module.exports = User; 30 | -------------------------------------------------------------------------------- /models/conversation.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("../config/database"); 2 | const Response = require("./response"); 3 | const uniqueIdentifier = require("../services/uniqueIdentifier"); 4 | 5 | const conversationSchema = new mongoose.Schema({ 6 | conversation_id: { 7 | type: String, 8 | required: false, 9 | default: uniqueIdentifier.generateUniqueId(), 10 | }, 11 | username: { 12 | type: String, 13 | required: true, 14 | }, 15 | agent_name: { 16 | type: String, 17 | required: true, 18 | }, 19 | messages: { type: [Response.schema], default: [] }, 20 | }); 21 | 22 | const Conversation = mongoose.model("Conversation", conversationSchema); 23 | 24 | module.exports = Conversation; 25 | -------------------------------------------------------------------------------- /models/agent.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("../config/database"); 2 | const uniqueIdentifier = require("../services/uniqueIdentifier"); 3 | 4 | const agentSchema = new mongoose.Schema({ 5 | agent_id: { 6 | type: String, 7 | required: false, 8 | default: uniqueIdentifier.generateUniqueId(), 9 | }, 10 | agent_name: { 11 | type: String, 12 | required: true, 13 | }, 14 | description: { 15 | type: String, 16 | required: true, 17 | }, 18 | persona: { 19 | type: String, 20 | required: true, 21 | }, 22 | model: { 23 | type: String, 24 | default: "gpt-3.5-turbo-0613", 25 | }, 26 | }); 27 | 28 | const Agent = mongoose.model("Agent", agentSchema); 29 | 30 | module.exports = Agent; 31 | -------------------------------------------------------------------------------- /models/response.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("../config/database"); 2 | const uniqueIdentifier = require("../services/uniqueIdentifier"); 3 | 4 | const responseSchema = new mongoose.Schema({ 5 | response_id: { 6 | type: String, 7 | required: false, 8 | default: uniqueIdentifier.generateUniqueId(), 9 | }, 10 | username: { 11 | type: String, 12 | required: true, 13 | }, 14 | agent_name: { 15 | type: String, 16 | required: true, 17 | }, 18 | initial_message: { 19 | type: String, 20 | required: true, 21 | }, 22 | message_reply: { 23 | type: String, 24 | required: true, 25 | }, 26 | timestamp: { 27 | type: Date, 28 | default: Date.now, 29 | }, 30 | }); 31 | 32 | const Response = mongoose.model("Response", responseSchema); 33 | 34 | module.exports = Response; 35 | -------------------------------------------------------------------------------- /middleware/auth.js: -------------------------------------------------------------------------------- 1 | function ensureAuthenticated(req, res, next) { 2 | if (req.isAuthenticated()) { 3 | return next(); // User is authenticated, continue to the next middleware/route handler 4 | } 5 | // User is not authenticated 6 | res.status(500).json({ message: "User not logged in." }); 7 | } 8 | 9 | function checkRole(allowedRoles) { 10 | return (req, res, next) => { 11 | // Check if user is authenticated and has the required role 12 | if (allowedRoles.includes(req.user.role)) { 13 | return next(); // User has the required role, continue to the next middleware 14 | } 15 | // User is not authorized 16 | return res 17 | .status(403) 18 | .json({ message: "Access denied, not enough clearance" }); 19 | }; 20 | } 21 | 22 | module.exports = { 23 | ensureAuthenticated, 24 | checkRole, 25 | }; 26 | -------------------------------------------------------------------------------- /routes/auth.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const passport = require("passport"); 3 | const authController = require("../controllers/authController"); 4 | const { ensureAuthenticated, checkRole } = require("../middleware/auth"); 5 | 6 | const router = express.Router(); 7 | 8 | router.post("/register", authController.registerUser); 9 | 10 | router.post("/login", passport.authenticate("local"), (req, res) => { 11 | res.json({ message: "User logged in successfully" }); 12 | }); 13 | 14 | router.get("/logout", checkRole(["user", "developer", "admin"]), (req, res) => { 15 | req.logout(function (err) { 16 | if (err) { 17 | return res.status(500).json({ error: err.message }); 18 | } else { 19 | return res.json({ message: "User logged out successfully" }); 20 | } 21 | }); 22 | }); 23 | 24 | router.get( 25 | "/current", 26 | checkRole(["user", "developer", "admin"]), 27 | authController.getCurrentUser 28 | ); 29 | 30 | module.exports = router; 31 | -------------------------------------------------------------------------------- /routes/user.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const userController = require("../controllers/userController"); 4 | const { ensureAuthenticated, checkRole } = require("../middleware/auth"); 5 | 6 | // GET /v1/user 7 | router.get( 8 | "/", 9 | ensureAuthenticated, 10 | checkRole(["developer", "admin"]), 11 | userController.getAllUsers 12 | ); 13 | 14 | // DELETE /v1/user (Delete all users) 15 | router.delete( 16 | "/", 17 | ensureAuthenticated, 18 | checkRole(["developer", "admin"]), 19 | userController.deleteAllUsers 20 | ); 21 | 22 | // GET /v1/user/:username 23 | router.get( 24 | "/:username", 25 | ensureAuthenticated, 26 | checkRole(["developer", "admin"]), 27 | userController.getUserByUsername 28 | ); 29 | 30 | // DELETE /v1/user/:username (Delete a single user by name) 31 | router.delete( 32 | "/:username", 33 | ensureAuthenticated, 34 | checkRole(["developer", "admin"]), 35 | userController.deleteUserByName 36 | ); 37 | 38 | module.exports = router; 39 | -------------------------------------------------------------------------------- /controllers/chatController.js: -------------------------------------------------------------------------------- 1 | const chatService = require("../services/chatService"); 2 | const User = require("../models/user"); 3 | const Agent = require("../models/agent"); 4 | 5 | // Create a response for the given message using conversation history 6 | async function generateChatResponse(req, res) { 7 | const { username, agent_name, message } = req.body; 8 | 9 | try { 10 | const user = await User.findOne({ username: username }); 11 | const agent = await Agent.findOne({ agent_name: agent_name }); 12 | if (!user) { 13 | return res.status(404).json({ message: "User not found" }); 14 | } 15 | if (!agent) { 16 | return res.status(404).json({ message: "Agent not found" }); 17 | } 18 | const response = await chatService.generateResponse( 19 | username, 20 | agent_name, 21 | message 22 | ); 23 | res.status(200).json(response); 24 | } catch (error) { 25 | console.error(error); 26 | res.status(500).json({ message: "Internal server error" }); 27 | } 28 | } 29 | 30 | module.exports = { 31 | generateChatResponse, 32 | }; 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "personatalk", 3 | "version": "1.0.0", 4 | "description": "The backend API for communicating with digital personas", 5 | "main": "app.js", 6 | "engines": { 7 | "node": ">=16.13.2" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "start": "node app.js" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/chris-cozy/JasmineAPI.git" 16 | }, 17 | "author": "Chris Cozy", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/chris-cozy/JasmineAPI/issues" 21 | }, 22 | "homepage": "https://github.com/chris-cozy/JasmineAPI#readme", 23 | "dependencies": { 24 | "bcrypt": "^5.1.1", 25 | "cors": "^2.8.5", 26 | "crypto": "^1.0.1", 27 | "dotenv": "^16.3.1", 28 | "express": "^4.18.2", 29 | "express-session": "^1.17.3", 30 | "mongoose": "^7.4.4", 31 | "nodemon": "^3.0.1", 32 | "openai": "^3.2.1", 33 | "passport": "^0.6.0", 34 | "passport-local": "^1.0.0", 35 | "passport-local-mongoose": "^8.0.0", 36 | "uuid": "^9.0.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /routes/agent.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const agentController = require("../controllers/agentController"); 4 | const { ensureAuthenticated, checkRole } = require("../middleware/auth"); 5 | 6 | // GET /v1/agent 7 | router.get( 8 | "/", 9 | ensureAuthenticated, 10 | checkRole(["user", "developer", "admin"]), 11 | agentController.getAllAgents 12 | ); 13 | 14 | // POST /v1/agent (Create a new agent) 15 | router.post( 16 | "/", 17 | ensureAuthenticated, 18 | checkRole(["user", "developer", "admin"]), 19 | agentController.createAgent 20 | ); 21 | 22 | // DELETE /v1/agent (Delete all agents) 23 | router.delete( 24 | "/", 25 | ensureAuthenticated, 26 | checkRole(["developer", "admin"]), 27 | agentController.deleteAllAgents 28 | ); 29 | 30 | // GET /v1/agent/:agent_name 31 | router.get( 32 | "/:agent_name", 33 | ensureAuthenticated, 34 | checkRole(["user", "developer", "admin"]), 35 | agentController.getAgentByName 36 | ); 37 | 38 | // DELETE /v1/agent/:agent_name (Delete a single agent by name) 39 | router.delete( 40 | "/:agent_name", 41 | ensureAuthenticated, 42 | checkRole(["developer", "admin"]), 43 | agentController.deleteAgentByName 44 | ); 45 | 46 | module.exports = router; 47 | -------------------------------------------------------------------------------- /controllers/authController.js: -------------------------------------------------------------------------------- 1 | const passport = require("passport"); 2 | const User = require("../models/user"); 3 | 4 | async function registerUser(req, res) { 5 | console.log(req.body); 6 | let newUser; 7 | const { username, password, display_name } = req.body; 8 | if (req.body.role) { 9 | newUser = new User({ 10 | username: username, 11 | password: password, 12 | display_name: display_name, 13 | role: req.body.role, 14 | }); 15 | } else { 16 | newUser = new User({ 17 | username: username, 18 | password: password, 19 | display_name: display_name, 20 | }); 21 | } 22 | 23 | User.register(newUser, password, (err, user) => { 24 | if (err) { 25 | return res.status(400).json({ error: err.message }); 26 | } 27 | passport.authenticate("local")(req, res, () => { 28 | res.status(201).json({ message: "Registration successful" }); 29 | }); 30 | }); 31 | } 32 | 33 | async function getCurrentUser(req, res) { 34 | // Check if the user is authenticated 35 | if (req.isAuthenticated()) { 36 | // The authenticated user's information is available in req.user 37 | const currentUser = req.user; 38 | res.json(currentUser); 39 | } else { 40 | // If the user is not authenticated, return an error or an appropriate response 41 | res.status(401).json({ message: "Not authenticated" }); 42 | } 43 | } 44 | 45 | module.exports = { 46 | registerUser, 47 | getCurrentUser, 48 | }; 49 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const session = require("express-session"); 3 | const uniqueIdentifier = require("./services/uniqueIdentifier"); 4 | const passport = require("passport"); 5 | const app = express(); 6 | const cors = require("cors"); 7 | app.use(express.json()); 8 | app.use(cors({ origin: true })); 9 | 10 | require("dotenv").config(); 11 | 12 | // Initialize Passport.js and session middleware 13 | app.use( 14 | session({ 15 | secret: uniqueIdentifier.generateSecretKey(32), 16 | resave: false, 17 | saveUninitialized: false, 18 | }) 19 | ); 20 | app.use(passport.initialize()); 21 | app.use(passport.session()); 22 | 23 | // Include the Passport local configuration 24 | require("./middleware/passport-local"); 25 | 26 | // Import route files 27 | const agentRoutes = require("./routes/agent"); 28 | const userRoutes = require("./routes/user"); 29 | const conversationRoutes = require("./routes/conversation"); 30 | const chatRoutes = require("./routes/chat"); 31 | const authRoutes = require("./routes/auth"); 32 | 33 | // Mount routers onto specific paths 34 | app.use("/v1/agent", agentRoutes); 35 | app.use("/v1/user", userRoutes); 36 | app.use("/v1/conversation", conversationRoutes); 37 | app.use("/v1/chat", chatRoutes); 38 | app.use("/v1/auth", authRoutes); 39 | 40 | // Start the server 41 | const PORT = process.env.PORT || 3000; 42 | const HOST = process.env.HOST; 43 | app.listen(PORT, HOST, () => { 44 | console.log(`Server is running on port ${PORT}`); 45 | }); 46 | -------------------------------------------------------------------------------- /routes/conversation.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const conversationController = require("../controllers/conversationController"); 4 | const { ensureAuthenticated, checkRole } = require("../middleware/auth"); 5 | 6 | // GET /v1/conversation 7 | router.get( 8 | "/", 9 | ensureAuthenticated, 10 | checkRole(["developer", "admin"]), 11 | conversationController.getAllConversations 12 | ); 13 | 14 | // DELETE /v1/conversation 15 | router.delete( 16 | "/", 17 | ensureAuthenticated, 18 | checkRole(["developer", "admin"]), 19 | conversationController.deleteAllConversations 20 | ); 21 | 22 | // GET /v1/conversation/:username 23 | router.get( 24 | "/:username", 25 | ensureAuthenticated, 26 | checkRole(["user", "developer", "admin"]), 27 | conversationController.getUsersConversations 28 | ); 29 | 30 | // DELETE /v1/conversation/:username 31 | router.delete( 32 | "/:username", 33 | ensureAuthenticated, 34 | checkRole(["user", "developer", "admin"]), 35 | conversationController.deleteUsersConversations 36 | ); 37 | 38 | // GET /v1/conversation/:username/:agent_name 39 | router.get( 40 | "/:username/:agent_name", 41 | ensureAuthenticated, 42 | checkRole(["user", "developer", "admin"]), 43 | conversationController.getSpecificConversation 44 | ); 45 | 46 | // DELETE /v1/conversation/:username/:agent_name 47 | router.delete( 48 | "/:username/:agent_name", 49 | ensureAuthenticated, 50 | checkRole(["user", "developer", "admin"]), 51 | conversationController.deleteSpecificConversation 52 | ); 53 | 54 | module.exports = router; 55 | -------------------------------------------------------------------------------- /controllers/userController.js: -------------------------------------------------------------------------------- 1 | // Import any required modules or models 2 | const User = require("../models/user"); 3 | 4 | // Get all users' information 5 | async function getAllUsers(req, res) { 6 | try { 7 | const users = await User.find(); 8 | if (users.length > 0) { 9 | res.status(200).json(users); 10 | } else { 11 | res.status(404).json({ message: "User(s) not found" }); 12 | } 13 | } catch (error) { 14 | console.error(error); 15 | res.status(500).json({ message: "Internal server error" }); 16 | } 17 | } 18 | 19 | // Delete all users 20 | async function deleteAllUsers(req, res) { 21 | try { 22 | await User.deleteMany({}); // Delete all users in the database 23 | res.status(204).json({ message: "All users deleted successfully" }); 24 | } catch (error) { 25 | console.error(error); 26 | res.status(500).json({ error: "Internal server error" }); 27 | } 28 | } 29 | 30 | // Get specified user's information by username 31 | async function getUserByUsername(req, res) { 32 | const username = req.params.username; 33 | try { 34 | const user = await User.findOne({ username: username }); 35 | if (!user) { 36 | return res.status(404).json({ message: "User not found" }); 37 | } 38 | res.status(200).json(user); 39 | } catch (error) { 40 | console.error(error); 41 | res.status(500).json({ message: "Internal server error" }); 42 | } 43 | } 44 | 45 | async function deleteUserByName(req, res) { 46 | try { 47 | const username = req.params.username; 48 | const deletedUser = await User.findOneAndDelete({ 49 | username: username, 50 | }); 51 | 52 | if (deletedUser) { 53 | res.status(204).json({ message: "User deleted successfully" }); 54 | } else { 55 | res.status(404).json({ message: "User not found" }); 56 | } 57 | } catch (error) { 58 | console.error(error); 59 | res.status(500).json({ error: "Internal server error" }); 60 | } 61 | } 62 | 63 | module.exports = { 64 | getAllUsers, 65 | getUserByUsername, 66 | deleteAllUsers, 67 | deleteUserByName, 68 | }; 69 | -------------------------------------------------------------------------------- /controllers/agentController.js: -------------------------------------------------------------------------------- 1 | // Import any required modules or models 2 | const Agent = require("../models/agent"); 3 | 4 | // Get all agents' information 5 | async function getAllAgents(req, res) { 6 | try { 7 | const agents = await Agent.find(); 8 | if (agents.length > 0) { 9 | res.status(200).json(agents); 10 | } else { 11 | res.status(404).json({ message: "Agent(s) not found" }); 12 | } 13 | } catch (error) { 14 | console.error(error); 15 | res.status(500).json({ message: "Internal server error" }); 16 | } 17 | } 18 | 19 | // Create a new agent 20 | async function createAgent(req, res) { 21 | const { agent_name, description, persona } = req.body; 22 | 23 | try { 24 | const agent = new Agent({ agent_name, description, persona }); 25 | await agent.save(); 26 | res.status(201).json(agent); 27 | } catch (error) { 28 | console.error(error); 29 | res.status(500).json({ message: "Internal server error" }); 30 | } 31 | } 32 | 33 | // Delete all agents 34 | async function deleteAllAgents(req, res) { 35 | try { 36 | await Agent.deleteMany({}); // Delete all agents in the database 37 | res.status(204).json({ message: "All agents deleted successfully" }); 38 | } catch (error) { 39 | console.error(error); 40 | res.status(500).json({ error: "Internal server error" }); 41 | } 42 | } 43 | 44 | // Get specified agent's information by name 45 | async function getAgentByName(req, res) { 46 | const agentName = req.params.agent_name; 47 | try { 48 | const agent = await Agent.findOne({ agent_name: agentName }); 49 | if (!agent) { 50 | return res.status(404).json({ message: "Agent not found" }); 51 | } 52 | res.status(200).json(agent); 53 | } catch (error) { 54 | console.error(error); 55 | res.status(500).json({ message: "Internal server error" }); 56 | } 57 | } 58 | 59 | async function deleteAgentByName(req, res) { 60 | try { 61 | const agentName = req.params.agent_name; 62 | const deletedAgent = await Agent.findOneAndDelete({ 63 | agent_name: agentName, 64 | }); 65 | 66 | if (deletedAgent) { 67 | res.status(204).json({ message: "Agent deleted successfully" }); 68 | } else { 69 | res.status(404).json({ message: "Agent not found" }); 70 | } 71 | } catch (error) { 72 | console.error(error); 73 | res.status(500).json({ error: "Internal server error" }); 74 | } 75 | } 76 | 77 | module.exports = { 78 | getAllAgents, 79 | getAgentByName, 80 | createAgent, 81 | deleteAllAgents, 82 | deleteAgentByName, 83 | }; 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | -------------------------------------------------------------------------------- /controllers/conversationController.js: -------------------------------------------------------------------------------- 1 | // Import any required modules or models 2 | const Conversation = require("../models/conversation"); 3 | 4 | // Get all conversations 5 | async function getAllConversations(req, res) { 6 | try { 7 | const conversations = await Conversation.find(); 8 | if (conversations.length > 0) { 9 | res.status(200).json(conversations); 10 | } else { 11 | return res.status(404).json({ message: "No conversations found" }); 12 | } 13 | } catch (error) { 14 | console.error(error); 15 | res.status(500).json({ message: "Internal server error" }); 16 | } 17 | } 18 | 19 | // Delete all conversations 20 | async function deleteAllConversations(req, res) { 21 | try { 22 | await Conversation.deleteMany({}); 23 | res.status(204).json({ message: "All conversations deleted successfully" }); 24 | } catch (error) { 25 | console.error(error); 26 | res.status(500).json({ error: "Internal server error" }); 27 | } 28 | } 29 | 30 | // Get all of a user's conversations 31 | async function getUsersConversations(req, res) { 32 | const username = req.params.username; 33 | try { 34 | const conversations = await Conversation.find({ 35 | username: username, 36 | }); 37 | if (conversations.length > 0) { 38 | res.status(200).json(conversations); 39 | } else { 40 | return res.status(404).json({ message: "No conversations found" }); 41 | } 42 | } catch (error) { 43 | console.error(error); 44 | res.status(500).json({ message: "Internal server error" }); 45 | } 46 | } 47 | 48 | async function deleteUsersConversations(req, res) { 49 | const username = req.params.username; 50 | try { 51 | const deletedConversations = await Conversation.deleteMany({ 52 | username: username, 53 | }); 54 | if (!deletedConversations) { 55 | return res.status(404).json({ message: "No conversations found" }); 56 | } 57 | res.status(204).json({ message: "Conversations successfully deleted" }); 58 | } catch (error) { 59 | console.error(error); 60 | res.status(500).json({ message: "Internal server error" }); 61 | } 62 | } 63 | 64 | // Get the entire conversation between a user and an agent 65 | async function getSpecificConversation(req, res) { 66 | const username = req.params.username; 67 | const agentName = req.params.agent_name; 68 | try { 69 | const conversation = await Conversation.findOne({ 70 | username: username, 71 | agent_name: agentName, 72 | }); 73 | if (!conversation || conversation.messages.length === 0) { 74 | return res.status(404).json({ message: "Conversation not found" }); 75 | } 76 | res.status(200).json(conversation); 77 | } catch (error) { 78 | console.error(error); 79 | res.status(500).json({ message: "Internal server error" }); 80 | } 81 | } 82 | 83 | async function deleteSpecificConversation(req, res) { 84 | const username = req.params.username; 85 | const agentName = req.params.agent_name; 86 | try { 87 | const deletedConversation = await Conversation.findOneAndDelete({ 88 | username: username, 89 | agent_name: agentName, 90 | }); 91 | if (!deletedConversation) { 92 | return res.status(404).json({ message: "Conversation not found" }); 93 | } 94 | res.status(204).json({ message: "Conversation successfully deleted" }); 95 | } catch (error) { 96 | console.error(error); 97 | res.status(500).json({ message: "Internal server error" }); 98 | } 99 | } 100 | 101 | // Implement other conversation-related controller functions as needed 102 | 103 | module.exports = { 104 | getAllConversations, 105 | deleteAllConversations, 106 | getUsersConversations, 107 | deleteUsersConversations, 108 | getSpecificConversation, 109 | deleteSpecificConversation, 110 | }; 111 | -------------------------------------------------------------------------------- /services/chatService.js: -------------------------------------------------------------------------------- 1 | // chatController.js 2 | const { Configuration, OpenAIApi } = require("openai"); 3 | const Response = require("../models/response"); 4 | const Conversation = require("../models/conversation"); 5 | const Agent = require("../models/agent"); 6 | 7 | // Generate a response using OpenAI's GPT-3 model 8 | async function generateResponse(username, agent_name, message) { 9 | try { 10 | const configuration = new Configuration({ 11 | apiKey: process.env.OPENAI_API_KEY, 12 | }); 13 | const openai = new OpenAIApi(configuration); 14 | 15 | const agent = await Agent.findOne({ agent_name: agent_name }); 16 | 17 | const userIntro = `You are talking to ${username}. It is currently ${new Date()}.`; 18 | 19 | const conversationContext = `${agent.persona}\n${userIntro}`; 20 | 21 | const conversationHistory = []; 22 | 23 | conversationHistory.push({ 24 | role: "system", 25 | content: conversationContext, 26 | }); 27 | 28 | // Fetch conversation history and add previous 5 interactions 29 | let conversation = await Conversation.findOne({ 30 | username: username, 31 | agent_name: agent_name, 32 | }); 33 | 34 | if (conversation) { 35 | const messageLimit = 5; 36 | let messageThread = conversation.messages; 37 | if (messageThread.length >= messageLimit) { 38 | messageThread = messageThread.slice(-messageLimit); 39 | } 40 | messageThread.forEach((message) => { 41 | conversationHistory.push({ 42 | role: "user", 43 | content: message.initial_message, 44 | }); 45 | 46 | conversationHistory.push({ 47 | role: "assistant", 48 | content: message.message_reply, 49 | }); 50 | }); 51 | } else { 52 | conversation = new Conversation({ 53 | username: username, 54 | agent_name: agent_name, 55 | }); 56 | } 57 | 58 | conversationHistory.push({ 59 | role: "user", 60 | content: message, 61 | }); 62 | 63 | return new Promise((resolve, reject) => { 64 | openai 65 | .createChatCompletion({ 66 | model: agent.model, 67 | messages: conversationHistory, 68 | max_tokens: 100, 69 | }) 70 | .then((response) => { 71 | // Validate the message fits the agent's personality 72 | openai 73 | .createChatCompletion({ 74 | model: agent.model, 75 | messages: [ 76 | { 77 | role: "user", 78 | content: `Message:"""${response.data.choices[0].message.content}""" Rewrite this message. Give it a friendly, casual, low-key vibe. Remove any cringe. Remove excess enthusiasm. Remove any emojis. Make the entire message lowercase. Shorten the message if possible.`, 79 | }, 80 | ], 81 | }) 82 | .then((response) => { 83 | // Save the response to the database 84 | const newResponse = new Response({ 85 | username: username, 86 | agent_name: agent_name, 87 | initial_message: message, 88 | message_reply: response.data.choices[0].message.content, 89 | }); 90 | console.log(newResponse); 91 | 92 | conversation.messages.push(newResponse); 93 | conversation.save().catch((err) => { 94 | console.error("Error updating conversation:", err); 95 | reject(err); 96 | }); 97 | 98 | newResponse.save().then((savedResponse) => { 99 | resolve(savedResponse); 100 | }); 101 | }); 102 | }); 103 | }); 104 | } catch (err) { 105 | console.error("Error generating chat response:", err); 106 | throw err; 107 | } 108 | } 109 | 110 | module.exports = { 111 | generateResponse, 112 | }; 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **PersonaTalk API** - Note: This repository is deprecated and has evolved into SyntheticSoulAPI. Navigate to that repository. 2 | 3 | PersonaTalk is a Node.js and Express.js-based API that enables users to interact with various digital personas using OpenAI's GPT model. It offers endpoints for creating and managing agents and users, retrieving agent information, conversation history, and generating responses using conversation history. 4 | 5 | ## **Table of Contents** 6 | 7 | - **[Installation](#installation)** 8 | - **[Usage](#usage)** 9 | - **[Endpoints](#endpoints)** 10 | - **[Environment Variables](#environment-variables)** 11 | - **[Contributing](#contributing)** 12 | - **[License](#license)** 13 | 14 | ## **Installation** 15 | 16 | 1. Clone this repository: 17 | 18 | ``` 19 | git clone https://github.com/chris-cozy/PersonaTalk.git 20 | cd PersonaTalk 21 | ``` 22 | 23 | 2. Install the dependencies: 24 | 25 | ``` 26 | npm install 27 | ``` 28 | 29 | 3. Set up your environment variables using a **`.env`** and fill in the required variables. 30 | 4. Start the server: 31 | 32 | ``` 33 | npm start 34 | ``` 35 | 36 | ## **Usage** 37 | 38 | Once the server is running, you can interact with the API using your preferred API client (e.g., Postman, cURL). Refer to the **[Endpoints](#endpoints)** section for details on available API routes. 39 | 40 | ## **Configuration** 41 | 42 | The configuration for the API can be found in the **`config`** directory. Adjust the settings in these files to tailor the API behavior according to your needs. 43 | 44 | ## **Endpoints** 45 | 46 | ### **Agents** 47 | 48 | - **GET /v1/agent**: Get all agents' information. 49 | - **POST /v1/agent**: Create a new agent. 50 | - **DELETE /v1/agent**: Delete all agents' information. 51 | 52 | - **GET /v1/agent/:agent_name**: Get specified agent's information. 53 | - **DELETE /v1/agent/:agent_name**: Delete specified agent. 54 | 55 | ### **Users** 56 | 57 | - **GET /v1/user**: Get all users' information. 58 | - **DELETE /v1/user**: Delete all users' information. 59 | 60 | - **GET /v1/user/:username**: Get specified user's information. 61 | - **DELETE /v1/user/:username**: Delete specified user. 62 | 63 | ### **Conversations** 64 | 65 | - **GET /v1/conversation**: Get all conversations 66 | - **DELETE /v1/conversation**: Delete all conversations 67 | 68 | - **GET /v1/conversation/:username**: Get all conversations for the specified user 69 | - **DELETE /v1/conversation/:username**: Delete all conversations for the specified user 70 | 71 | - **GET /v1/conversation/:username/:agent_name**: Get conversation between specified user and agent 72 | - **DELETE /v1/conversation/:username/:agent_name**: Delete conversation between specified user and agent 73 | 74 | ### **Chatting** 75 | 76 | - **POST /v1/chat/completion**: Create a response for the given message using conversation history. 77 | 78 | ### **Authentication** 79 | 80 | - **POST /v1/auth/register**: Register a new user of the application 81 | - **POST /v1/auth/login**: Login as a user of the application 82 | - **GET /v1/auth/logout**: Logout as a user of the application 83 | - **GET /v1/auth/current**: Get the currently authenticated user of the application 84 | 85 | For detailed information on request and response formats, refer to the **API Specification**. 86 | 87 | ## **Database** 88 | 89 | PersonaTalk uses MongoDB to store conversation history and response data. Refer to the database config files and models documentation for details on the database schema and interaction. 90 | 91 | ## **Environment Variables** 92 | 93 | The API requires certain environment variables to be set for proper functionality. Refer to the **`.env.example`** file for a list of required variables. 94 | 95 | ## **Contributing** 96 | 97 | Contributions to PersonaTalk are welcome! Feel free to open issues and submit pull requests. 98 | 99 | 1. Fork the repository. 100 | 2. Create a new branch for your feature: **`git checkout -b feature-name`** 101 | 3. Make your changes and commit: **`git commit -m 'Add some feature'`** 102 | 4. Push to the branch: **`git push origin feature-name`** 103 | 5. Submit a pull request. 104 | 105 | ## **License** 106 | 107 | This project is licensed under the **[MIT License](https://opensource.org/license/mit/)**. 108 | -------------------------------------------------------------------------------- /spec/openapi.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: PersonaTalk 4 | description: The backend API for communicating with digital personas 5 | version: 1.0.0 6 | 7 | paths: 8 | /v1/agent: 9 | get: 10 | tags: 11 | - Agent 12 | summary: Get all agents' information 13 | responses: 14 | "200": 15 | description: HTTP 200 OK - Successfully returned agents' information 16 | content: 17 | application/json: 18 | schema: 19 | type: array 20 | items: 21 | $ref: "#/components/schemas/Agent" 22 | "401": 23 | $ref: "#/components/responses/401UnauthorizedError" 24 | "404": 25 | $ref: "#/components/responses/404AgentError" 26 | "500": 27 | $ref: "#/components/responses/500Error" 28 | 29 | post: 30 | tags: 31 | - Agent 32 | summary: Create a new agent 33 | requestBody: 34 | required: true 35 | content: 36 | application/json: 37 | schema: 38 | $ref: "#/components/schemas/Agent" 39 | responses: 40 | "201": 41 | description: HTTP 201 Created - Agent created successfully 42 | content: 43 | application/json: 44 | schema: 45 | $ref: "#/components/schemas/Agent" 46 | "401": 47 | $ref: "#/components/responses/401UnauthorizedError" 48 | "500": 49 | $ref: "#/components/responses/500Error" 50 | 51 | delete: 52 | tags: 53 | - Agent 54 | summary: Delete all agents 55 | responses: 56 | "204": 57 | $ref: "#/components/responses/204Success" 58 | "401": 59 | $ref: "#/components/responses/401UnauthorizedError" 60 | "500": 61 | $ref: "#/components/responses/500Error" 62 | 63 | /v1/agent/{agent_name}: 64 | get: 65 | tags: 66 | - Agent 67 | summary: Get specified agent's information 68 | parameters: 69 | - name: agent_name 70 | in: path 71 | required: true 72 | schema: 73 | type: string 74 | responses: 75 | "200": 76 | description: HTTP 200 OK - Successfully returned agent information 77 | content: 78 | application/json: 79 | schema: 80 | $ref: "#/components/schemas/Agent" 81 | "401": 82 | $ref: "#/components/responses/401UnauthorizedError" 83 | "404": 84 | $ref: "#/components/responses/404AgentError" 85 | "500": 86 | $ref: "#/components/responses/500Error" 87 | 88 | delete: 89 | tags: 90 | - Agent 91 | summary: Delete specified agent 92 | parameters: 93 | - name: agent_name 94 | in: path 95 | required: true 96 | schema: 97 | type: string 98 | responses: 99 | "204": 100 | $ref: "#/components/responses/204Success" 101 | "401": 102 | $ref: "#/components/responses/401UnauthorizedError" 103 | "404": 104 | $ref: "#/components/responses/404AgentError" 105 | "500": 106 | $ref: "#/components/responses/500Error" 107 | 108 | /v1/user: 109 | get: 110 | tags: 111 | - User 112 | summary: Get all users' information 113 | responses: 114 | "200": 115 | description: HTTP 200 - Successfully returned users' information 116 | content: 117 | application/json: 118 | schema: 119 | type: array 120 | items: 121 | $ref: "#/components/schemas/User" 122 | "404": 123 | $ref: "#/components/responses/404UserError" 124 | "401": 125 | $ref: "#/components/responses/401UnauthorizedError" 126 | "500": 127 | $ref: "#/components/responses/500Error" 128 | 129 | delete: 130 | tags: 131 | - User 132 | summary: Delete all users 133 | responses: 134 | "204": 135 | $ref: "#/components/responses/204Success" 136 | "401": 137 | $ref: "#/components/responses/401UnauthorizedError" 138 | "500": 139 | $ref: "#/components/responses/500Error" 140 | 141 | /v1/user/{username}: 142 | get: 143 | tags: 144 | - Agent 145 | summary: Get specified user's information 146 | parameters: 147 | - name: username 148 | in: path 149 | required: true 150 | schema: 151 | type: string 152 | responses: 153 | "200": 154 | description: HTTP 200 - Successfully returned user information 155 | content: 156 | application/json: 157 | schema: 158 | $ref: "#/components/schemas/User" 159 | "404": 160 | $ref: "#/components/responses/404UserError" 161 | "401": 162 | $ref: "#/components/responses/401UnauthorizedError" 163 | "500": 164 | $ref: "#/components/responses/500Error" 165 | 166 | delete: 167 | tags: 168 | - User 169 | summary: Delete specified user 170 | parameters: 171 | - name: username 172 | in: path 173 | required: true 174 | schema: 175 | type: string 176 | responses: 177 | "204": 178 | $ref: "#/components/responses/204Success" 179 | "404": 180 | $ref: "#/components/responses/404UserError" 181 | "401": 182 | $ref: "#/components/responses/401UnauthorizedError" 183 | "500": 184 | $ref: "#/components/responses/500Error" 185 | 186 | /v1/conversation: 187 | get: 188 | tags: 189 | - Conversation 190 | summary: Get all conversations 191 | responses: 192 | "200": 193 | description: HTTP 200 OK - Successfully returned all conversations 194 | content: 195 | application/json: 196 | schema: 197 | type: array 198 | items: 199 | $ref: "#/components/schemas/Conversation" 200 | "404": 201 | $ref: "#/components/responses/404ConversationError" 202 | "401": 203 | $ref: "#/components/responses/401UnauthorizedError" 204 | "500": 205 | $ref: "#/components/responses/500Error" 206 | 207 | delete: 208 | tags: 209 | - Conversation 210 | summary: Delete all conversations 211 | responses: 212 | "204": 213 | $ref: "#/components/responses/204Success" 214 | "401": 215 | $ref: "#/components/responses/401UnauthorizedError" 216 | "500": 217 | $ref: "#/components/responses/500Error" 218 | 219 | /v1/conversation/{username}: 220 | get: 221 | tags: 222 | - Conversation 223 | summary: Get all conversation for the specified user 224 | parameters: 225 | - name: username 226 | in: path 227 | required: true 228 | schema: 229 | type: string 230 | responses: 231 | "200": 232 | description: HTTP 200 OK - Successfully returned all user's conversations 233 | content: 234 | application/json: 235 | schema: 236 | type: array 237 | items: 238 | $ref: "#/components/schemas/Conversation" 239 | "404": 240 | $ref: "#/components/responses/404ConversationError" 241 | "401": 242 | $ref: "#/components/responses/401UnauthorizedError" 243 | "500": 244 | $ref: "#/components/responses/500Error" 245 | 246 | delete: 247 | tags: 248 | - Conversation 249 | summary: Delete all conversations for the specified user 250 | parameters: 251 | - name: username 252 | in: path 253 | required: true 254 | schema: 255 | type: string 256 | responses: 257 | "204": 258 | $ref: "#/components/responses/204Success" 259 | "404": 260 | $ref: "#/components/responses/404ConversationError" 261 | "401": 262 | $ref: "#/components/responses/401UnauthorizedError" 263 | "500": 264 | $ref: "#/components/responses/500Error" 265 | 266 | /v1/conversation/{username}/{agent_name}: 267 | get: 268 | tags: 269 | - Conversation 270 | summary: Get conversation between the specified user and agent 271 | parameters: 272 | - name: username 273 | in: path 274 | required: true 275 | schema: 276 | type: string 277 | - name: agent_name 278 | in: path 279 | required: true 280 | schema: 281 | type: string 282 | responses: 283 | "200": 284 | description: HTTP 200 OK - Successfully returned specified conversation 285 | content: 286 | application/json: 287 | schema: 288 | $ref: "#/components/schemas/Conversation" 289 | "404": 290 | $ref: "#/components/responses/404ConversationError" 291 | "401": 292 | $ref: "#/components/responses/401UnauthorizedError" 293 | "500": 294 | $ref: "#/components/responses/500Error" 295 | 296 | delete: 297 | tags: 298 | - Conversation 299 | summary: Delete specified conversation 300 | parameters: 301 | - name: username 302 | in: path 303 | required: true 304 | schema: 305 | type: string 306 | - name: agent_name 307 | in: path 308 | required: true 309 | schema: 310 | type: string 311 | responses: 312 | "204": 313 | $ref: "#/components/responses/204Success" 314 | "404": 315 | $ref: "#/components/responses/404ConversationError" 316 | "401": 317 | $ref: "#/components/responses/401UnauthorizedError" 318 | "500": 319 | $ref: "#/components/responses/500Error" 320 | 321 | /v1/chat/completion: 322 | post: 323 | tags: 324 | - Chat 325 | summary: Create a response for the given message using conversation history 326 | requestBody: 327 | content: 328 | application/json: 329 | schema: 330 | $ref: "#/components/schemas/Message" 331 | responses: 332 | "200": 333 | description: HTTP 200 OK - Response generated successfully 334 | content: 335 | application/json: 336 | schema: 337 | $ref: "#/components/schemas/Response" 338 | "404": 339 | $ref: "#/components/responses/404Error" 340 | "401": 341 | $ref: "#/components/responses/401UnauthorizedError" 342 | "500": 343 | $ref: "#/components/responses/500Error" 344 | 345 | /v1/auth/register: 346 | post: 347 | tags: 348 | - Auth 349 | summary: Register a new user 350 | requestBody: 351 | required: true 352 | content: 353 | application/json: 354 | schema: 355 | $ref: "#/components/schemas/User" 356 | responses: 357 | "201": 358 | description: HTTP 201 - User registered successfully 359 | content: 360 | application/json: 361 | schema: 362 | $ref: "#/components/schemas/User" 363 | "500": 364 | $ref: "#/components/responses/500Error" 365 | 366 | /v1/auth/login: 367 | post: 368 | tags: 369 | - Auth 370 | summary: Log in an existing user 371 | requestBody: 372 | required: true 373 | content: 374 | application/json: 375 | schema: 376 | type: object 377 | properties: 378 | username: 379 | type: string 380 | password: 381 | type: string 382 | responses: 383 | "200": 384 | description: HTTP 200 OK - User logged in successfully 385 | content: 386 | application/json: 387 | schema: 388 | $ref: "#/components/schemas/User" 389 | "500": 390 | $ref: "#/components/responses/500Error" 391 | 392 | /v1/auth/logout: 393 | get: 394 | tags: 395 | - Auth 396 | summary: Log out the current user 397 | responses: 398 | "204": 399 | $ref: "#/components/responses/204Success" 400 | "401": 401 | $ref: "#/components/responses/401UnauthorizedError" 402 | "500": 403 | $ref: "#/components/responses/500Error" 404 | 405 | /v1/auth/current: 406 | get: 407 | tags: 408 | - Auth 409 | summary: Reply with the currently authenticated user 410 | responses: 411 | "200": 412 | description: HTTP 200 OK - Currently authenticated user returned successfully 413 | content: 414 | application/json: 415 | schema: 416 | $ref: "#/components/schemas/User" 417 | "500": 418 | $ref: "#/components/responses/500Error" 419 | 420 | components: 421 | schemas: 422 | Agent: 423 | type: object 424 | properties: 425 | agent_name: 426 | type: string 427 | description: 428 | type: string 429 | persona: 430 | type: string 431 | model: 432 | type: string 433 | 434 | User: 435 | type: object 436 | properties: 437 | username: 438 | type: string 439 | password: 440 | type: string 441 | display_name: 442 | type: string 443 | role: 444 | type: string 445 | 446 | Message: 447 | type: object 448 | properties: 449 | username: 450 | type: string 451 | agent_name: 452 | type: string 453 | message: 454 | type: string 455 | 456 | Response: 457 | type: object 458 | properties: 459 | response_id: 460 | type: integer 461 | username: 462 | type: string 463 | agent_name: 464 | type: string 465 | initial_message: 466 | type: string 467 | message_reply: 468 | type: string 469 | timestamp: 470 | type: string 471 | format: date-time 472 | 473 | Conversation: 474 | type: object 475 | properties: 476 | conversation_id: 477 | type: integer 478 | username: 479 | type: string 480 | agent_name: 481 | type: string 482 | messages: 483 | type: array 484 | items: 485 | $ref: "#/components/schemas/Response" 486 | 487 | responses: 488 | 204Success: 489 | description: HTTP 204 - No content to return 490 | content: 491 | application/json: 492 | schema: 493 | type: object 494 | properties: 495 | message: 496 | type: string 497 | 498 | 400Error: 499 | description: HTTP 400 - Invalid request 500 | content: 501 | application/json: 502 | schema: 503 | type: object 504 | properties: 505 | message: 506 | type: string 507 | 508 | 404Error: 509 | description: HTTP 404 - Parameter not found 510 | content: 511 | application/json: 512 | schema: 513 | type: object 514 | properties: 515 | message: 516 | type: string 517 | 518 | 404UserError: 519 | description: HTTP 404 - User(s) not found 520 | content: 521 | application/json: 522 | schema: 523 | type: object 524 | properties: 525 | message: 526 | type: string 527 | 528 | 404AgentError: 529 | description: HTTP 404 - Agent(s) not found 530 | content: 531 | application/json: 532 | schema: 533 | type: object 534 | properties: 535 | message: 536 | type: string 537 | 538 | 404ConversationError: 539 | description: HTTP 404 - Conversation(s) not found 540 | content: 541 | application/json: 542 | schema: 543 | type: object 544 | properties: 545 | message: 546 | type: string 547 | 548 | 401UnauthorizedError: 549 | description: HTTP 401 - Unauthorized to access resource 550 | content: 551 | application/json: 552 | schema: 553 | type: object 554 | properties: 555 | message: 556 | type: string 557 | 558 | 403Error: 559 | description: HTTP 403 - Forbidden to access resource 560 | content: 561 | application/json: 562 | schema: 563 | type: object 564 | properties: 565 | message: 566 | type: string 567 | 568 | 500Error: 569 | description: HTTP 500 - Internal server error 570 | content: 571 | application/json: 572 | schema: 573 | type: object 574 | properties: 575 | message: 576 | type: string 577 | 578 | x-rate-limits: 579 | description: Rate limiting is applied to prevent abuse of the API. Requests beyond the rate limit will receive a '429 Too Many Requests' response. 580 | headers: 581 | X-RateLimit-Limit: 582 | description: The maximum number of requests allowed within the rate limit window. 583 | X-RateLimit-Remaining: 584 | description: The number of remaining requests within the current rate limit window. 585 | X-RateLimit-Reset: 586 | description: The time at which the rate limit window will reset. 587 | global: 588 | rateLimit: 10 589 | rateLimitPeriod: minute 590 | 591 | tags: 592 | - name: Agent 593 | description: Operations related to the agent 594 | - name: User 595 | description: Operations related to the user 596 | - name: Conversation 597 | description: Operations related to conversation 598 | - name: Chat 599 | description: Operations related to communicating with user 600 | --------------------------------------------------------------------------------