peterluo3131 commited on
Commit
4ce003a
·
2 Parent(s): 70eba01d9d2539

feature(#130): remove conflicts

Browse files
Files changed (49) hide show
  1. .gitignore +2 -0
  2. Android/README.md +0 -1
  3. Android/app/src/main/res/drawable/ic_attachment_48.xml +5 -0
  4. Brain/README.md +1 -6
  5. Brain/logs/activity.log +0 -82
  6. Brain/src/commands/command.py +5 -5
  7. Brain/src/common/assembler.py +16 -1
  8. Brain/src/common/program_type.py +14 -11
  9. Brain/src/common/utils.py +6 -0
  10. Brain/src/gradio_debug.py +47 -0
  11. Brain/src/model/requests/request_model.py +29 -0
  12. Brain/src/rising_plugin/gmail/email_plugin.py +359 -0
  13. Brain/src/rising_plugin/guardrails-config/actions/actions.py +1 -107
  14. Brain/src/rising_plugin/guardrails-config/off-security.co +1 -1
  15. Brain/src/rising_plugin/llm/llms.py +35 -1
  16. Brain/src/rising_plugin/rails_validate.py +15 -0
  17. Brain/src/rising_plugin/risingplugin.py +109 -47
  18. Brain/src/router/api.py +91 -3
  19. Brain/src/router/email_router.py +77 -0
  20. Brain/src/router/train_router.py +27 -0
  21. Brain/src/service/auto_task_service.py +14 -2
  22. Brain/src/service/contact_service.py +67 -1
  23. Brain/src/service/train_service.py +6 -0
  24. Brain/tests/functional/test_api.py +26 -0
  25. Extension/.idea/.gitignore +0 -5
  26. Extension/.idea/Extension.iml +0 -12
  27. Extension/.idea/inspectionProfiles/Project_Default.xml +0 -6
  28. Extension/.idea/modules.xml +0 -8
  29. Extension/.idea/vcs.xml +0 -6
  30. Extension/src/pages/Content/modules/DraggablePanel.jsx +2 -0
  31. Extension/src/pages/Panel/Message/index.css +14 -8
  32. Extension/src/pages/Panel/Panel.css +15 -2
  33. Extension/src/pages/Panel/Panel.jsx +24 -12
  34. README.md +1 -5
  35. WatchApp/WatchApp Watch App/Assets.xcassets/AccentColor.colorset/Contents.json +0 -11
  36. WatchApp/WatchApp Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -13
  37. WatchApp/WatchApp Watch App/Assets.xcassets/Contents.json +0 -6
  38. WatchApp/WatchApp Watch App/Components/ChatMessageRow.swift +57 -0
  39. WatchApp/WatchApp Watch App/ContentView.swift +0 -73
  40. WatchApp/WatchApp Watch App/MainView.swift +28 -0
  41. WatchApp/WatchApp Watch App/Pages/ChatView.swift +112 -0
  42. WatchApp/WatchApp Watch App/Pages/SettingView.swift +46 -0
  43. WatchApp/WatchApp Watch App/WatchAppApp.swift +1 -1
  44. WatchApp/WatchApp.xcodeproj/project.pbxproj +59 -20
  45. WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +14 -0
  46. WatchApp/WatchApp.xcodeproj/project.xcworkspace/xcuserdata/darkhorse.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  47. WatchApp/WatchApp.xcodeproj/xcuserdata/darkhorse.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +6 -0
  48. app.py +14 -2
  49. 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
- ).__str_json__(),
66
  Command(
67
  "notification",
68
  "send notification or alert",
69
  "send that #notification",
70
  ["#notification"],
71
  True,
72
- ).__str_json__(),
73
  Command(
74
  "sms",
75
  "send a sms",
76
  "",
77
  [],
78
  True,
79
- ).__str_json__(),
80
  Command(
81
  "browsing",
82
  "search browser",
83
  "Search something that #description",
84
  ["#description"],
85
  True,
86
- ).__str_json__(),
87
  Command(
88
  "social",
89
  "search something in social",
90
  "Search something in twitter or facebook that #description",
91
  ["#description"],
92
  True,
93
- ).__str_json__(),
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 | select_item_detail_info,
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 = "open_tab"
14
- OPEN_TAB_SEARCH = "open_tab_search"
15
- CLOSE_TAB = "close_tab"
16
- PREVIOUS_PAGE = "previous_page"
17
- NEXT_PAGE = "next_page"
18
- SCROLL_UP = "scroll_up"
19
- SCROLL_DOWN = "scroll_down"
20
- SCROLL_TOP = "scroll_top"
21
- SCROLL_BOTTOM = "scroll_bottom"
22
- SELECT_ITEM_DETAIL_INFO = "select_item_detail_info"
23
- SELECT_ITEM = "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
- """init falcon model"""
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": "message", "content": "Sorry, I cannot comment on anything which is relevant to the password or pin code."}'
 
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(model=model, openai_key=setting.openai_key)
 
 
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.llms import get_llm, GPT_4, FALCON_7B
 
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
- """step 0: convert string to json"""
63
- index = init_pinecone(index_name=PINECONE_INDEX_NAME, setting=setting)
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": rails_input_with_args(
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
- return message
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
 
103
  def processLargeText(
@@ -117,11 +134,7 @@ def processLargeText(
117
  image_search=image_search,
118
  is_browser=is_browser,
119
  )
120
- try:
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
- try:
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(setting=setting)
 
 
 
 
 
 
 
 
 
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(setting=setting)
 
 
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(setting=setting)
 
 
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
- autogpt_llm.ask_task(
25
- query=query, firebase_app=firebase_app, reference_link=reference_link
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
- def __init__(self, setting: ReqModel):
 
 
 
 
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: #04c4f8 1px solid;
11
- border-radius: 3px;
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: #bc0fdb 1px solid;
21
- border-radius: 3px;
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: 5px;
7
- background-color: #f5f5f5dd;
 
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 'open_tab':
116
  addMessage("open tab", false)
117
  window.open('https://google.com/search?q=', '_blank', 'noreferrer')
118
  break
119
- case 'open_tab_search':
120
  addMessage("open tab and search", false)
121
  window.open('https://google.com/search?q=' + data.result.content, '_blank', 'noreferrer')
122
  break
123
- case 'close_tab':
124
  addMessage("close tab", false)
125
  window.close()
126
  break
127
- case 'previous_page':
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 'next_page':
138
  page += 10
139
 
140
  addMessage("go to next page", false)
141
  window.location.assign(currentUrl + '&start=' + page)
142
  break
143
- case 'scroll_up':
144
  addMessage("scroll up", false)
145
  window.scrollBy(0, -300)
146
  break
147
- case 'scroll_down':
148
  addMessage("scroll down", false)
149
  window.scrollBy(0, 300)
150
  break
151
- case 'scroll_top':
152
  addMessage("scroll to top", false)
153
  window.scrollTo(0, 0)
154
  break
155
- case 'scroll_bottom':
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 'select_item_detail_info':
163
  addMessage("I need more detail info to select item", false)
164
  selectItem()
165
  break
166
- case 'ask_website':
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/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 +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
- ContentView()
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 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
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
- FE56FAE92A4C5810008410B4 /* ContentView.swift in Sources */,
 
 
 
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.85.0
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