Camel AGI first code commit
This commit is contained in:
286
server/agent_convo.py
Normal file
286
server/agent_convo.py
Normal file
@@ -0,0 +1,286 @@
|
||||
from database import *
|
||||
import urllib.parse
|
||||
from flask import jsonify,request,session,render_template,redirect,url_for,Blueprint
|
||||
from requests_oauthlib import OAuth2Session
|
||||
from flask_login import login_required, login_user, current_user, logout_user
|
||||
import secrets
|
||||
from datetime import datetime, date, timedelta, timezone
|
||||
import os, pickle, codecs
|
||||
from typing import List
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.prompts.chat import (
|
||||
SystemMessagePromptTemplate,
|
||||
HumanMessagePromptTemplate,
|
||||
)
|
||||
from langchain.schema import (
|
||||
AIMessage,
|
||||
HumanMessage,
|
||||
SystemMessage,
|
||||
BaseMessage,
|
||||
)
|
||||
|
||||
authorization_base_url = "https://accounts.google.com/o/oauth2/v2/auth"
|
||||
scope = [
|
||||
"https://www.googleapis.com/auth/userinfo.email",
|
||||
"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"openid"
|
||||
]
|
||||
google_client_id = os.environ['google_client_id']
|
||||
google_client_secret = os.environ['google_client_secret']
|
||||
word_limit = 50 # word limit for task brainstorming
|
||||
|
||||
rp = Blueprint('rp', __name__)
|
||||
|
||||
|
||||
@rp.route("/rp/isLoggedIn", methods=['GET'])
|
||||
def rp_isLoggedIn():
|
||||
url_host = urllib.parse.urlsplit(request.url).hostname
|
||||
if "5000" in request.url:
|
||||
redirect_uri = "http://"+url_host+":5000/rp/google_callback"
|
||||
else:
|
||||
redirect_uri = "https://"+url_host+"/rp/google_callback"
|
||||
google = OAuth2Session(
|
||||
google_client_id, scope=scope, redirect_uri=redirect_uri)
|
||||
login_url, state = google.authorization_url(authorization_base_url)
|
||||
session['oauth_state'] = google_client_id
|
||||
if current_user.is_authenticated:
|
||||
if current_user.openai_key == "" or current_user.openai_key == None:
|
||||
keyAdded = None
|
||||
else:
|
||||
keyAdded = current_user.openai_key
|
||||
return jsonify(isLoggedIn=current_user.is_authenticated,userId=current_user.id,key_added=keyAdded,image=current_user.profile_image)
|
||||
else:
|
||||
return jsonify(isLoggedIn=False,auth_url=login_url)
|
||||
|
||||
@rp.route("/rp/google_callback", methods=['GET'])
|
||||
def rp_google_callback():
|
||||
url_host = urllib.parse.urlsplit(request.url).hostname
|
||||
if "5000" in request.url:
|
||||
redirect_uri = "http://"+url_host+":5000/rp/google_callback"
|
||||
else:
|
||||
redirect_uri = "https://"+url_host+"/rp/google_callback"
|
||||
google = OAuth2Session(
|
||||
google_client_id, scope=scope, redirect_uri=redirect_uri)
|
||||
token_url = "https://www.googleapis.com/oauth2/v4/token"
|
||||
welcome = False
|
||||
try:
|
||||
google.fetch_token(token_url, client_secret=google_client_secret,
|
||||
authorization_response=request.url)
|
||||
except:
|
||||
pass
|
||||
response = google.get(
|
||||
'https://www.googleapis.com/oauth2/v1/userinfo').json()
|
||||
email = response["email"].lower()
|
||||
googleId = str(response["id"])
|
||||
name = response["name"]
|
||||
image = response["picture"]
|
||||
getAdmin = Admin.query.filter_by(email=email).first()
|
||||
if getAdmin == None:
|
||||
getAdmin = Admin(id=secrets.token_urlsafe(24), email=email,google_id=googleId, name=name,profile_image=image, created_date=datetime.now())
|
||||
db.session.add(getAdmin)
|
||||
db.session.commit()
|
||||
else:
|
||||
getAdmin.google_id = googleId
|
||||
getAdmin.profile_image = image
|
||||
db.session.commit()
|
||||
login_user(getAdmin, remember=True)
|
||||
return redirect("http://localhost:3000/")
|
||||
|
||||
class CAMELAgent:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
system_message,
|
||||
model: ChatOpenAI,
|
||||
store
|
||||
) -> None:
|
||||
self.model = model
|
||||
if store == None:
|
||||
self.system_message = system_message
|
||||
self.init_messages()
|
||||
# print("NEW")
|
||||
else:
|
||||
self.stored_messages = store
|
||||
self.system_message = store[0]
|
||||
# print("MESSAGES \n",self.stored_messages,"\n SYSTEM MESSAGE \n",self.system_message)
|
||||
|
||||
def reset(self) -> None:
|
||||
self.init_messages()
|
||||
return self.stored_messages
|
||||
|
||||
def init_messages(self) -> None:
|
||||
self.stored_messages = [self.system_message]
|
||||
# for msg in self.stored_messages:
|
||||
# print("INTIALIZED",msg.content,"\n")
|
||||
|
||||
def update_messages(self, message: BaseMessage) -> List[BaseMessage]:
|
||||
self.stored_messages.append(message)
|
||||
# for msg in self.stored_messages:
|
||||
# print("UPDATED",msg.content,"\n")
|
||||
return self.stored_messages
|
||||
|
||||
def step(
|
||||
self,
|
||||
input_message: HumanMessage,
|
||||
) -> AIMessage:
|
||||
messages = self.update_messages(input_message)
|
||||
output_message = self.model(messages)
|
||||
self.update_messages(output_message)
|
||||
|
||||
return output_message
|
||||
|
||||
def store_messages(self) -> None:
|
||||
return self.stored_messages
|
||||
|
||||
|
||||
|
||||
|
||||
def starting_convo(assistant_role_name,user_role_name,task):
|
||||
task_specifier_sys_msg = SystemMessage(content="You can make a task more specific.")
|
||||
task_specifier_prompt = (
|
||||
"""Here is a task that {assistant_role_name} will help {user_role_name} to complete: {task}.
|
||||
Please make it more specific. Be creative and imaginative.
|
||||
Please reply with the specified task in {word_limit} words or less. Do not add anything else."""
|
||||
)
|
||||
task_specifier_template = HumanMessagePromptTemplate.from_template(template=task_specifier_prompt)
|
||||
task_specify_agent = CAMELAgent(task_specifier_sys_msg, ChatOpenAI(temperature=1.0),None)
|
||||
task_specifier_msg = task_specifier_template.format_messages(assistant_role_name=assistant_role_name,
|
||||
user_role_name=user_role_name,
|
||||
task=task, word_limit=word_limit)[0]
|
||||
specified_task_msg = task_specify_agent.step(task_specifier_msg)
|
||||
# print(f"Specified task: {specified_task_msg.content}")
|
||||
specified_task = specified_task_msg.content
|
||||
|
||||
assistant_inception_prompt = (
|
||||
"""Never forget you are a {assistant_role_name} and I am a {user_role_name}. Never flip roles! Never instruct me!
|
||||
We share a common interest in collaborating to successfully complete a task.
|
||||
You must help me to complete the task.
|
||||
Here is the task: {task}. Never forget our task!
|
||||
I must instruct you based on your expertise and my needs to complete the task.
|
||||
|
||||
I must give you one instruction at a time.
|
||||
You must write a specific solution that appropriately completes the requested instruction.
|
||||
You must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons.
|
||||
Do not add anything else other than your solution to my instruction.
|
||||
You are never supposed to ask me any questions you only answer questions.
|
||||
You are never supposed to reply with a flake solution. Explain your solutions.
|
||||
Your solution must be declarative sentences and simple present tense.
|
||||
Unless I say the task is completed, you should always start with:
|
||||
|
||||
Solution: <YOUR_SOLUTION>
|
||||
|
||||
<YOUR_SOLUTION> should be specific and provide preferable implementations and examples for task-solving.
|
||||
Always end <YOUR_SOLUTION> with: Next request."""
|
||||
)
|
||||
|
||||
user_inception_prompt = (
|
||||
"""Never forget you are a {user_role_name} and I am a {assistant_role_name}. Never flip roles! You will always instruct me.
|
||||
We share a common interest in collaborating to successfully complete a task.
|
||||
I must help you to complete the task.
|
||||
Here is the task: {task}. Never forget our task!
|
||||
You must instruct me based on my expertise and your needs to complete the task ONLY in the following two ways:
|
||||
|
||||
1. Instruct with a necessary input:
|
||||
Instruction: <YOUR_INSTRUCTION>
|
||||
Input: <YOUR_INPUT>
|
||||
|
||||
2. Instruct without any input:
|
||||
Instruction: <YOUR_INSTRUCTION>
|
||||
Input: None
|
||||
|
||||
The "Instruction" describes a task or question. The paired "Input" provides further context or information for the requested "Instruction".
|
||||
|
||||
You must give me one instruction at a time.
|
||||
I must write a response that appropriately completes the requested instruction.
|
||||
I must decline your instruction honestly if I cannot perform the instruction due to physical, moral, legal reasons or my capability and explain the reasons.
|
||||
You should instruct me not ask me questions.
|
||||
Now you must start to instruct me using the two ways described above.
|
||||
Do not add anything else other than your instruction and the optional corresponding input!
|
||||
Keep giving me instructions and necessary inputs until you think the task is completed.
|
||||
When the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.
|
||||
Never say <CAMEL_TASK_DONE> unless my responses have solved your task."""
|
||||
)
|
||||
return specified_task,assistant_inception_prompt,user_inception_prompt
|
||||
|
||||
def get_sys_msgs(assistant_role_name: str, user_role_name: str, task: str,assistant_inception_prompt,user_inception_prompt):
|
||||
|
||||
assistant_sys_template = SystemMessagePromptTemplate.from_template(template=assistant_inception_prompt)
|
||||
assistant_sys_msg = assistant_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task)[0]
|
||||
|
||||
user_sys_template = SystemMessagePromptTemplate.from_template(template=user_inception_prompt)
|
||||
user_sys_msg = user_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task)[0]
|
||||
|
||||
return assistant_sys_msg, user_sys_msg
|
||||
|
||||
@rp.route("/rp/start", methods=['POST'])
|
||||
def start_rp():
|
||||
if not current_user.is_authenticated:
|
||||
return redirect("/agent_convo")
|
||||
os.environ["OPENAI_API_KEY"] = current_user.openai_key
|
||||
assistant_role_name = request.json["role1"]
|
||||
user_role_name = request.json["role2"]
|
||||
task = request.json["task"]
|
||||
sessId = request.json["sessId"]
|
||||
if sessId == 0:
|
||||
getSession = Agent_Session(role_1=assistant_role_name,role_2=user_role_name,task=task,admin_id=current_user.id)
|
||||
db.session.add(getSession)
|
||||
db.session.commit()
|
||||
specified_task,assistant_inception_prompt,user_inception_prompt = starting_convo(assistant_role_name, user_role_name, task)
|
||||
assistant_sys_msg, user_sys_msg = get_sys_msgs(assistant_role_name, user_role_name, specified_task,assistant_inception_prompt,user_inception_prompt)
|
||||
assistant_agent = CAMELAgent(assistant_sys_msg, ChatOpenAI(temperature=0.2),None)
|
||||
user_agent = CAMELAgent(user_sys_msg, ChatOpenAI(temperature=0.2),None)
|
||||
# Reset agents
|
||||
assistant_agent.reset()
|
||||
user_agent.reset()
|
||||
|
||||
# Initialize chats
|
||||
assistant_msg = HumanMessage(
|
||||
content=(f"{user_sys_msg.content}. "
|
||||
"Now start to give me introductions one by one. "
|
||||
"Only reply with Instruction and Input."))
|
||||
|
||||
user_msg = HumanMessage(content=f"{assistant_sys_msg.content}")
|
||||
user_msg = assistant_agent.step(user_msg)
|
||||
else:
|
||||
getSession = Agent_Session.query.filter_by(id=sessId).first()
|
||||
user_store = pickle.loads(codecs.decode((getSession.user_store).encode(), "base64"))
|
||||
assistant_store = pickle.loads(codecs.decode((getSession.assistant_store).encode(), "base64"))
|
||||
user_agent = CAMELAgent(None, ChatOpenAI(temperature=0.2),user_store)
|
||||
assistant_agent = CAMELAgent(None, ChatOpenAI(temperature=0.2),assistant_store)
|
||||
assistant_msg = HumanMessage(
|
||||
content=(f"{assistant_store[-1].content}"))
|
||||
|
||||
# chat_turn_limit, n = 10, 0
|
||||
# while n < chat_turn_limit:
|
||||
# n += 1
|
||||
user_ai_msg = user_agent.step(assistant_msg)
|
||||
user_msg = HumanMessage(content=user_ai_msg.content)
|
||||
userMsg = user_msg.content.replace("Instruction: ","").replace("Input: None","").replace("Input: None.","")
|
||||
# print(f"AI User ({user_role_name}):\n\n{user_msg.content}\n\n")
|
||||
assistant_ai_msg = assistant_agent.step(user_msg)
|
||||
assistant_msg = HumanMessage(content=assistant_ai_msg.content)
|
||||
assistantMsg = assistant_msg.content.replace("Solution: ","").replace("Next request.","")
|
||||
# print(f"AI Assistant ({assistant_role_name}):\n\n{assistant_msg.content}\n\n")
|
||||
convoEnd = False
|
||||
if "<CAMEL_TASK_DONE>" in user_msg.content:
|
||||
convoEnd = True
|
||||
getUserStore = user_agent.store_messages()
|
||||
getSession.user_store = codecs.encode(pickle.dumps(getUserStore), "base64").decode()
|
||||
getAssistantStore = assistant_agent.store_messages()
|
||||
getSession.assistant_store = codecs.encode(pickle.dumps(getAssistantStore), "base64").decode()
|
||||
db.session.commit()
|
||||
return jsonify(sessId=getSession.id,userMsg=userMsg,assistantMsg=assistantMsg,convoEnd=convoEnd)
|
||||
|
||||
|
||||
@rp.route("/rp/get_chat", methods=['get'])
|
||||
def rp_get_chat():
|
||||
sessId = request.args.get('sessId')
|
||||
getSession = Agent_Session.query.filter_by(id=sessId).first()
|
||||
assistant_store = pickle.loads(codecs.decode((getSession.assistant_store).encode(), "base64"))
|
||||
messages = []
|
||||
for store in assistant_store[2:]:
|
||||
if str(type(store)) == "<class 'langchain.schema.HumanMessage'>":
|
||||
messages.append({"role":0,"msg":store.content.replace("Instruction: ","").replace("Input: None","").replace("Input: None.","")})
|
||||
elif str(type(store)) == "<class 'langchain.schema.AIMessage'>":
|
||||
messages.append({"role":1,"msg":store.content.replace("Solution: ","").replace("Next request.","")})
|
||||
return jsonify(role1=getSession.role_1,role2=getSession.role_2,task=getSession.task,messages=messages)
|
||||
43
server/database.py
Normal file
43
server/database.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import DateTime, ForeignKey, MetaData
|
||||
from flask_login import UserMixin
|
||||
|
||||
from flask import Flask
|
||||
|
||||
convention = {
|
||||
"ix": 'ix_%(column_0_label)s',
|
||||
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
||||
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
||||
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
||||
"pk": "pk_%(table_name)s"
|
||||
}
|
||||
|
||||
metadata = MetaData(naming_convention=convention)
|
||||
db = SQLAlchemy(metadata=metadata)
|
||||
app = Flask(__name__)
|
||||
|
||||
class Agent_Session(db.Model):
|
||||
__tablename__ = "agent_session"
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
role_1 = db.Column(db.String(200), default="", server_default = "")
|
||||
role_2 = db.Column(db.String(200), default="", server_default = "")
|
||||
task = db.Column(db.String(3000), default="", server_default = "")
|
||||
user_store = db.Column(db.String, default="", server_default = "")
|
||||
assistant_store = db.Column(db.String, default="", server_default = "")
|
||||
admin_id = db.Column(db.String(100), ForeignKey("admin.id"), index=True)
|
||||
|
||||
class Admin(UserMixin,db.Model):
|
||||
__tablename__ = "admin"
|
||||
id = db.Column(db.String(100), primary_key=True)
|
||||
name = db.Column(db.String(100))
|
||||
email = db.Column(db.String(100), unique=True, index=True)
|
||||
google_id = db.Column(db.String(100))
|
||||
openai_key = db.Column(db.String(100))
|
||||
profile_image = db.Column(db.String(100000))
|
||||
password = db.Column(db.String(100))
|
||||
created_date = db.Column(DateTime)
|
||||
gpt_model = db.Column(db.String, default="gpt-3.5-turbo", server_default="gpt-3.5-turbo")
|
||||
agent_sessions = db.relationship('Agent_Session', backref='admin',
|
||||
cascade="all,delete", lazy='dynamic')
|
||||
def get_id(self):
|
||||
return (self.id)
|
||||
0
server/requirements.txt
Normal file
0
server/requirements.txt
Normal file
66
server/webserver.py
Normal file
66
server/webserver.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from flask import Flask
|
||||
from flask_migrate import Migrate
|
||||
from database import *
|
||||
import os
|
||||
import urllib.parse
|
||||
from flask import jsonify,request,session,render_template,redirect,url_for,Blueprint
|
||||
from requests_oauthlib import OAuth2Session
|
||||
from flask_login import UserMixin, LoginManager, login_required, login_user, current_user, logout_user
|
||||
import secrets
|
||||
from datetime import datetime, date, timedelta, timezone
|
||||
import os
|
||||
import json
|
||||
import random
|
||||
import requests
|
||||
from agent_convo import rp
|
||||
|
||||
try:
|
||||
import config
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
app.register_blueprint(rp)
|
||||
app.secret_key = 'autogptsamurai@123'
|
||||
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///./test.db'
|
||||
db.init_app(app)
|
||||
db.app = app
|
||||
migrate = Migrate(app, db, compare_type=True,
|
||||
render_as_batch=True)
|
||||
|
||||
login_manager = LoginManager(app)
|
||||
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return Admin.query.filter_by(id=user_id).first()
|
||||
|
||||
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
|
||||
|
||||
@app.route("/change_model", methods=['POST'])
|
||||
def change_model():
|
||||
model = request.values["model"]
|
||||
current_user.gpt_model = model
|
||||
db.session.commit()
|
||||
return "Success"
|
||||
|
||||
@app.route("/logout", methods=['GET'])
|
||||
def logout():
|
||||
logout_user()
|
||||
return "Success", 200
|
||||
|
||||
@app.route("/store_key", methods=['POST'])
|
||||
def store_key():
|
||||
key = request.json['key']
|
||||
getAdmin = Admin.query.filter_by(id=current_user.id).first()
|
||||
if len(key) == 51:
|
||||
getAdmin.openai_key = key
|
||||
db.session.commit()
|
||||
return jsonify(True)
|
||||
else:
|
||||
return jsonify(False), 400
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="0.0.0.0", debug=True)
|
||||
Reference in New Issue
Block a user