├── LICENSE
├── README.md
├── client
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.js
│ ├── App.test.js
│ ├── assets
│ ├── camelagi.png
│ ├── discord.svg
│ ├── google.svg
│ ├── key.svg
│ ├── logout-white.svg
│ ├── question-mark.svg
│ ├── reload.svg
│ ├── send.svg
│ ├── share-white.svg
│ ├── user-1.svg
│ ├── user-2.svg
│ ├── user-3.svg
│ ├── user-4.svg
│ └── user.png
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── pages
│ ├── AgentConvo.js
│ └── AgentConvoShare.js
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ └── styles
│ ├── agent-convo.css
│ └── home.css
├── server
├── agent_convo.py
├── database.py
├── requirements.txt
└── webserver.py
└── steps_to_run.md
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 SamurAIGPT
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Camel-AutoGPT
2 |
3 | You must have seen how powerful AI agents are with AutoGPT/BabyAGI ⚡️
4 |
5 | Imagine 2 of these agents interacting on a common goal🤯
6 |
7 | Camel AutoGPT allows you to configure and deploy communicating Autonomous AI agents. Name your own custom AI characters and have them embark on any goal imaginable 🚀.
8 |
9 | ### 🎉 Roadmap
10 |
11 | * Share agents conversation 🔗
12 |
13 | * Saving agent runs 💾
14 |
15 | * Prefixed instructor/assistant examples 🧠
16 |
17 | * Web browsing capabilities 🌐
18 |
19 | * Writing capabilities via a document API 📄
20 |
21 | * More Coming soon...
22 |
23 | ### Getting Started
24 |
25 | Code is up, ⭐ (Star) the repo to receive updates
26 |
27 | Follow [Anil Chandra Naidu Matcha](https://twitter.com/matchaman11) & [Ankur Singh](https://twitter.com/ankur_maker) on twitter for updates
28 |
29 | ### How to run ?
30 |
31 | Follow steps from here https://github.com/SamurAIGPT/Camel-AutoGPT/blob/main/steps_to_run.md
32 |
33 | ### References
34 |
35 | https://github.com/lightaime/camel
36 |
37 | ### Demo link
38 |
39 | https://camelagi.thesamur.ai/
40 |
41 | ### Support
42 |
43 | Join our discord https://discord.gg/A6EzvsKX4u to get support
44 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "autogpt",
3 | "version": "0.1.0",
4 | "private": true,
5 | "proxy": "http://localhost:5000",
6 | "dependencies": {
7 | "@reduxjs/toolkit": "^1.9.0",
8 | "@testing-library/jest-dom": "^5.16.5",
9 | "@testing-library/react": "^13.4.0",
10 | "@testing-library/user-event": "^13.5.0",
11 | "axios": "^1.2.0",
12 | "bootstrap": "^5.2.3",
13 | "react": "^18.2.0",
14 | "react-bootstrap": "^2.6.0",
15 | "react-dom": "^18.2.0",
16 | "react-markdown": "^8.0.5",
17 | "react-redux": "^8.0.5",
18 | "react-router-dom": "^6.4.3",
19 | "react-scripts": "5.0.1",
20 | "react-toastify": "^9.1.1",
21 | "remark-gfm": "^3.0.1",
22 | "web-vitals": "^2.1.4"
23 | },
24 | "scripts": {
25 | "start": "react-scripts start",
26 | "build": "react-scripts build",
27 | "test": "react-scripts test",
28 | "eject": "react-scripts eject"
29 | },
30 | "eslintConfig": {
31 | "extends": [
32 | "react-app",
33 | "react-app/jest"
34 | ]
35 | },
36 | "browserslist": {
37 | "production": [
38 | ">0.2%",
39 | "not dead",
40 | "not op_mini all"
41 | ],
42 | "development": [
43 | "last 1 chrome version",
44 | "last 1 firefox version",
45 | "last 1 safari version"
46 | ]
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamurAIGPT/GPT-Agent/bbcd4adf887897396a7c021784e7a67dc557a567/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
31 | AutoGPT
32 |
33 |
34 |
35 |
36 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamurAIGPT/GPT-Agent/bbcd4adf887897396a7c021784e7a67dc557a567/client/public/logo192.png
--------------------------------------------------------------------------------
/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamurAIGPT/GPT-Agent/bbcd4adf887897396a7c021784e7a67dc557a567/client/public/logo512.png
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/client/src/App.js:
--------------------------------------------------------------------------------
1 | import './styles/home.css';
2 | import { BrowserRouter, Route, Routes,Navigate } from 'react-router-dom';
3 | import AgentConvo from './pages/AgentConvo';
4 | import AgentConvoShare from './pages/AgentConvoShare';
5 |
6 |
7 | function App() {
8 | return (
9 |
10 |
11 |
12 | }/>
13 | }/>
14 |
15 |
16 |
17 | );
18 | }
19 |
20 | export default App;
21 |
--------------------------------------------------------------------------------
/client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/client/src/assets/camelagi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamurAIGPT/GPT-Agent/bbcd4adf887897396a7c021784e7a67dc557a567/client/src/assets/camelagi.png
--------------------------------------------------------------------------------
/client/src/assets/discord.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/google.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/client/src/assets/key.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/client/src/assets/logout-white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/question-mark.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/client/src/assets/reload.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/client/src/assets/send.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/share-white.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/client/src/assets/user-1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/user-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/user-3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/user-4.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SamurAIGPT/GPT-Agent/bbcd4adf887897396a7c021784e7a67dc557a567/client/src/assets/user.png
--------------------------------------------------------------------------------
/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 | import "bootstrap/dist/css/bootstrap.min.css";
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 | root.render(
10 |
11 |
12 |
13 | );
14 |
15 | // If you want to start measuring performance in your app, pass a function
16 | // to log results (for example: reportWebVitals(console.log))
17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
18 | reportWebVitals();
19 |
--------------------------------------------------------------------------------
/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/pages/AgentConvo.js:
--------------------------------------------------------------------------------
1 | import {useState,useEffect,useRef} from 'react';
2 | import '../styles/agent-convo.css'
3 | import { Button, Stack, Image, Form, Row, Col, Spinner, InputGroup,FormControl, Modal } from "react-bootstrap";
4 | import { ReactComponent as ReloadIcon } from "../assets/reload.svg";
5 | import { ReactComponent as KeyIcon } from "../assets/key.svg";
6 | import { ReactComponent as LogoutIcon } from "../assets/logout-white.svg";
7 | import { ReactComponent as Bot1Icon } from "../assets/user-1.svg";
8 | import { ReactComponent as Bot2Icon } from "../assets/user-2.svg";
9 | import { ReactComponent as Bot3Icon } from "../assets/user-3.svg";
10 | import { ReactComponent as Bot4Icon } from "../assets/user-4.svg";
11 | import logoImage from '../assets/camelagi.png'
12 | import {ReactComponent as SendIcon} from '../assets/send.svg'
13 | import { ToastContainer, toast } from 'react-toastify';
14 | import {ReactComponent as GoogleIcon} from '../assets/google.svg'
15 | import { ReactComponent as DiscordIcon } from "../assets/discord.svg";
16 | import axios from "axios"
17 | import ReactMarkdown from 'react-markdown'
18 | import remarkGfm from 'remark-gfm'
19 | import { ReactComponent as ShareIcon } from "../assets/share-white.svg";
20 |
21 |
22 | function AgentConvo() {
23 | const [isLoggedIn,setIsLoggedIn] = useState(false);
24 | const [authUrl,setAuthUrl] = useState("")
25 | const [ranUser1, setRanUser1] = useState(null);
26 | const [ranUser2, setRanUser2] = useState(null);
27 | const [started, setStarted] = useState(false);
28 | const [key, setKey] = useState("");
29 | const [task, setTask] = useState("");
30 | const [finished, setFinished] = useState(false);
31 | const [keyAdded, setKeyAdded] = useState(false);
32 | const [user, setUser] = useState(false);
33 | const [role1, setRole1] = useState("");
34 | const [role2, setRole2] = useState("");
35 | const [chat,setChat] = useState([])
36 | const [sessId,setSessId] = useState(0)
37 | const [showBanner, setShowBanner] = useState(false);
38 | const [turn,setTurn] = useState(0)
39 | const sessionRef = useRef(null)
40 | sessionRef.current = sessId
41 | const chatRef = useRef(null)
42 | chatRef.current = chat
43 | const turnRef = useRef(null)
44 | turnRef.current = turn
45 |
46 | let fetchMessages = () => {
47 | setChat([...chatRef.current,{role:0,msg:null}])
48 |
49 | axios.post("/rp/start",{role1:role1,role2:role2,task:task,sessId:sessionRef.current}).then((res)=>{
50 | setSessId(res.data.sessId)
51 | if(res.data.convoEnd==true){
52 | setFinished((prev)=>true)
53 | }else{
54 | chatRef.current.at(-1).msg = res.data.userMsg
55 | setChat([...chatRef.current,{role:1,msg:null}])
56 | setTimeout(() => {
57 | chatRef.current.at(-1).msg = res.data.assistantMsg;
58 | setTurn((prev)=>prev+1)
59 | startDiscussion(false)
60 | }, 3000);
61 | // setUpdate((prev)=>!prev)
62 |
63 | }
64 |
65 | })
66 | .catch((err)=>{
67 | toast("Failed to respond " + err.response.data);
68 | })
69 | }
70 |
71 | let startDiscussion = (newTurn) => {
72 | let getTurn = turnRef.current
73 | if(newTurn==true){
74 | getTurn = 0
75 | setTurn((prev)=>0)
76 | setStarted((prev)=>true)
77 | }
78 |
79 | if(getTurn<2){
80 | fetchMessages()
81 | }
82 | }
83 |
84 | const addKey = () => {
85 | axios.post("/store_key",{key:key}).then((res)=>{
86 | setKeyAdded(true)
87 | }).catch((err)=>{
88 | toast("Key cannot be verified, try again");
89 | })
90 | }
91 |
92 | const logout = () => {
93 | axios.get("/heybot/logout").then((res)=>{
94 | window.location.reload();
95 | }).catch((err)=>{
96 | console.log(err)
97 | })
98 | }
99 |
100 | const shareChat = () => {
101 | navigator.clipboard.writeText(window.location.host+'/conversation/share?session='+sessionRef.current)
102 | window.open('/conversation/share?session='+sessionRef.current, "_blank");
103 | }
104 |
105 | useEffect(() => {
106 | setRanUser1(Math.random())
107 | setRanUser2(Math.random())
108 | axios.get("/rp/isLoggedIn").then((res)=>{
109 | setIsLoggedIn(res.data.isLoggedIn)
110 | if(res.data.isLoggedIn == false){
111 | setAuthUrl(res.data.auth_url)
112 | }else{
113 | setUser({id:res.data.userId,image:res.data.image})
114 | if(res.data.key_added==null){
115 | setKeyAdded((prev)=>false)
116 | }else{
117 | setKeyAdded((prev)=>true)
118 | setKey(res.data.key_added)
119 | }
120 |
121 | }
122 | }).catch((err)=>{
123 | console.log(err)
124 | })
125 |
126 | window.setTimeout(()=>setShowBanner(true),30000)
127 | },[])
128 | useEffect(() => {
129 | if(document.querySelector('.end-chat')!=null){document.querySelector('.end-chat').scrollIntoView({ behavior: 'smooth', block: 'end' });}
130 | }, [chat])
131 |
132 | return (
133 | <>
134 |
135 |
136 |
137 |
CamelAGI
138 | {isLoggedIn&&
139 | window.location.reload()} className="icon"/>
140 | {setKeyAdded(false)} className="icon"/>}
141 |
142 |
}
143 |
144 | {isLoggedIn?
145 |
146 | {keyAdded?
147 | <>
148 | {started?
149 | <>
150 |
151 | {chatRef.current.length>0&&chatRef.current.map((message)=>
152 | message.role==0?
153 |
154 | {ranUser1!=null&&ranUser1>0.5?
:
}
155 |
156 |
157 | {message.msg==null?
158 |
159 |
160 |
161 |
162 | :
163 |
}
164 |
165 |
{role1}
166 |
167 |
:
168 |
169 |
170 |
171 | {message.msg==null?
172 |
173 |
174 |
175 |
176 | :
177 |
}
178 |
179 |
{role2}
180 |
181 | {ranUser2!=null&&ranUser2>0.5?
:
}
182 |
183 | )}
184 | {sessionRef.current!=0&&}
185 |
186 |
187 | {finished?
188 | Task Completed!
189 | :
190 | <>
191 | {turnRef.current<3?
192 |
193 | :}
194 | >}
195 | >
196 | :
197 | <>
198 | Get started with a task to discuss
199 |
200 | Enter Role of the Instructor
201 | setRole1(e.target.value)}/>
202 |
203 |
204 | Enter Role of the Assistant
205 | setRole2(e.target.value)}/>
206 |
207 |
208 | Enter topic of discussion
209 | setTask(e.target.value)}/>
210 |
211 |
212 | >
213 |
214 | }
215 | >:
216 |
217 | Add your OpenAI Key
218 | Get your OpenAI Key by signing up/ logging in from the OpenAI Dashboard. Go to Dashboard
219 |
220 | setKey(e.target.value)}
224 | onKeyDown={(e)=>{e.code=="Enter"&&addKey()}}
225 | />
226 |
229 |
230 | Watch this video to get started
231 |
232 |
233 | }
234 | :
235 |
236 |
237 | {/* Login to agi
*/}
238 | Accomplish your task with AI agents
239 |
240 |
241 | {/* navigate('/agi/faq')}> Know More */}
242 |
243 | }
244 |
245 |
246 |
setShowBanner(false)}>
247 |
248 | setShowBanner(false)} className="position-absolute top-0 end-0 me-4 mt-2">X
249 |
250 |
251 | Join Our Discord
252 | Star CamelAGI on Github
253 |
254 |
255 |
256 |
257 | >
258 | )
259 |
260 | }
261 |
262 | export default AgentConvo;
--------------------------------------------------------------------------------
/client/src/pages/AgentConvoShare.js:
--------------------------------------------------------------------------------
1 | import {useState,useEffect,useRef} from 'react';
2 | import '../styles/agent-convo.css'
3 | import { Button, Stack, Image, Form,Modal, Spinner, } from "react-bootstrap";
4 | import { ReactComponent as Bot1Icon } from "../assets/user-1.svg";
5 | import { ReactComponent as Bot2Icon } from "../assets/user-2.svg";
6 | import { ReactComponent as Bot3Icon } from "../assets/user-3.svg";
7 | import { ReactComponent as Bot4Icon } from "../assets/user-4.svg";
8 | import logoImage from '../assets/camelagi.png'
9 | import { useNavigate } from "react-router-dom";
10 | import { ToastContainer, toast } from 'react-toastify';
11 | import axios from "axios"
12 | import ReactMarkdown from 'react-markdown'
13 | import remarkGfm from 'remark-gfm'
14 | import { ReactComponent as ShareIcon } from "../assets/share-white.svg";
15 | import { useSearchParams, useParams } from "react-router-dom";
16 |
17 |
18 | function AgentConvoShare() {
19 |
20 | const [ranUser1, setRanUser1] = useState(null);
21 | const [ranUser2, setRanUser2] = useState(null);
22 | const navigate = useNavigate()
23 | const [showBanner, setShowBanner] = useState(false);
24 | const [user, setUser] = useState(false);
25 | const [role1, setRole1] = useState("");
26 | const [role2, setRole2] = useState("");
27 | const [task, setTask] = useState("");
28 | const [chat,setChat] = useState([])
29 | const [sessId,setSessId] = useState(0)
30 | const sessionRef = useRef(null)
31 | sessionRef.current = sessId
32 | const chatRef = useRef(null)
33 | chatRef.current = chat
34 | let [searchParams, setSearchParams] = useSearchParams();
35 |
36 |
37 | useEffect(() => {
38 | setRanUser1(Math.random())
39 | setRanUser2(Math.random())
40 | axios.get("/rp/get_chat?sessId="+searchParams.get("session")).then((res)=>{
41 | setChat(res.data.messages)
42 | setRole1(res.data.role1)
43 | setRole2(res.data.role2)
44 | setTask(res.data.task)
45 |
46 |
47 | }).catch((err)=>{
48 | console.log(err)
49 | })
50 | window.setTimeout(()=>setShowBanner(true),30000)
51 | },[])
52 | // useEffect(() => {
53 | // if(document.querySelector('.end-chat')!=null){document.querySelector('.end-chat').scrollIntoView({ behavior: 'smooth', block: 'end' });}
54 | // }, [chat])
55 |
56 | return (
57 | <>
58 |
59 |
60 |
61 |
CamelAGI
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Check out this conversation between {role1} and {role2} to discuss:
{task}
70 | {chatRef.current.length>0&&chatRef.current.map((message)=>
71 | message.role==0?
72 |
73 | {ranUser1!=null&&ranUser1>0.5?
:
}
74 |
75 |
76 | {message.msg==null?
77 |
78 |
79 |
80 |
81 | :
82 |
}
83 |
84 |
{role1}
85 |
86 |
:
87 |
88 |
89 |
90 | {message.msg==null?
91 |
92 |
93 |
94 |
95 | :
96 |
}
97 |
98 |
{role2}
99 |
100 | {ranUser2!=null&&ranUser2>0.5?
:
}
101 |
102 | )}
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
setShowBanner(false)}>
112 |
113 | setShowBanner(false)} className="position-absolute top-0 end-0 me-4 mt-2">X
114 |
115 |
116 |
117 |
118 |
119 |
120 | >
121 | )
122 |
123 | }
124 |
125 | export default AgentConvoShare;
--------------------------------------------------------------------------------
/client/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/client/src/styles/agent-convo.css:
--------------------------------------------------------------------------------
1 | .agent-convo-container{
2 | background: #eee;
3 | }
4 | .agent-convo-box{
5 | border-radius: 12px;
6 | background: #2b2d2f;
7 | box-shadow: 10px 10px 40px #2b2d2f;
8 | height: 80%;
9 | width: 60%;
10 | }
11 | .agent-msg-data{
12 | color: #fff !important;
13 | background-color: transparent !important;
14 | font-family: var(--fontFamily) !important;
15 | white-space: break-spaces;
16 | font-size: 1rem !important;
17 | margin: 0 !important;
18 | overflow: hidden;
19 | padding: 0 !important;
20 | }
21 |
22 | .bubble {
23 | --r: 12px;
24 | --t: 10px;
25 |
26 | padding: calc(2*var(--r)/3);
27 | -webkit-mask:
28 | radial-gradient(var(--t) at var(--_d) 0,#0000 98%,#000 102%)
29 | var(--_d) 100%/calc(100% - var(--r)) var(--t) no-repeat,
30 | conic-gradient(at var(--r) var(--r),#000 75%,#0000 0)
31 | calc(var(--r)/-2) calc(var(--r)/-2) padding-box,
32 | radial-gradient(50% 50%,#000 98%,#0000 101%)
33 | 0 0/var(--r) var(--r) space padding-box;
34 |
35 | color: #fff;
36 | }
37 | .agent-1-chat {
38 | --_d: 0%;
39 | border-left: var(--t) solid #0000;
40 | margin-right: var(--t);
41 | box-shadow: 10px 10px 40px #2b2d2f;
42 | background: var(--themeColor) border-box;
43 | }
44 | .agent-2-chat {
45 | --_d: 100%;
46 | border-right: var(--t) solid #0000;
47 | margin-left: var(--t);
48 | box-shadow: 10px 10px 40px #2b2d2f;
49 | background: #3f65f9 border-box;
50 | }
51 | .agent-chat-icon{
52 | min-width: 2.5rem;
53 | min-height: 2.5rem;
54 | max-width: 2.5rem;
55 | max-height: 2.5rem;
56 |
57 | }
58 | .continue-button{
59 | background-color: #eee !important;
60 | color: #000 !important;
61 | border: none !important;
62 | border-radius: 12px !important;
63 | /* font-size: 12px !important; */
64 | font-weight: 800 !important;
65 | }
66 | .agent-input{
67 | background-color: transparent !important;
68 | color: #fff !important;
69 | border-top: none !important;
70 | border-left: none !important;
71 | border-right: none !important;
72 | }
73 | .agent-scroll{
74 | overflow-y: scroll;
75 | scrollbar-width: thin;
76 | }
77 | .agent-scroll::-webkit-scrollbar {
78 | width: 0;
79 | }
80 | .scroll-container{
81 | height: 90% !important;
82 | }
83 | .agent-msg-container>pre{
84 | max-width: 30rem;
85 | }
86 | .key-video-agent{
87 | width: 60%;
88 | min-height: 14rem;
89 | border-radius: 12px;
90 | }
91 | .role-name{
92 | opacity: 60%;
93 | font-size: 12px;
94 | }
95 | .role1-container{
96 | animation: role1msg 0.3s ease-out 0s forwards;
97 |
98 | }
99 | .role2-container{
100 | animation: role2msg 0.3s ease-out 0s forwards;
101 |
102 | }
103 | @keyframes role1msg {
104 | 0% {
105 | margin-left: -2rem;
106 | opacity: 0;
107 | }
108 | 80% {
109 | transform: scale(1.1);
110 | }
111 | 100% {
112 | transform: scale(1);
113 | opacity: 1;
114 | }
115 | }
116 | .agent-share-btn{
117 | opacity: 0.8;
118 | background: transparent !important;
119 | border: 1px solid white !important;
120 | padding: 0.2rem 0.4rem !important;
121 | font-size: 12px !important;
122 | }
123 | @keyframes role1msg {
124 | 0% {
125 | margin-right: -2rem;
126 | opacity: 0;
127 | }
128 | 80% {
129 | transform: scale(1.1);
130 | }
131 | 100% {
132 | transform: scale(1);
133 | opacity: 1;
134 | }
135 | }
136 | @media screen and (max-width:1000px){
137 | .agent-convo-box{
138 | height: 100%;
139 | width: 100%;
140 | border-radius: 0;
141 | }
142 | .agent-msg-container>pre{
143 | max-width: 20rem;
144 | }
145 | }
146 |
147 | .logo{
148 | width: 4rem;
149 | }
--------------------------------------------------------------------------------
/client/src/styles/home.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700;800&display=swap");
2 | :root {
3 |
4 | --hoverColor: rgb(71, 24, 182) !important ;
5 | --fontFamily: "Nunito", sans-serif;
6 | --border: 1px solid #dfdfdf;
7 | --themeColor: #763FF9;
8 |
9 | }
10 |
11 | .powered-by{
12 | background-color: #F6F3FF;
13 | border-radius: 22px 22px 0 0;
14 | opacity: 0.8;
15 | z-index: 99;
16 | position: fixed;
17 | bottom: 0;
18 | right: 1rem;
19 | }
20 | .banner-modal>.modal-dialog>.modal-content{
21 | border-radius: 22px !important;
22 | }
23 | .producthunt-banner{
24 | z-index: 99;
25 | position: fixed;
26 | top: 1.5rem;
27 | right: 1rem;
28 | }
29 |
30 | .powered-by a{
31 | color: black;
32 | font-size: 0.8rem;
33 | }
34 | .discord-invite{
35 | background-color: #5865f2;
36 | color: white;
37 | border-radius: 12px;
38 | text-decoration: none;
39 | }
40 |
41 | .powered-by a:hover{
42 | color: black;
43 | text-decoration: underline !important;
44 | }
45 |
46 | .btn-filled{
47 | background: #763FF9 !important;
48 | box-shadow: 0px 2px 25px #F0EDF9 !important;
49 | border-radius: 12px !important;
50 | border: 1px solid #763FF9 !important;
51 | color: white !important;
52 | }
53 |
54 | .btn-filled:hover{
55 | background: var(--hoverColor) !important;
56 |
57 | }
58 | .side-nav{
59 | width: 13.5rem ;
60 | min-height: 100vh;
61 | background: #FFFFFF;
62 | border-right: 1px solid #DFDFDF;
63 | box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.04);
64 | font-size: 0.75rem;
65 | font-weight: 700;
66 | }
67 | /* .mobile-nav{
68 | font-size: 0.75rem !important;
69 | } */
70 | body,html{
71 | background-color: #ffffff !important;
72 | font-family: var(--fontFamily) !important;
73 | color:#000000 !important;
74 | }
75 | .nav-body,
76 | .nav-header > .accordion-button {
77 | padding:0.5rem 0rem !important;
78 | border:0 !important;
79 | background-color: transparent !important;
80 | color: #000 !important;
81 | font-size: 0.75rem;
82 | font-weight: 700;
83 | }
84 | .os-logo{
85 | width: 3.75rem;
86 | height: 3.75rem;
87 | margin: 2.5rem 0;
88 | }
89 | .os-logo-mobile{
90 | width: 2.5rem;
91 | height: 2.5rem;
92 | }
93 | .offcanvas-backdrop{
94 | width: 100% !important;
95 | height: 100% !important;
96 | }
97 | .nav-icon{
98 | height: 1rem;
99 | width: 1rem;
100 | margin-right: 1.5rem;
101 | }
102 | .side-accordion{
103 | --bs-accordion-bg: transparent !important;
104 | }
105 | .nav-width{
106 | width: 10.5rem;
107 | }
108 | .nav-width>.nav-item{
109 | width: 100%;
110 | }
111 |
112 | .nav-header > .accordion-button::after {
113 | margin-left: auto;
114 |
115 | }
116 | .accordion-button.collapsed::after{
117 | background-size: 1rem;
118 | color: #000 !important;
119 | margin-left: auto;
120 | }
121 | .accordion-button:not(.collapsed) {
122 | box-shadow: none !important;
123 | color: #000 !important;
124 | }
125 | .nav-header > .accordion-button:not(.collapsed)::after {
126 | transform: rotate(-180deg) !important;
127 | background-size: 1rem;
128 | color: #000 !important;
129 | }
130 | .nav-header > .accordion-button:focus {
131 | border: none !important;
132 | box-shadow: none !important;
133 | }
134 |
135 | .side-nav-links >.nav-link.active{
136 | color: #763FF9 !important;
137 | border-radius: 1.875rem;
138 | }
139 |
140 | .side-nav-links >.nav-link{
141 | color: #5F5B66 !important;
142 | padding: 0.375rem 2.5rem;
143 | }
144 |
145 | .side-nav-links > .active{
146 | background-color: #F6F3FF !important;
147 | color: #763FF9 !important;
148 | }
149 |
150 |
151 | .rounded-cards{
152 | box-sizing: border-box;
153 | background: #FFFFFF !important;
154 | border: 1px solid #DFDFDF;
155 | box-shadow: 0px 2px 25px #F0EDF9;
156 | border-radius: 22px;
157 | }
158 |
159 | .top-filters-cards{
160 | height: 2.81rem;
161 | background: #FFFFFF !important;
162 | border: 1px solid #DFDFDF !important;
163 | box-shadow: 0px 2px 25px #F0EDF9 !important;
164 | border-radius: 0.75rem;
165 | color: #000 !important;
166 | font-size: 0.75rem !important;
167 | padding: 0.5rem 0.75rem !important;
168 | }
169 |
170 | .dropdown>.dropdown-toggle::after{
171 | margin-left:20px !important;
172 | }
173 |
174 | .small-text{
175 | font-size: 0.75rem !important ;
176 | }
177 | .content-container{
178 | max-width: 50rem;
179 | }
180 | .number-text{
181 | font-size: 1.5rem !important;
182 | font-weight: 600 !important;
183 | }
184 |
185 | .navbar-toggler:focus{
186 | box-shadow: none;
187 | }
188 | .graph-title{
189 | font-weight: 400;
190 | }
191 | .stats-table{
192 | background: #FFFFFF !important;
193 | border: 1px solid #DFDFDF !important;
194 | }
195 | .stats-table>thead{
196 | background-color: #F2F2F2;
197 | font-size: 0.75rem;
198 | }
199 | .stats-table>thead>tr>th,.stats-table>tbody>tr>td{
200 | padding: 1.5rem;
201 |
202 | }
203 | /* .stats-table tr:first-child th:first-child {
204 | border-top-left-radius: 22px;
205 | }
206 |
207 | .stats-table tr:first-child th:last-child {
208 | border-top-right-radius: 22px;
209 | }
210 | .stats-table tr:last-child td:first-child {
211 | border-bottom-left-radius: 22px;
212 | }
213 |
214 | .stats-table tr:last-child td:last-child {
215 | border-bottom-right-radius: 22px;
216 | } */
217 | @media screen and (max-width:992px){
218 | .main-col{
219 | margin-top: 7rem !important;
220 | }
221 | .nav-header > .accordion-button {
222 | font-size: 1rem;
223 | }
224 | .graph-title{
225 | font-size: 0.9rem;
226 | }
227 | .stats-table>thead>tr>th,.stats-table>tbody>tr>td{
228 | padding: 1rem;
229 |
230 | }
231 | .powered-by{
232 | background-color: #21cd9c;
233 | border-radius: 0 0 12px 12px ;
234 | top: 0;
235 | right: 0;
236 | bottom: auto;
237 | }
238 | }
239 |
240 | @media screen and (min-width:1600px){
241 | .content-container{
242 | max-width: 75rem;
243 | }
244 | }
245 | @media screen and (max-width:500px){
246 | .stats-table>thead>tr>th,.stats-table>tbody>tr>td{
247 | padding: 0.5rem;
248 |
249 | }
250 | }
251 |
252 | .options-bg{
253 | box-sizing: border-box;
254 | background: #FFFFFF !important;
255 | border: 1px solid #DFDFDF !important;
256 | box-shadow: 0px 2px 25px #F0EDF9 !important;
257 | border-radius: 50px !important;
258 | color: #000000 !important;
259 | font-size: 12px !important;
260 | }
261 |
262 | .filter-drop > button{
263 | background-color: white !important;
264 | color: #000 !important;
265 | border: 0px !important;
266 | font-size: 12px !important;
267 | padding-left: 3px !important;
268 | padding-right: 3px !important;
269 | padding-top: 6px !important;
270 | padding-bottom: 6px !important;
271 | }
272 | .filter-drop >.dropdown-toggle::after{
273 | content:none !important;
274 | }
275 |
276 | .filter-drop > .dropdown-menu{
277 | font-size: 12px !important;
278 | min-width: 5rem !important;
279 | border: 1px solid #ececec!important;
280 | box-shadow: 0px 2px 25px #F0EDF9 !important;
281 | }
282 |
283 | .vr{
284 | background-color: #acacac !important;
285 | }
286 |
287 | .icon{
288 | width: 1.3rem ;
289 | height: 1.3rem ;
290 | cursor: pointer ;
291 | }
292 |
--------------------------------------------------------------------------------
/server/agent_convo.py:
--------------------------------------------------------------------------------
1 | from database import *
2 | import urllib.parse
3 | from flask import jsonify,request,session,render_template,redirect,url_for,Blueprint
4 | from requests_oauthlib import OAuth2Session
5 | from flask_login import login_required, login_user, current_user, logout_user
6 | import secrets
7 | from datetime import datetime, date, timedelta, timezone
8 | import os, pickle, codecs
9 | from typing import List
10 | from langchain.chat_models import ChatOpenAI
11 | from langchain.prompts.chat import (
12 | SystemMessagePromptTemplate,
13 | HumanMessagePromptTemplate,
14 | )
15 | from langchain.schema import (
16 | AIMessage,
17 | HumanMessage,
18 | SystemMessage,
19 | BaseMessage,
20 | )
21 |
22 | authorization_base_url = "https://accounts.google.com/o/oauth2/v2/auth"
23 | scope = [
24 | "https://www.googleapis.com/auth/userinfo.email",
25 | "https://www.googleapis.com/auth/userinfo.profile",
26 | "openid"
27 | ]
28 | google_client_id = os.environ['google_client_id']
29 | google_client_secret = os.environ['google_client_secret']
30 | word_limit = 50 # word limit for task brainstorming
31 |
32 | rp = Blueprint('rp', __name__)
33 |
34 |
35 | @rp.route("/rp/isLoggedIn", methods=['GET'])
36 | def rp_isLoggedIn():
37 | url_host = urllib.parse.urlsplit(request.url).hostname
38 | if "5000" in request.url:
39 | redirect_uri = "http://"+url_host+":5000/rp/google_callback"
40 | else:
41 | redirect_uri = "https://"+url_host+"/rp/google_callback"
42 | google = OAuth2Session(
43 | google_client_id, scope=scope, redirect_uri=redirect_uri)
44 | login_url, state = google.authorization_url(authorization_base_url)
45 | session['oauth_state'] = google_client_id
46 | if current_user.is_authenticated:
47 | if current_user.openai_key == "" or current_user.openai_key == None:
48 | keyAdded = None
49 | else:
50 | keyAdded = current_user.openai_key
51 | return jsonify(isLoggedIn=current_user.is_authenticated,userId=current_user.id,key_added=keyAdded,image=current_user.profile_image)
52 | else:
53 | return jsonify(isLoggedIn=False,auth_url=login_url)
54 |
55 | @rp.route("/rp/google_callback", methods=['GET'])
56 | def rp_google_callback():
57 | url_host = urllib.parse.urlsplit(request.url).hostname
58 | if "5000" in request.url:
59 | redirect_uri = "http://"+url_host+":5000/rp/google_callback"
60 | else:
61 | redirect_uri = "https://"+url_host+"/rp/google_callback"
62 | google = OAuth2Session(
63 | google_client_id, scope=scope, redirect_uri=redirect_uri)
64 | token_url = "https://www.googleapis.com/oauth2/v4/token"
65 | welcome = False
66 | try:
67 | google.fetch_token(token_url, client_secret=google_client_secret,
68 | authorization_response=request.url)
69 | except:
70 | pass
71 | response = google.get(
72 | 'https://www.googleapis.com/oauth2/v1/userinfo').json()
73 | email = response["email"].lower()
74 | googleId = str(response["id"])
75 | name = response["name"]
76 | image = response["picture"]
77 | getAdmin = Admin.query.filter_by(email=email).first()
78 | if getAdmin == None:
79 | getAdmin = Admin(id=secrets.token_urlsafe(24), email=email,google_id=googleId, name=name,profile_image=image, created_date=datetime.now())
80 | db.session.add(getAdmin)
81 | db.session.commit()
82 | else:
83 | getAdmin.google_id = googleId
84 | getAdmin.profile_image = image
85 | db.session.commit()
86 | login_user(getAdmin, remember=True)
87 | return redirect("http://localhost:3000/")
88 |
89 | class CAMELAgent:
90 |
91 | def __init__(
92 | self,
93 | system_message,
94 | model: ChatOpenAI,
95 | store
96 | ) -> None:
97 | self.model = model
98 | if store == None:
99 | self.system_message = system_message
100 | self.init_messages()
101 | # print("NEW")
102 | else:
103 | self.stored_messages = store
104 | self.system_message = store[0]
105 | # print("MESSAGES \n",self.stored_messages,"\n SYSTEM MESSAGE \n",self.system_message)
106 |
107 | def reset(self) -> None:
108 | self.init_messages()
109 | return self.stored_messages
110 |
111 | def init_messages(self) -> None:
112 | self.stored_messages = [self.system_message]
113 | # for msg in self.stored_messages:
114 | # print("INTIALIZED",msg.content,"\n")
115 |
116 | def update_messages(self, message: BaseMessage) -> List[BaseMessage]:
117 | self.stored_messages.append(message)
118 | # for msg in self.stored_messages:
119 | # print("UPDATED",msg.content,"\n")
120 | return self.stored_messages
121 |
122 | def step(
123 | self,
124 | input_message: HumanMessage,
125 | ) -> AIMessage:
126 | messages = self.update_messages(input_message)
127 | output_message = self.model(messages)
128 | self.update_messages(output_message)
129 |
130 | return output_message
131 |
132 | def store_messages(self) -> None:
133 | return self.stored_messages
134 |
135 |
136 |
137 |
138 | def starting_convo(assistant_role_name,user_role_name,task):
139 | task_specifier_sys_msg = SystemMessage(content="You can make a task more specific.")
140 | task_specifier_prompt = (
141 | """Here is a task that {assistant_role_name} will help {user_role_name} to complete: {task}.
142 | Please make it more specific. Be creative and imaginative.
143 | Please reply with the specified task in {word_limit} words or less. Do not add anything else."""
144 | )
145 | task_specifier_template = HumanMessagePromptTemplate.from_template(template=task_specifier_prompt)
146 | task_specify_agent = CAMELAgent(task_specifier_sys_msg, ChatOpenAI(temperature=1.0),None)
147 | task_specifier_msg = task_specifier_template.format_messages(assistant_role_name=assistant_role_name,
148 | user_role_name=user_role_name,
149 | task=task, word_limit=word_limit)[0]
150 | specified_task_msg = task_specify_agent.step(task_specifier_msg)
151 | # print(f"Specified task: {specified_task_msg.content}")
152 | specified_task = specified_task_msg.content
153 |
154 | assistant_inception_prompt = (
155 | """Never forget you are a {assistant_role_name} and I am a {user_role_name}. Never flip roles! Never instruct me!
156 | We share a common interest in collaborating to successfully complete a task.
157 | You must help me to complete the task.
158 | Here is the task: {task}. Never forget our task!
159 | I must instruct you based on your expertise and my needs to complete the task.
160 |
161 | I must give you one instruction at a time.
162 | You must write a specific solution that appropriately completes the requested instruction.
163 | 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.
164 | Do not add anything else other than your solution to my instruction.
165 | You are never supposed to ask me any questions you only answer questions.
166 | You are never supposed to reply with a flake solution. Explain your solutions.
167 | Your solution must be declarative sentences and simple present tense.
168 | Unless I say the task is completed, you should always start with:
169 |
170 | Solution:
171 |
172 | should be specific and provide preferable implementations and examples for task-solving.
173 | Always end with: Next request."""
174 | )
175 |
176 | user_inception_prompt = (
177 | """Never forget you are a {user_role_name} and I am a {assistant_role_name}. Never flip roles! You will always instruct me.
178 | We share a common interest in collaborating to successfully complete a task.
179 | I must help you to complete the task.
180 | Here is the task: {task}. Never forget our task!
181 | You must instruct me based on my expertise and your needs to complete the task ONLY in the following two ways:
182 |
183 | 1. Instruct with a necessary input:
184 | Instruction:
185 | Input:
186 |
187 | 2. Instruct without any input:
188 | Instruction:
189 | Input: None
190 |
191 | The "Instruction" describes a task or question. The paired "Input" provides further context or information for the requested "Instruction".
192 |
193 | You must give me one instruction at a time.
194 | I must write a response that appropriately completes the requested instruction.
195 | 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.
196 | You should instruct me not ask me questions.
197 | Now you must start to instruct me using the two ways described above.
198 | Do not add anything else other than your instruction and the optional corresponding input!
199 | Keep giving me instructions and necessary inputs until you think the task is completed.
200 | When the task is completed, you must only reply with a single word .
201 | Never say unless my responses have solved your task."""
202 | )
203 | return specified_task,assistant_inception_prompt,user_inception_prompt
204 |
205 | def get_sys_msgs(assistant_role_name: str, user_role_name: str, task: str,assistant_inception_prompt,user_inception_prompt):
206 |
207 | assistant_sys_template = SystemMessagePromptTemplate.from_template(template=assistant_inception_prompt)
208 | assistant_sys_msg = assistant_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task)[0]
209 |
210 | user_sys_template = SystemMessagePromptTemplate.from_template(template=user_inception_prompt)
211 | user_sys_msg = user_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task)[0]
212 |
213 | return assistant_sys_msg, user_sys_msg
214 |
215 | @rp.route("/rp/start", methods=['POST'])
216 | def start_rp():
217 | if not current_user.is_authenticated:
218 | return redirect("/agent_convo")
219 | os.environ["OPENAI_API_KEY"] = current_user.openai_key
220 | assistant_role_name = request.json["role1"]
221 | user_role_name = request.json["role2"]
222 | task = request.json["task"]
223 | sessId = request.json["sessId"]
224 | if sessId == 0:
225 | getSession = Agent_Session(role_1=assistant_role_name,role_2=user_role_name,task=task,admin_id=current_user.id)
226 | db.session.add(getSession)
227 | db.session.commit()
228 | specified_task,assistant_inception_prompt,user_inception_prompt = starting_convo(assistant_role_name, user_role_name, task)
229 | assistant_sys_msg, user_sys_msg = get_sys_msgs(assistant_role_name, user_role_name, specified_task,assistant_inception_prompt,user_inception_prompt)
230 | assistant_agent = CAMELAgent(assistant_sys_msg, ChatOpenAI(temperature=0.2),None)
231 | user_agent = CAMELAgent(user_sys_msg, ChatOpenAI(temperature=0.2),None)
232 | # Reset agents
233 | assistant_agent.reset()
234 | user_agent.reset()
235 |
236 | # Initialize chats
237 | assistant_msg = HumanMessage(
238 | content=(f"{user_sys_msg.content}. "
239 | "Now start to give me introductions one by one. "
240 | "Only reply with Instruction and Input."))
241 |
242 | user_msg = HumanMessage(content=f"{assistant_sys_msg.content}")
243 | user_msg = assistant_agent.step(user_msg)
244 | else:
245 | getSession = Agent_Session.query.filter_by(id=sessId).first()
246 | user_store = pickle.loads(codecs.decode((getSession.user_store).encode(), "base64"))
247 | assistant_store = pickle.loads(codecs.decode((getSession.assistant_store).encode(), "base64"))
248 | user_agent = CAMELAgent(None, ChatOpenAI(temperature=0.2),user_store)
249 | assistant_agent = CAMELAgent(None, ChatOpenAI(temperature=0.2),assistant_store)
250 | assistant_msg = HumanMessage(
251 | content=(f"{assistant_store[-1].content}"))
252 |
253 | # chat_turn_limit, n = 10, 0
254 | # while n < chat_turn_limit:
255 | # n += 1
256 | user_ai_msg = user_agent.step(assistant_msg)
257 | user_msg = HumanMessage(content=user_ai_msg.content)
258 | userMsg = user_msg.content.replace("Instruction: ","").replace("Input: None","").replace("Input: None.","")
259 | # print(f"AI User ({user_role_name}):\n\n{user_msg.content}\n\n")
260 | assistant_ai_msg = assistant_agent.step(user_msg)
261 | assistant_msg = HumanMessage(content=assistant_ai_msg.content)
262 | assistantMsg = assistant_msg.content.replace("Solution: ","").replace("Next request.","")
263 | # print(f"AI Assistant ({assistant_role_name}):\n\n{assistant_msg.content}\n\n")
264 | convoEnd = False
265 | if "" in user_msg.content:
266 | convoEnd = True
267 | getUserStore = user_agent.store_messages()
268 | getSession.user_store = codecs.encode(pickle.dumps(getUserStore), "base64").decode()
269 | getAssistantStore = assistant_agent.store_messages()
270 | getSession.assistant_store = codecs.encode(pickle.dumps(getAssistantStore), "base64").decode()
271 | db.session.commit()
272 | return jsonify(sessId=getSession.id,userMsg=userMsg,assistantMsg=assistantMsg,convoEnd=convoEnd)
273 |
274 |
275 | @rp.route("/rp/get_chat", methods=['get'])
276 | def rp_get_chat():
277 | sessId = request.args.get('sessId')
278 | getSession = Agent_Session.query.filter_by(id=sessId).first()
279 | assistant_store = pickle.loads(codecs.decode((getSession.assistant_store).encode(), "base64"))
280 | messages = []
281 | for store in assistant_store[2:]:
282 | if str(type(store)) == "":
283 | messages.append({"role":0,"msg":store.content.replace("Instruction: ","").replace("Input: None","").replace("Input: None.","")})
284 | elif str(type(store)) == "":
285 | messages.append({"role":1,"msg":store.content.replace("Solution: ","").replace("Next request.","")})
286 | return jsonify(role1=getSession.role_1,role2=getSession.role_2,task=getSession.task,messages=messages)
287 |
--------------------------------------------------------------------------------
/server/database.py:
--------------------------------------------------------------------------------
1 | from flask_sqlalchemy import SQLAlchemy
2 | from sqlalchemy import DateTime, ForeignKey, MetaData
3 | from flask_login import UserMixin
4 |
5 | from flask import Flask
6 |
7 | convention = {
8 | "ix": 'ix_%(column_0_label)s',
9 | "uq": "uq_%(table_name)s_%(column_0_name)s",
10 | "ck": "ck_%(table_name)s_%(constraint_name)s",
11 | "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
12 | "pk": "pk_%(table_name)s"
13 | }
14 |
15 | metadata = MetaData(naming_convention=convention)
16 | db = SQLAlchemy(metadata=metadata)
17 | app = Flask(__name__)
18 |
19 | class Agent_Session(db.Model):
20 | __tablename__ = "agent_session"
21 | id = db.Column(db.Integer, primary_key=True, autoincrement=True)
22 | role_1 = db.Column(db.String(200), default="", server_default = "")
23 | role_2 = db.Column(db.String(200), default="", server_default = "")
24 | task = db.Column(db.String(3000), default="", server_default = "")
25 | user_store = db.Column(db.String, default="", server_default = "")
26 | assistant_store = db.Column(db.String, default="", server_default = "")
27 | admin_id = db.Column(db.String(100), ForeignKey("admin.id"), index=True)
28 |
29 | class Admin(UserMixin,db.Model):
30 | __tablename__ = "admin"
31 | id = db.Column(db.String(100), primary_key=True)
32 | name = db.Column(db.String(100))
33 | email = db.Column(db.String(100), unique=True, index=True)
34 | google_id = db.Column(db.String(100))
35 | openai_key = db.Column(db.String(100))
36 | profile_image = db.Column(db.String(100000))
37 | password = db.Column(db.String(100))
38 | created_date = db.Column(DateTime)
39 | gpt_model = db.Column(db.String, default="gpt-3.5-turbo", server_default="gpt-3.5-turbo")
40 | agent_sessions = db.relationship('Agent_Session', backref='admin',
41 | cascade="all,delete", lazy='dynamic')
42 | def get_id(self):
43 | return (self.id)
--------------------------------------------------------------------------------
/server/requirements.txt:
--------------------------------------------------------------------------------
1 | aiohttp==3.8.4
2 | aiosignal==1.3.1
3 | alembic==1.10.4
4 | async-timeout==4.0.2
5 | attrs==23.1.0
6 | blinker==1.6.2
7 | certifi==2022.12.7
8 | charset-normalizer==3.1.0
9 | click==8.1.3
10 | colorama==0.4.6
11 | dataclasses-json==0.5.7
12 | Flask==2.3.1
13 | Flask-Login==0.6.2
14 | Flask-Migrate==4.0.4
15 | Flask-SQLAlchemy==3.0.3
16 | frozenlist==1.3.3
17 | greenlet==2.0.2
18 | idna==3.4
19 | importlib-metadata==6.6.0
20 | importlib-resources==5.12.0
21 | itsdangerous==2.1.2
22 | Jinja2==3.1.2
23 | langchain==0.0.152
24 | Mako==1.2.4
25 | MarkupSafe==2.1.2
26 | marshmallow==3.19.0
27 | marshmallow-enum==1.5.1
28 | multidict==6.0.4
29 | mypy-extensions==1.0.0
30 | numexpr==2.8.4
31 | numpy==1.24.3
32 | oauthlib==3.2.2
33 | openai==0.27.5
34 | openapi-schema-pydantic==1.2.4
35 | packaging==23.1
36 | pydantic==1.10.7
37 | PyYAML==6.0
38 | requests==2.29.0
39 | requests-oauthlib==1.3.1
40 | SQLAlchemy==2.0.11
41 | tenacity==8.2.2
42 | tqdm==4.65.0
43 | typing-extensions==4.5.0
44 | typing-inspect==0.8.0
45 | urllib3==1.26.15
46 | Werkzeug==2.3.1
47 | yarl==1.9.2
48 | zipp==3.15.0
49 |
--------------------------------------------------------------------------------
/server/webserver.py:
--------------------------------------------------------------------------------
1 | from flask import Flask
2 | from flask_migrate import Migrate
3 | from database import *
4 | import os
5 | import urllib.parse
6 | from flask import jsonify,request,session,render_template,redirect,url_for,Blueprint
7 | from requests_oauthlib import OAuth2Session
8 | from flask_login import UserMixin, LoginManager, login_required, login_user, current_user, logout_user
9 | import secrets
10 | from datetime import datetime, date, timedelta, timezone
11 | import os
12 | import json
13 | import random
14 | import requests
15 | from agent_convo import rp
16 |
17 | try:
18 | import config
19 | except ModuleNotFoundError:
20 | pass
21 |
22 |
23 | app = Flask(__name__)
24 | app.register_blueprint(rp)
25 | app.secret_key = 'autogptsamurai@123'
26 |
27 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///./test.db'
28 | db.init_app(app)
29 | db.app = app
30 | migrate = Migrate(app, db, compare_type=True,
31 | render_as_batch=True)
32 |
33 | login_manager = LoginManager(app)
34 |
35 |
36 | @login_manager.user_loader
37 | def load_user(user_id):
38 | return Admin.query.filter_by(id=user_id).first()
39 |
40 | os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
41 |
42 | @app.route("/change_model", methods=['POST'])
43 | def change_model():
44 | model = request.values["model"]
45 | current_user.gpt_model = model
46 | db.session.commit()
47 | return "Success"
48 |
49 | @app.route("/logout", methods=['GET'])
50 | def logout():
51 | logout_user()
52 | return "Success", 200
53 |
54 | @app.route("/store_key", methods=['POST'])
55 | def store_key():
56 | key = request.json['key']
57 | getAdmin = Admin.query.filter_by(id=current_user.id).first()
58 | if len(key) == 51:
59 | getAdmin.openai_key = key
60 | db.session.commit()
61 | return jsonify(True)
62 | else:
63 | return jsonify(False), 400
64 |
65 | if __name__ == '__main__':
66 | app.run(host="0.0.0.0", debug=True)
67 |
--------------------------------------------------------------------------------
/steps_to_run.md:
--------------------------------------------------------------------------------
1 | # Server
2 |
3 | 1. To run server, install virtualenv first https://virtualenv.pypa.io/en/latest/ and create a new virtual environment to load all necessary python packages
4 |
5 | 2. Go to server folder and install all necessary packages using command "pip install -r requirements.txt"
6 |
7 | 3. Set environment variables FLASK_ENV=dev and FLASK_APP=webserver.py
8 |
9 | 4. Create a db for storing all the info using commands i) flask db init ii) flask db migrate iii) flask db upgrade
10 |
11 | 5. Run the server using python webserver.py
12 |
13 |
14 | # Client
15 |
16 | 1. To run client, go to client folder and do npm install
17 |
18 | 2. Now run "npm start" and this should start the client
19 |
--------------------------------------------------------------------------------