feature(#130): remove conflicts
Browse files- .gitignore +2 -0
- Android/README.md +0 -1
- Android/app/src/main/res/drawable/ic_attachment_48.xml +5 -0
- Brain/README.md +1 -6
- Brain/logs/activity.log +0 -82
- Brain/src/commands/command.py +5 -5
- Brain/src/common/assembler.py +16 -1
- Brain/src/common/program_type.py +14 -11
- Brain/src/common/utils.py +6 -0
- Brain/src/gradio_debug.py +47 -0
- Brain/src/model/requests/request_model.py +29 -0
- Brain/src/rising_plugin/gmail/email_plugin.py +359 -0
- Brain/src/rising_plugin/guardrails-config/actions/actions.py +1 -107
- Brain/src/rising_plugin/guardrails-config/off-security.co +1 -1
- Brain/src/rising_plugin/llm/llms.py +35 -1
- Brain/src/rising_plugin/rails_validate.py +15 -0
- Brain/src/rising_plugin/risingplugin.py +109 -47
- Brain/src/router/api.py +91 -3
- Brain/src/router/email_router.py +77 -0
- Brain/src/router/train_router.py +27 -0
- Brain/src/service/auto_task_service.py +14 -2
- Brain/src/service/contact_service.py +67 -1
- Brain/src/service/train_service.py +6 -0
- Brain/tests/functional/test_api.py +26 -0
- Extension/.idea/.gitignore +0 -5
- Extension/.idea/Extension.iml +0 -12
- Extension/.idea/inspectionProfiles/Project_Default.xml +0 -6
- Extension/.idea/modules.xml +0 -8
- Extension/.idea/vcs.xml +0 -6
- Extension/src/pages/Content/modules/DraggablePanel.jsx +2 -0
- Extension/src/pages/Panel/Message/index.css +14 -8
- Extension/src/pages/Panel/Panel.css +15 -2
- Extension/src/pages/Panel/Panel.jsx +24 -12
- README.md +1 -5
- WatchApp/WatchApp Watch App/Assets.xcassets/AccentColor.colorset/Contents.json +0 -11
- WatchApp/WatchApp Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -13
- WatchApp/WatchApp Watch App/Assets.xcassets/Contents.json +0 -6
- WatchApp/WatchApp Watch App/Components/ChatMessageRow.swift +57 -0
- WatchApp/WatchApp Watch App/ContentView.swift +0 -73
- WatchApp/WatchApp Watch App/MainView.swift +28 -0
- WatchApp/WatchApp Watch App/Pages/ChatView.swift +112 -0
- WatchApp/WatchApp Watch App/Pages/SettingView.swift +46 -0
- WatchApp/WatchApp Watch App/WatchAppApp.swift +1 -1
- WatchApp/WatchApp.xcodeproj/project.pbxproj +59 -20
- WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +14 -0
- WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcuserdata/darkhorse.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- WatchApp/WatchApp.xcodeproj/xcuserdata/darkhorse.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +6 -0
- app.py +14 -2
- requirements.txt +5 -2
.gitignore
CHANGED
|
@@ -1,3 +1,5 @@
|
|
| 1 |
/Brain/firebase_cred.json
|
| 2 |
/.idea
|
| 3 |
Brain/firebase_cred.json
|
|
|
|
|
|
|
|
|
| 1 |
/Brain/firebase_cred.json
|
| 2 |
/.idea
|
| 3 |
Brain/firebase_cred.json
|
| 4 |
+
Brain/logs
|
| 5 |
+
|
Android/README.md
CHANGED
|
@@ -23,7 +23,6 @@ All complex software including operating systems will need to be rewritten from
|
|
| 23 |
| Image Search System | A user can search image on Android local storage |
|
| 24 |
| Send SMS | If a user says that send SMS, mobile open SMS editor and a user can send SMS using the editor. |
|
| 25 |
|
| 26 |
-
[[Rising Brain](https://github.com/ttt246/RisingBrain)]
|
| 27 |
### Run locally
|
| 28 |
- Copy google-services.json into app folder of project
|
| 29 |
|
|
|
|
| 23 |
| Image Search System | A user can search image on Android local storage |
|
| 24 |
| Send SMS | If a user says that send SMS, mobile open SMS editor and a user can send SMS using the editor. |
|
| 25 |
|
|
|
|
| 26 |
### Run locally
|
| 27 |
- Copy google-services.json into app folder of project
|
| 28 |
|
Android/app/src/main/res/drawable/ic_attachment_48.xml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<vector android:height="48dp" android:tint="#000000"
|
| 2 |
+
android:viewportHeight="24" android:viewportWidth="24"
|
| 3 |
+
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
| 4 |
+
<path android:fillColor="@android:color/white" android:pathData="M2,12.5C2,9.46 4.46,7 7.5,7H18c2.21,0 4,1.79 4,4s-1.79,4 -4,4H9.5C8.12,15 7,13.88 7,12.5S8.12,10 9.5,10H17v2H9.41c-0.55,0 -0.55,1 0,1H18c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2H7.5C5.57,9 4,10.57 4,12.5S5.57,16 7.5,16H17v2H7.5C4.46,18 2,15.54 2,12.5z"/>
|
| 5 |
+
</vector>
|
Brain/README.md
CHANGED
|
@@ -27,8 +27,7 @@ All complex software including operating systems will need to be rewritten from
|
|
| 27 |
- 🌍 Support all web browsers to manipulate it automatically as its extension.
|
| 28 |
- 🔗 Multiple API support (Web API for Free and Plus users, GPT-3.5, GPT-4, etc.).
|
| 29 |
- 🔍 Integration to all mainstream search engines, and custom queries to support additional sites.
|
| 30 |
-
|
| 31 |
-
[[Android Application](https://github.com/ttt246/RisingPhone)] [[Brrowser Extension](https://github.com/ttt246/Rising_Browser)] [[Rising Plugin](https://github.com/ttt246/Rising_Plugin)]
|
| 32 |
#### 1.2 Feature
|
| 33 |
|
| 34 |
- Chat with Rising AI as an assistant.
|
|
@@ -39,10 +38,6 @@ All complex software including operating systems will need to be rewritten from
|
|
| 39 |
- Manipulate all browsers with user's input(tab, page, search, scroll, or etc) and it will follow you to go on the real website or blog what you are thinking of.
|
| 40 |
|
| 41 |
## 2. Installing / Getting started
|
| 42 |
-
Install the latest version of rising-plugin package to use / custom something on what you want.
|
| 43 |
-
```
|
| 44 |
-
pip install rising-plugin
|
| 45 |
-
```
|
| 46 |
#### 2.1 how to run on local
|
| 47 |
It's a standard fastapi application so no configuration is needed beyond the included Procfile
|
| 48 |
#### 2.2 Create firebase project
|
|
|
|
| 27 |
- 🌍 Support all web browsers to manipulate it automatically as its extension.
|
| 28 |
- 🔗 Multiple API support (Web API for Free and Plus users, GPT-3.5, GPT-4, etc.).
|
| 29 |
- 🔍 Integration to all mainstream search engines, and custom queries to support additional sites.
|
| 30 |
+
-
|
|
|
|
| 31 |
#### 1.2 Feature
|
| 32 |
|
| 33 |
- Chat with Rising AI as an assistant.
|
|
|
|
| 38 |
- Manipulate all browsers with user's input(tab, page, search, scroll, or etc) and it will follow you to go on the real website or blog what you are thinking of.
|
| 39 |
|
| 40 |
## 2. Installing / Getting started
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
#### 2.1 how to run on local
|
| 42 |
It's a standard fastapi application so no configuration is needed beyond the included Procfile
|
| 43 |
#### 2.2 Create firebase project
|
Brain/logs/activity.log
DELETED
|
@@ -1,82 +0,0 @@
|
|
| 1 |
-
2023-06-11 01:39:05,597 ERROR sendNotification
|
| 2 |
-
2023-06-11 03:49:04,950 DEBUG Chat with AI on model : gpt-3.5-turbo
|
| 3 |
-
2023-06-11 03:49:04,950 DEBUG ------------ CONTEXT SENT TO AI ---------------
|
| 4 |
-
2023-06-11 03:49:04,950 DEBUG System: You are a helpful assistant.
|
| 5 |
-
2023-06-11 03:49:04,950 DEBUG
|
| 6 |
-
2023-06-11 03:49:04,950 DEBUG User: Who won the world series in 2020?
|
| 7 |
-
2023-06-11 03:49:04,950 DEBUG
|
| 8 |
-
2023-06-11 03:49:04,950 DEBUG Assistant: The Los Angeles Dodgers won the World Series in 2020.
|
| 9 |
-
2023-06-11 03:49:04,950 DEBUG
|
| 10 |
-
2023-06-11 03:49:04,950 DEBUG User: Where was it played?
|
| 11 |
-
2023-06-11 03:49:04,951 DEBUG
|
| 12 |
-
2023-06-11 03:49:04,951 DEBUG ----------- END OF CONTEXT ----------------
|
| 13 |
-
2023-06-11 03:49:14,350 WARNING API Rate Limit Reached. Waiting 10 seconds... Error:
|
| 14 |
-
2023-06-11 03:49:34,004 DEBUG Chat with AI on model : gpt-3.5-turbo
|
| 15 |
-
2023-06-11 03:49:34,004 DEBUG ------------ CONTEXT SENT TO AI ---------------
|
| 16 |
-
2023-06-11 03:49:34,004 DEBUG System: You are a helpful assistant.
|
| 17 |
-
2023-06-11 03:49:34,004 DEBUG
|
| 18 |
-
2023-06-11 03:49:34,004 DEBUG User: Who won the world series in 2020?
|
| 19 |
-
2023-06-11 03:49:34,004 DEBUG
|
| 20 |
-
2023-06-11 03:49:34,004 DEBUG Assistant: The Los Angeles Dodgers won the World Series in 2020.
|
| 21 |
-
2023-06-11 03:49:34,004 DEBUG
|
| 22 |
-
2023-06-11 03:49:34,004 DEBUG User: Where was it played?
|
| 23 |
-
2023-06-11 03:49:34,004 DEBUG
|
| 24 |
-
2023-06-11 03:49:34,004 DEBUG ----------- END OF CONTEXT ----------------
|
| 25 |
-
2023-06-11 03:50:02,195 DEBUG Chat with AI on model : gpt-3.5-turbo
|
| 26 |
-
2023-06-11 03:50:02,196 DEBUG ------------ CONTEXT SENT TO AI ---------------
|
| 27 |
-
2023-06-11 03:50:02,196 DEBUG System: You are a helpful assistant.
|
| 28 |
-
2023-06-11 03:50:02,196 DEBUG
|
| 29 |
-
2023-06-11 03:50:02,196 DEBUG User: Who won the world series in 2020?
|
| 30 |
-
2023-06-11 03:50:02,197 DEBUG
|
| 31 |
-
2023-06-11 03:50:02,197 DEBUG Assistant: The Los Angeles Dodgers won the World Series in 2020.
|
| 32 |
-
2023-06-11 03:50:02,197 DEBUG
|
| 33 |
-
2023-06-11 03:50:02,197 DEBUG User: Where was it played?
|
| 34 |
-
2023-06-11 03:50:02,197 DEBUG
|
| 35 |
-
2023-06-11 03:50:02,197 DEBUG ----------- END OF CONTEXT ----------------
|
| 36 |
-
2023-06-11 03:52:01,682 WARNING API Rate Limit Reached. Waiting 10 seconds... Error:
|
| 37 |
-
2023-06-11 03:52:04,881 DEBUG Chat with AI on model : gpt-3.5-turbo
|
| 38 |
-
2023-06-11 03:52:04,882 DEBUG ------------ CONTEXT SENT TO AI ---------------
|
| 39 |
-
2023-06-11 03:52:04,882 DEBUG System: You are a helpful assistant.
|
| 40 |
-
2023-06-11 03:52:04,882 DEBUG
|
| 41 |
-
2023-06-11 03:52:04,882 DEBUG User: Who won the world series in 2020?
|
| 42 |
-
2023-06-11 03:52:04,883 DEBUG
|
| 43 |
-
2023-06-11 03:52:04,883 DEBUG Assistant: The Los Angeles Dodgers won the World Series in 2020.
|
| 44 |
-
2023-06-11 03:52:04,883 DEBUG
|
| 45 |
-
2023-06-11 03:52:04,884 DEBUG User: Where was it played?
|
| 46 |
-
2023-06-11 03:52:04,884 DEBUG
|
| 47 |
-
2023-06-11 03:52:04,884 DEBUG ----------- END OF CONTEXT ----------------
|
| 48 |
-
2023-06-11 03:59:41,875 DEBUG Chat with AI on model : gpt-3.5-turbo
|
| 49 |
-
2023-06-11 03:59:41,876 DEBUG ------------ CONTEXT SENT TO AI ---------------
|
| 50 |
-
2023-06-11 03:59:41,876 DEBUG System: You are a helpful assistant.
|
| 51 |
-
2023-06-11 03:59:41,876 DEBUG
|
| 52 |
-
2023-06-11 03:59:41,876 DEBUG User: Who won the world series in 2020?
|
| 53 |
-
2023-06-11 03:59:41,876 DEBUG
|
| 54 |
-
2023-06-11 03:59:41,876 DEBUG Assistant: The Los Angeles Dodgers won the World Series in 2020.
|
| 55 |
-
2023-06-11 03:59:41,876 DEBUG
|
| 56 |
-
2023-06-11 03:59:41,876 DEBUG User: Where was it played?
|
| 57 |
-
2023-06-11 03:59:41,876 DEBUG
|
| 58 |
-
2023-06-11 03:59:41,876 DEBUG ----------- END OF CONTEXT ----------------
|
| 59 |
-
2023-06-12 17:08:50,779 DEBUG Chat with AI on model : gpt-3.5-turbo
|
| 60 |
-
2023-06-12 17:08:50,780 DEBUG ------------ CONTEXT SENT TO AI ---------------
|
| 61 |
-
2023-06-12 17:08:50,780 DEBUG System: You are a helpful assistant.
|
| 62 |
-
2023-06-12 17:08:50,780 DEBUG
|
| 63 |
-
2023-06-12 17:08:50,780 DEBUG User: Who won the world series in 2020?
|
| 64 |
-
2023-06-12 17:08:50,780 DEBUG
|
| 65 |
-
2023-06-12 17:08:50,780 DEBUG Assistant: The Los Angeles Dodgers won the World Series in 2020.
|
| 66 |
-
2023-06-12 17:08:50,780 DEBUG
|
| 67 |
-
2023-06-12 17:08:50,780 DEBUG User: Where was it played?
|
| 68 |
-
2023-06-12 17:08:50,780 DEBUG
|
| 69 |
-
2023-06-12 17:08:50,780 DEBUG ----------- END OF CONTEXT ----------------
|
| 70 |
-
2023-06-16 14:22:55,555 ERROR sendNotification json parsing or get completion error
|
| 71 |
-
2023-06-16 14:23:59,508 ERROR sendNotification json parsing or get completion error
|
| 72 |
-
2023-06-16 15:58:51,640 DEBUG Chat with AI on model : gpt-3.5-turbo
|
| 73 |
-
2023-06-16 15:58:51,641 DEBUG ------------ CONTEXT SENT TO AI ---------------
|
| 74 |
-
2023-06-16 15:58:51,641 DEBUG System: You are a helpful assistant.
|
| 75 |
-
2023-06-16 15:58:51,642 DEBUG
|
| 76 |
-
2023-06-16 15:58:51,642 DEBUG User: Who won the world series in 2020?
|
| 77 |
-
2023-06-16 15:58:51,642 DEBUG
|
| 78 |
-
2023-06-16 15:58:51,642 DEBUG Assistant: The Los Angeles Dodgers won the World Series in 2020.
|
| 79 |
-
2023-06-16 15:58:51,642 DEBUG
|
| 80 |
-
2023-06-16 15:58:51,642 DEBUG User: Where was it played?
|
| 81 |
-
2023-06-16 15:58:51,642 DEBUG
|
| 82 |
-
2023-06-16 15:58:51,642 DEBUG ----------- END OF CONTEXT ----------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Brain/src/commands/command.py
CHANGED
|
@@ -62,35 +62,35 @@ class CommandRegistry:
|
|
| 62 |
"Search a image that #description",
|
| 63 |
["#description"],
|
| 64 |
True,
|
| 65 |
-
)
|
| 66 |
Command(
|
| 67 |
"notification",
|
| 68 |
"send notification or alert",
|
| 69 |
"send that #notification",
|
| 70 |
["#notification"],
|
| 71 |
True,
|
| 72 |
-
)
|
| 73 |
Command(
|
| 74 |
"sms",
|
| 75 |
"send a sms",
|
| 76 |
"",
|
| 77 |
[],
|
| 78 |
True,
|
| 79 |
-
)
|
| 80 |
Command(
|
| 81 |
"browsing",
|
| 82 |
"search browser",
|
| 83 |
"Search something that #description",
|
| 84 |
["#description"],
|
| 85 |
True,
|
| 86 |
-
)
|
| 87 |
Command(
|
| 88 |
"social",
|
| 89 |
"search something in social",
|
| 90 |
"Search something in twitter or facebook that #description",
|
| 91 |
["#description"],
|
| 92 |
True,
|
| 93 |
-
)
|
| 94 |
]
|
| 95 |
|
| 96 |
def get_all_commands(self) -> Any:
|
|
|
|
| 62 |
"Search a image that #description",
|
| 63 |
["#description"],
|
| 64 |
True,
|
| 65 |
+
),
|
| 66 |
Command(
|
| 67 |
"notification",
|
| 68 |
"send notification or alert",
|
| 69 |
"send that #notification",
|
| 70 |
["#notification"],
|
| 71 |
True,
|
| 72 |
+
),
|
| 73 |
Command(
|
| 74 |
"sms",
|
| 75 |
"send a sms",
|
| 76 |
"",
|
| 77 |
[],
|
| 78 |
True,
|
| 79 |
+
),
|
| 80 |
Command(
|
| 81 |
"browsing",
|
| 82 |
"search browser",
|
| 83 |
"Search something that #description",
|
| 84 |
["#description"],
|
| 85 |
True,
|
| 86 |
+
),
|
| 87 |
Command(
|
| 88 |
"social",
|
| 89 |
"search something in social",
|
| 90 |
"Search something in twitter or facebook that #description",
|
| 91 |
["#description"],
|
| 92 |
True,
|
| 93 |
+
),
|
| 94 |
]
|
| 95 |
|
| 96 |
def get_all_commands(self) -> Any:
|
Brain/src/common/assembler.py
CHANGED
|
@@ -57,7 +57,7 @@ class Assembler:
|
|
| 57 |
|
| 58 |
"""mapping result type into json
|
| 59 |
{
|
| 60 |
-
"program": sms | contacts | browser |
|
| 61 |
"content": string
|
| 62 |
}
|
| 63 |
"""
|
|
@@ -69,3 +69,18 @@ class Assembler:
|
|
| 69 |
|
| 70 |
def to_req_model(self, basic_req: BasicReq.Confs) -> ReqModel:
|
| 71 |
return ReqModel(basic_req.to_json())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
"""mapping result type into json
|
| 59 |
{
|
| 60 |
+
"program": sms | contacts | browser | selectitemdetailinfo,
|
| 61 |
"content": string
|
| 62 |
}
|
| 63 |
"""
|
|
|
|
| 69 |
|
| 70 |
def to_req_model(self, basic_req: BasicReq.Confs) -> ReqModel:
|
| 71 |
return ReqModel(basic_req.to_json())
|
| 72 |
+
|
| 73 |
+
"""mapping data from a ContactModel into json
|
| 74 |
+
{
|
| 75 |
+
"contactId": int,
|
| 76 |
+
"displayName": string,
|
| 77 |
+
"phoneNumbers": [string]
|
| 78 |
+
}
|
| 79 |
+
"""
|
| 80 |
+
|
| 81 |
+
def to_contact_result_format(self, contact: ContactModel) -> Any:
|
| 82 |
+
return {
|
| 83 |
+
"contactId": contact.contact_id,
|
| 84 |
+
"displayName": contact.display_name,
|
| 85 |
+
"phoneNumbers": contact.phone_numbers,
|
| 86 |
+
}
|
Brain/src/common/program_type.py
CHANGED
|
@@ -8,17 +8,20 @@ class ProgramType:
|
|
| 8 |
SMS = "sms"
|
| 9 |
CONTACT = "contact"
|
| 10 |
MESSAGE = "message"
|
|
|
|
|
|
|
| 11 |
|
| 12 |
class BrowserType:
|
| 13 |
-
OPEN_TAB = "
|
| 14 |
-
OPEN_TAB_SEARCH = "
|
| 15 |
-
CLOSE_TAB = "
|
| 16 |
-
PREVIOUS_PAGE = "
|
| 17 |
-
NEXT_PAGE = "
|
| 18 |
-
SCROLL_UP = "
|
| 19 |
-
SCROLL_DOWN = "
|
| 20 |
-
SCROLL_TOP = "
|
| 21 |
-
SCROLL_BOTTOM = "
|
| 22 |
-
SELECT_ITEM_DETAIL_INFO = "
|
| 23 |
-
SELECT_ITEM = "
|
| 24 |
MESSAGE = "message"
|
|
|
|
|
|
| 8 |
SMS = "sms"
|
| 9 |
CONTACT = "contact"
|
| 10 |
MESSAGE = "message"
|
| 11 |
+
AUTO_TASK = "autotask"
|
| 12 |
+
RAILS_OFF_TOPIC = "rails_off_topic"
|
| 13 |
|
| 14 |
class BrowserType:
|
| 15 |
+
OPEN_TAB = "opentab"
|
| 16 |
+
OPEN_TAB_SEARCH = "opentabsearch"
|
| 17 |
+
CLOSE_TAB = "closetab"
|
| 18 |
+
PREVIOUS_PAGE = "previouspage"
|
| 19 |
+
NEXT_PAGE = "nextpage"
|
| 20 |
+
SCROLL_UP = "scrollup"
|
| 21 |
+
SCROLL_DOWN = "scrolldown"
|
| 22 |
+
SCROLL_TOP = "scrolltop"
|
| 23 |
+
SCROLL_BOTTOM = "scrollbottom"
|
| 24 |
+
SELECT_ITEM_DETAIL_INFO = "selectitemdetailinfo"
|
| 25 |
+
SELECT_ITEM = "selectitem"
|
| 26 |
MESSAGE = "message"
|
| 27 |
+
ASK_WEBSITE = "askwebsite"
|
Brain/src/common/utils.py
CHANGED
|
@@ -40,6 +40,10 @@ AUTH_TOKEN = os.getenv("TWILIO_AUTH_TOKEN")
|
|
| 40 |
HUGGINGFACEHUB_API_TOKEN = os.getenv("HUGGINGFACEHUB_API_TOKEN")
|
| 41 |
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
class ProgramType:
|
| 44 |
BROWSER = "browser"
|
| 45 |
ALERT = "alert"
|
|
@@ -47,6 +51,8 @@ class ProgramType:
|
|
| 47 |
SMS = "sms"
|
| 48 |
CONTACT = "contact"
|
| 49 |
MESSAGE = "message"
|
|
|
|
|
|
|
| 50 |
|
| 51 |
|
| 52 |
# validate json format
|
|
|
|
| 40 |
HUGGINGFACEHUB_API_TOKEN = os.getenv("HUGGINGFACEHUB_API_TOKEN")
|
| 41 |
|
| 42 |
|
| 43 |
+
# actions flag :True -> Directly with Category_prompt
|
| 44 |
+
ACTION_FLAG = True
|
| 45 |
+
|
| 46 |
+
|
| 47 |
class ProgramType:
|
| 48 |
BROWSER = "browser"
|
| 49 |
ALERT = "alert"
|
|
|
|
| 51 |
SMS = "sms"
|
| 52 |
CONTACT = "contact"
|
| 53 |
MESSAGE = "message"
|
| 54 |
+
AUTO_TASK = "autotask"
|
| 55 |
+
RAILS_OFF_TOPIC = "rails_off_topic"
|
| 56 |
|
| 57 |
|
| 58 |
# validate json format
|
Brain/src/gradio_debug.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""gradio implementaion"""
|
| 2 |
+
# import gradio as gr
|
| 3 |
+
# import requests
|
| 4 |
+
# import json
|
| 5 |
+
# from gradio.components import Textbox, Number
|
| 6 |
+
#
|
| 7 |
+
# DEFAULT_UUID = "c40a09075d11940f"
|
| 8 |
+
#
|
| 9 |
+
#
|
| 10 |
+
# def gradio_send_notification(uuid: str, query: str):
|
| 11 |
+
# url = "http://localhost:7860/sendNotification"
|
| 12 |
+
# data = {
|
| 13 |
+
# "confs": {
|
| 14 |
+
# "openai_key": "",
|
| 15 |
+
# "pinecone_key": "",
|
| 16 |
+
# "pinecone_env": "",
|
| 17 |
+
# "firebase_key": "",
|
| 18 |
+
# "settings": {"temperature": 0.6},
|
| 19 |
+
# "token": "eSyP3i7ITZuq8hWn2qutTl:APA91bH1FtWkaTSJwuX4WKWAl3Q-ZFyrOw4UtMP4IfwuvNrHOThH7EvEGIhtguilLRyQNlLiXatEN0xntHAc8bbKobSGjge3wxIHlspbIWY_855CzONqaVdl3y3zOmgKZNnuhYi4gwbh",
|
| 20 |
+
# "uuid": uuid,
|
| 21 |
+
# },
|
| 22 |
+
# "message": query,
|
| 23 |
+
# }
|
| 24 |
+
#
|
| 25 |
+
# response = requests.post(
|
| 26 |
+
# url, data=json.dumps(data), headers={"Content-Type": "application/json"}
|
| 27 |
+
# )
|
| 28 |
+
# response = response.json()
|
| 29 |
+
# return json.dumps(response["result"]), response["status_code"]
|
| 30 |
+
#
|
| 31 |
+
#
|
| 32 |
+
# debug_send_notification = gr.Interface(
|
| 33 |
+
# fn=gradio_send_notification,
|
| 34 |
+
# inputs=[
|
| 35 |
+
# Textbox(
|
| 36 |
+
# label="UUID",
|
| 37 |
+
# placeholder="Please input your UUID.",
|
| 38 |
+
# value="c40a09075d11940f",
|
| 39 |
+
# ),
|
| 40 |
+
# Textbox(label="query", placeholder="Please input your prompt."),
|
| 41 |
+
# ],
|
| 42 |
+
# outputs=[
|
| 43 |
+
# Textbox(label="Result"),
|
| 44 |
+
# Number(label="Status Code"),
|
| 45 |
+
# ],
|
| 46 |
+
# allow_flagging="never",
|
| 47 |
+
# )
|
Brain/src/model/requests/request_model.py
CHANGED
|
@@ -205,3 +205,32 @@ class Train(BasicReq):
|
|
| 205 |
id: str
|
| 206 |
data: TrainData
|
| 207 |
status: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
id: str
|
| 206 |
data: TrainData
|
| 207 |
status: str
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
"""endpoint /auto_task/delete"""
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
class AutoTaskDelete(BasicReq):
|
| 214 |
+
class Body(BaseModel):
|
| 215 |
+
reference_link: str
|
| 216 |
+
|
| 217 |
+
data: Body
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
"""endpoint /read_emails"""
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
class EmailReader(BasicReq):
|
| 224 |
+
class Body(BaseModel):
|
| 225 |
+
sender: str
|
| 226 |
+
pwd: str
|
| 227 |
+
imap_folder: str
|
| 228 |
+
|
| 229 |
+
data: Body
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
"""endpoint : /contact/get_by_ids"""
|
| 233 |
+
|
| 234 |
+
|
| 235 |
+
class GetContactsByIds(BasicReq):
|
| 236 |
+
contactIds: list[str]
|
Brain/src/rising_plugin/gmail/email_plugin.py
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import email
|
| 2 |
+
import imaplib
|
| 3 |
+
import json
|
| 4 |
+
import mimetypes
|
| 5 |
+
import os
|
| 6 |
+
import re
|
| 7 |
+
import smtplib
|
| 8 |
+
import time
|
| 9 |
+
from email.header import decode_header
|
| 10 |
+
from email.message import EmailMessage
|
| 11 |
+
|
| 12 |
+
from bs4 import BeautifulSoup
|
| 13 |
+
|
| 14 |
+
# email variables
|
| 15 |
+
EMAIL_SMTP_HOST = "smtp.gmail.com"
|
| 16 |
+
EMAIL_SMTP_PORT = 587
|
| 17 |
+
EMAIL_IMAP_SERVER = "imap.gmail.com"
|
| 18 |
+
EMAIL_SIGNATURE = "This was sent by Brain Service"
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class EmailPlugin:
|
| 22 |
+
def send_email(
|
| 23 |
+
self, sender: str, pwd: str, to: str, subject: str, body: str, to_send: bool
|
| 24 |
+
) -> str:
|
| 25 |
+
return self.send_email_with_attachment_internal(
|
| 26 |
+
sender=sender,
|
| 27 |
+
pwd=pwd,
|
| 28 |
+
to=to,
|
| 29 |
+
title=subject,
|
| 30 |
+
message=body,
|
| 31 |
+
attachment=None,
|
| 32 |
+
attachment_path=None,
|
| 33 |
+
to_send=to_send,
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
def send_email_with_attachment(
|
| 37 |
+
self,
|
| 38 |
+
sender: str,
|
| 39 |
+
pwd: str,
|
| 40 |
+
to: str,
|
| 41 |
+
subject: str,
|
| 42 |
+
body: str,
|
| 43 |
+
filename: str,
|
| 44 |
+
to_send: bool,
|
| 45 |
+
) -> str:
|
| 46 |
+
attachment_path = filename
|
| 47 |
+
attachment = os.path.basename(filename)
|
| 48 |
+
return self.send_email_with_attachment_internal(
|
| 49 |
+
sender=sender,
|
| 50 |
+
pwd=pwd,
|
| 51 |
+
to=to,
|
| 52 |
+
title=subject,
|
| 53 |
+
message=body,
|
| 54 |
+
attachment_path=attachment_path,
|
| 55 |
+
attachment=attachment,
|
| 56 |
+
to_send=to_send,
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
def send_email_with_attachment_internal(
|
| 60 |
+
self,
|
| 61 |
+
sender: str,
|
| 62 |
+
pwd: str,
|
| 63 |
+
to: str,
|
| 64 |
+
title: str,
|
| 65 |
+
message: str,
|
| 66 |
+
attachment_path: str | None,
|
| 67 |
+
attachment: str | None,
|
| 68 |
+
to_send: bool,
|
| 69 |
+
) -> str:
|
| 70 |
+
"""Send an email
|
| 71 |
+
|
| 72 |
+
Args:
|
| 73 |
+
sender (str): The email of the sender
|
| 74 |
+
pwd (str): The password of the sender
|
| 75 |
+
to (str): The email of the recipient
|
| 76 |
+
title (str): The title of the email
|
| 77 |
+
message (str): The message content of the email
|
| 78 |
+
|
| 79 |
+
Returns:
|
| 80 |
+
str: Any error messages
|
| 81 |
+
"""
|
| 82 |
+
email_sender = sender
|
| 83 |
+
email_password = pwd
|
| 84 |
+
|
| 85 |
+
msg = EmailMessage()
|
| 86 |
+
msg["Subject"] = title
|
| 87 |
+
msg["From"] = email_sender
|
| 88 |
+
msg["To"] = to
|
| 89 |
+
|
| 90 |
+
signature = EMAIL_SIGNATURE
|
| 91 |
+
if signature:
|
| 92 |
+
message += f"\n{signature}"
|
| 93 |
+
|
| 94 |
+
msg.set_content(message)
|
| 95 |
+
|
| 96 |
+
if attachment_path:
|
| 97 |
+
ctype, encoding = mimetypes.guess_type(attachment_path)
|
| 98 |
+
if ctype is None or encoding is not None:
|
| 99 |
+
# No guess could be made, or the file is encoded (compressed)
|
| 100 |
+
ctype = "application/octet-stream"
|
| 101 |
+
maintype, subtype = ctype.split("/", 1)
|
| 102 |
+
with open(file=attachment_path, mode="rb") as fp:
|
| 103 |
+
msg.add_attachment(
|
| 104 |
+
fp.read(), maintype=maintype, subtype=subtype, filename=attachment
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
if to_send:
|
| 108 |
+
smtp_host = EMAIL_SMTP_HOST
|
| 109 |
+
smtp_port = EMAIL_SMTP_PORT
|
| 110 |
+
# send email
|
| 111 |
+
with smtplib.SMTP(host=smtp_host, port=smtp_port) as smtp:
|
| 112 |
+
smtp.ehlo()
|
| 113 |
+
smtp.starttls()
|
| 114 |
+
smtp.login(user=email_sender, password=email_password)
|
| 115 |
+
smtp.send_message(msg)
|
| 116 |
+
smtp.quit()
|
| 117 |
+
return f"Email was sent to {to}!"
|
| 118 |
+
else:
|
| 119 |
+
conn = self.imap_open(
|
| 120 |
+
imap_folder="[Gmail]/Drafts",
|
| 121 |
+
email_sender=email_sender,
|
| 122 |
+
email_password=email_password,
|
| 123 |
+
)
|
| 124 |
+
conn.append(
|
| 125 |
+
mailbox="[Gmail]/Drafts",
|
| 126 |
+
flags="",
|
| 127 |
+
date_time=imaplib.Time2Internaldate(time.time()),
|
| 128 |
+
message=str(msg).encode("UTF-8"),
|
| 129 |
+
)
|
| 130 |
+
return f"Email went to [Gmail]/Drafts!"
|
| 131 |
+
|
| 132 |
+
def read_emails(
|
| 133 |
+
self,
|
| 134 |
+
sender: str,
|
| 135 |
+
pwd: str,
|
| 136 |
+
imap_folder: str = "inbox",
|
| 137 |
+
imap_search_command: str = "UNSEEN",
|
| 138 |
+
limit: int = 5,
|
| 139 |
+
page: int = 1,
|
| 140 |
+
) -> str:
|
| 141 |
+
"""Read emails from an IMAP mailbox.
|
| 142 |
+
|
| 143 |
+
This function reads emails from a specified IMAP folder, using a given IMAP search command, limits, and page numbers.
|
| 144 |
+
It returns a list of emails with their details, including the sender, recipient, date, CC, subject, and message body.
|
| 145 |
+
|
| 146 |
+
Args:
|
| 147 |
+
sender (str): The email of the sender
|
| 148 |
+
pwd (str): The password of the sender
|
| 149 |
+
imap_folder (str, optional): The name of the IMAP folder to read emails from. Defaults to "inbox".
|
| 150 |
+
imap_search_command (str, optional): The IMAP search command to filter emails. Defaults to "UNSEEN".
|
| 151 |
+
limit (int, optional): Number of email's the function should return. Defaults to 5 emails.
|
| 152 |
+
page (int, optional): The index of the page result the function should resturn. Defaults to 0, the first page.
|
| 153 |
+
|
| 154 |
+
Returns:
|
| 155 |
+
str: A list of dictionaries containing email details if there are any matching emails.
|
| 156 |
+
"""
|
| 157 |
+
email_sender = sender
|
| 158 |
+
imap_folder = self.adjust_imap_folder_for_gmail(
|
| 159 |
+
imap_folder=imap_folder, email_sender=email_sender
|
| 160 |
+
)
|
| 161 |
+
imap_folder = self.enclose_with_quotes(imap_folder)
|
| 162 |
+
imap_search_ar = self.split_imap_search_command(imap_search_command)
|
| 163 |
+
email_password = pwd
|
| 164 |
+
|
| 165 |
+
mark_as_seen = "False"
|
| 166 |
+
if isinstance(mark_as_seen, str):
|
| 167 |
+
mark_as_seen = json.loads(mark_as_seen.lower())
|
| 168 |
+
|
| 169 |
+
conn = self.imap_open(
|
| 170 |
+
imap_folder=imap_folder,
|
| 171 |
+
email_sender=email_sender,
|
| 172 |
+
email_password=email_password,
|
| 173 |
+
)
|
| 174 |
+
|
| 175 |
+
imap_keyword = imap_search_ar[0]
|
| 176 |
+
if len(imap_search_ar) == 1:
|
| 177 |
+
_, search_data = conn.search(None, imap_keyword)
|
| 178 |
+
else:
|
| 179 |
+
argument = self.enclose_with_quotes(imap_search_ar[1])
|
| 180 |
+
_, search_data = conn.search(None, imap_keyword, argument)
|
| 181 |
+
|
| 182 |
+
messages = []
|
| 183 |
+
for num in search_data[0].split():
|
| 184 |
+
if mark_as_seen:
|
| 185 |
+
message_parts = "(RFC822)"
|
| 186 |
+
else:
|
| 187 |
+
message_parts = "(BODY.PEEK[])"
|
| 188 |
+
_, msg_data = conn.fetch(message_set=num, message_parts=message_parts)
|
| 189 |
+
for response_part in msg_data:
|
| 190 |
+
if isinstance(response_part, tuple):
|
| 191 |
+
msg = email.message_from_bytes(response_part[1])
|
| 192 |
+
|
| 193 |
+
# If the subject has unknown encoding, return blank
|
| 194 |
+
if msg["Subject"] is not None:
|
| 195 |
+
subject, encoding = decode_header(msg["Subject"])[0]
|
| 196 |
+
else:
|
| 197 |
+
subject = ""
|
| 198 |
+
encoding = ""
|
| 199 |
+
|
| 200 |
+
if isinstance(subject, bytes):
|
| 201 |
+
try:
|
| 202 |
+
# If the subject has unknown encoding, return blank
|
| 203 |
+
if encoding is not None:
|
| 204 |
+
subject = subject.decode(encoding)
|
| 205 |
+
else:
|
| 206 |
+
subject = ""
|
| 207 |
+
except [LookupError] as e:
|
| 208 |
+
pass
|
| 209 |
+
|
| 210 |
+
body = self.get_email_body(msg)
|
| 211 |
+
# Clean email body
|
| 212 |
+
body = self.clean_email_body(body)
|
| 213 |
+
|
| 214 |
+
from_address = msg["From"]
|
| 215 |
+
to_address = msg["To"]
|
| 216 |
+
date = msg["Date"]
|
| 217 |
+
cc = msg["CC"] if msg["CC"] else ""
|
| 218 |
+
|
| 219 |
+
messages.append(
|
| 220 |
+
{
|
| 221 |
+
"From": from_address,
|
| 222 |
+
"To": to_address,
|
| 223 |
+
"Date": date,
|
| 224 |
+
"CC": cc,
|
| 225 |
+
"Subject": subject,
|
| 226 |
+
"Message Body": body,
|
| 227 |
+
}
|
| 228 |
+
)
|
| 229 |
+
|
| 230 |
+
conn.logout()
|
| 231 |
+
if not messages:
|
| 232 |
+
messages.append(
|
| 233 |
+
{
|
| 234 |
+
"From": "",
|
| 235 |
+
"To": "",
|
| 236 |
+
"Date": "",
|
| 237 |
+
"CC": "",
|
| 238 |
+
"Subject": "",
|
| 239 |
+
"Message Body": "There are no Emails",
|
| 240 |
+
}
|
| 241 |
+
)
|
| 242 |
+
return json.dumps(messages)
|
| 243 |
+
|
| 244 |
+
# Confirm that integer parameters are the right type
|
| 245 |
+
limit = int(limit)
|
| 246 |
+
page = int(page)
|
| 247 |
+
|
| 248 |
+
# Validate parameter values
|
| 249 |
+
if limit < 1:
|
| 250 |
+
raise ValueError("Error: The message limit should be 1 or greater")
|
| 251 |
+
|
| 252 |
+
page_count = len(messages) // limit + (len(messages) % limit > 0)
|
| 253 |
+
|
| 254 |
+
if page < 1 or page > page_count:
|
| 255 |
+
raise ValueError(
|
| 256 |
+
"Error: The page value references a page that is not part of the results"
|
| 257 |
+
)
|
| 258 |
+
|
| 259 |
+
# Calculate paginated indexes
|
| 260 |
+
start_index = len(messages) - (page * limit + 1)
|
| 261 |
+
end_index = start_index + limit
|
| 262 |
+
start_index = max(start_index, 0)
|
| 263 |
+
|
| 264 |
+
# Return paginated indexes
|
| 265 |
+
if start_index == end_index:
|
| 266 |
+
return json.dumps([messages[start_index]])
|
| 267 |
+
else:
|
| 268 |
+
return json.dumps(messages[start_index:end_index])
|
| 269 |
+
|
| 270 |
+
def adjust_imap_folder_for_gmail(self, imap_folder: str, email_sender: str) -> str:
|
| 271 |
+
if "@gmail" in email_sender.lower() or "@googlemail" in email_sender.lower():
|
| 272 |
+
if "sent" in imap_folder.lower():
|
| 273 |
+
return '"[Gmail]/Sent Mail"'
|
| 274 |
+
if "draft" in imap_folder.lower():
|
| 275 |
+
return "[Gmail]/Drafts"
|
| 276 |
+
return imap_folder
|
| 277 |
+
|
| 278 |
+
def imap_open(
|
| 279 |
+
self, imap_folder: str, email_sender: str, email_password: str
|
| 280 |
+
) -> imaplib.IMAP4_SSL:
|
| 281 |
+
imap_server = EMAIL_IMAP_SERVER
|
| 282 |
+
conn = imaplib.IMAP4_SSL(imap_server)
|
| 283 |
+
conn.login(user=email_sender, password=email_password)
|
| 284 |
+
conn.select(imap_folder)
|
| 285 |
+
return conn
|
| 286 |
+
|
| 287 |
+
def get_email_body(self, msg: email.message.Message) -> str:
|
| 288 |
+
if msg.is_multipart():
|
| 289 |
+
for part in msg.walk():
|
| 290 |
+
content_type = part.get_content_type()
|
| 291 |
+
content_disposition = str(part.get("Content-Disposition"))
|
| 292 |
+
if (
|
| 293 |
+
content_type == "text/plain"
|
| 294 |
+
and "attachment" not in content_disposition
|
| 295 |
+
):
|
| 296 |
+
# If the email body has unknown encoding, return null
|
| 297 |
+
try:
|
| 298 |
+
return part.get_payload(decode=True).decode()
|
| 299 |
+
except UnicodeDecodeError as e:
|
| 300 |
+
pass
|
| 301 |
+
else:
|
| 302 |
+
try:
|
| 303 |
+
# If the email body has unknown encoding, return null
|
| 304 |
+
return msg.get_payload(decode=True).decode()
|
| 305 |
+
except UnicodeDecodeError as e:
|
| 306 |
+
pass
|
| 307 |
+
|
| 308 |
+
def enclose_with_quotes(self, s):
|
| 309 |
+
# Check if string contains whitespace
|
| 310 |
+
has_whitespace = bool(re.search(r"\s", s))
|
| 311 |
+
|
| 312 |
+
# Check if string is already enclosed by quotes
|
| 313 |
+
is_enclosed = s.startswith(("'", '"')) and s.endswith(("'", '"'))
|
| 314 |
+
|
| 315 |
+
# If string has whitespace and is not enclosed by quotes, enclose it with double quotes
|
| 316 |
+
if has_whitespace and not is_enclosed:
|
| 317 |
+
return f'"{s}"'
|
| 318 |
+
else:
|
| 319 |
+
return s
|
| 320 |
+
|
| 321 |
+
def split_imap_search_command(self, input_string):
|
| 322 |
+
input_string = input_string.strip()
|
| 323 |
+
parts = input_string.split(maxsplit=1)
|
| 324 |
+
parts = [part.strip() for part in parts]
|
| 325 |
+
|
| 326 |
+
return parts
|
| 327 |
+
|
| 328 |
+
def clean_email_body(self, email_body):
|
| 329 |
+
"""Remove formating and URL's from an email's body
|
| 330 |
+
|
| 331 |
+
Args:
|
| 332 |
+
email_body (str, optional): The email's body
|
| 333 |
+
|
| 334 |
+
Returns:
|
| 335 |
+
str: The email's body without any formating or URL's
|
| 336 |
+
"""
|
| 337 |
+
|
| 338 |
+
# If body is None, return an empty string
|
| 339 |
+
if email_body is None:
|
| 340 |
+
email_body = ""
|
| 341 |
+
|
| 342 |
+
# Remove any HTML tags
|
| 343 |
+
email_body = BeautifulSoup(email_body, "html.parser")
|
| 344 |
+
email_body = email_body.get_text()
|
| 345 |
+
|
| 346 |
+
# Remove return characters
|
| 347 |
+
email_body = "".join(email_body.splitlines())
|
| 348 |
+
|
| 349 |
+
# Remove extra spaces
|
| 350 |
+
email_body = " ".join(email_body.split())
|
| 351 |
+
|
| 352 |
+
# Remove unicode characters
|
| 353 |
+
email_body = email_body.encode("ascii", "ignore")
|
| 354 |
+
email_body = email_body.decode("utf-8", "ignore")
|
| 355 |
+
|
| 356 |
+
# Remove any remaining URL's
|
| 357 |
+
email_body = re.sub(r"http\S+", "", email_body)
|
| 358 |
+
|
| 359 |
+
return email_body
|
Brain/src/rising_plugin/guardrails-config/actions/actions.py
CHANGED
|
@@ -13,117 +13,11 @@
|
|
| 13 |
# See the License for the specific language governing permissions and
|
| 14 |
# limitations under the License.
|
| 15 |
|
| 16 |
-
import os
|
| 17 |
import json
|
| 18 |
-
import numpy as np
|
| 19 |
-
|
| 20 |
-
from Brain.src.service.train_service import TrainService
|
| 21 |
-
from langchain.docstore.document import Document
|
| 22 |
-
|
| 23 |
-
from Brain.src.common.brain_exception import BrainException
|
| 24 |
-
from Brain.src.common.utils import (
|
| 25 |
-
COMMAND_SMS_INDEXES,
|
| 26 |
-
COMMAND_BROWSER_OPEN,
|
| 27 |
-
PINECONE_INDEX_NAME,
|
| 28 |
-
DEFAULT_GPT_MODEL,
|
| 29 |
-
)
|
| 30 |
-
from Brain.src.model.req_model import ReqModel
|
| 31 |
-
from Brain.src.model.requests.request_model import BasicReq
|
| 32 |
-
from Brain.src.rising_plugin.image_embedding import (
|
| 33 |
-
query_image_text,
|
| 34 |
-
)
|
| 35 |
-
from Brain.src.rising_plugin.csv_embed import get_embed
|
| 36 |
|
| 37 |
from nemoguardrails.actions import action
|
| 38 |
|
| 39 |
-
from Brain.src.rising_plugin.llm.falcon_llm import FalconLLM
|
| 40 |
-
from Brain.src.rising_plugin.llm.gpt_llm import GptLLM
|
| 41 |
-
from Brain.src.rising_plugin.llm.llms import (
|
| 42 |
-
get_llm_chain,
|
| 43 |
-
GPT_3_5_TURBO,
|
| 44 |
-
GPT_4_32K,
|
| 45 |
-
GPT_4,
|
| 46 |
-
FALCON_7B,
|
| 47 |
-
GPT_LLM_MODELS,
|
| 48 |
-
)
|
| 49 |
-
|
| 50 |
-
from Brain.src.rising_plugin.pinecone_engine import (
|
| 51 |
-
get_pinecone_index_namespace,
|
| 52 |
-
init_pinecone,
|
| 53 |
-
)
|
| 54 |
-
|
| 55 |
-
"""
|
| 56 |
-
query is json string with below format
|
| 57 |
-
{
|
| 58 |
-
"query": string,
|
| 59 |
-
"model": string,
|
| 60 |
-
"uuid": string,
|
| 61 |
-
"image_search": bool,
|
| 62 |
-
"setting": {
|
| 63 |
-
"host_name": string,
|
| 64 |
-
"openai_key": string,
|
| 65 |
-
"pinecone_key": string,
|
| 66 |
-
"pinecone_env": string,
|
| 67 |
-
"firebase_key": string,
|
| 68 |
-
"firebase_env": string
|
| 69 |
-
"settings": {
|
| 70 |
-
"temperature": float
|
| 71 |
-
},
|
| 72 |
-
"token": string,
|
| 73 |
-
"uuid": string,
|
| 74 |
-
}
|
| 75 |
-
}
|
| 76 |
-
"""
|
| 77 |
-
|
| 78 |
|
| 79 |
@action()
|
| 80 |
async def general_question(query):
|
| 81 |
-
""
|
| 82 |
-
falcon_llm = FalconLLM()
|
| 83 |
-
docs = []
|
| 84 |
-
|
| 85 |
-
"""step 0-->: parsing parms from the json query"""
|
| 86 |
-
try:
|
| 87 |
-
json_query = json.loads(query)
|
| 88 |
-
except Exception as ex:
|
| 89 |
-
raise BrainException(BrainException.JSON_PARSING_ISSUE_MSG)
|
| 90 |
-
query = json_query["query"]
|
| 91 |
-
image_search = json_query["image_search"]
|
| 92 |
-
page_content = json_query["page_content"]
|
| 93 |
-
document_id = json_query["document_id"]
|
| 94 |
-
setting = ReqModel(json_query["setting"])
|
| 95 |
-
is_browser = json_query["is_browser"]
|
| 96 |
-
|
| 97 |
-
docs.append(Document(page_content=page_content, metadata=""))
|
| 98 |
-
""" 1. calling gpt model to categorize for all message"""
|
| 99 |
-
chain_data = get_llm_chain(model=DEFAULT_GPT_MODEL, setting=setting).run(
|
| 100 |
-
input_documents=docs, question=query
|
| 101 |
-
)
|
| 102 |
-
try:
|
| 103 |
-
result = json.loads(chain_data)
|
| 104 |
-
# check image query with only its text
|
| 105 |
-
if result["program"] == "image":
|
| 106 |
-
if image_search:
|
| 107 |
-
result["content"] = {
|
| 108 |
-
"image_name": query_image_text(result["content"], "", setting)
|
| 109 |
-
}
|
| 110 |
-
""" 2. check program is message to handle it with falcon llm """
|
| 111 |
-
if result["program"] == "message":
|
| 112 |
-
if is_browser:
|
| 113 |
-
result["program"] = "ask_website"
|
| 114 |
-
else:
|
| 115 |
-
# """FALCON_7B:"""
|
| 116 |
-
result["content"] = falcon_llm.query(question=query)
|
| 117 |
-
return json.dumps(result)
|
| 118 |
-
except ValueError as e:
|
| 119 |
-
# Check sms and browser query
|
| 120 |
-
if document_id in COMMAND_SMS_INDEXES:
|
| 121 |
-
return json.dumps({"program": "sms", "content": chain_data})
|
| 122 |
-
elif document_id in COMMAND_BROWSER_OPEN:
|
| 123 |
-
return json.dumps({"program": "browser", "content": "https://google.com"})
|
| 124 |
-
|
| 125 |
-
if is_browser:
|
| 126 |
-
return json.dumps({"program": "ask_website", "content": ""})
|
| 127 |
-
return json.dumps(
|
| 128 |
-
{"program": "message", "content": falcon_llm.query(question=query)}
|
| 129 |
-
)
|
|
|
|
| 13 |
# See the License for the specific language governing permissions and
|
| 14 |
# limitations under the License.
|
| 15 |
|
|
|
|
| 16 |
import json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
from nemoguardrails.actions import action
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
@action()
|
| 22 |
async def general_question(query):
|
| 23 |
+
return json.dumps({"program": "message", "content": query})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Brain/src/rising_plugin/guardrails-config/off-security.co
CHANGED
|
@@ -15,4 +15,4 @@ define flow
|
|
| 15 |
bot explain cant off security
|
| 16 |
|
| 17 |
define bot explain cant off security
|
| 18 |
-
'{"program": "
|
|
|
|
| 15 |
bot explain cant off security
|
| 16 |
|
| 17 |
define bot explain cant off security
|
| 18 |
+
'{"program": "rails_off_topic", "content": "Sorry, I cannot comment on anything which is relevant to the password or pin code."}'
|
Brain/src/rising_plugin/llm/llms.py
CHANGED
|
@@ -20,6 +20,38 @@ GPT_LLM_MODELS = [GPT_3_5_TURBO, GPT_4, GPT_4_32K]
|
|
| 20 |
"""exception message"""
|
| 21 |
EXCEPTION_MSG = f"The model is not correct. It should be in {LLM_MODELS}"
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
"""validate model"""
|
| 24 |
|
| 25 |
|
|
@@ -61,7 +93,9 @@ def get_llm(
|
|
| 61 |
"""check model"""
|
| 62 |
llm = GptLLM(openai_key=setting.openai_key)
|
| 63 |
if model == GPT_3_5_TURBO or model == GPT_4 or model == GPT_4_32K:
|
| 64 |
-
llm = GptLLM(
|
|
|
|
|
|
|
| 65 |
elif model == FALCON_7B:
|
| 66 |
llm = FalconLLM(temperature=temperature, max_new_tokens=max_new_tokens)
|
| 67 |
return llm
|
|
|
|
| 20 |
"""exception message"""
|
| 21 |
EXCEPTION_MSG = f"The model is not correct. It should be in {LLM_MODELS}"
|
| 22 |
|
| 23 |
+
|
| 24 |
+
"""prompt"""
|
| 25 |
+
CATEGORY_PROMPT = """
|
| 26 |
+
If user is going to say about a image with its description to search, please answer belowing json format. {"program": "image", "content": "description of the image that user is going to search"}
|
| 27 |
+
If user is going to ask about a image, please answer belowing json format. {"program": "image", "content": "description of the image that user is going to search"}
|
| 28 |
+
If user said that send sms or text, please answer belowing json format. {"program": "sms", "content": "ask who"}
|
| 29 |
+
If user said that compose, write, or create an sms message, please answer belowing json format. {"program": "sms", "content": "ask who"}
|
| 30 |
+
If user said that search contact with its description such as display name or phone number, please answer belowing json format. {"program": "contact", "content": "description of the contact that user is going to search"}
|
| 31 |
+
If user said that open a tab, go to a tab, or open a page, please answer belowing json format. {"program": "opentab", "content": ""}
|
| 32 |
+
If user said that open a tab and search, go to a tab and search, or open a page and search, please answer belowing json format. {"program": "opentabsearch", "content": "keyword that user is going to search"}
|
| 33 |
+
If user said that close a tab, please answer belowing json format. {"program": "closetab", "content": ""}
|
| 34 |
+
If user said that launch a browser or open a browser, please answer belowing json format. {"program": "browser", "content": "https://google.com"}
|
| 35 |
+
If user said that go to a previous page, or open a previous page, please answer belowing json format. {"program": "previouspage", "content": ""}
|
| 36 |
+
If user said that go to a next page, or open a next page, please answer belowing json format. {"program": "nextpage", "content": ""}
|
| 37 |
+
If user said that scroll up, scroll up page, or page scroll up, please answer belowing json format. {"program": "scrollup", "content": ""}
|
| 38 |
+
If user said that scroll down, scroll down page, page scroll down, please answer belowing json format. {"program": "scrolldown", "content": ""}
|
| 39 |
+
If user said that scroll top, scroll top page, or scroll top of page, please answer belowing json format. {"program": "scrolltop", "content": ""}
|
| 40 |
+
If user said that scroll bottom, scroll bottom page, or scroll bottom of page, please answer belowing json format. {"program": "scrollbottom", "content": ""}
|
| 41 |
+
If user is going to select an item, an article or a website with its description in a web browser, please answer belowing json format. {"program": "selectitemdetailinfo", "content": "the description of an item, an article or a website in a browser"}
|
| 42 |
+
If user said that ask about the content in website, for example, if users ask something like 'what is #query in this website?' or 'Can you tell me about #query based on this website?', please answer belowing json format. {"program": "askwebsite", "content": ""}
|
| 43 |
+
If user said that open a website using web browsers, please answer belowing json format. The url user is going to open can exist or not. If user doesn\\'t say exact url and want to open some sites, you have to find the best proper url. If user didn\\'t say any url and you can't find proper url, please set website url to "https://www.google.com". {"program": "browser", "url": "website url that user is going to open"}
|
| 44 |
+
If users are going to ask something based on the data of website, please answer belowing json format. {"program": "askwebsite", "content": ""}
|
| 45 |
+
If user is going to set or create alarm with time and label, please answer belowing json format.\n {"program": "alarm", "content": {"type":"create", "time":"please set time as 24-hours format that user is going to set. If user did not provide any alarm time, set "0:0"", "label":"please set label that user is going to set. If user did not provide any label, set "alarm""}}\n This is example data.\n User: Set an alarm.\n AI: {"program":"alarm", "content": {"type":"create", "time":"0:0", "label":"alarm"}}\n User: Set an alarm with label as "wake up".\n AI: {"program":"alarm", "content": {"type":"create", "time":"0:0", "label":"wake up"}}\n User: Set an alarm for 5:00 AM.\n AI: {"program":"alarm", "content": {"type":"create", "time":"5:00", "label":"alarm"}}\n User: Set an alarm for 5:00 PM with label as "wake up".\n AI: {"program":"alarm", "content": {"type":"create", "time":"17:00", "label":"wake up"}}
|
| 46 |
+
If user is going to read email or message, please answer belowing json format. {"program": "reademail", "content": ""}
|
| 47 |
+
If user is going to send email or message, please answer belowing json format. {"program": "sendemail", "content": ""}
|
| 48 |
+
If user is going to compose, write, or create an email, please answer belowing json format. {"program": "writeemail", "content": ""}
|
| 49 |
+
User wants to help organization in achieving its goals, which bridges the gap between the user is (present) and where he/she wants to go (future), or that is deciding in advance what to do, how to do when to do it and by whom it is to be done. Also the description ensures in thoughts and actions, work is carried on smoothly without any confusion and misunderstanding. \n And it can be done for the future and the future is full of uncertainties. \n So it looks like to make a decision as well. It helps make rational decisions by choosing the best most profitable alternative which may bring lower cost, adaptable to the organization and situations. \n If user is going to say about planning strategy, or something like that , please answer belowing json format. {"program": "autotask", "content": ""}
|
| 50 |
+
If all of above is not correct, please give the most appropriate answer to the user's question. Please answer belowing json format. {"program":"message", "content":"your answer"}
|
| 51 |
+
If users are going to know about real-time capabilities such as News, Weather, Stocks, Booking, Planning, or etc, then please answer belowing json format. {"program": "autotask", "content": ""}
|
| 52 |
+
If your answer is not correct with the program type which mentioned in this rules, please answer belowing json format. {"program": "autotask", "content": ""}
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
"""validate model"""
|
| 56 |
|
| 57 |
|
|
|
|
| 93 |
"""check model"""
|
| 94 |
llm = GptLLM(openai_key=setting.openai_key)
|
| 95 |
if model == GPT_3_5_TURBO or model == GPT_4 or model == GPT_4_32K:
|
| 96 |
+
llm = GptLLM(
|
| 97 |
+
model=model, openai_key=setting.openai_key, temperature=temperature
|
| 98 |
+
)
|
| 99 |
elif model == FALCON_7B:
|
| 100 |
llm = FalconLLM(temperature=temperature, max_new_tokens=max_new_tokens)
|
| 101 |
return llm
|
Brain/src/rising_plugin/rails_validate.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""validate rails result:
|
| 2 |
+
checking with program whether is it message or rails_off_topic"""
|
| 3 |
+
import json
|
| 4 |
+
|
| 5 |
+
from Brain.src.common.program_type import ProgramType
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def validate_rails(data: str) -> bool:
|
| 9 |
+
try:
|
| 10 |
+
json_obj = json.loads(data["content"])
|
| 11 |
+
if json_obj["program"] == ProgramType.RAILS_OFF_TOPIC:
|
| 12 |
+
return False
|
| 13 |
+
return True
|
| 14 |
+
except Exception as ex:
|
| 15 |
+
return False
|
Brain/src/rising_plugin/risingplugin.py
CHANGED
|
@@ -14,20 +14,26 @@ from langchain.chains.question_answering import load_qa_chain
|
|
| 14 |
from nemoguardrails.rails import LLMRails, RailsConfig
|
| 15 |
|
| 16 |
from langchain.chat_models import ChatOpenAI
|
| 17 |
-
|
| 18 |
from firebase_admin import storage
|
| 19 |
|
| 20 |
from .csv_embed import get_embed
|
| 21 |
-
from .llm.
|
|
|
|
| 22 |
from .pinecone_engine import init_pinecone
|
|
|
|
| 23 |
from ..common.brain_exception import BrainException
|
| 24 |
from ..common.http_response_codes import responses
|
|
|
|
| 25 |
from ..common.utils import (
|
| 26 |
OPENAI_API_KEY,
|
| 27 |
FIREBASE_STORAGE_ROOT,
|
| 28 |
DEFAULT_GPT_MODEL,
|
| 29 |
parseJsonFromCompletion,
|
| 30 |
PINECONE_INDEX_NAME,
|
|
|
|
|
|
|
|
|
|
| 31 |
)
|
| 32 |
from .image_embedding import (
|
| 33 |
query_image_text,
|
|
@@ -35,6 +41,7 @@ from .image_embedding import (
|
|
| 35 |
)
|
| 36 |
from ..model.req_model import ReqModel
|
| 37 |
from ..model.requests.request_model import BasicReq
|
|
|
|
| 38 |
from ..service.train_service import TrainService
|
| 39 |
|
| 40 |
# Give the path to the folder containing the rails
|
|
@@ -59,45 +66,55 @@ def llm_rails(
|
|
| 59 |
image_search: bool = True,
|
| 60 |
is_browser: bool = False,
|
| 61 |
) -> Any:
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
train_service = TrainService(firebase_app=firebase_app, setting=setting)
|
| 65 |
-
|
| 66 |
-
"""step 1: handle with gpt-4"""
|
| 67 |
-
|
| 68 |
-
query_result = get_embed(data=query, setting=setting)
|
| 69 |
-
try:
|
| 70 |
-
relatedness_data = index.query(
|
| 71 |
-
vector=query_result,
|
| 72 |
-
top_k=1,
|
| 73 |
-
include_values=False,
|
| 74 |
-
namespace=train_service.get_pinecone_index_train_namespace(),
|
| 75 |
-
)
|
| 76 |
-
except Exception as ex:
|
| 77 |
-
raise BrainException(code=508, message=responses[508])
|
| 78 |
-
if len(relatedness_data["matches"]) == 0:
|
| 79 |
-
return str({"program": "message", "content": ""})
|
| 80 |
-
document_id = relatedness_data["matches"][0]["id"]
|
| 81 |
-
|
| 82 |
-
document = train_service.read_one_document(document_id)
|
| 83 |
-
page_content = document["page_content"]
|
| 84 |
-
|
| 85 |
-
message = rails_app.generate(
|
| 86 |
messages=[
|
| 87 |
{
|
| 88 |
"role": "user",
|
| 89 |
-
"content":
|
| 90 |
-
setting=setting,
|
| 91 |
-
query=query,
|
| 92 |
-
image_search=image_search,
|
| 93 |
-
page_content=page_content,
|
| 94 |
-
document_id=document_id,
|
| 95 |
-
is_browser=is_browser,
|
| 96 |
-
),
|
| 97 |
}
|
| 98 |
]
|
| 99 |
)
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
|
| 103 |
def processLargeText(
|
|
@@ -117,11 +134,7 @@ def processLargeText(
|
|
| 117 |
image_search=image_search,
|
| 118 |
is_browser=is_browser,
|
| 119 |
)
|
| 120 |
-
|
| 121 |
-
return json.loads(message["content"])
|
| 122 |
-
except Exception as e:
|
| 123 |
-
result = json.dumps(message["content"])
|
| 124 |
-
return parseJsonFromCompletion(result)
|
| 125 |
else:
|
| 126 |
first_query = "The total length of the content that I want to send you is too large to send in only one piece.\nFor sending you that content, I will follow this rule:\n[START PART 1/10]\nThis is the content of the part 1 out of 10 in total\n[END PART 1/10]\nThen you just answer: 'Received part 1/10'\nAnd when I tell you 'ALL PART SENT', then you can continue processing the data and answering my requests."
|
| 127 |
app.generate(messages=[{"role": "user", "content": first_query}])
|
|
@@ -177,11 +190,7 @@ def processLargeText(
|
|
| 177 |
image_search=image_search,
|
| 178 |
is_browser=is_browser,
|
| 179 |
)
|
| 180 |
-
|
| 181 |
-
return json.loads(message["content"])
|
| 182 |
-
except Exception as e:
|
| 183 |
-
result = json.dumps(message["content"])
|
| 184 |
-
return parseJsonFromCompletion(result)
|
| 185 |
# out of for-loop
|
| 186 |
|
| 187 |
|
|
@@ -309,9 +318,9 @@ def rails_input_with_args(
|
|
| 309 |
setting: ReqModel,
|
| 310 |
query: str,
|
| 311 |
image_search: bool,
|
| 312 |
-
page_content: str,
|
| 313 |
-
document_id: str,
|
| 314 |
is_browser: bool,
|
|
|
|
|
|
|
| 315 |
) -> str:
|
| 316 |
# convert json with params for rails.
|
| 317 |
json_query_with_params = {
|
|
@@ -325,6 +334,59 @@ def rails_input_with_args(
|
|
| 325 |
return json.dumps(json_query_with_params)
|
| 326 |
|
| 327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
def handle_chat_completion(messages: Any, model: str = "gpt-3.5-turbo") -> Any:
|
| 329 |
openai.api_key = OPENAI_API_KEY
|
| 330 |
|
|
|
|
| 14 |
from nemoguardrails.rails import LLMRails, RailsConfig
|
| 15 |
|
| 16 |
from langchain.chat_models import ChatOpenAI
|
| 17 |
+
from langchain.docstore.document import Document
|
| 18 |
from firebase_admin import storage
|
| 19 |
|
| 20 |
from .csv_embed import get_embed
|
| 21 |
+
from .llm.falcon_llm import FalconLLM
|
| 22 |
+
from .llm.llms import get_llm, GPT_4, FALCON_7B, get_llm_chain, CATEGORY_PROMPT
|
| 23 |
from .pinecone_engine import init_pinecone
|
| 24 |
+
from .rails_validate import validate_rails
|
| 25 |
from ..common.brain_exception import BrainException
|
| 26 |
from ..common.http_response_codes import responses
|
| 27 |
+
from ..common.program_type import ProgramType
|
| 28 |
from ..common.utils import (
|
| 29 |
OPENAI_API_KEY,
|
| 30 |
FIREBASE_STORAGE_ROOT,
|
| 31 |
DEFAULT_GPT_MODEL,
|
| 32 |
parseJsonFromCompletion,
|
| 33 |
PINECONE_INDEX_NAME,
|
| 34 |
+
ACTION_FLAG,
|
| 35 |
+
COMMAND_SMS_INDEXES,
|
| 36 |
+
COMMAND_BROWSER_OPEN,
|
| 37 |
)
|
| 38 |
from .image_embedding import (
|
| 39 |
query_image_text,
|
|
|
|
| 41 |
)
|
| 42 |
from ..model.req_model import ReqModel
|
| 43 |
from ..model.requests.request_model import BasicReq
|
| 44 |
+
from ..service.auto_task_service import AutoTaskService
|
| 45 |
from ..service.train_service import TrainService
|
| 46 |
|
| 47 |
# Give the path to the folder containing the rails
|
|
|
|
| 66 |
image_search: bool = True,
|
| 67 |
is_browser: bool = False,
|
| 68 |
) -> Any:
|
| 69 |
+
# rails validation
|
| 70 |
+
rails_resp = rails_app.generate(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
messages=[
|
| 72 |
{
|
| 73 |
"role": "user",
|
| 74 |
+
"content": query,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
}
|
| 76 |
]
|
| 77 |
)
|
| 78 |
+
if not validate_rails(rails_resp):
|
| 79 |
+
json_resp = json.loads(rails_resp["content"])
|
| 80 |
+
json_resp["program"] = ProgramType.MESSAGE
|
| 81 |
+
return json_resp
|
| 82 |
+
|
| 83 |
+
# querying
|
| 84 |
+
document_id = ""
|
| 85 |
+
page_content = ""
|
| 86 |
+
if not ACTION_FLAG:
|
| 87 |
+
"""step 0: convert string to json"""
|
| 88 |
+
index = init_pinecone(index_name=PINECONE_INDEX_NAME, setting=setting)
|
| 89 |
+
train_service = TrainService(firebase_app=firebase_app, setting=setting)
|
| 90 |
+
|
| 91 |
+
"""step 1: handle with gpt-4"""
|
| 92 |
+
|
| 93 |
+
query_result = get_embed(data=query, setting=setting)
|
| 94 |
+
try:
|
| 95 |
+
relatedness_data = index.query(
|
| 96 |
+
vector=query_result,
|
| 97 |
+
top_k=1,
|
| 98 |
+
include_values=False,
|
| 99 |
+
namespace=train_service.get_pinecone_index_train_namespace(),
|
| 100 |
+
)
|
| 101 |
+
except Exception as ex:
|
| 102 |
+
raise BrainException(code=508, message=responses[508])
|
| 103 |
+
if len(relatedness_data["matches"]) == 0:
|
| 104 |
+
return str({"program": "message", "content": ""})
|
| 105 |
+
document_id = relatedness_data["matches"][0]["id"]
|
| 106 |
+
|
| 107 |
+
document = train_service.read_one_document(document_id)
|
| 108 |
+
page_content = document["page_content"]
|
| 109 |
+
|
| 110 |
+
return ask_question(
|
| 111 |
+
query=query,
|
| 112 |
+
setting=setting,
|
| 113 |
+
is_browser=is_browser,
|
| 114 |
+
image_search=image_search,
|
| 115 |
+
document_id=document_id,
|
| 116 |
+
page_content=page_content,
|
| 117 |
+
)
|
| 118 |
|
| 119 |
|
| 120 |
def processLargeText(
|
|
|
|
| 134 |
image_search=image_search,
|
| 135 |
is_browser=is_browser,
|
| 136 |
)
|
| 137 |
+
return message
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
else:
|
| 139 |
first_query = "The total length of the content that I want to send you is too large to send in only one piece.\nFor sending you that content, I will follow this rule:\n[START PART 1/10]\nThis is the content of the part 1 out of 10 in total\n[END PART 1/10]\nThen you just answer: 'Received part 1/10'\nAnd when I tell you 'ALL PART SENT', then you can continue processing the data and answering my requests."
|
| 140 |
app.generate(messages=[{"role": "user", "content": first_query}])
|
|
|
|
| 190 |
image_search=image_search,
|
| 191 |
is_browser=is_browser,
|
| 192 |
)
|
| 193 |
+
return message
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
# out of for-loop
|
| 195 |
|
| 196 |
|
|
|
|
| 318 |
setting: ReqModel,
|
| 319 |
query: str,
|
| 320 |
image_search: bool,
|
|
|
|
|
|
|
| 321 |
is_browser: bool,
|
| 322 |
+
page_content: str = "",
|
| 323 |
+
document_id: str = "",
|
| 324 |
) -> str:
|
| 325 |
# convert json with params for rails.
|
| 326 |
json_query_with_params = {
|
|
|
|
| 334 |
return json.dumps(json_query_with_params)
|
| 335 |
|
| 336 |
|
| 337 |
+
"""main method to handle basic query"""
|
| 338 |
+
|
| 339 |
+
|
| 340 |
+
def ask_question(
|
| 341 |
+
query: str,
|
| 342 |
+
setting: ReqModel,
|
| 343 |
+
is_browser: bool,
|
| 344 |
+
image_search: bool,
|
| 345 |
+
document_id: str = "",
|
| 346 |
+
page_content: str = "",
|
| 347 |
+
) -> Any:
|
| 348 |
+
"""init falcon model"""
|
| 349 |
+
falcon_llm = FalconLLM()
|
| 350 |
+
autotask_service = AutoTaskService()
|
| 351 |
+
docs = []
|
| 352 |
+
|
| 353 |
+
if ACTION_FLAG:
|
| 354 |
+
docs.append(Document(page_content=CATEGORY_PROMPT, metadata=""))
|
| 355 |
+
# temperature shouldbe 0.
|
| 356 |
+
chain_data = get_llm_chain(
|
| 357 |
+
model=DEFAULT_GPT_MODEL, setting=setting, temperature=0.0
|
| 358 |
+
).run(input_documents=docs, question=query)
|
| 359 |
+
else:
|
| 360 |
+
docs.append(Document(page_content=page_content, metadata=""))
|
| 361 |
+
""" 1. calling gpt model to categorize for all message"""
|
| 362 |
+
chain_data = get_llm_chain(model=DEFAULT_GPT_MODEL, setting=setting).run(
|
| 363 |
+
input_documents=docs, question=query
|
| 364 |
+
)
|
| 365 |
+
try:
|
| 366 |
+
result = json.loads(chain_data)
|
| 367 |
+
# check image query with only its text
|
| 368 |
+
if result["program"] == ProgramType.IMAGE:
|
| 369 |
+
if image_search:
|
| 370 |
+
result["content"] = {
|
| 371 |
+
"image_name": query_image_text(result["content"], "", setting)
|
| 372 |
+
}
|
| 373 |
+
""" 2. check program is message to handle it with falcon llm """
|
| 374 |
+
if result["program"] == ProgramType.MESSAGE:
|
| 375 |
+
if is_browser:
|
| 376 |
+
result["program"] = ProgramType.BrowserType.ASK_WEBSITE
|
| 377 |
+
return result
|
| 378 |
+
except ValueError as e:
|
| 379 |
+
# Check sms and browser query
|
| 380 |
+
if document_id in COMMAND_SMS_INDEXES:
|
| 381 |
+
return {"program": ProgramType.SMS, "content": chain_data}
|
| 382 |
+
elif document_id in COMMAND_BROWSER_OPEN:
|
| 383 |
+
return {"program": ProgramType.BROWSER, "content": "https://google.com"}
|
| 384 |
+
|
| 385 |
+
if is_browser:
|
| 386 |
+
return {"program": ProgramType.BrowserType.ASK_WEBSITE, "content": ""}
|
| 387 |
+
return {"program": ProgramType.MESSAGE, "content": chain_data}
|
| 388 |
+
|
| 389 |
+
|
| 390 |
def handle_chat_completion(messages: Any, model: str = "gpt-3.5-turbo") -> Any:
|
| 391 |
openai.api_key = OPENAI_API_KEY
|
| 392 |
|
Brain/src/router/api.py
CHANGED
|
@@ -18,6 +18,9 @@ from Brain.src.model.requests.request_model import (
|
|
| 18 |
BasicReq,
|
| 19 |
ClientInfo,
|
| 20 |
get_client_info,
|
|
|
|
|
|
|
|
|
|
| 21 |
)
|
| 22 |
from Brain.src.rising_plugin.risingplugin import (
|
| 23 |
getCompletion,
|
|
@@ -30,11 +33,13 @@ from Brain.src.rising_plugin.image_embedding import embed_image_text, query_imag
|
|
| 30 |
from Brain.src.logs import logger
|
| 31 |
from Brain.src.model.basic_model import BasicModel
|
| 32 |
from Brain.src.model.feedback_model import FeedbackModel
|
|
|
|
| 33 |
from Brain.src.service.command_service import CommandService
|
| 34 |
from Brain.src.service.contact_service import ContactsService
|
| 35 |
from Brain.src.service.feedback_service import FeedbackService
|
| 36 |
from Brain.src.service.llm.chat_service import ChatService
|
| 37 |
from Brain.src.service.twilio_service import TwilioService
|
|
|
|
| 38 |
|
| 39 |
from fastapi import APIRouter, Depends
|
| 40 |
|
|
@@ -87,7 +92,16 @@ def construct_blueprint_api() -> APIRouter:
|
|
| 87 |
|
| 88 |
# check contact querying
|
| 89 |
try:
|
| 90 |
-
contacts_service = ContactsService(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
if result["program"] == ProgramType.CONTACT:
|
| 92 |
# querying contacts to getting its expected results
|
| 93 |
contacts_results = contacts_service.query_contacts(
|
|
@@ -403,7 +417,9 @@ def construct_blueprint_api() -> APIRouter:
|
|
| 403 |
for contact in data.contacts:
|
| 404 |
contacts.append(assembler.to_contact_model(contact))
|
| 405 |
# train contact
|
| 406 |
-
contacts_service = ContactsService(
|
|
|
|
|
|
|
| 407 |
contacts_service.train(uuid, contacts)
|
| 408 |
except Exception as e:
|
| 409 |
if isinstance(e, BrainException):
|
|
@@ -434,7 +450,9 @@ def construct_blueprint_api() -> APIRouter:
|
|
| 434 |
|
| 435 |
# parsing contacts
|
| 436 |
# train contact
|
| 437 |
-
contacts_service = ContactsService(
|
|
|
|
|
|
|
| 438 |
contacts_service.delete_all(uuid)
|
| 439 |
except Exception as e:
|
| 440 |
if isinstance(e, BrainException):
|
|
@@ -444,4 +462,74 @@ def construct_blueprint_api() -> APIRouter:
|
|
| 444 |
200, "Deleted all contacts from pinecone successfully", ""
|
| 445 |
)
|
| 446 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
return router
|
|
|
|
| 18 |
BasicReq,
|
| 19 |
ClientInfo,
|
| 20 |
get_client_info,
|
| 21 |
+
AutoTaskDelete,
|
| 22 |
+
EmailReader,
|
| 23 |
+
GetContactsByIds,
|
| 24 |
)
|
| 25 |
from Brain.src.rising_plugin.risingplugin import (
|
| 26 |
getCompletion,
|
|
|
|
| 33 |
from Brain.src.logs import logger
|
| 34 |
from Brain.src.model.basic_model import BasicModel
|
| 35 |
from Brain.src.model.feedback_model import FeedbackModel
|
| 36 |
+
from Brain.src.service.auto_task_service import AutoTaskService
|
| 37 |
from Brain.src.service.command_service import CommandService
|
| 38 |
from Brain.src.service.contact_service import ContactsService
|
| 39 |
from Brain.src.service.feedback_service import FeedbackService
|
| 40 |
from Brain.src.service.llm.chat_service import ChatService
|
| 41 |
from Brain.src.service.twilio_service import TwilioService
|
| 42 |
+
from Brain.src.service.auto_task_service import delete_db_data
|
| 43 |
|
| 44 |
from fastapi import APIRouter, Depends
|
| 45 |
|
|
|
|
| 92 |
|
| 93 |
# check contact querying
|
| 94 |
try:
|
| 95 |
+
contacts_service = ContactsService(
|
| 96 |
+
firebase_app=firebase_app, setting=setting
|
| 97 |
+
)
|
| 98 |
+
if result["program"] == ProgramType.AUTO_TASK:
|
| 99 |
+
auto_task_service = AutoTaskService()
|
| 100 |
+
result["content"] = auto_task_service.ask_task_with_autogpt(
|
| 101 |
+
query=query, firebase_app=firebase_app, setting=setting
|
| 102 |
+
)
|
| 103 |
+
return assembler.to_response(200, "", result)
|
| 104 |
+
|
| 105 |
if result["program"] == ProgramType.CONTACT:
|
| 106 |
# querying contacts to getting its expected results
|
| 107 |
contacts_results = contacts_service.query_contacts(
|
|
|
|
| 417 |
for contact in data.contacts:
|
| 418 |
contacts.append(assembler.to_contact_model(contact))
|
| 419 |
# train contact
|
| 420 |
+
contacts_service = ContactsService(
|
| 421 |
+
firebase_app=firebase_app, setting=setting
|
| 422 |
+
)
|
| 423 |
contacts_service.train(uuid, contacts)
|
| 424 |
except Exception as e:
|
| 425 |
if isinstance(e, BrainException):
|
|
|
|
| 450 |
|
| 451 |
# parsing contacts
|
| 452 |
# train contact
|
| 453 |
+
contacts_service = ContactsService(
|
| 454 |
+
firebase_app=firebase_app, setting=setting
|
| 455 |
+
)
|
| 456 |
contacts_service.delete_all(uuid)
|
| 457 |
except Exception as e:
|
| 458 |
if isinstance(e, BrainException):
|
|
|
|
| 462 |
200, "Deleted all contacts from pinecone successfully", ""
|
| 463 |
)
|
| 464 |
|
| 465 |
+
"""@generator.request_body(
|
| 466 |
+
{
|
| 467 |
+
"token": "String",
|
| 468 |
+
"uuid": "String",
|
| 469 |
+
"data": {
|
| 470 |
+
"reference_link": "test link",
|
| 471 |
+
},
|
| 472 |
+
}
|
| 473 |
+
)
|
| 474 |
+
|
| 475 |
+
@generator.response(
|
| 476 |
+
status_code=200, schema={"message": "message", "result": "test_result"}
|
| 477 |
+
)
|
| 478 |
+
|
| 479 |
+
"""
|
| 480 |
+
|
| 481 |
+
@router.post("/auto_task/delete")
|
| 482 |
+
def delete_data(data: AutoTaskDelete):
|
| 483 |
+
# firebase admin init
|
| 484 |
+
try:
|
| 485 |
+
setting, firebase_app = firebase_admin_with_setting(data)
|
| 486 |
+
except BrainException as ex:
|
| 487 |
+
return assembler.to_response(ex.code, ex.message, "")
|
| 488 |
+
try:
|
| 489 |
+
token = setting.token
|
| 490 |
+
uuid = setting.uuid
|
| 491 |
+
|
| 492 |
+
# parsing contacts
|
| 493 |
+
# train contact
|
| 494 |
+
delete_db_data(data.data.reference_link, firebase_app)
|
| 495 |
+
except Exception as e:
|
| 496 |
+
if isinstance(e, BrainException):
|
| 497 |
+
return e.get_response_exp()
|
| 498 |
+
return assembler.to_response(400, "Failed to delete data", "")
|
| 499 |
+
return assembler.to_response(
|
| 500 |
+
200, "Deleted data from real-time database of firebase", ""
|
| 501 |
+
)
|
| 502 |
+
|
| 503 |
+
"""@generator.request_body(
|
| 504 |
+
{
|
| 505 |
+
"token": "String",
|
| 506 |
+
"uuid": "String",
|
| 507 |
+
"contactIds": [
|
| 508 |
+
"String"
|
| 509 |
+
]
|
| 510 |
+
}
|
| 511 |
+
)
|
| 512 |
+
|
| 513 |
+
@generator.response(
|
| 514 |
+
status_code=200, schema={"message": "message", "result": "test_result"}
|
| 515 |
+
)
|
| 516 |
+
|
| 517 |
+
"""
|
| 518 |
+
|
| 519 |
+
@router.post("/contacts/get_by_ids")
|
| 520 |
+
def get_contacts_by_ids(data: GetContactsByIds):
|
| 521 |
+
try:
|
| 522 |
+
setting, firebase_app = firebase_admin_with_setting(data)
|
| 523 |
+
except BrainException as ex:
|
| 524 |
+
return ex.get_response_exp()
|
| 525 |
+
|
| 526 |
+
token: str = setting.token
|
| 527 |
+
uuid: str = setting.uuid
|
| 528 |
+
|
| 529 |
+
result = ContactsService(
|
| 530 |
+
firebase_app=firebase_app, setting=setting
|
| 531 |
+
).get_contacts_by_ids(uuid=uuid, contactIds=data.contactIds)
|
| 532 |
+
|
| 533 |
+
return assembler.to_response(200, "Success to get contacts by uuid", result)
|
| 534 |
+
|
| 535 |
return router
|
Brain/src/router/email_router.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
|
| 3 |
+
from fastapi import APIRouter
|
| 4 |
+
|
| 5 |
+
from Brain.src.common.assembler import Assembler
|
| 6 |
+
from Brain.src.common.brain_exception import BrainException
|
| 7 |
+
from Brain.src.model.requests.request_model import (
|
| 8 |
+
EmailReader,
|
| 9 |
+
)
|
| 10 |
+
from Brain.src.rising_plugin.gmail.email_plugin import EmailPlugin
|
| 11 |
+
from Brain.src.firebase.firebase import firebase_admin_with_setting
|
| 12 |
+
|
| 13 |
+
router = APIRouter()
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def construct_blueprint_email_api() -> APIRouter:
|
| 17 |
+
# Assembler
|
| 18 |
+
assembler = Assembler()
|
| 19 |
+
# Services
|
| 20 |
+
|
| 21 |
+
"""@generator.request_body(
|
| 22 |
+
{
|
| 23 |
+
"token": "String",
|
| 24 |
+
"uuid": "String",
|
| 25 |
+
"data": {
|
| 26 |
+
"sender": "test@gmail.com",
|
| 27 |
+
"pwd": "use app password of your google account",
|
| 28 |
+
"imap_folder": "inbox or drafts"
|
| 29 |
+
},
|
| 30 |
+
}
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
@generator.response(
|
| 34 |
+
status_code=200, schema={"message": "message", "result": [{
|
| 35 |
+
"From": "testfrom@test.com",
|
| 36 |
+
"To": "test@gmail.com",
|
| 37 |
+
"Date": "Tue, 04 Jul 2023 12:55:19 +0000",
|
| 38 |
+
"CC": "",
|
| 39 |
+
"Subject": "subject",
|
| 40 |
+
"Message Body": "message"
|
| 41 |
+
}]}
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
"""
|
| 45 |
+
|
| 46 |
+
@router.post("/read_emails")
|
| 47 |
+
def read_emails(data: EmailReader):
|
| 48 |
+
# firebase admin init
|
| 49 |
+
try:
|
| 50 |
+
setting, firebase_app = firebase_admin_with_setting(data)
|
| 51 |
+
except BrainException as ex:
|
| 52 |
+
return assembler.to_response(ex.code, ex.message, "")
|
| 53 |
+
try:
|
| 54 |
+
token = setting.token
|
| 55 |
+
uuid = setting.uuid
|
| 56 |
+
|
| 57 |
+
# if imap_folder is drafts, then search is ALL
|
| 58 |
+
imap_search_cmd = "UNSEEN"
|
| 59 |
+
if data.data.imap_folder not in "inbox":
|
| 60 |
+
imap_search_cmd = "(ALL)"
|
| 61 |
+
|
| 62 |
+
# read emails
|
| 63 |
+
email_manager = EmailPlugin()
|
| 64 |
+
result = email_manager.read_emails(
|
| 65 |
+
sender=data.data.sender,
|
| 66 |
+
pwd=data.data.pwd,
|
| 67 |
+
imap_folder=data.data.imap_folder,
|
| 68 |
+
imap_search_command=imap_search_cmd,
|
| 69 |
+
)
|
| 70 |
+
result = json.loads(result)
|
| 71 |
+
except Exception as e:
|
| 72 |
+
if isinstance(e, BrainException):
|
| 73 |
+
return e.get_response_exp()
|
| 74 |
+
return assembler.to_response(400, "Failed to read emails", "")
|
| 75 |
+
return assembler.to_response(200, "", result)
|
| 76 |
+
|
| 77 |
+
return router
|
Brain/src/router/train_router.py
CHANGED
|
@@ -157,4 +157,31 @@ def construct_blueprint_train_api() -> APIRouter:
|
|
| 157 |
200, "deleted one document and train data successfully", result
|
| 158 |
)
|
| 159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
return router
|
|
|
|
| 157 |
200, "deleted one document and train data successfully", result
|
| 158 |
)
|
| 159 |
|
| 160 |
+
"""@generator.request_body(
|
| 161 |
+
{
|
| 162 |
+
"token": "test_token",
|
| 163 |
+
"uuid": "test_uuid",
|
| 164 |
+
}
|
| 165 |
+
)
|
| 166 |
+
@generator.response( status_code=200, schema={"message": "message", "result": {"document_id": "document_id"}} )"""
|
| 167 |
+
|
| 168 |
+
@router.post("/delete/all/vectors")
|
| 169 |
+
def delete_all_pinecone(data: BasicReq):
|
| 170 |
+
# parsing params
|
| 171 |
+
try:
|
| 172 |
+
setting, firebase_app = firebase_admin_with_setting(data)
|
| 173 |
+
except BrainException as ex:
|
| 174 |
+
return ex.get_response_exp()
|
| 175 |
+
# Services
|
| 176 |
+
train_service = TrainService(firebase_app=firebase_app, setting=setting)
|
| 177 |
+
try:
|
| 178 |
+
result = train_service.delete_all_training_from_pinecone()
|
| 179 |
+
except Exception as e:
|
| 180 |
+
if isinstance(e, BrainException):
|
| 181 |
+
return e.get_response_exp()
|
| 182 |
+
return assembler.to_response(400, "fail to delete one train", "")
|
| 183 |
+
return assembler.to_response(
|
| 184 |
+
200, "deleted one document and train data successfully", result
|
| 185 |
+
)
|
| 186 |
+
|
| 187 |
return router
|
Brain/src/service/auto_task_service.py
CHANGED
|
@@ -1,9 +1,20 @@
|
|
| 1 |
"""auto task management to get the expected output"""
|
| 2 |
import firebase_admin
|
|
|
|
| 3 |
|
| 4 |
from Brain.src.model.req_model import ReqModel
|
| 5 |
from Brain.src.rising_plugin.llm.autogpt_llm import AutoGPTLLM
|
| 6 |
import time
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
|
| 9 |
class AutoTaskService:
|
|
@@ -21,9 +32,10 @@ class AutoTaskService:
|
|
| 21 |
llm_name="autogpt", uuid=setting.uuid
|
| 22 |
)
|
| 23 |
# call autogpt
|
| 24 |
-
|
| 25 |
-
|
| 26 |
)
|
|
|
|
| 27 |
|
| 28 |
return reference_link
|
| 29 |
|
|
|
|
| 1 |
"""auto task management to get the expected output"""
|
| 2 |
import firebase_admin
|
| 3 |
+
from firebase_admin import db
|
| 4 |
|
| 5 |
from Brain.src.model.req_model import ReqModel
|
| 6 |
from Brain.src.rising_plugin.llm.autogpt_llm import AutoGPTLLM
|
| 7 |
import time
|
| 8 |
+
import asyncio
|
| 9 |
+
import threading
|
| 10 |
+
|
| 11 |
+
"""delete data from real time database of firebase using reference link
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def delete_db_data(reference_link: str, firebase_app: firebase_admin.App):
|
| 16 |
+
ref = db.reference(reference_link, app=firebase_app)
|
| 17 |
+
ref.delete()
|
| 18 |
|
| 19 |
|
| 20 |
class AutoTaskService:
|
|
|
|
| 32 |
llm_name="autogpt", uuid=setting.uuid
|
| 33 |
)
|
| 34 |
# call autogpt
|
| 35 |
+
thread = threading.Thread(
|
| 36 |
+
target=autogpt_llm.ask_task, args=(query, firebase_app, reference_link)
|
| 37 |
)
|
| 38 |
+
thread.start()
|
| 39 |
|
| 40 |
return reference_link
|
| 41 |
|
Brain/src/service/contact_service.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
| 1 |
"""service to manage contacts"""
|
| 2 |
from typing import List, Any
|
| 3 |
|
|
|
|
|
|
|
| 4 |
from Brain.src.model.req_model import ReqModel
|
| 5 |
from Brain.src.rising_plugin.csv_embed import get_embed
|
| 6 |
from Brain.src.rising_plugin.pinecone_engine import (
|
|
@@ -15,10 +17,18 @@ from Brain.src.rising_plugin.pinecone_engine import (
|
|
| 15 |
from Brain.src.common.utils import PINECONE_INDEX_NAME
|
| 16 |
from Brain.src.model.contact_model import ContactModel, ContactStatus
|
| 17 |
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
class ContactsService:
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
self.setting = setting
|
|
|
|
| 22 |
|
| 23 |
"""train contacts (getting embedding) and update pinecone with embeddings by contact_id
|
| 24 |
train datatype:
|
|
@@ -28,7 +38,9 @@ class ContactsService:
|
|
| 28 |
def train(self, uuid: str, contacts: List[ContactModel]) -> None:
|
| 29 |
# getting index namespaceof pinecone
|
| 30 |
pinecone_namespace = self.get_pinecone_index_namespace(uuid)
|
|
|
|
| 31 |
for contact in contacts:
|
|
|
|
| 32 |
# generate key and values for pinecone data
|
| 33 |
key = contact.contact_id
|
| 34 |
value = f"{contact.display_name}, {contact.get_str_phones()}"
|
|
@@ -42,12 +54,14 @@ class ContactsService:
|
|
| 42 |
value=vectoring_values,
|
| 43 |
setting=self.setting,
|
| 44 |
)
|
|
|
|
| 45 |
elif contact.status == ContactStatus.DELETED:
|
| 46 |
delete_pinecone(
|
| 47 |
namespace=pinecone_namespace,
|
| 48 |
key=key,
|
| 49 |
setting=self.setting,
|
| 50 |
)
|
|
|
|
| 51 |
elif contact.status == ContactStatus.UPDATED:
|
| 52 |
update_pinecone(
|
| 53 |
namespace=pinecone_namespace,
|
|
@@ -55,6 +69,7 @@ class ContactsService:
|
|
| 55 |
value=vectoring_values,
|
| 56 |
setting=self.setting,
|
| 57 |
)
|
|
|
|
| 58 |
|
| 59 |
""""query contact with search text
|
| 60 |
response: list of contactId as index key of pinecone"""
|
|
@@ -85,3 +100,54 @@ class ContactsService:
|
|
| 85 |
|
| 86 |
def get_pinecone_index_namespace(self, uuid: str) -> str:
|
| 87 |
return get_pinecone_index_namespace(f"{uuid}-contacts")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
"""service to manage contacts"""
|
| 2 |
from typing import List, Any
|
| 3 |
|
| 4 |
+
|
| 5 |
+
from Brain.src.common.assembler import Assembler
|
| 6 |
from Brain.src.model.req_model import ReqModel
|
| 7 |
from Brain.src.rising_plugin.csv_embed import get_embed
|
| 8 |
from Brain.src.rising_plugin.pinecone_engine import (
|
|
|
|
| 17 |
from Brain.src.common.utils import PINECONE_INDEX_NAME
|
| 18 |
from Brain.src.model.contact_model import ContactModel, ContactStatus
|
| 19 |
|
| 20 |
+
import firebase_admin
|
| 21 |
+
from firebase_admin import firestore
|
| 22 |
+
|
| 23 |
|
| 24 |
class ContactsService:
|
| 25 |
+
db: Any
|
| 26 |
+
phones_ref: Any
|
| 27 |
+
|
| 28 |
+
def __init__(self, firebase_app: firebase_admin.App, setting: ReqModel):
|
| 29 |
+
self.firebase_app = firebase_app
|
| 30 |
self.setting = setting
|
| 31 |
+
self.init_firestore()
|
| 32 |
|
| 33 |
"""train contacts (getting embedding) and update pinecone with embeddings by contact_id
|
| 34 |
train datatype:
|
|
|
|
| 38 |
def train(self, uuid: str, contacts: List[ContactModel]) -> None:
|
| 39 |
# getting index namespaceof pinecone
|
| 40 |
pinecone_namespace = self.get_pinecone_index_namespace(uuid)
|
| 41 |
+
|
| 42 |
for contact in contacts:
|
| 43 |
+
# Save the data
|
| 44 |
# generate key and values for pinecone data
|
| 45 |
key = contact.contact_id
|
| 46 |
value = f"{contact.display_name}, {contact.get_str_phones()}"
|
|
|
|
| 54 |
value=vectoring_values,
|
| 55 |
setting=self.setting,
|
| 56 |
)
|
| 57 |
+
self.create_one_contact(uuid=uuid, contact=contact)
|
| 58 |
elif contact.status == ContactStatus.DELETED:
|
| 59 |
delete_pinecone(
|
| 60 |
namespace=pinecone_namespace,
|
| 61 |
key=key,
|
| 62 |
setting=self.setting,
|
| 63 |
)
|
| 64 |
+
self.delete_one_contact(uuid=uuid, contact=contact)
|
| 65 |
elif contact.status == ContactStatus.UPDATED:
|
| 66 |
update_pinecone(
|
| 67 |
namespace=pinecone_namespace,
|
|
|
|
| 69 |
value=vectoring_values,
|
| 70 |
setting=self.setting,
|
| 71 |
)
|
| 72 |
+
self.update_one_contact(uuid=uuid, contact=contact)
|
| 73 |
|
| 74 |
""""query contact with search text
|
| 75 |
response: list of contactId as index key of pinecone"""
|
|
|
|
| 100 |
|
| 101 |
def get_pinecone_index_namespace(self, uuid: str) -> str:
|
| 102 |
return get_pinecone_index_namespace(f"{uuid}-contacts")
|
| 103 |
+
|
| 104 |
+
"""init firestore to save user's contacts"""
|
| 105 |
+
|
| 106 |
+
def init_firestore(self):
|
| 107 |
+
self.db = firestore.client(app=self.firebase_app)
|
| 108 |
+
self.phones_ref = self.db.collection("phones")
|
| 109 |
+
|
| 110 |
+
"""create a contact into document which name is uuid in phone collections in firestore"""
|
| 111 |
+
|
| 112 |
+
def create_one_contact(self, uuid: str, contact: ContactModel):
|
| 113 |
+
assembler = Assembler()
|
| 114 |
+
data = assembler.to_contact_result_format(contact)
|
| 115 |
+
phones_doc_ref = self.phones_ref.document(uuid)
|
| 116 |
+
contacts_doc_ref = phones_doc_ref.collection("contacts").document(
|
| 117 |
+
contact.contact_id
|
| 118 |
+
)
|
| 119 |
+
contacts_doc_ref.set(data)
|
| 120 |
+
|
| 121 |
+
"""update a contact into document which name is uuid in phone collections in firestore"""
|
| 122 |
+
|
| 123 |
+
def update_one_contact(self, uuid: str, contact: ContactModel):
|
| 124 |
+
assembler = Assembler()
|
| 125 |
+
data = assembler.to_contact_result_format(contact)
|
| 126 |
+
phones_doc_ref = self.phones_ref.document(uuid)
|
| 127 |
+
contacts_doc_ref = phones_doc_ref.collection("contacts").document(
|
| 128 |
+
contact.contact_id
|
| 129 |
+
)
|
| 130 |
+
contacts_doc_ref.update(data)
|
| 131 |
+
|
| 132 |
+
"""delete a contact into document which name is uuid in phone collections in firestore"""
|
| 133 |
+
|
| 134 |
+
def delete_one_contact(self, uuid: str, contact: ContactModel):
|
| 135 |
+
phones_doc_ref = self.phones_ref.document(uuid)
|
| 136 |
+
contacts_doc_ref = phones_doc_ref.collection("contacts").document(
|
| 137 |
+
contact.contact_id
|
| 138 |
+
)
|
| 139 |
+
contacts_doc_ref.delete()
|
| 140 |
+
|
| 141 |
+
def get_contacts_by_ids(self, uuid: str, contactIds: list[str]) -> []:
|
| 142 |
+
phones_doc_ref = self.phones_ref.document(uuid)
|
| 143 |
+
contacts_ref = phones_doc_ref.collection("contacts")
|
| 144 |
+
|
| 145 |
+
# Retrieve all documents in the 'contacts' sub-collection
|
| 146 |
+
contacts = contacts_ref.where("contactId", "in", contactIds).stream()
|
| 147 |
+
|
| 148 |
+
result = []
|
| 149 |
+
# Iterate through the documents and print out their data
|
| 150 |
+
for contact in contacts:
|
| 151 |
+
result.append(contact.to_dict())
|
| 152 |
+
|
| 153 |
+
return result
|
Brain/src/service/train_service.py
CHANGED
|
@@ -148,6 +148,12 @@ class TrainService:
|
|
| 148 |
setting=self.setting,
|
| 149 |
)
|
| 150 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
def get_pinecone_index_namespace(self) -> str:
|
| 152 |
self.init_firestore()
|
| 153 |
return get_pinecone_index_namespace(f"trains")
|
|
|
|
| 148 |
setting=self.setting,
|
| 149 |
)
|
| 150 |
|
| 151 |
+
def delete_all_training_from_pinecone(self) -> Any:
|
| 152 |
+
self.init_firestore()
|
| 153 |
+
return delete_all_pinecone(
|
| 154 |
+
namespace=self.get_pinecone_index_namespace(), setting=self.setting
|
| 155 |
+
)
|
| 156 |
+
|
| 157 |
def get_pinecone_index_namespace(self) -> str:
|
| 158 |
self.init_firestore()
|
| 159 |
return get_pinecone_index_namespace(f"trains")
|
Brain/tests/functional/test_api.py
CHANGED
|
@@ -209,3 +209,29 @@ def test_chat_rising(body):
|
|
| 209 |
def test_train_contacts(body):
|
| 210 |
response = client.post("/train/contacts", json=body)
|
| 211 |
assert response.status_code == 200
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
def test_train_contacts(body):
|
| 210 |
response = client.post("/train/contacts", json=body)
|
| 211 |
assert response.status_code == 200
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
@pytest.mark.parametrize(
|
| 215 |
+
"body",
|
| 216 |
+
[
|
| 217 |
+
(
|
| 218 |
+
{
|
| 219 |
+
"data": {
|
| 220 |
+
"reference_link": "test link",
|
| 221 |
+
},
|
| 222 |
+
"confs": {
|
| 223 |
+
"token": "test_token",
|
| 224 |
+
"uuid": "test-uuid",
|
| 225 |
+
"openai_key": "",
|
| 226 |
+
"pinecone_key": "",
|
| 227 |
+
"pinecone_env": "",
|
| 228 |
+
"firebase_key": "",
|
| 229 |
+
"settings": {"temperature": 0.6},
|
| 230 |
+
},
|
| 231 |
+
}
|
| 232 |
+
)
|
| 233 |
+
],
|
| 234 |
+
)
|
| 235 |
+
def test_delete_data(body):
|
| 236 |
+
response = client.post("/auto_task/delete", json=body)
|
| 237 |
+
assert response.status_code == 200
|
Extension/.idea/.gitignore
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
# Default ignored files
|
| 2 |
-
/shelf/
|
| 3 |
-
/workspace.xml
|
| 4 |
-
# Editor-based HTTP Client requests
|
| 5 |
-
/httpRequests/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Extension/.idea/Extension.iml
DELETED
|
@@ -1,12 +0,0 @@
|
|
| 1 |
-
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
-
<module type="WEB_MODULE" version="4">
|
| 3 |
-
<component name="NewModuleRootManager">
|
| 4 |
-
<content url="file://$MODULE_DIR$">
|
| 5 |
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
| 6 |
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
| 7 |
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
| 8 |
-
</content>
|
| 9 |
-
<orderEntry type="inheritedJdk" />
|
| 10 |
-
<orderEntry type="sourceFolder" forTests="false" />
|
| 11 |
-
</component>
|
| 12 |
-
</module>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Extension/.idea/inspectionProfiles/Project_Default.xml
DELETED
|
@@ -1,6 +0,0 @@
|
|
| 1 |
-
<component name="InspectionProjectProfileManager">
|
| 2 |
-
<profile version="1.0">
|
| 3 |
-
<option name="myName" value="Project Default" />
|
| 4 |
-
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
| 5 |
-
</profile>
|
| 6 |
-
</component>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Extension/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
| 1 |
-
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
-
<project version="4">
|
| 3 |
-
<component name="ProjectModuleManager">
|
| 4 |
-
<modules>
|
| 5 |
-
<module fileurl="file://$PROJECT_DIR$/.idea/Extension.iml" filepath="$PROJECT_DIR$/.idea/Extension.iml" />
|
| 6 |
-
</modules>
|
| 7 |
-
</component>
|
| 8 |
-
</project>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Extension/.idea/vcs.xml
DELETED
|
@@ -1,6 +0,0 @@
|
|
| 1 |
-
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
-
<project version="4">
|
| 3 |
-
<component name="VcsDirectoryMappings">
|
| 4 |
-
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
| 5 |
-
</component>
|
| 6 |
-
</project>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Extension/src/pages/Content/modules/DraggablePanel.jsx
CHANGED
|
@@ -61,6 +61,8 @@ class DraggablePanel extends React.Component {
|
|
| 61 |
cursor: 'move',
|
| 62 |
right: 0, // Add this property
|
| 63 |
bottom: 0, // Add this property
|
|
|
|
|
|
|
| 64 |
}}
|
| 65 |
>
|
| 66 |
<Panel />
|
|
|
|
| 61 |
cursor: 'move',
|
| 62 |
right: 0, // Add this property
|
| 63 |
bottom: 0, // Add this property
|
| 64 |
+
width: '400px',
|
| 65 |
+
height: '350px'
|
| 66 |
}}
|
| 67 |
>
|
| 68 |
<Panel />
|
Extension/src/pages/Panel/Message/index.css
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
.message {
|
| 2 |
display: flex;
|
| 3 |
flex-direction: column;
|
|
@@ -7,20 +17,16 @@
|
|
| 7 |
.message_sent {
|
| 8 |
width: fit-content;
|
| 9 |
padding: 5px;
|
| 10 |
-
border:
|
| 11 |
-
|
| 12 |
-
background-color: transparent;
|
| 13 |
-
color: #04c4f8;
|
| 14 |
align-self: end;
|
| 15 |
}
|
| 16 |
|
| 17 |
.message_received {
|
| 18 |
width: fit-content;
|
| 19 |
padding: 5px;
|
| 20 |
-
border:
|
| 21 |
-
|
| 22 |
-
background-color: transparent;
|
| 23 |
-
color: #bc0fdb;
|
| 24 |
}
|
| 25 |
|
| 26 |
|
|
|
|
| 1 |
+
[data-theme='light'] {
|
| 2 |
+
--send-theme-color: #0a164d;
|
| 3 |
+
--receive-theme-color: #0d0c0d;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
[data-theme='dark'] {
|
| 7 |
+
--send-theme-color: #0a164d;
|
| 8 |
+
--receive-theme-color: #333333;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
.message {
|
| 12 |
display: flex;
|
| 13 |
flex-direction: column;
|
|
|
|
| 17 |
.message_sent {
|
| 18 |
width: fit-content;
|
| 19 |
padding: 5px;
|
| 20 |
+
border-radius: 5px;
|
| 21 |
+
background-color: var(--send-theme-color);
|
|
|
|
|
|
|
| 22 |
align-self: end;
|
| 23 |
}
|
| 24 |
|
| 25 |
.message_received {
|
| 26 |
width: fit-content;
|
| 27 |
padding: 5px;
|
| 28 |
+
border-radius: 5px;
|
| 29 |
+
background-color: var(--receive-theme-color);
|
|
|
|
|
|
|
| 30 |
}
|
| 31 |
|
| 32 |
|
Extension/src/pages/Panel/Panel.css
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
.main-layout {
|
| 2 |
display: flex;
|
| 3 |
flex-direction: column;
|
| 4 |
height: 350px; /* Set the height of the layout to be 100% of the viewport */
|
| 5 |
width: 400px;
|
| 6 |
-
border-radius:
|
| 7 |
-
background-color:
|
|
|
|
| 8 |
}
|
| 9 |
|
| 10 |
.main-layout .ant-layout-content {
|
|
@@ -19,6 +30,7 @@
|
|
| 19 |
.footer {
|
| 20 |
padding: 10px;
|
| 21 |
justify-self: end;
|
|
|
|
| 22 |
}
|
| 23 |
|
| 24 |
.content {
|
|
@@ -44,4 +56,5 @@
|
|
| 44 |
|
| 45 |
.divider {
|
| 46 |
margin: 0;
|
|
|
|
| 47 |
}
|
|
|
|
| 1 |
+
[data-theme='light'] {
|
| 2 |
+
--font-color: #c9d1d9;
|
| 3 |
+
--theme-color: #333333;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
[data-theme='dark'] {
|
| 7 |
+
--font-color: #aeafb2;
|
| 8 |
+
--theme-color: #0d0c0d;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
.main-layout {
|
| 12 |
display: flex;
|
| 13 |
flex-direction: column;
|
| 14 |
height: 350px; /* Set the height of the layout to be 100% of the viewport */
|
| 15 |
width: 400px;
|
| 16 |
+
border-radius: 10px;
|
| 17 |
+
background-color: var(--theme-color);
|
| 18 |
+
color: var(--font-color);
|
| 19 |
}
|
| 20 |
|
| 21 |
.main-layout .ant-layout-content {
|
|
|
|
| 30 |
.footer {
|
| 31 |
padding: 10px;
|
| 32 |
justify-self: end;
|
| 33 |
+
background-color: var(--theme-color);
|
| 34 |
}
|
| 35 |
|
| 36 |
.content {
|
|
|
|
| 56 |
|
| 57 |
.divider {
|
| 58 |
margin: 0;
|
| 59 |
+
background-color: grey;
|
| 60 |
}
|
Extension/src/pages/Panel/Panel.jsx
CHANGED
|
@@ -112,19 +112,19 @@ const Panel = () => {
|
|
| 112 |
addMessage(data.result.content, false)
|
| 113 |
window.location.assign(data.result.content)
|
| 114 |
break
|
| 115 |
-
case '
|
| 116 |
addMessage("open tab", false)
|
| 117 |
window.open('https://google.com/search?q=', '_blank', 'noreferrer')
|
| 118 |
break
|
| 119 |
-
case '
|
| 120 |
addMessage("open tab and search", false)
|
| 121 |
window.open('https://google.com/search?q=' + data.result.content, '_blank', 'noreferrer')
|
| 122 |
break
|
| 123 |
-
case '
|
| 124 |
addMessage("close tab", false)
|
| 125 |
window.close()
|
| 126 |
break
|
| 127 |
-
case '
|
| 128 |
if (page === 0) {
|
| 129 |
page = 0
|
| 130 |
} else {
|
|
@@ -134,36 +134,36 @@ const Panel = () => {
|
|
| 134 |
addMessage("go to previous page", false)
|
| 135 |
window.location.assign(currentUrl + '&start=' + page)
|
| 136 |
break
|
| 137 |
-
case '
|
| 138 |
page += 10
|
| 139 |
|
| 140 |
addMessage("go to next page", false)
|
| 141 |
window.location.assign(currentUrl + '&start=' + page)
|
| 142 |
break
|
| 143 |
-
case '
|
| 144 |
addMessage("scroll up", false)
|
| 145 |
window.scrollBy(0, -300)
|
| 146 |
break
|
| 147 |
-
case '
|
| 148 |
addMessage("scroll down", false)
|
| 149 |
window.scrollBy(0, 300)
|
| 150 |
break
|
| 151 |
-
case '
|
| 152 |
addMessage("scroll to top", false)
|
| 153 |
window.scrollTo(0, 0)
|
| 154 |
break
|
| 155 |
-
case '
|
| 156 |
addMessage("scroll to bottom", false)
|
| 157 |
window.scrollTo(0, document.body.scrollHeight)
|
| 158 |
break
|
| 159 |
case 'message':
|
| 160 |
addMessage(data.result.content, false)
|
| 161 |
break
|
| 162 |
-
case '
|
| 163 |
addMessage("I need more detail info to select item", false)
|
| 164 |
selectItem()
|
| 165 |
break
|
| 166 |
-
case '
|
| 167 |
askAboutCurrentWebsite()
|
| 168 |
break
|
| 169 |
default:
|
|
@@ -231,8 +231,20 @@ const Panel = () => {
|
|
| 231 |
return data
|
| 232 |
}
|
| 233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
return (
|
| 235 |
-
<Layout className="main-layout">
|
| 236 |
<div className="header">
|
| 237 |
<h4>RisingBrowser</h4>
|
| 238 |
</div>
|
|
|
|
| 112 |
addMessage(data.result.content, false)
|
| 113 |
window.location.assign(data.result.content)
|
| 114 |
break
|
| 115 |
+
case 'opentab':
|
| 116 |
addMessage("open tab", false)
|
| 117 |
window.open('https://google.com/search?q=', '_blank', 'noreferrer')
|
| 118 |
break
|
| 119 |
+
case 'opentabsearch':
|
| 120 |
addMessage("open tab and search", false)
|
| 121 |
window.open('https://google.com/search?q=' + data.result.content, '_blank', 'noreferrer')
|
| 122 |
break
|
| 123 |
+
case 'closetab':
|
| 124 |
addMessage("close tab", false)
|
| 125 |
window.close()
|
| 126 |
break
|
| 127 |
+
case 'previouspage':
|
| 128 |
if (page === 0) {
|
| 129 |
page = 0
|
| 130 |
} else {
|
|
|
|
| 134 |
addMessage("go to previous page", false)
|
| 135 |
window.location.assign(currentUrl + '&start=' + page)
|
| 136 |
break
|
| 137 |
+
case 'nextpage':
|
| 138 |
page += 10
|
| 139 |
|
| 140 |
addMessage("go to next page", false)
|
| 141 |
window.location.assign(currentUrl + '&start=' + page)
|
| 142 |
break
|
| 143 |
+
case 'scrollup':
|
| 144 |
addMessage("scroll up", false)
|
| 145 |
window.scrollBy(0, -300)
|
| 146 |
break
|
| 147 |
+
case 'scrolldown':
|
| 148 |
addMessage("scroll down", false)
|
| 149 |
window.scrollBy(0, 300)
|
| 150 |
break
|
| 151 |
+
case 'scrolltop':
|
| 152 |
addMessage("scroll to top", false)
|
| 153 |
window.scrollTo(0, 0)
|
| 154 |
break
|
| 155 |
+
case 'scrollbottom':
|
| 156 |
addMessage("scroll to bottom", false)
|
| 157 |
window.scrollTo(0, document.body.scrollHeight)
|
| 158 |
break
|
| 159 |
case 'message':
|
| 160 |
addMessage(data.result.content, false)
|
| 161 |
break
|
| 162 |
+
case 'selectitemdetailinfo':
|
| 163 |
addMessage("I need more detail info to select item", false)
|
| 164 |
selectItem()
|
| 165 |
break
|
| 166 |
+
case 'askwebsite':
|
| 167 |
askAboutCurrentWebsite()
|
| 168 |
break
|
| 169 |
default:
|
|
|
|
| 231 |
return data
|
| 232 |
}
|
| 233 |
|
| 234 |
+
/// Check if the user's system is in dark mode
|
| 235 |
+
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
| 236 |
+
const isDarkMode = darkModeMediaQuery.matches;
|
| 237 |
+
|
| 238 |
+
const handleThemeChange = (e) => {
|
| 239 |
+
const isDarkMode = e.matches;
|
| 240 |
+
// Do something based on the new theme data
|
| 241 |
+
};
|
| 242 |
+
|
| 243 |
+
// Listen for changes in the theme data
|
| 244 |
+
darkModeMediaQuery.addEventListener('change', handleThemeChange);
|
| 245 |
+
|
| 246 |
return (
|
| 247 |
+
<Layout className="main-layout" data-theme={isDarkMode ? 'dark': 'light'}>
|
| 248 |
<div className="header">
|
| 249 |
<h4>RisingBrowser</h4>
|
| 250 |
</div>
|
README.md
CHANGED
|
@@ -28,7 +28,7 @@ All complex software including operating systems will need to be rewritten from
|
|
| 28 |
- 🔗 Multiple API support (Web API for Free and Plus users, GPT-3.5, GPT-4, etc.).
|
| 29 |
- 🔍 Integration to all mainstream search engines, and custom queries to support additional sites.
|
| 30 |
|
| 31 |
-
[[Android Application](https://github.com/ttt246/
|
| 32 |
#### 1.2 Feature
|
| 33 |
|
| 34 |
- Chat with Rising AI as an assistant.
|
|
@@ -39,10 +39,6 @@ All complex software including operating systems will need to be rewritten from
|
|
| 39 |
- Manipulate all browsers with user's input(tab, page, search, scroll, or etc) and it will follow you to go on the real website or blog what you are thinking of.
|
| 40 |
|
| 41 |
## 2. Installing / Getting started
|
| 42 |
-
Install the latest version of rising-plugin package to use / custom something on what you want.
|
| 43 |
-
```
|
| 44 |
-
pip install rising-plugin
|
| 45 |
-
```
|
| 46 |
#### 2.1 how to run on local
|
| 47 |
It's a standard fastapi application so no configuration is needed beyond the included Procfile
|
| 48 |
#### 2.2 Create firebase project
|
|
|
|
| 28 |
- 🔗 Multiple API support (Web API for Free and Plus users, GPT-3.5, GPT-4, etc.).
|
| 29 |
- 🔍 Integration to all mainstream search engines, and custom queries to support additional sites.
|
| 30 |
|
| 31 |
+
[[Brain](https://github.com/ttt246/Brain)] [[Android Application](https://github.com/ttt246/Brain/tree/main/Android)] [[Brrowser Extension](https://github.com/ttt246/Brain/tree/main/Extension)] [[Apple Watch](https://github.com/ttt246/Brain/tree/main/WatchApp)]
|
| 32 |
#### 1.2 Feature
|
| 33 |
|
| 34 |
- Chat with Rising AI as an assistant.
|
|
|
|
| 39 |
- Manipulate all browsers with user's input(tab, page, search, scroll, or etc) and it will follow you to go on the real website or blog what you are thinking of.
|
| 40 |
|
| 41 |
## 2. Installing / Getting started
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
#### 2.1 how to run on local
|
| 43 |
It's a standard fastapi application so no configuration is needed beyond the included Procfile
|
| 44 |
#### 2.2 Create firebase project
|
WatchApp/WatchApp Watch App/Assets.xcassets/AccentColor.colorset/Contents.json
DELETED
|
@@ -1,11 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"colors" : [
|
| 3 |
-
{
|
| 4 |
-
"idiom" : "universal"
|
| 5 |
-
}
|
| 6 |
-
],
|
| 7 |
-
"info" : {
|
| 8 |
-
"author" : "xcode",
|
| 9 |
-
"version" : 1
|
| 10 |
-
}
|
| 11 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WatchApp/WatchApp Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"images" : [
|
| 3 |
-
{
|
| 4 |
-
"idiom" : "universal",
|
| 5 |
-
"platform" : "watchos",
|
| 6 |
-
"size" : "1024x1024"
|
| 7 |
-
}
|
| 8 |
-
],
|
| 9 |
-
"info" : {
|
| 10 |
-
"author" : "xcode",
|
| 11 |
-
"version" : 1
|
| 12 |
-
}
|
| 13 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WatchApp/WatchApp Watch App/Assets.xcassets/Contents.json
DELETED
|
@@ -1,6 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"info" : {
|
| 3 |
-
"author" : "xcode",
|
| 4 |
-
"version" : 1
|
| 5 |
-
}
|
| 6 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WatchApp/WatchApp Watch App/Components/ChatMessageRow.swift
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//
|
| 2 |
+
// MessageView.swift
|
| 3 |
+
// WatchApp Watch App
|
| 4 |
+
//
|
| 5 |
+
// Created by DarkHorse on 7/1/23.
|
| 6 |
+
//
|
| 7 |
+
|
| 8 |
+
import SwiftUI
|
| 9 |
+
|
| 10 |
+
struct ChatMessage: Hashable {
|
| 11 |
+
let message: String
|
| 12 |
+
let isUser: Bool
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
struct ChatBubble: Shape {
|
| 16 |
+
let isUser: Bool
|
| 17 |
+
|
| 18 |
+
func path(in rect: CGRect) -> Path {
|
| 19 |
+
let path = UIBezierPath(roundedRect: rect,
|
| 20 |
+
byRoundingCorners: [.topLeft, .topRight, isUser ? .bottomLeft : .bottomRight],
|
| 21 |
+
cornerRadii: CGSize(width: 3, height: 3))
|
| 22 |
+
return Path(path.cgPath)
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
struct ChatMessageRow: View {
|
| 27 |
+
let message: ChatMessage
|
| 28 |
+
|
| 29 |
+
var body: some View {
|
| 30 |
+
HStack {
|
| 31 |
+
if message.isUser {
|
| 32 |
+
Spacer()
|
| 33 |
+
Text(message.message)
|
| 34 |
+
.font(.system(size: 15))
|
| 35 |
+
.foregroundColor(.white)
|
| 36 |
+
.padding(5)
|
| 37 |
+
.background(Color.blue)
|
| 38 |
+
.clipShape(ChatBubble(isUser: message.isUser))
|
| 39 |
+
} else {
|
| 40 |
+
Text(message.message)
|
| 41 |
+
.italic()
|
| 42 |
+
.font(.system(size: 15))
|
| 43 |
+
.foregroundColor(.black)
|
| 44 |
+
.padding(5)
|
| 45 |
+
.background(Color.primary)
|
| 46 |
+
.clipShape(ChatBubble(isUser: message.isUser))
|
| 47 |
+
Spacer()
|
| 48 |
+
}
|
| 49 |
+
}.listRowBackground(Color.clear)
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
struct ChatMessageRow_Previews: PreviewProvider {
|
| 54 |
+
static var previews: some View {
|
| 55 |
+
ChatMessageRow(message: ChatMessage(message: "Hello!", isUser: false))
|
| 56 |
+
}
|
| 57 |
+
}
|
WatchApp/WatchApp Watch App/ContentView.swift
DELETED
|
@@ -1,73 +0,0 @@
|
|
| 1 |
-
//
|
| 2 |
-
// ContentView.swift
|
| 3 |
-
// WatchApp Watch App
|
| 4 |
-
//
|
| 5 |
-
// Created by DarkHorse on 6/28/23.
|
| 6 |
-
//
|
| 7 |
-
|
| 8 |
-
import SwiftUI
|
| 9 |
-
|
| 10 |
-
struct ChatMessage: Hashable {
|
| 11 |
-
let message: String
|
| 12 |
-
let isUser: Bool
|
| 13 |
-
}
|
| 14 |
-
|
| 15 |
-
struct ChatBubble: Shape {
|
| 16 |
-
let isUser: Bool
|
| 17 |
-
|
| 18 |
-
func path(in rect: CGRect) -> Path {
|
| 19 |
-
let path = UIBezierPath(roundedRect: rect,
|
| 20 |
-
byRoundingCorners: [.topLeft, .topRight, isUser ? .bottomLeft : .bottomRight],
|
| 21 |
-
cornerRadii: CGSize(width: 10, height: 10))
|
| 22 |
-
return Path(path.cgPath)
|
| 23 |
-
}
|
| 24 |
-
}
|
| 25 |
-
|
| 26 |
-
struct ContentView: View {
|
| 27 |
-
@State private var messages: [ChatMessage] = []
|
| 28 |
-
@State private var newMessage = ""
|
| 29 |
-
|
| 30 |
-
var body: some View {
|
| 31 |
-
VStack {
|
| 32 |
-
List {
|
| 33 |
-
ForEach(messages, id: \.self) { message in
|
| 34 |
-
HStack {
|
| 35 |
-
if message.isUser {
|
| 36 |
-
Spacer()
|
| 37 |
-
Text(message.message)
|
| 38 |
-
.foregroundColor(.white)
|
| 39 |
-
.padding(10)
|
| 40 |
-
.background(Color.blue)
|
| 41 |
-
.clipShape(ChatBubble(isUser: message.isUser))
|
| 42 |
-
} else {
|
| 43 |
-
Text(message.message)
|
| 44 |
-
.foregroundColor(.white)
|
| 45 |
-
.padding(10)
|
| 46 |
-
.background(Color.gray)
|
| 47 |
-
.clipShape(ChatBubble(isUser: message.isUser))
|
| 48 |
-
Spacer()
|
| 49 |
-
}
|
| 50 |
-
}
|
| 51 |
-
}
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
HStack {
|
| 55 |
-
TextField("Message...", text: $newMessage)
|
| 56 |
-
Button(action: {
|
| 57 |
-
let userMessage = ChatMessage(message: newMessage, isUser: true)
|
| 58 |
-
messages.append(userMessage)
|
| 59 |
-
newMessage = ""
|
| 60 |
-
}) {
|
| 61 |
-
Text("Send")
|
| 62 |
-
}
|
| 63 |
-
}
|
| 64 |
-
.padding()
|
| 65 |
-
}
|
| 66 |
-
}
|
| 67 |
-
}
|
| 68 |
-
|
| 69 |
-
struct ContentView_Previews: PreviewProvider {
|
| 70 |
-
static var previews: some View {
|
| 71 |
-
ContentView()
|
| 72 |
-
}
|
| 73 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WatchApp/WatchApp Watch App/MainView.swift
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//
|
| 2 |
+
// MainView.swift
|
| 3 |
+
// WatchApp Watch App
|
| 4 |
+
//
|
| 5 |
+
// Created by DarkHorse on 7/1/23.
|
| 6 |
+
//
|
| 7 |
+
|
| 8 |
+
import SwiftUI
|
| 9 |
+
|
| 10 |
+
struct MainView: View {
|
| 11 |
+
@State private var isPresented = false
|
| 12 |
+
|
| 13 |
+
var body: some View {
|
| 14 |
+
ZStack {
|
| 15 |
+
if isPresented {
|
| 16 |
+
SettingView(isPresented: $isPresented)
|
| 17 |
+
} else {
|
| 18 |
+
ChatView(isPresented: $isPresented)
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
struct MainView_Previews: PreviewProvider {
|
| 25 |
+
static var previews: some View {
|
| 26 |
+
MainView()
|
| 27 |
+
}
|
| 28 |
+
}
|
WatchApp/WatchApp Watch App/Pages/ChatView.swift
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//
|
| 2 |
+
// ContentView.swift
|
| 3 |
+
// WatchApp Watch App
|
| 4 |
+
//
|
| 5 |
+
// Created by Hideki Sato on 6/27/23.
|
| 6 |
+
//
|
| 7 |
+
|
| 8 |
+
import SwiftUI
|
| 9 |
+
import KeychainSwift
|
| 10 |
+
|
| 11 |
+
struct ChatView: View {
|
| 12 |
+
@Binding var isPresented: Bool
|
| 13 |
+
@State private var messages: [ChatMessage] = []
|
| 14 |
+
@State private var newMessage = ""
|
| 15 |
+
@State private var uuid: String = "956a11be45cba4a4"
|
| 16 |
+
|
| 17 |
+
var body: some View {
|
| 18 |
+
VStack{
|
| 19 |
+
Button(action: {
|
| 20 |
+
self.isPresented = true
|
| 21 |
+
}) {
|
| 22 |
+
Image(systemName: "gearshape.fill")
|
| 23 |
+
.resizable()
|
| 24 |
+
.frame(width: 15, height: 15)
|
| 25 |
+
}
|
| 26 |
+
.frame(width: 50, height: 30)
|
| 27 |
+
.background(Color.clear).buttonStyle(PlainButtonStyle()).padding(.trailing)
|
| 28 |
+
|
| 29 |
+
List {
|
| 30 |
+
ForEach(messages, id: \.self) { message in
|
| 31 |
+
ChatMessageRow(message:message)
|
| 32 |
+
}
|
| 33 |
+
}.listStyle(PlainListStyle()).padding(.bottom, 10)
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
HStack() {
|
| 37 |
+
TextField("Message...", text: $newMessage).frame(width: 120.0, height: 0)
|
| 38 |
+
Button(action: {
|
| 39 |
+
let keychain = KeychainSwift()
|
| 40 |
+
|
| 41 |
+
// Try to get the UUID from the keychain
|
| 42 |
+
if keychain.get("uuid") == "" {
|
| 43 |
+
let uuid = "956a11be45cba4a4"
|
| 44 |
+
keychain.set(uuid, forKey: "uuid")
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
let userMessage = ChatMessage(message: newMessage, isUser: true)
|
| 48 |
+
messages.append(userMessage)
|
| 49 |
+
|
| 50 |
+
// Replace this URL with your server's URL
|
| 51 |
+
if let url = URL(string: "https://ttt246-brain.hf.space/sendNotification") {
|
| 52 |
+
var request = URLRequest(url: url)
|
| 53 |
+
request.httpMethod = "POST" // Change this to any HTTP method you want
|
| 54 |
+
request.addValue("application/json", forHTTPHeaderField: "Content-Type") // Add any necessary headers
|
| 55 |
+
|
| 56 |
+
let confsData: [String: Any] = [
|
| 57 |
+
"openai_key": "",
|
| 58 |
+
"pinecone_key": "",
|
| 59 |
+
"pinecone_env": "",
|
| 60 |
+
"firebase_key": "",
|
| 61 |
+
"token":"cI3EvimJQv-G5imdWrBprf:APA91bEZ5u6uq9Yq4a6NglN0L9pVM7p-rlxKB_FikbfKlzHnZT5GeAjxF0deuPT2GurS8bK6JTE2XPZLQqbsrtjxeRGhGOH5INoQ7MrRlr4TR3xFswKxJSkfi1aBUWDaLGALeirZ7GuZ",
|
| 62 |
+
"uuid": uuid,
|
| 63 |
+
"settings": [
|
| 64 |
+
"temperature": 0.6
|
| 65 |
+
]
|
| 66 |
+
]
|
| 67 |
+
|
| 68 |
+
let postData: [String: Any] = ["confs": confsData, "message": newMessage]
|
| 69 |
+
|
| 70 |
+
do {
|
| 71 |
+
let jsonData = try JSONSerialization.data(withJSONObject: postData, options: .prettyPrinted)
|
| 72 |
+
URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in
|
| 73 |
+
guard error == nil, let data = data else {
|
| 74 |
+
print("Error: \(error?.localizedDescription ?? "Unknown error")")
|
| 75 |
+
return
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
do {
|
| 79 |
+
// Here we are converting data into JSON using JSONSerialization
|
| 80 |
+
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
| 81 |
+
if let result = jsonResult["result"] as? [String: Any], let content = result["content"] as? String {
|
| 82 |
+
DispatchQueue.main.async {
|
| 83 |
+
let serverResponse = ChatMessage(message: content, isUser: false)
|
| 84 |
+
messages.append(serverResponse)
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
}
|
| 88 |
+
} catch {
|
| 89 |
+
print("JSONSerialization error: \(error.localizedDescription)")
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
}.resume()
|
| 93 |
+
} catch {
|
| 94 |
+
print("Error: \(error.localizedDescription)")
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
newMessage = ""
|
| 98 |
+
}) {
|
| 99 |
+
Image(systemName: "paperplane.fill")
|
| 100 |
+
}.frame(width: 50.0, height: 35)
|
| 101 |
+
}
|
| 102 |
+
}.padding().edgesIgnoringSafeArea(.all)
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
struct ChatView_Previews: PreviewProvider {
|
| 109 |
+
static var previews: some View {
|
| 110 |
+
ChatView(isPresented: .constant(false))
|
| 111 |
+
}
|
| 112 |
+
}
|
WatchApp/WatchApp Watch App/Pages/SettingView.swift
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//
|
| 2 |
+
// SettingView.swift
|
| 3 |
+
// WatchApp Watch App
|
| 4 |
+
//
|
| 5 |
+
// Created by DarkHorse on 7/1/23.
|
| 6 |
+
//
|
| 7 |
+
|
| 8 |
+
import SwiftUI
|
| 9 |
+
import KeychainSwift
|
| 10 |
+
|
| 11 |
+
struct SettingView: View {
|
| 12 |
+
@Binding var isPresented: Bool
|
| 13 |
+
@State private var uuid: String = "956a11be45cba4a4"
|
| 14 |
+
|
| 15 |
+
var body: some View {
|
| 16 |
+
VStack {
|
| 17 |
+
TextField("uuid", text: $uuid)
|
| 18 |
+
.foregroundColor(.white)
|
| 19 |
+
.font(.system(size: 20))
|
| 20 |
+
.padding()
|
| 21 |
+
HStack {
|
| 22 |
+
Spacer()
|
| 23 |
+
Button(action: {
|
| 24 |
+
let keychain = KeychainSwift()
|
| 25 |
+
keychain.set("\($uuid)", forKey: "uuid")
|
| 26 |
+
self.isPresented = false
|
| 27 |
+
}) {
|
| 28 |
+
Text("Yes")
|
| 29 |
+
}
|
| 30 |
+
Spacer()
|
| 31 |
+
Button(action: {
|
| 32 |
+
self.isPresented = false
|
| 33 |
+
}) {
|
| 34 |
+
Text("No")
|
| 35 |
+
}
|
| 36 |
+
Spacer()
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
struct SettingView_Previews: PreviewProvider {
|
| 43 |
+
static var previews: some View {
|
| 44 |
+
SettingView(isPresented: .constant(true))
|
| 45 |
+
}
|
| 46 |
+
}
|
WatchApp/WatchApp Watch App/WatchAppApp.swift
CHANGED
|
@@ -11,7 +11,7 @@ import SwiftUI
|
|
| 11 |
struct WatchApp_Watch_AppApp: App {
|
| 12 |
var body: some Scene {
|
| 13 |
WindowGroup {
|
| 14 |
-
|
| 15 |
}
|
| 16 |
}
|
| 17 |
}
|
|
|
|
| 11 |
struct WatchApp_Watch_AppApp: App {
|
| 12 |
var body: some Scene {
|
| 13 |
WindowGroup {
|
| 14 |
+
MainView()
|
| 15 |
}
|
| 16 |
}
|
| 17 |
}
|
WatchApp/WatchApp.xcodeproj/project.pbxproj
CHANGED
|
@@ -9,12 +9,14 @@
|
|
| 9 |
/* Begin PBXBuildFile section */
|
| 10 |
FE56FAE22A4C5810008410B4 /* WatchApp Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = FE56FAE12A4C5810008410B4 /* WatchApp Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
| 11 |
FE56FAE72A4C5810008410B4 /* WatchAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FAE62A4C5810008410B4 /* WatchAppApp.swift */; };
|
| 12 |
-
FE56FAE92A4C5810008410B4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FAE82A4C5810008410B4 /* ContentView.swift */; };
|
| 13 |
-
FE56FAEB2A4C5814008410B4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FE56FAEA2A4C5814008410B4 /* Assets.xcassets */; };
|
| 14 |
-
FE56FAEE2A4C5814008410B4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FE56FAED2A4C5814008410B4 /* Preview Assets.xcassets */; };
|
| 15 |
FE56FAF82A4C5814008410B4 /* WatchApp_Watch_AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FAF72A4C5814008410B4 /* WatchApp_Watch_AppTests.swift */; };
|
| 16 |
FE56FB022A4C5814008410B4 /* WatchApp_Watch_AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FB012A4C5814008410B4 /* WatchApp_Watch_AppUITests.swift */; };
|
| 17 |
FE56FB042A4C5814008410B4 /* WatchApp_Watch_AppUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FB032A4C5814008410B4 /* WatchApp_Watch_AppUITestsLaunchTests.swift */; };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
/* End PBXBuildFile section */
|
| 19 |
|
| 20 |
/* Begin PBXContainerItemProxy section */
|
|
@@ -59,14 +61,15 @@
|
|
| 59 |
FE56FADB2A4C5810008410B4 /* WatchApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WatchApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 60 |
FE56FAE12A4C5810008410B4 /* WatchApp Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WatchApp Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 61 |
FE56FAE62A4C5810008410B4 /* WatchAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAppApp.swift; sourceTree = "<group>"; };
|
| 62 |
-
FE56FAE82A4C5810008410B4 /*
|
| 63 |
-
FE56FAEA2A4C5814008410B4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
| 64 |
-
FE56FAED2A4C5814008410B4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
| 65 |
FE56FAF32A4C5814008410B4 /* WatchApp Watch AppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WatchApp Watch AppTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 66 |
FE56FAF72A4C5814008410B4 /* WatchApp_Watch_AppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchApp_Watch_AppTests.swift; sourceTree = "<group>"; };
|
| 67 |
FE56FAFD2A4C5814008410B4 /* WatchApp Watch AppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WatchApp Watch AppUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 68 |
FE56FB012A4C5814008410B4 /* WatchApp_Watch_AppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchApp_Watch_AppUITests.swift; sourceTree = "<group>"; };
|
| 69 |
FE56FB032A4C5814008410B4 /* WatchApp_Watch_AppUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchApp_Watch_AppUITestsLaunchTests.swift; sourceTree = "<group>"; };
|
|
|
|
|
|
|
|
|
|
| 70 |
/* End PBXFileReference section */
|
| 71 |
|
| 72 |
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -74,6 +77,7 @@
|
|
| 74 |
isa = PBXFrameworksBuildPhase;
|
| 75 |
buildActionMask = 2147483647;
|
| 76 |
files = (
|
|
|
|
| 77 |
);
|
| 78 |
runOnlyForDeploymentPostprocessing = 0;
|
| 79 |
};
|
|
@@ -118,22 +122,14 @@
|
|
| 118 |
FE56FAE52A4C5810008410B4 /* WatchApp Watch App */ = {
|
| 119 |
isa = PBXGroup;
|
| 120 |
children = (
|
|
|
|
|
|
|
|
|
|
| 121 |
FE56FAE62A4C5810008410B4 /* WatchAppApp.swift */,
|
| 122 |
-
FE56FAE82A4C5810008410B4 /* ContentView.swift */,
|
| 123 |
-
FE56FAEA2A4C5814008410B4 /* Assets.xcassets */,
|
| 124 |
-
FE56FAEC2A4C5814008410B4 /* Preview Content */,
|
| 125 |
);
|
| 126 |
path = "WatchApp Watch App";
|
| 127 |
sourceTree = "<group>";
|
| 128 |
};
|
| 129 |
-
FE56FAEC2A4C5814008410B4 /* Preview Content */ = {
|
| 130 |
-
isa = PBXGroup;
|
| 131 |
-
children = (
|
| 132 |
-
FE56FAED2A4C5814008410B4 /* Preview Assets.xcassets */,
|
| 133 |
-
);
|
| 134 |
-
path = "Preview Content";
|
| 135 |
-
sourceTree = "<group>";
|
| 136 |
-
};
|
| 137 |
FE56FAF62A4C5814008410B4 /* WatchApp Watch AppTests */ = {
|
| 138 |
isa = PBXGroup;
|
| 139 |
children = (
|
|
@@ -151,6 +147,23 @@
|
|
| 151 |
path = "WatchApp Watch AppUITests";
|
| 152 |
sourceTree = "<group>";
|
| 153 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
/* End PBXGroup section */
|
| 155 |
|
| 156 |
/* Begin PBXNativeTarget section */
|
|
@@ -184,6 +197,9 @@
|
|
| 184 |
dependencies = (
|
| 185 |
);
|
| 186 |
name = "WatchApp Watch App";
|
|
|
|
|
|
|
|
|
|
| 187 |
productName = "WatchApp Watch App";
|
| 188 |
productReference = FE56FAE12A4C5810008410B4 /* WatchApp Watch App.app */;
|
| 189 |
productType = "com.apple.product-type.application";
|
|
@@ -259,6 +275,9 @@
|
|
| 259 |
Base,
|
| 260 |
);
|
| 261 |
mainGroup = FE56FAD42A4C580F008410B4;
|
|
|
|
|
|
|
|
|
|
| 262 |
productRefGroup = FE56FADC2A4C5810008410B4 /* Products */;
|
| 263 |
projectDirPath = "";
|
| 264 |
projectRoot = "";
|
|
@@ -283,8 +302,6 @@
|
|
| 283 |
isa = PBXResourcesBuildPhase;
|
| 284 |
buildActionMask = 2147483647;
|
| 285 |
files = (
|
| 286 |
-
FE56FAEE2A4C5814008410B4 /* Preview Assets.xcassets in Resources */,
|
| 287 |
-
FE56FAEB2A4C5814008410B4 /* Assets.xcassets in Resources */,
|
| 288 |
);
|
| 289 |
runOnlyForDeploymentPostprocessing = 0;
|
| 290 |
};
|
|
@@ -309,7 +326,10 @@
|
|
| 309 |
isa = PBXSourcesBuildPhase;
|
| 310 |
buildActionMask = 2147483647;
|
| 311 |
files = (
|
| 312 |
-
|
|
|
|
|
|
|
|
|
|
| 313 |
FE56FAE72A4C5810008410B4 /* WatchAppApp.swift in Sources */,
|
| 314 |
);
|
| 315 |
runOnlyForDeploymentPostprocessing = 0;
|
|
@@ -680,6 +700,25 @@
|
|
| 680 |
defaultConfigurationName = Release;
|
| 681 |
};
|
| 682 |
/* End XCConfigurationList section */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 683 |
};
|
| 684 |
rootObject = FE56FAD52A4C580F008410B4 /* Project object */;
|
| 685 |
}
|
|
|
|
| 9 |
/* Begin PBXBuildFile section */
|
| 10 |
FE56FAE22A4C5810008410B4 /* WatchApp Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = FE56FAE12A4C5810008410B4 /* WatchApp Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
| 11 |
FE56FAE72A4C5810008410B4 /* WatchAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FAE62A4C5810008410B4 /* WatchAppApp.swift */; };
|
|
|
|
|
|
|
|
|
|
| 12 |
FE56FAF82A4C5814008410B4 /* WatchApp_Watch_AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FAF72A4C5814008410B4 /* WatchApp_Watch_AppTests.swift */; };
|
| 13 |
FE56FB022A4C5814008410B4 /* WatchApp_Watch_AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FB012A4C5814008410B4 /* WatchApp_Watch_AppUITests.swift */; };
|
| 14 |
FE56FB042A4C5814008410B4 /* WatchApp_Watch_AppUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FB032A4C5814008410B4 /* WatchApp_Watch_AppUITestsLaunchTests.swift */; };
|
| 15 |
+
FE56FB142A4C80A5008410B4 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE56FAE82A4C5810008410B4 /* ChatView.swift */; };
|
| 16 |
+
FE673FCB2A4CDBF7003EF230 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = FE673FCA2A4CDBF7003EF230 /* KeychainSwift */; };
|
| 17 |
+
FE673FCE2A5022C9003EF230 /* ChatMessageRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE673FCD2A5022C9003EF230 /* ChatMessageRow.swift */; };
|
| 18 |
+
FE673FD02A504903003EF230 /* SettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE673FCF2A504903003EF230 /* SettingView.swift */; };
|
| 19 |
+
FE673FD32A504EAF003EF230 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE673FD22A504EAF003EF230 /* MainView.swift */; };
|
| 20 |
/* End PBXBuildFile section */
|
| 21 |
|
| 22 |
/* Begin PBXContainerItemProxy section */
|
|
|
|
| 61 |
FE56FADB2A4C5810008410B4 /* WatchApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WatchApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 62 |
FE56FAE12A4C5810008410B4 /* WatchApp Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WatchApp Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 63 |
FE56FAE62A4C5810008410B4 /* WatchAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAppApp.swift; sourceTree = "<group>"; };
|
| 64 |
+
FE56FAE82A4C5810008410B4 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = "<group>"; };
|
|
|
|
|
|
|
| 65 |
FE56FAF32A4C5814008410B4 /* WatchApp Watch AppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WatchApp Watch AppTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 66 |
FE56FAF72A4C5814008410B4 /* WatchApp_Watch_AppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchApp_Watch_AppTests.swift; sourceTree = "<group>"; };
|
| 67 |
FE56FAFD2A4C5814008410B4 /* WatchApp Watch AppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WatchApp Watch AppUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 68 |
FE56FB012A4C5814008410B4 /* WatchApp_Watch_AppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchApp_Watch_AppUITests.swift; sourceTree = "<group>"; };
|
| 69 |
FE56FB032A4C5814008410B4 /* WatchApp_Watch_AppUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchApp_Watch_AppUITestsLaunchTests.swift; sourceTree = "<group>"; };
|
| 70 |
+
FE673FCD2A5022C9003EF230 /* ChatMessageRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageRow.swift; sourceTree = "<group>"; };
|
| 71 |
+
FE673FCF2A504903003EF230 /* SettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingView.swift; sourceTree = "<group>"; };
|
| 72 |
+
FE673FD22A504EAF003EF230 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
| 73 |
/* End PBXFileReference section */
|
| 74 |
|
| 75 |
/* Begin PBXFrameworksBuildPhase section */
|
|
|
|
| 77 |
isa = PBXFrameworksBuildPhase;
|
| 78 |
buildActionMask = 2147483647;
|
| 79 |
files = (
|
| 80 |
+
FE673FCB2A4CDBF7003EF230 /* KeychainSwift in Frameworks */,
|
| 81 |
);
|
| 82 |
runOnlyForDeploymentPostprocessing = 0;
|
| 83 |
};
|
|
|
|
| 122 |
FE56FAE52A4C5810008410B4 /* WatchApp Watch App */ = {
|
| 123 |
isa = PBXGroup;
|
| 124 |
children = (
|
| 125 |
+
FE673FCC2A502280003EF230 /* Components */,
|
| 126 |
+
FE673FD12A504913003EF230 /* Pages */,
|
| 127 |
+
FE673FD22A504EAF003EF230 /* MainView.swift */,
|
| 128 |
FE56FAE62A4C5810008410B4 /* WatchAppApp.swift */,
|
|
|
|
|
|
|
|
|
|
| 129 |
);
|
| 130 |
path = "WatchApp Watch App";
|
| 131 |
sourceTree = "<group>";
|
| 132 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
FE56FAF62A4C5814008410B4 /* WatchApp Watch AppTests */ = {
|
| 134 |
isa = PBXGroup;
|
| 135 |
children = (
|
|
|
|
| 147 |
path = "WatchApp Watch AppUITests";
|
| 148 |
sourceTree = "<group>";
|
| 149 |
};
|
| 150 |
+
FE673FCC2A502280003EF230 /* Components */ = {
|
| 151 |
+
isa = PBXGroup;
|
| 152 |
+
children = (
|
| 153 |
+
FE673FCD2A5022C9003EF230 /* ChatMessageRow.swift */,
|
| 154 |
+
);
|
| 155 |
+
path = Components;
|
| 156 |
+
sourceTree = "<group>";
|
| 157 |
+
};
|
| 158 |
+
FE673FD12A504913003EF230 /* Pages */ = {
|
| 159 |
+
isa = PBXGroup;
|
| 160 |
+
children = (
|
| 161 |
+
FE673FCF2A504903003EF230 /* SettingView.swift */,
|
| 162 |
+
FE56FAE82A4C5810008410B4 /* ChatView.swift */,
|
| 163 |
+
);
|
| 164 |
+
path = Pages;
|
| 165 |
+
sourceTree = "<group>";
|
| 166 |
+
};
|
| 167 |
/* End PBXGroup section */
|
| 168 |
|
| 169 |
/* Begin PBXNativeTarget section */
|
|
|
|
| 197 |
dependencies = (
|
| 198 |
);
|
| 199 |
name = "WatchApp Watch App";
|
| 200 |
+
packageProductDependencies = (
|
| 201 |
+
FE673FCA2A4CDBF7003EF230 /* KeychainSwift */,
|
| 202 |
+
);
|
| 203 |
productName = "WatchApp Watch App";
|
| 204 |
productReference = FE56FAE12A4C5810008410B4 /* WatchApp Watch App.app */;
|
| 205 |
productType = "com.apple.product-type.application";
|
|
|
|
| 275 |
Base,
|
| 276 |
);
|
| 277 |
mainGroup = FE56FAD42A4C580F008410B4;
|
| 278 |
+
packageReferences = (
|
| 279 |
+
FE673FC92A4CDBF7003EF230 /* XCRemoteSwiftPackageReference "keychain-swift" */,
|
| 280 |
+
);
|
| 281 |
productRefGroup = FE56FADC2A4C5810008410B4 /* Products */;
|
| 282 |
projectDirPath = "";
|
| 283 |
projectRoot = "";
|
|
|
|
| 302 |
isa = PBXResourcesBuildPhase;
|
| 303 |
buildActionMask = 2147483647;
|
| 304 |
files = (
|
|
|
|
|
|
|
| 305 |
);
|
| 306 |
runOnlyForDeploymentPostprocessing = 0;
|
| 307 |
};
|
|
|
|
| 326 |
isa = PBXSourcesBuildPhase;
|
| 327 |
buildActionMask = 2147483647;
|
| 328 |
files = (
|
| 329 |
+
FE673FCE2A5022C9003EF230 /* ChatMessageRow.swift in Sources */,
|
| 330 |
+
FE673FD02A504903003EF230 /* SettingView.swift in Sources */,
|
| 331 |
+
FE56FB142A4C80A5008410B4 /* ChatView.swift in Sources */,
|
| 332 |
+
FE673FD32A504EAF003EF230 /* MainView.swift in Sources */,
|
| 333 |
FE56FAE72A4C5810008410B4 /* WatchAppApp.swift in Sources */,
|
| 334 |
);
|
| 335 |
runOnlyForDeploymentPostprocessing = 0;
|
|
|
|
| 700 |
defaultConfigurationName = Release;
|
| 701 |
};
|
| 702 |
/* End XCConfigurationList section */
|
| 703 |
+
|
| 704 |
+
/* Begin XCRemoteSwiftPackageReference section */
|
| 705 |
+
FE673FC92A4CDBF7003EF230 /* XCRemoteSwiftPackageReference "keychain-swift" */ = {
|
| 706 |
+
isa = XCRemoteSwiftPackageReference;
|
| 707 |
+
repositoryURL = "https://github.com/evgenyneu/keychain-swift.git";
|
| 708 |
+
requirement = {
|
| 709 |
+
kind = upToNextMajorVersion;
|
| 710 |
+
minimumVersion = 20.0.0;
|
| 711 |
+
};
|
| 712 |
+
};
|
| 713 |
+
/* End XCRemoteSwiftPackageReference section */
|
| 714 |
+
|
| 715 |
+
/* Begin XCSwiftPackageProductDependency section */
|
| 716 |
+
FE673FCA2A4CDBF7003EF230 /* KeychainSwift */ = {
|
| 717 |
+
isa = XCSwiftPackageProductDependency;
|
| 718 |
+
package = FE673FC92A4CDBF7003EF230 /* XCRemoteSwiftPackageReference "keychain-swift" */;
|
| 719 |
+
productName = KeychainSwift;
|
| 720 |
+
};
|
| 721 |
+
/* End XCSwiftPackageProductDependency section */
|
| 722 |
};
|
| 723 |
rootObject = FE56FAD52A4C580F008410B4 /* Project object */;
|
| 724 |
}
|
WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"pins" : [
|
| 3 |
+
{
|
| 4 |
+
"identity" : "keychain-swift",
|
| 5 |
+
"kind" : "remoteSourceControl",
|
| 6 |
+
"location" : "https://github.com/evgenyneu/keychain-swift.git",
|
| 7 |
+
"state" : {
|
| 8 |
+
"revision" : "d108a1fa6189e661f91560548ef48651ed8d93b9",
|
| 9 |
+
"version" : "20.0.0"
|
| 10 |
+
}
|
| 11 |
+
}
|
| 12 |
+
],
|
| 13 |
+
"version" : 2
|
| 14 |
+
}
|
WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcuserdata/darkhorse.xcuserdatad/UserInterfaceState.xcuserstate
CHANGED
|
Binary files a/WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcuserdata/darkhorse.xcuserdatad/UserInterfaceState.xcuserstate and b/WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcuserdata/darkhorse.xcuserdatad/UserInterfaceState.xcuserstate differ
|
|
|
WatchApp/WatchApp.xcodeproj/xcuserdata/darkhorse.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<Bucket
|
| 3 |
+
uuid = "78398B09-67A6-447A-BDF1-6FF7D60370C3"
|
| 4 |
+
type = "1"
|
| 5 |
+
version = "2.0">
|
| 6 |
+
</Bucket>
|
app.py
CHANGED
|
@@ -3,11 +3,16 @@ from fastapi import FastAPI
|
|
| 3 |
from fastapi.middleware.cors import CORSMiddleware
|
| 4 |
import uvicorn
|
| 5 |
|
|
|
|
| 6 |
from Brain.src.router.browser_router import construct_blueprint_browser_api
|
| 7 |
from Brain.src.router.train_router import construct_blueprint_train_api
|
| 8 |
-
|
| 9 |
from Brain.src.router.api import construct_blueprint_api
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
app = FastAPI()
|
| 12 |
# Set up CORS middleware
|
| 13 |
app.add_middleware(
|
|
@@ -23,9 +28,16 @@ app.include_router(construct_blueprint_api(), tags=["ai_app"])
|
|
| 23 |
app.include_router(
|
| 24 |
construct_blueprint_browser_api(), prefix="/browser", tags=["ai_browser"]
|
| 25 |
)
|
| 26 |
-
|
| 27 |
app.include_router(construct_blueprint_train_api(), prefix="/train", tags=["ai_train"])
|
|
|
|
|
|
|
|
|
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
if __name__ == "__main__":
|
| 31 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|
|
|
|
| 3 |
from fastapi.middleware.cors import CORSMiddleware
|
| 4 |
import uvicorn
|
| 5 |
|
| 6 |
+
# from Brain.src.gradio_debug import debug_send_notification
|
| 7 |
from Brain.src.router.browser_router import construct_blueprint_browser_api
|
| 8 |
from Brain.src.router.train_router import construct_blueprint_train_api
|
| 9 |
+
from Brain.src.router.email_router import construct_blueprint_email_api
|
| 10 |
from Brain.src.router.api import construct_blueprint_api
|
| 11 |
|
| 12 |
+
import gradio as gr
|
| 13 |
+
import random
|
| 14 |
+
import time
|
| 15 |
+
|
| 16 |
app = FastAPI()
|
| 17 |
# Set up CORS middleware
|
| 18 |
app.add_middleware(
|
|
|
|
| 28 |
app.include_router(
|
| 29 |
construct_blueprint_browser_api(), prefix="/browser", tags=["ai_browser"]
|
| 30 |
)
|
|
|
|
| 31 |
app.include_router(construct_blueprint_train_api(), prefix="/train", tags=["ai_train"])
|
| 32 |
+
app.include_router(construct_blueprint_email_api(), prefix="/email", tags=["ai_email"])
|
| 33 |
+
|
| 34 |
+
# gradio
|
| 35 |
|
| 36 |
+
# CUSTOM_PATH = "/gradio"
|
| 37 |
+
#
|
| 38 |
+
# app = gr.mount_gradio_app(
|
| 39 |
+
# app, debug_send_notification, path=f"{CUSTOM_PATH}/sendNotification"
|
| 40 |
+
# )
|
| 41 |
|
| 42 |
if __name__ == "__main__":
|
| 43 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|
requirements.txt
CHANGED
|
@@ -3,6 +3,7 @@ replicate==0.8.1
|
|
| 3 |
pytest==7.3.0
|
| 4 |
async-timeout==4.0.2
|
| 5 |
attrs==22.2.0
|
|
|
|
| 6 |
black==23.3.0
|
| 7 |
CacheControl==0.12.11
|
| 8 |
cachetools==5.3.0
|
|
@@ -24,7 +25,7 @@ fastapi==0.95.0
|
|
| 24 |
uvicorn==0.21.1
|
| 25 |
frozenlist==1.3.3
|
| 26 |
google-api-core==2.11.0
|
| 27 |
-
google-api-python-client==2.
|
| 28 |
google-auth==2.17.3
|
| 29 |
google-auth-httplib2==0.1.0
|
| 30 |
google-cloud-core==2.3.2
|
|
@@ -72,4 +73,6 @@ user-agents==2.2.0
|
|
| 72 |
faiss-cpu==1.7.4
|
| 73 |
google-search-results==2.4.2
|
| 74 |
tiktoken==0.4.0
|
| 75 |
-
tiktoken==0.4.0
|
|
|
|
|
|
|
|
|
| 3 |
pytest==7.3.0
|
| 4 |
async-timeout==4.0.2
|
| 5 |
attrs==22.2.0
|
| 6 |
+
beautifulsoup4==4.12.2
|
| 7 |
black==23.3.0
|
| 8 |
CacheControl==0.12.11
|
| 9 |
cachetools==5.3.0
|
|
|
|
| 25 |
uvicorn==0.21.1
|
| 26 |
frozenlist==1.3.3
|
| 27 |
google-api-core==2.11.0
|
| 28 |
+
google-api-python-client==2.90.0
|
| 29 |
google-auth==2.17.3
|
| 30 |
google-auth-httplib2==0.1.0
|
| 31 |
google-cloud-core==2.3.2
|
|
|
|
| 73 |
faiss-cpu==1.7.4
|
| 74 |
google-search-results==2.4.2
|
| 75 |
tiktoken==0.4.0
|
| 76 |
+
tiktoken==0.4.0
|
| 77 |
+
gradio-client==0.2.7
|
| 78 |
+
gradio==3.14.0
|