Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #1072

Merged
merged 43 commits into from
Aug 17, 2023
Merged

Dev #1072

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b441007
Added code to connect weaviate vectoro db
Aug 9, 2023
f78396c
add embeddings to vector_db weaviate
Aug 9, 2023
d06c2a7
weaviate frontend complete
namansleeps2 Aug 9, 2023
dc2e423
minor changes
namansleeps2 Aug 9, 2023
f043d55
code for uninstall
Aug 9, 2023
26d6fef
Merge branch 'dev' into weaviate-backend
Aug 9, 2023
b581735
Dimensions change for weaviate
Aug 9, 2023
b044045
Fix for getting index stats
Aug 9, 2023
9e5e87c
Is valid dimension changed
Aug 10, 2023
2e38844
change in creation of client
Aug 10, 2023
897a8e8
Made changes
Aug 10, 2023
0775823
Vector store add tests fixed for weaviate
Aug 10, 2023
cf252bf
Fixes for get matching text
Aug 10, 2023
d3d8609
Merge branch 'dev' into weaviate-backend
Aug 10, 2023
3c8cb5c
fixed get_matching_texts
Aug 10, 2023
fc6a018
changes
Aug 10, 2023
f1496d7
Minor fixes
Aug 10, 2023
0b08f3f
Fix for extra variable
Aug 10, 2023
45f769c
Merge branch 'dev' into weaviate-backend
Aug 10, 2023
989c62b
minor bug
namansleeps2 Aug 10, 2023
87dc198
PR Comments resolved
Aug 11, 2023
5320b12
Tests for weaviate.py
Aug 11, 2023
80bcbcf
Test for vector embedding weaaviate
Aug 11, 2023
268ed3d
Tests for vector embedding factory
Aug 11, 2023
0c77bf1
Schedule Agent Fix (#1043)
rounak610 Aug 11, 2023
e90b59b
add small check (#1046)
Fluder-Paradyne Aug 11, 2023
cf869a2
detail bug in schedule agent and naming of new run in edit agent (#1049)
namansleeps Aug 12, 2023
502a705
Merge pull request #1036 from TransformerOptimus/weaviate_frontend
Tarraann Aug 16, 2023
9cb2cf0
Merge branch 'dev' into weaviate-backend
Aug 16, 2023
9b8592b
PR Comments resolved
Aug 16, 2023
b0d4a68
Merge pull request #1031 from TransformerOptimus/weaviate-backend
Tarraann Aug 16, 2023
77455ce
External tools, marketplace tools fix (#1058)
lalitlj Aug 16, 2023
4c81845
MInor fix
Aug 16, 2023
ec299e5
Merge pull request #1064 from TransformerOptimus/hash_map_weaviate_fix
Tarraann Aug 16, 2023
e14b118
bug fixes of weaviate and profile dropdown bug (#1062)
namansleeps Aug 16, 2023
240cccb
New run fix (#1055)
rounak610 Aug 17, 2023
a9a8392
Test tool builder fix (#1067)
lalitlj Aug 17, 2023
f8e9127
removing apollo from superagi workflow
Aug 17, 2023
96be7ed
removing apollo from superagi workflow
Aug 17, 2023
846d5f5
Super agi api (#992)
Aryan-Singh-14 Aug 17, 2023
0eb1ba0
Update docker-compose-dev.yaml (#1073)
Fluder-Paradyne Aug 17, 2023
154d046
merge complete
Fluder-Paradyne Aug 17, 2023
8e1d1ad
Merge pull request #1074 from TransformerOptimus/dev_to_main
Tarraann Aug 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ jobs:
ENV: DEV
PLAIN_OUTPUT: True
REDIS_URL: "localhost:6379"
IS_TESTING: True

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
2 changes: 1 addition & 1 deletion docker-compose-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ networks:
driver: bridge
volumes:
superagi_postgres_data:
redis_data:
redis_data:
2 changes: 1 addition & 1 deletion gui/pages/Content/Agents/AgentCreate.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ export default function AgentCreate({
setEditButtonClicked(true);
agentData.agent_id = editAgentId;
const name = agentData.name
const adjustedDate = new Date((new Date()).getTime() + 6*24*60*60*1000 - 1*60*1000);
const adjustedDate = new Date((new Date()).getTime());
const formattedDate = `${adjustedDate.getDate()} ${['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][adjustedDate.getMonth()]} ${adjustedDate.getFullYear()} ${adjustedDate.getHours().toString().padStart(2, '0')}:${adjustedDate.getMinutes().toString().padStart(2, '0')}`;
agentData.name = "Run " + formattedDate
addAgentRun(agentData)
Expand Down
31 changes: 31 additions & 0 deletions gui/pages/Content/Agents/Agents.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -429,4 +429,35 @@
color: #888888 !important;
text-decoration: line-through;
pointerEvents: none !important;
}

.modal_buttons{
display: flex;
justify-content: flex-end;
margin-top: 20px
}

.modal_info_class{
margin-left: -5px;
margin-right: 5px;
}

.table_contents{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 40px;
width: 100%
}

.create_settings_button{
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px
}

.button_margin{
margin-top: -10px;
}
14 changes: 14 additions & 0 deletions gui/pages/Content/Marketplace/Market.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -515,3 +515,17 @@
overflow-y:scroll;
overflow-x:hidden;
}

.settings_tab_button_clicked{
background: #454254;
padding-right: 15px
}

.settings_tab_button{
background: transparent;
padding-right: 15px
}

.settings_tab_img{
margin-top: -1px;
}
286 changes: 286 additions & 0 deletions gui/pages/Dashboard/Settings/ApiKeys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
import React, {useState, useEffect, useRef} from 'react';
import {ToastContainer, toast} from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import agentStyles from "@/pages/Content/Agents/Agents.module.css";
import {
createApiKey, deleteApiKey,
editApiKey, getApiKeys,
} from "@/pages/api/DashboardService";
import {EventBus} from "@/utils/eventBus";
import {createInternalId, loadingTextEffect, preventDefault, removeTab, returnToolkitIcon} from "@/utils/utils";
import Image from "next/image";
import styles from "@/pages/Content/Marketplace/Market.module.css";
import styles1 from "@/pages/Content/Knowledge/Knowledge.module.css";

export default function ApiKeys() {
const [apiKeys, setApiKeys] = useState([]);
const [keyName, setKeyName] = useState('');
const [editKey, setEditKey] = useState('');
const apiKeyRef = useRef(null);
const editKeyRef = useRef(null);
const [editKeyId, setEditKeyId] = useState(-1);
const [deleteKey, setDeleteKey] = useState('')
const [isLoading, setIsLoading] = useState(true)
const [activeDropdown, setActiveDropdown] = useState(null);
const [editModal, setEditModal] = useState(false);
const [deleteKeyId, setDeleteKeyId] = useState(-1);
const [deleteModal, setDeleteModal] = useState(false);
const [createModal, setCreateModal] = useState(false);
const [displayModal, setDisplayModal] = useState(false);
const [apiKeyGenerated, setApiKeyGenerated] = useState('');
const [loadingText, setLoadingText] = useState("Loading Api Keys");



useEffect(() => {
loadingTextEffect('Loading Api Keys', setLoadingText, 500);
fetchApiKeys()
}, []);


const handleModelApiKey = (event) => {
setKeyName(event.target.value);
};

const handleEditApiKey = (event) => {
setEditKey(event.target.value);
};

const createApikey = () => {
if(!keyName){
toast.error("Enter key name", {autoClose: 1800});
return;
}
createApiKey({name : keyName})
.then((response) => {
setApiKeyGenerated(response.data.api_key)
toast.success("Api Key Generated", {autoClose: 1800});
setCreateModal(false);
setDisplayModal(true);
fetchApiKeys();
})
.catch((error) => {
console.error('Error creating api key', error);
});
}
const handleCopyClick = async () => {
if (apiKeyRef.current) {
try {
await navigator.clipboard.writeText(apiKeyRef.current.value);
toast.success("Key Copied", {autoClose: 1800});
} catch (err) {
toast.error('Failed to Copy', {autoClose: 1800});
}
}
};

const fetchApiKeys = () => {
getApiKeys()
.then((response) => {
const formattedData = response.data.map(item => {
return {
...item,
created_at: `${new Date(item.created_at).getDate()}-${["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"][new Date(item.created_at).getMonth()]}-${new Date(item.created_at).getFullYear()}`
};
});
setApiKeys(formattedData)
setIsLoading(false)
})
.catch((error) => {
console.error('Error fetching Api Keys', error);
});
}

const handleEditClick = () => {
if(editKeyRef.current.value.length <1){
toast.error("Enter valid key name", {autoClose: 1800});
return;
}
editApiKey({id: editKeyId,name : editKey})
.then((response) => {
toast.success("Api Key Edited", {autoClose: 1800});
fetchApiKeys();
setEditModal(false);
setEditKey('')
setEditKeyId(-1)
})
.catch((error) => {
console.error('Error editing api key', error);
});
}

const handleDeleteClick = () => {
deleteApiKey(deleteKeyId)
.then((response) => {
toast.success("Api Key Deleted", {autoClose: 1800});
fetchApiKeys();
setDeleteModal(false);
setDeleteKeyId(-1)
setDeleteKey('')
})
.catch((error) => {
toast.error("Error deleting api key", {autoClose: 1800});
console.error('Error deleting api key', error);
});
}

return (<>
<div className="row">
<div className="col-2"></div>
<div className="col-8 col-6-scrollable">
{!isLoading ? <div>
<div className="title_wrapper mb_15">
<div className={styles.page_title}>API Keys</div>
{apiKeys && apiKeys.length > 0 && !isLoading &&
<button className={`${'primary_button mr_20'} ${agentStyles.button_margin}`} onClick={() => {setCreateModal(true); setKeyName('')}}>
Create Key
</button>}
</div>
<div>
<label className={agentStyles.form_label}>Your secret API keys are important and should be kept safe. Do not share them with anyone or expose them in any case.</label>
<label className={agentStyles.form_label}>To help keep your API keys safe, you can store them in a secure location, rotate them regularly, and use different API keys for different applications. By following these tips, you can help protect your account and your data.</label>

{apiKeys.length < 1 && <div className={agentStyles.table_contents}>
<Image width={150} height={60} src="/images/no_permissions.svg" alt="no-permissions"/>
<span className={`${styles.feed_title} ${'mt_8'}`}>No API Keys created!</span>
<div className={agentStyles.create_settings_button}>
<button className="primary_button" onClick={() => {setCreateModal(true); setKeyName('')}}>Create Key
</button>
</div>
</div>}

{apiKeys.length > 0 && <div className="scrollable_container table_container">
<table className="table_css margin_0 padding_0">
<thead>
<tr className="border_top_none">
<th className="table_header w_60">Name</th>
<th className="table_header w_18">Key</th>
<th className="table_header w_18">Created Date</th>
<th className="table_header w_4"></th>
</tr>
</thead>
</table>
<div className="overflow_auto w_100">
<table className="table_css margin_0">
<tbody>
{apiKeys.map((item, index) => (
<tr key={index}>
<td className="table_data w_60">{item.name}</td>
<td className="table_data w_18">{item.key.slice(0, 2) + "****" + item.key.slice(-4)}</td>
<td className="table_data w_18">{item.created_at}</td>
<td className="table_data w_4 cursor_pointer" onMouseLeave={() => setActiveDropdown(null)} onClick={() => {
if (activeDropdown === index) {
setActiveDropdown(null);
} else {
setActiveDropdown(index);
}
}}>
<Image className="rotate_90" width={16} height={16} src="/images/three_dots.svg" alt="run-icon"/>
<div style={activeDropdown === index ? {display: 'block'} : {display: 'none'}} onMouseLeave={() => setActiveDropdown(null)}>
<ul className="dropdown_container">
<li className="dropdown_item" onClick={() => {setEditKey(item.name); setEditKeyId(item.id); setEditModal(true); setActiveDropdown(null);}}>Edit</li>
<li className="dropdown_item" onClick={() => {setDeleteKeyId(item.id); setDeleteKey(item.name) ; setDeleteModal(true); setActiveDropdown(null);}}>Delete</li>
</ul> </div></td>
</tr>
))}
</tbody>
</table>
</div>
</div>}
</div>
</div> : <div className="loading_container">
<div className="signInInfo loading_text">{loadingText}</div>
</div>}
</div>
<div className="col-2"></div>
</div>

{createModal && (<div className="modal" onClick={() => setCreateModal(false)}>
<div className="modal-content w_35" onClick={preventDefault}>
<div className={styles.detail_name}>Create new API Key</div>
<div>
<label className={styles.form_label}>Name</label>
<input placeholder="Enter key name" className="input_medium" type="text" value={keyName} onChange={handleModelApiKey}/>
</div>
<div className={agentStyles.modal_buttons}>
<button className="secondary_button mr_10" onClick={() => setCreateModal(false)}>
Cancel
</button>
<button className="primary_button" onClick={() => createApikey()}>
Create Key
</button>
</div>
</div>
</div>)}

{displayModal && apiKeyGenerated && (<div className="modal" onClick={() => setDisplayModal(false)}>
<div className="modal-content w_35" onClick={preventDefault}>
<div className={styles.detail_name}>{keyName} is created</div>
<div>
<div className="mt_15 mb_25">
<div className={styles1.knowledge_alert}>
<div className={agentStyles.modal_info_class}>
<Image width={20} height={20} src='/images/info.svg' alt="info-icon"/>
</div>
<div>
Your secret API keys are sensitive pieces of information that should be kept confidential. Do not share them with anyone, and do not expose them in any way. If your secret API keys are compromised, someone could use them to access your API and make unauthorized changes to your data. This secret key is only displayed once for security reasons. Please save it in a secure location where you can access it easily.
</div>
</div>
</div>
<div>
<div className="title_wrapper">
<div className="flex_1"><input ref={apiKeyRef} className="input_medium" type="text" value={apiKeyGenerated} disabled />
</div>
<div>
<button className="secondary_button ml_4 padding_5" onClick={handleCopyClick}>
<Image width={20} height={21} src="/images/copy_icon.svg" alt="copy-icon"/>
</button>
</div>
</div>
</div>
</div>
<div className={agentStyles.modal_buttons}>
<button className="primary_button" onClick={() => setDisplayModal(false)}>
OK
</button>
</div>
</div>
</div>)}

{editModal && (<div className="modal" onClick={() => {setEditModal(false); setEditKey(''); setEditKeyId(-1)}}>
<div className="modal-content w_35" onClick={preventDefault}>
<div className={styles.detail_name}>Edit API Key</div>
<div>
<label className={styles.form_label}>Name</label>
<input ref={editKeyRef} placeholder={editKey} className="input_medium" type="text" onChange={handleEditApiKey}/>
</div>
<div className={agentStyles.modal_buttons}>
<button className="secondary_button mr_10" onClick={() => {setEditModal(false); setEditKey(''); setEditKeyId(-1)}}>
Cancel
</button>
<button className="primary_button" onClick={() => handleEditClick()}>
Update Changes
</button>
</div>
</div>
</div>)}

{deleteModal && (<div className="modal" onClick={() => {setDeleteModal(false); setDeleteKeyId(-1); setDeleteKey('')}}>
<div className="modal-content w_35" onClick={preventDefault}>
<div className={styles.detail_name}>Delete {deleteKey} Key</div>
<div>
<label className={styles.form_label}>Deleting this API key will make it unusable. Any API requests made using this key will be rejected. Are you sure you want to proceed?</label>
</div>
<div className={agentStyles.modal_buttons}>
<button className="secondary_button mr_10" onClick={() => {setDeleteModal(false); setDeleteKeyId(-1); setDeleteKey('')}}>
Cancel
</button>
<button className="primary_button" onClick={() => handleDeleteClick()}>
Delete Key
</button>
</div>
</div>
</div>)}
<ToastContainer/>
</>)
}
8 changes: 8 additions & 0 deletions gui/pages/Dashboard/Settings/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import styles from "@/pages/Content/Marketplace/Market.module.css";
import Image from "next/image";
import Model from "@/pages/Dashboard/Settings/Model";
import Database from "@/pages/Dashboard/Settings/Database";
import ApiKeys from "@/pages/Dashboard/Settings/ApiKeys";

export default function Settings({organisationId, sendDatabaseData}) {
const [activeTab, setActiveTab] = useState('model');
Expand Down Expand Up @@ -44,11 +45,18 @@ export default function Settings({organisationId, sendDatabaseData}) {
alt="database-icon"/>&nbsp;Database
</button>
</div>
<div>
<button onClick={() => switchTab('apikeys')} className={`${styles.tab_button} ${activeTab === 'apikeys' ? styles.settings_tab_button_clicked : styles.settings_tab_button}`}>
<Image className={styles.settings_tab_img} width={14} height={14} src="/images/key_white.svg"
alt="database-icon"/>&nbsp;API Keys
</button>
</div>
</div>
</div>
<div>
{activeTab === 'model' && <Model organisationId={organisationId}/>}
{activeTab === 'database' && <Database sendDatabaseData={sendDatabaseData} organisationId={organisationId}/>}
{activeTab === 'apikeys' && <ApiKeys />}
</div>
</div>
</div>
Expand Down
Loading