open-swarm 0.1.1743070217__py3-none-any.whl → 0.1.1743364176__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. open_swarm-0.1.1743364176.dist-info/METADATA +286 -0
  2. open_swarm-0.1.1743364176.dist-info/RECORD +260 -0
  3. {open_swarm-0.1.1743070217.dist-info → open_swarm-0.1.1743364176.dist-info}/WHEEL +1 -2
  4. open_swarm-0.1.1743364176.dist-info/entry_points.txt +2 -0
  5. swarm/__init__.py +0 -2
  6. swarm/auth.py +53 -49
  7. swarm/blueprints/README.md +67 -0
  8. swarm/blueprints/burnt_noodles/blueprint_burnt_noodles.py +412 -0
  9. swarm/blueprints/chatbot/blueprint_chatbot.py +98 -0
  10. swarm/blueprints/chatbot/templates/chatbot/chatbot.html +33 -0
  11. swarm/blueprints/digitalbutlers/blueprint_digitalbutlers.py +183 -0
  12. swarm/blueprints/dilbot_universe/blueprint_dilbot_universe.py +285 -0
  13. swarm/blueprints/divine_code/__init__.py +0 -0
  14. swarm/blueprints/divine_code/apps.py +11 -0
  15. swarm/blueprints/divine_code/blueprint_divine_code.py +219 -0
  16. swarm/blueprints/django_chat/apps.py +6 -0
  17. swarm/blueprints/django_chat/blueprint_django_chat.py +84 -0
  18. swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html +37 -0
  19. swarm/blueprints/django_chat/urls.py +8 -0
  20. swarm/blueprints/django_chat/views.py +32 -0
  21. swarm/blueprints/echocraft/blueprint_echocraft.py +44 -0
  22. swarm/blueprints/family_ties/apps.py +11 -0
  23. swarm/blueprints/family_ties/blueprint_family_ties.py +152 -0
  24. swarm/blueprints/family_ties/models.py +19 -0
  25. swarm/blueprints/family_ties/serializers.py +7 -0
  26. swarm/blueprints/family_ties/settings.py +16 -0
  27. swarm/blueprints/family_ties/urls.py +10 -0
  28. swarm/blueprints/family_ties/views.py +26 -0
  29. swarm/blueprints/flock/__init__.py +0 -0
  30. swarm/blueprints/gaggle/blueprint_gaggle.py +184 -0
  31. swarm/blueprints/gotchaman/blueprint_gotchaman.py +232 -0
  32. swarm/blueprints/mcp_demo/blueprint_mcp_demo.py +133 -0
  33. swarm/blueprints/messenger/templates/messenger/messenger.html +46 -0
  34. swarm/blueprints/mission_improbable/blueprint_mission_improbable.py +234 -0
  35. swarm/blueprints/monkai_magic/blueprint_monkai_magic.py +248 -0
  36. swarm/blueprints/nebula_shellz/blueprint_nebula_shellz.py +156 -0
  37. swarm/blueprints/omniplex/blueprint_omniplex.py +221 -0
  38. swarm/blueprints/rue_code/__init__.py +0 -0
  39. swarm/blueprints/rue_code/blueprint_rue_code.py +291 -0
  40. swarm/blueprints/suggestion/blueprint_suggestion.py +110 -0
  41. swarm/blueprints/unapologetic_press/blueprint_unapologetic_press.py +298 -0
  42. swarm/blueprints/whiskeytango_foxtrot/__init__.py +0 -0
  43. swarm/blueprints/whiskeytango_foxtrot/apps.py +11 -0
  44. swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py +256 -0
  45. swarm/extensions/blueprint/__init__.py +30 -15
  46. swarm/extensions/blueprint/agent_utils.py +16 -40
  47. swarm/extensions/blueprint/blueprint_base.py +141 -543
  48. swarm/extensions/blueprint/blueprint_discovery.py +112 -98
  49. swarm/extensions/blueprint/cli_handler.py +185 -0
  50. swarm/extensions/blueprint/config_loader.py +122 -0
  51. swarm/extensions/blueprint/django_utils.py +181 -79
  52. swarm/extensions/blueprint/interactive_mode.py +1 -1
  53. swarm/extensions/config/config_loader.py +83 -200
  54. swarm/extensions/launchers/build_swarm_wrapper.py +0 -0
  55. swarm/extensions/launchers/swarm_cli.py +199 -287
  56. swarm/llm/chat_completion.py +26 -55
  57. swarm/management/__init__.py +0 -0
  58. swarm/management/commands/__init__.py +0 -0
  59. swarm/management/commands/runserver.py +58 -0
  60. swarm/permissions.py +38 -0
  61. swarm/serializers.py +96 -5
  62. swarm/settings.py +95 -110
  63. swarm/static/contrib/fonts/fontawesome-webfont.ttf +7 -0
  64. swarm/static/contrib/fonts/fontawesome-webfont.woff +7 -0
  65. swarm/static/contrib/fonts/fontawesome-webfont.woff2 +7 -0
  66. swarm/static/contrib/markedjs/marked.min.js +6 -0
  67. swarm/static/contrib/tabler-icons/adjustments-horizontal.svg +27 -0
  68. swarm/static/contrib/tabler-icons/alert-triangle.svg +21 -0
  69. swarm/static/contrib/tabler-icons/archive.svg +21 -0
  70. swarm/static/contrib/tabler-icons/artboard.svg +27 -0
  71. swarm/static/contrib/tabler-icons/automatic-gearbox.svg +23 -0
  72. swarm/static/contrib/tabler-icons/box-multiple.svg +19 -0
  73. swarm/static/contrib/tabler-icons/carambola.svg +19 -0
  74. swarm/static/contrib/tabler-icons/copy.svg +20 -0
  75. swarm/static/contrib/tabler-icons/download.svg +21 -0
  76. swarm/static/contrib/tabler-icons/edit.svg +21 -0
  77. swarm/static/contrib/tabler-icons/filled/carambola.svg +13 -0
  78. swarm/static/contrib/tabler-icons/filled/paint.svg +13 -0
  79. swarm/static/contrib/tabler-icons/headset.svg +22 -0
  80. swarm/static/contrib/tabler-icons/layout-sidebar-left-collapse.svg +21 -0
  81. swarm/static/contrib/tabler-icons/layout-sidebar-left-expand.svg +21 -0
  82. swarm/static/contrib/tabler-icons/layout-sidebar-right-collapse.svg +21 -0
  83. swarm/static/contrib/tabler-icons/layout-sidebar-right-expand.svg +21 -0
  84. swarm/static/contrib/tabler-icons/message-chatbot.svg +22 -0
  85. swarm/static/contrib/tabler-icons/message-star.svg +22 -0
  86. swarm/static/contrib/tabler-icons/message-x.svg +23 -0
  87. swarm/static/contrib/tabler-icons/message.svg +21 -0
  88. swarm/static/contrib/tabler-icons/paperclip.svg +18 -0
  89. swarm/static/contrib/tabler-icons/playlist-add.svg +22 -0
  90. swarm/static/contrib/tabler-icons/robot.svg +26 -0
  91. swarm/static/contrib/tabler-icons/search.svg +19 -0
  92. swarm/static/contrib/tabler-icons/settings.svg +20 -0
  93. swarm/static/contrib/tabler-icons/thumb-down.svg +19 -0
  94. swarm/static/contrib/tabler-icons/thumb-up.svg +19 -0
  95. swarm/static/css/dropdown.css +22 -0
  96. swarm/static/htmx/htmx.min.js +0 -0
  97. swarm/static/js/dropdown.js +23 -0
  98. swarm/static/rest_mode/css/base.css +470 -0
  99. swarm/static/rest_mode/css/chat-history.css +286 -0
  100. swarm/static/rest_mode/css/chat.css +251 -0
  101. swarm/static/rest_mode/css/chatbot.css +74 -0
  102. swarm/static/rest_mode/css/chatgpt.css +62 -0
  103. swarm/static/rest_mode/css/colors/corporate.css +74 -0
  104. swarm/static/rest_mode/css/colors/pastel.css +81 -0
  105. swarm/static/rest_mode/css/colors/tropical.css +82 -0
  106. swarm/static/rest_mode/css/general.css +142 -0
  107. swarm/static/rest_mode/css/layout.css +167 -0
  108. swarm/static/rest_mode/css/layouts/messenger-layout.css +17 -0
  109. swarm/static/rest_mode/css/layouts/minimalist-layout.css +57 -0
  110. swarm/static/rest_mode/css/layouts/mobile-layout.css +8 -0
  111. swarm/static/rest_mode/css/messages.css +84 -0
  112. swarm/static/rest_mode/css/messenger.css +135 -0
  113. swarm/static/rest_mode/css/settings.css +91 -0
  114. swarm/static/rest_mode/css/simple.css +44 -0
  115. swarm/static/rest_mode/css/slack.css +58 -0
  116. swarm/static/rest_mode/css/style.css +156 -0
  117. swarm/static/rest_mode/css/theme.css +30 -0
  118. swarm/static/rest_mode/css/toast.css +40 -0
  119. swarm/static/rest_mode/js/auth.js +9 -0
  120. swarm/static/rest_mode/js/blueprint.js +41 -0
  121. swarm/static/rest_mode/js/blueprintUtils.js +12 -0
  122. swarm/static/rest_mode/js/chatLogic.js +79 -0
  123. swarm/static/rest_mode/js/debug.js +63 -0
  124. swarm/static/rest_mode/js/events.js +98 -0
  125. swarm/static/rest_mode/js/main.js +19 -0
  126. swarm/static/rest_mode/js/messages.js +264 -0
  127. swarm/static/rest_mode/js/messengerLogic.js +355 -0
  128. swarm/static/rest_mode/js/modules/apiService.js +84 -0
  129. swarm/static/rest_mode/js/modules/blueprintManager.js +162 -0
  130. swarm/static/rest_mode/js/modules/chatHistory.js +110 -0
  131. swarm/static/rest_mode/js/modules/debugLogger.js +14 -0
  132. swarm/static/rest_mode/js/modules/eventHandlers.js +107 -0
  133. swarm/static/rest_mode/js/modules/messageProcessor.js +120 -0
  134. swarm/static/rest_mode/js/modules/state.js +7 -0
  135. swarm/static/rest_mode/js/modules/userInteractions.js +29 -0
  136. swarm/static/rest_mode/js/modules/validation.js +23 -0
  137. swarm/static/rest_mode/js/rendering.js +119 -0
  138. swarm/static/rest_mode/js/settings.js +130 -0
  139. swarm/static/rest_mode/js/sidebar.js +94 -0
  140. swarm/static/rest_mode/js/simpleLogic.js +37 -0
  141. swarm/static/rest_mode/js/slackLogic.js +66 -0
  142. swarm/static/rest_mode/js/splash.js +76 -0
  143. swarm/static/rest_mode/js/theme.js +111 -0
  144. swarm/static/rest_mode/js/toast.js +36 -0
  145. swarm/static/rest_mode/js/ui.js +265 -0
  146. swarm/static/rest_mode/js/validation.js +57 -0
  147. swarm/static/rest_mode/svg/animated_spinner.svg +12 -0
  148. swarm/static/rest_mode/svg/arrow_down.svg +5 -0
  149. swarm/static/rest_mode/svg/arrow_left.svg +5 -0
  150. swarm/static/rest_mode/svg/arrow_right.svg +5 -0
  151. swarm/static/rest_mode/svg/arrow_up.svg +5 -0
  152. swarm/static/rest_mode/svg/attach.svg +8 -0
  153. swarm/static/rest_mode/svg/avatar.svg +7 -0
  154. swarm/static/rest_mode/svg/canvas.svg +6 -0
  155. swarm/static/rest_mode/svg/chat_history.svg +4 -0
  156. swarm/static/rest_mode/svg/close.svg +5 -0
  157. swarm/static/rest_mode/svg/copy.svg +4 -0
  158. swarm/static/rest_mode/svg/dark_mode.svg +3 -0
  159. swarm/static/rest_mode/svg/edit.svg +5 -0
  160. swarm/static/rest_mode/svg/layout.svg +9 -0
  161. swarm/static/rest_mode/svg/logo.svg +29 -0
  162. swarm/static/rest_mode/svg/logout.svg +5 -0
  163. swarm/static/rest_mode/svg/mobile.svg +5 -0
  164. swarm/static/rest_mode/svg/new_chat.svg +4 -0
  165. swarm/static/rest_mode/svg/not_visible.svg +5 -0
  166. swarm/static/rest_mode/svg/plus.svg +7 -0
  167. swarm/static/rest_mode/svg/run_code.svg +6 -0
  168. swarm/static/rest_mode/svg/save.svg +4 -0
  169. swarm/static/rest_mode/svg/search.svg +6 -0
  170. swarm/static/rest_mode/svg/settings.svg +4 -0
  171. swarm/static/rest_mode/svg/speaker.svg +5 -0
  172. swarm/static/rest_mode/svg/stop.svg +6 -0
  173. swarm/static/rest_mode/svg/thumbs_down.svg +3 -0
  174. swarm/static/rest_mode/svg/thumbs_up.svg +3 -0
  175. swarm/static/rest_mode/svg/toggle_off.svg +6 -0
  176. swarm/static/rest_mode/svg/toggle_on.svg +6 -0
  177. swarm/static/rest_mode/svg/trash.svg +10 -0
  178. swarm/static/rest_mode/svg/undo.svg +3 -0
  179. swarm/static/rest_mode/svg/visible.svg +8 -0
  180. swarm/static/rest_mode/svg/voice.svg +10 -0
  181. swarm/templates/account/login.html +22 -0
  182. swarm/templates/account/signup.html +32 -0
  183. swarm/templates/base.html +30 -0
  184. swarm/templates/chat.html +43 -0
  185. swarm/templates/index.html +35 -0
  186. swarm/templates/rest_mode/components/chat_sidebar.html +55 -0
  187. swarm/templates/rest_mode/components/header.html +45 -0
  188. swarm/templates/rest_mode/components/main_chat_pane.html +41 -0
  189. swarm/templates/rest_mode/components/settings_dialog.html +97 -0
  190. swarm/templates/rest_mode/components/splash_screen.html +7 -0
  191. swarm/templates/rest_mode/components/top_bar.html +28 -0
  192. swarm/templates/rest_mode/message_ui.html +50 -0
  193. swarm/templates/rest_mode/slackbot.html +30 -0
  194. swarm/templates/simple_blueprint_page.html +24 -0
  195. swarm/templates/websocket_partials/final_system_message.html +3 -0
  196. swarm/templates/websocket_partials/system_message.html +4 -0
  197. swarm/templates/websocket_partials/user_message.html +5 -0
  198. swarm/urls.py +57 -74
  199. swarm/utils/log_utils.py +63 -0
  200. swarm/views/api_views.py +48 -39
  201. swarm/views/chat_views.py +156 -70
  202. swarm/views/core_views.py +85 -90
  203. swarm/views/model_views.py +64 -121
  204. swarm/views/utils.py +65 -441
  205. open_swarm-0.1.1743070217.dist-info/METADATA +0 -258
  206. open_swarm-0.1.1743070217.dist-info/RECORD +0 -89
  207. open_swarm-0.1.1743070217.dist-info/entry_points.txt +0 -3
  208. open_swarm-0.1.1743070217.dist-info/top_level.txt +0 -1
  209. swarm/agent/agent.py +0 -49
  210. swarm/core.py +0 -326
  211. swarm/extensions/mcp/__init__.py +0 -1
  212. swarm/extensions/mcp/cache_utils.py +0 -36
  213. swarm/extensions/mcp/mcp_client.py +0 -341
  214. swarm/extensions/mcp/mcp_constants.py +0 -7
  215. swarm/extensions/mcp/mcp_tool_provider.py +0 -110
  216. swarm/types.py +0 -126
  217. {open_swarm-0.1.1743070217.dist-info → open_swarm-0.1.1743364176.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,94 @@
1
+ // src/swarm/static/rest_mode/js/sidebar.js
2
+
3
+ import { showToast } from './toast.js';
4
+
5
+ /* Existing toggleSidebar function */
6
+ export function toggleSidebar(sidebar) {
7
+ if (sidebar === 'left') {
8
+ const chatHistoryPane = document.getElementById('chatHistoryPane');
9
+ const chatHistoryToggleButton = document.getElementById('chatHistoryToggleButton');
10
+
11
+ if (!chatHistoryPane || !chatHistoryToggleButton) {
12
+ console.warn('Chat History Pane or Toggle Button is missing.');
13
+ return;
14
+ }
15
+
16
+ // Toggle the 'hidden' class
17
+ const isHidden = chatHistoryPane.classList.toggle('hidden');
18
+
19
+
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Sets up resizable sidebars with draggable dividers.
25
+ */
26
+ function setupResizableSidebars() {
27
+ const leftDivider = document.getElementById("divider-left");
28
+ const rightDivider = document.getElementById("divider-right");
29
+
30
+ if (!leftDivider || !chatHistoryPane) {
31
+ console.warn('One or more elements for resizable sidebars are missing.');
32
+ return;
33
+ }
34
+
35
+ const handleMouseMove = (e, targetPane, isLeft) => {
36
+ const newWidth = isLeft
37
+ ? e.clientX
38
+ : window.innerWidth - e.clientX;
39
+ // if (newWidth > 100 && newWidth < 750) {
40
+ // targetPane.style.width = `${newWidth}px`;
41
+ // }
42
+ };
43
+
44
+ const setupResizer = (divider, targetPane, isLeft) => {
45
+ divider.addEventListener("mousedown", (e) => {
46
+ e.preventDefault();
47
+ const onMouseMove = (event) =>
48
+ handleMouseMove(event, targetPane, isLeft);
49
+ document.addEventListener("mousemove", onMouseMove);
50
+ document.addEventListener("mouseup", () => {
51
+ document.removeEventListener("mousemove", onMouseMove);
52
+ });
53
+ });
54
+ };
55
+
56
+ setupResizer(leftDivider, chatHistoryPane, true);
57
+ }
58
+
59
+ /**
60
+ * Initializes the sidebar logic.
61
+ */
62
+ export function initializeSidebar() {
63
+ // Attach event listeners to toggle buttons
64
+ const chatHistoryToggleButton = document.getElementById('chatHistoryToggleButton');
65
+ const optionsToggleButton = document.getElementById('optionsSidebarToggleButton'); // Ensure an ID exists
66
+
67
+ if (chatHistoryToggleButton) {
68
+ chatHistoryToggleButton.addEventListener('click', () => toggleSidebar('left'));
69
+ } else {
70
+ console.warn('Chat History Toggle Button is missing.');
71
+ }
72
+
73
+ if (optionsToggleButton) {
74
+ // Add event listener for closing the dialog when clicking outside
75
+ document.addEventListener('click', function(event) {
76
+ if (event.target === settingsDialog) {
77
+ settingsDialog.classList.add('hidden');
78
+ }
79
+ });
80
+
81
+ // Add event listener for closing the dialog when pressing Escape
82
+ document.addEventListener('keydown', function(event) {
83
+ if (event.key === 'Escape' && !settingsDialog.classList.contains('hidden')) {
84
+ settingsDialog.classList.add('hidden');
85
+ }
86
+ });
87
+ optionsToggleButton.addEventListener('click', () => toggleSidebar('options'));
88
+ } else {
89
+ console.warn('Options Toggle Button is missing.');
90
+ }
91
+
92
+ // Setup resizable sidebars
93
+ setupResizableSidebars();
94
+ }
@@ -0,0 +1,37 @@
1
+ async function handleSubmit(event) {
2
+ event.preventDefault();
3
+ const input = document.getElementById('userInput');
4
+ const message = input.value.trim();
5
+ const blueprintName = document.getElementById('blueprintTitle').textContent;
6
+ if (!message) return;
7
+
8
+ input.value = '';
9
+ const history = document.getElementById('messageHistory');
10
+ history.innerHTML += `<div class="user-message">${message}</div>`;
11
+
12
+ try {
13
+ const response = await fetch('/v1/chat/completions/', {
14
+ method: 'POST',
15
+ headers: {
16
+ 'Content-Type': 'application/json',
17
+ 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').content
18
+ },
19
+ body: JSON.stringify({
20
+ model: blueprintName,
21
+ messages: [{ role: 'user', content: message }]
22
+ })
23
+ });
24
+ const data = await response.json();
25
+ history.innerHTML += `<div class="assistant-message">${data.choices[0].message.content}</div>`;
26
+ history.scrollTop = history.scrollHeight;
27
+ } catch (error) {
28
+ history.innerHTML += `<div class="error-message">Error: ${error.message}</div>`;
29
+ }
30
+ }
31
+
32
+ document.addEventListener('DOMContentLoaded', () => {
33
+ document.getElementById('sendButton').addEventListener('click', handleSubmit);
34
+ document.getElementById('userInput').addEventListener('keypress', (e) => {
35
+ if (e.key === 'Enter') handleSubmit(e);
36
+ });
37
+ });
@@ -0,0 +1,66 @@
1
+ async function fetchBlueprints() {
2
+ const response = await fetch('/v1/models/');
3
+ const data = await response.json();
4
+ return data.data.filter(model => model.object === 'model');
5
+ }
6
+
7
+ function populateChannelList(blueprints) {
8
+ const list = document.getElementById('channelList');
9
+ list.innerHTML = '';
10
+ blueprints.forEach(bp => {
11
+ const li = document.createElement('li');
12
+ li.textContent = `# ${bp.title}`;
13
+ li.dataset.blueprintId = bp.id;
14
+ li.addEventListener('click', () => switchChannel(bp.id));
15
+ list.appendChild(li);
16
+ });
17
+ }
18
+
19
+ let currentBlueprint = null;
20
+ function switchChannel(blueprintId) {
21
+ currentBlueprint = blueprintId;
22
+ document.getElementById('messageHistory').innerHTML = '';
23
+ document.getElementById('blueprintTitle').textContent = blueprintId;
24
+ console.log(`Switched to channel: ${blueprintId}`);
25
+ }
26
+
27
+ async function handleSubmit(event) {
28
+ event.preventDefault();
29
+ const input = document.getElementById('userInput');
30
+ const message = input.value.trim();
31
+ if (!message || !currentBlueprint) return;
32
+
33
+ input.value = '';
34
+ const history = document.getElementById('messageHistory');
35
+ history.innerHTML += `<div class="user-message">${message}</div>`;
36
+
37
+ try {
38
+ const response = await fetch('/v1/chat/completions/', {
39
+ method: 'POST',
40
+ headers: {
41
+ 'Content-Type': 'application/json',
42
+ 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').content
43
+ },
44
+ body: JSON.stringify({
45
+ model: currentBlueprint,
46
+ messages: [{ role: 'user', content: message }]
47
+ })
48
+ });
49
+ const data = await response.json();
50
+ history.innerHTML += `<div class="assistant-message">${data.choices[0].message.content}</div>`;
51
+ history.scrollTop = history.scrollHeight;
52
+ } catch (error) {
53
+ history.innerHTML += `<div class="error-message">Error: ${error.message}</div>`;
54
+ }
55
+ }
56
+
57
+ document.addEventListener('DOMContentLoaded', async () => {
58
+ const blueprints = await fetchBlueprints();
59
+ populateChannelList(blueprints);
60
+ if (blueprints.length > 0) switchChannel(blueprints[0].id);
61
+
62
+ document.getElementById('sendButton').addEventListener('click', handleSubmit);
63
+ document.getElementById('userInput').addEventListener('keypress', (e) => {
64
+ if (e.key === 'Enter') handleSubmit(e);
65
+ });
66
+ });
@@ -0,0 +1,76 @@
1
+ // splash.js - Manages the Splash Screen
2
+
3
+ /**
4
+ * Initializes the splash screen. Fades out after loading finishes and removes it from the DOM.
5
+ */
6
+ export function initializeSplashScreen() {
7
+ console.log("[DEBUG] Initializing splash screen.");
8
+
9
+ window.addEventListener('load', () => {
10
+ const splashScreen = document.getElementById('splashScreen');
11
+ const splashText = document.getElementById('splashText');
12
+
13
+ // List of possible splash texts
14
+ const splashTexts = [
15
+ "Welcome to Open-Swarm Chat!",
16
+ "Connecting to the AI...",
17
+ "Preparing your AI experience...",
18
+ "Loading AI capabilities..."
19
+ ];
20
+
21
+ // Set a random splash text
22
+ if (splashTexts.length > 0 && splashText) {
23
+ const randomIndex = Math.floor(Math.random() * splashTexts.length);
24
+ splashText.textContent = splashTexts[randomIndex];
25
+ console.log(`[DEBUG] Set splash text: ${splashText.textContent}`);
26
+ }
27
+
28
+ // Simulate AI connection establishment
29
+ simulateAIConnection()
30
+ .then(() => {
31
+ // After AI is connected, fade out the splash screen
32
+ if (splashScreen) {
33
+ console.log("[DEBUG] AI connection established. Fading out splash screen.");
34
+ splashScreen.classList.add('fade-out');
35
+ }
36
+ })
37
+ .catch(() => {
38
+ // Handle connection errors
39
+ if (splashText) {
40
+ splashText.textContent = "Failed to connect to the AI.";
41
+ console.warn("[DEBUG] AI connection failed. Displaying error message.");
42
+ }
43
+ // Fade out after showing error
44
+ setTimeout(() => {
45
+ if (splashScreen) {
46
+ splashScreen.classList.add('fade-out');
47
+ }
48
+ }, 3000);
49
+ });
50
+
51
+ // Remove the splash screen from the DOM after the fade-out transition
52
+ if (splashScreen) {
53
+ splashScreen.addEventListener('transitionend', () => {
54
+ if (splashScreen && splashScreen.parentNode) {
55
+ splashScreen.parentNode.removeChild(splashScreen);
56
+ console.log("[DEBUG] Splash screen removed from the DOM.");
57
+ }
58
+ });
59
+ }
60
+ });
61
+ }
62
+
63
+ /**
64
+ * Simulates AI connection establishment.
65
+ * Replace this function with actual connection logic.
66
+ */
67
+ function simulateAIConnection() {
68
+ console.log("[DEBUG] Simulating AI connection...");
69
+ return new Promise((resolve, reject) => {
70
+ // Simulate a successful connection after 2 seconds
71
+ setTimeout(() => {
72
+ resolve();
73
+ console.log("[DEBUG] AI connection simulation resolved.");
74
+ }, 2000);
75
+ });
76
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * theme.js - Handles theme switching (style, layout, dark/light mode)
3
+ */
4
+
5
+ import { showToast } from './toast.js';
6
+
7
+ /**
8
+ * Initializes theme settings based on user preferences or defaults.
9
+ */
10
+ export function initializeTheme() {
11
+ const colorSelect = document.getElementById('colorSelect');
12
+ const layoutSelect = document.getElementById('layoutSelect');
13
+ const darkModeToggle = document.getElementById('darkModeToggle');
14
+
15
+ // Default values
16
+ const defaultSettings = {
17
+ colorTheme: 'corporate',
18
+ layoutTheme: 'messenger-layout',
19
+ darkMode: true,
20
+ };
21
+
22
+ // Load saved preferences from localStorage or use defaults
23
+ const savedColor = localStorage.getItem('selectedColor') || defaultSettings.colorTheme;
24
+ const savedLayout = localStorage.getItem('selectedLayout') || defaultSettings.layoutTheme;
25
+ const savedDarkMode = localStorage.getItem('darkMode') === 'true' || defaultSettings.darkMode;
26
+
27
+ // Apply preferences
28
+ applyColorTheme(savedColor);
29
+ applyLayoutTheme(savedLayout);
30
+ setDarkMode(savedDarkMode);
31
+
32
+ // Sync UI elements with preferences
33
+ if (colorSelect) colorSelect.value = savedColor;
34
+ if (layoutSelect) layoutSelect.value = savedLayout;
35
+ if (darkModeToggle) darkModeToggle.checked = savedDarkMode;
36
+
37
+ // Attach event listeners
38
+ if (colorSelect) {
39
+ colorSelect.addEventListener('change', (e) => {
40
+ applyColorTheme(e.target.value);
41
+ localStorage.setItem('selectedColor', e.target.value);
42
+ });
43
+ }
44
+
45
+ if (layoutSelect) {
46
+ layoutSelect.addEventListener('change', (e) => {
47
+ applyLayoutTheme(e.target.value);
48
+ localStorage.setItem('selectedLayout', e.target.value);
49
+ });
50
+ }
51
+
52
+ if (darkModeToggle) {
53
+ darkModeToggle.addEventListener('change', (e) => {
54
+ const isDarkMode = e.target.checked;
55
+ setDarkMode(isDarkMode);
56
+ localStorage.setItem('darkMode', isDarkMode);
57
+ });
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Applies the selected color theme by adding a data attribute and ensuring all theme-related styles are updated.
63
+ * @param {string} theme - The selected style theme ('pastel', 'tropical', 'corporate').
64
+ */
65
+ function applyColorTheme(theme) {
66
+ const rootElement = document.documentElement; // Use <html> element
67
+ rootElement.setAttribute('data-theme', theme);
68
+
69
+ // Apply variables for custom elements and dynamic parts of the UI
70
+ document.querySelectorAll('.dynamic-theme-element').forEach((element) => {
71
+ const bgColor = getComputedStyle(rootElement).getPropertyValue('--bg-container').trim();
72
+ const textColor = getComputedStyle(rootElement).getPropertyValue('--text-primary').trim();
73
+
74
+ element.style.backgroundColor = bgColor;
75
+ element.style.color = textColor;
76
+ });
77
+
78
+ // Update SVG icon colors dynamically
79
+ document.querySelectorAll('.icon-svg').forEach((icon) => {
80
+ icon.style.fill = getComputedStyle(rootElement).getPropertyValue('--icon-color');
81
+ });
82
+
83
+ showToast(`Theme applied: ${theme.charAt(0).toUpperCase() + theme.slice(1)}`);
84
+ }
85
+
86
+ /**
87
+ * Applies the selected layout theme by adding a data attribute.
88
+ * @param {string} layout - The selected layout theme ('messenger-layout', 'mobile-layout', 'minimalist-layout').
89
+ */
90
+ function applyLayoutTheme(layout) {
91
+ const rootElement = document.documentElement; // Use <html> element
92
+ rootElement.setAttribute('data-theme-layout', layout);
93
+ }
94
+
95
+ /**
96
+ * Sets the dark mode by adding a data attribute and ensuring global variables are updated.
97
+ * @param {boolean} isDarkMode - Whether dark mode is enabled.
98
+ */
99
+ function setDarkMode(isDarkMode) {
100
+ const rootElement = document.documentElement; // Use <html> element
101
+ rootElement.setAttribute('data-theme-dark', isDarkMode ? 'true' : 'false');
102
+
103
+ // Optionally, adjust custom styles for dark mode
104
+ document.querySelectorAll('.dynamic-theme-element').forEach((element) => {
105
+ const bgColor = getComputedStyle(rootElement).getPropertyValue('--bg-container').trim();
106
+ const textColor = getComputedStyle(rootElement).getPropertyValue('--text-primary').trim();
107
+
108
+ element.style.backgroundColor = bgColor;
109
+ element.style.color = textColor;
110
+ });
111
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * toast.js - Handles toast notifications
3
+ */
4
+
5
+ /**
6
+ * Displays a toast notification.
7
+ * @param {string} message - The message to display.
8
+ * @param {string} type - The type of toast ('info', 'success', 'error', 'warning').
9
+ */
10
+ export function showToast(message, type = 'info') {
11
+ const toastContainer = document.getElementById('toastContainer');
12
+ if (!toastContainer) return;
13
+
14
+ // Create toast element
15
+ const toast = document.createElement('div');
16
+ toast.classList.add('toast', type);
17
+ toast.innerHTML = `
18
+ <span>${message}</span>
19
+ <button class="close-btn" aria-label="Close">&times;</button>
20
+ `;
21
+
22
+ // Append to container
23
+ toastContainer.appendChild(toast);
24
+
25
+ // Auto-remove after 5 seconds (handled by CSS animation)
26
+ setTimeout(() => {
27
+ toast.classList.add('fade-out');
28
+ toast.addEventListener('transitionend', () => toast.remove());
29
+ }, 5000);
30
+
31
+ // Remove toast on close button click
32
+ toast.querySelector('.close-btn').addEventListener('click', () => {
33
+ toast.classList.add('fade-out');
34
+ toast.addEventListener('transitionend', () => toast.remove());
35
+ });
36
+ }
@@ -0,0 +1,265 @@
1
+ import { initializeSidebar } from './sidebar.js';
2
+ import { initializeApplication } from './events.js';
3
+ import { initializeChatLogic } from './chatLogic.js';
4
+ import { initializeTheme } from './theme.js';
5
+ import { renderQuickPrompts } from './messages.js';
6
+ import { showToast } from './toast.js';
7
+
8
+ /**
9
+ * Shows the splash page during initialization.
10
+ */
11
+ function showSplashPage() {
12
+ const splashScreen = document.getElementById('splashScreen');
13
+ const appContainer = document.getElementById('appContainer');
14
+
15
+ if (splashScreen) {
16
+ splashScreen.style.display = 'flex';
17
+ appContainer.style.display = 'none';
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Hides the splash page and reveals the app.
23
+ */
24
+ function hideSplashPage() {
25
+ const splashScreen = document.getElementById('splashScreen');
26
+ const appContainer = document.getElementById('appContainer');
27
+
28
+ if (splashScreen) {
29
+ splashScreen.style.display = 'none';
30
+ appContainer.style.display = 'flex';
31
+ }
32
+ }
33
+ /**
34
+ * Sets up the chat history pane, including toggle visibility.
35
+ */
36
+ function setupChatHistoryPane() {
37
+ const chatHistoryPane = document.getElementById('chatHistoryPane');
38
+ const chatHistoryToggleButton = document.getElementById('chatHistoryToggleButton');
39
+ const buttonsToToggle = [
40
+ 'settingsButton-main',
41
+ 'searchButton-main',
42
+ 'newChatButton-main',
43
+ ].map(id => document.getElementById(id));
44
+
45
+ if (!chatHistoryPane || !chatHistoryToggleButton) {
46
+ console.warn("Missing elements for chat history pane.");
47
+ return;
48
+ }
49
+
50
+ // Toggle visibility on button clicks
51
+ const chatHistoryToggleButtonVisible = document.getElementById('chatHistoryToggleButtonVisible');
52
+
53
+ // Toggle button in sidebar
54
+ chatHistoryToggleButton.addEventListener('click', () => {
55
+ chatHistoryPane.classList.add('hidden');
56
+ chatHistoryToggleButtonVisible.style.display = 'block';
57
+
58
+ buttonsToToggle.forEach(button => {
59
+ if (button) {
60
+ button.style.display = 'block';
61
+ }
62
+ });
63
+
64
+ showToast("Chat history minimized.", "info");
65
+
66
+ });
67
+
68
+ // New toggle button in main pane
69
+ if (chatHistoryToggleButtonVisible) {
70
+ chatHistoryToggleButtonVisible.addEventListener('click', () => {
71
+ chatHistoryPane.classList.remove('hidden');
72
+ chatHistoryToggleButtonVisible.style.display = 'none';
73
+ showToast("Chat history expanded.", "info");
74
+
75
+ buttonsToToggle.forEach(button => {
76
+ if (button) {
77
+ button.style.display = 'none';
78
+ }
79
+ });
80
+ });
81
+ }
82
+
83
+ }
84
+
85
+ /**
86
+ * Sets up the settings toggle button functionality.
87
+ */
88
+ import { toggleSidebar } from './sidebar.js';
89
+
90
+ function setupSettingsToggleButton() {
91
+ const settingsToggleButton = document.getElementById('settingsToggleButton');
92
+ const settingsButtonMain = document.getElementById('settingsButton-main');
93
+
94
+ if (settingsToggleButton) {
95
+ settingsToggleButton.addEventListener('click', () => {
96
+ toggleSidebar('options');
97
+ });
98
+ } else {
99
+ console.warn('Warning: Settings toggle button not found.');
100
+ }
101
+
102
+ if (settingsButtonMain) {
103
+ settingsButtonMain.addEventListener('click', () => {
104
+ toggleSidebar('options');
105
+ });
106
+ } else {
107
+ console.warn('Warning: Settings button main not found.');
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Sets up resizable sidebars.
113
+ */
114
+ function setupResizableSidebars() {
115
+ const leftDivider = document.getElementById("divider-left");
116
+ const rightDivider = document.getElementById("divider-right");
117
+ const chatHistoryPane = document.getElementById("chatHistoryPane");
118
+ const optionsPane = document.getElementById("optionsPane");
119
+
120
+ const resize = (divider, targetPane, isLeft) => {
121
+ divider.addEventListener("mousedown", (e) => {
122
+ e.preventDefault();
123
+
124
+ const handleMouseMove = (event) => {
125
+ const newWidth = isLeft
126
+ ? event.clientX - chatHistoryPane.getBoundingClientRect().left
127
+ : optionsPane.getBoundingClientRect().right - event.clientX;
128
+
129
+ // Apply constraints
130
+ if (newWidth >= 150 && newWidth <= 500) {
131
+ targetPane.style.width = `${newWidth}px`;
132
+ }
133
+ };
134
+
135
+ const stopResize = () => {
136
+ document.removeEventListener("mousemove", handleMouseMove);
137
+ document.removeEventListener("mouseup", stopResize);
138
+ };
139
+
140
+ document.addEventListener("mousemove", handleMouseMove);
141
+ document.addEventListener("mouseup", stopResize);
142
+ });
143
+ };
144
+
145
+ if (leftDivider) resize(leftDivider, chatHistoryPane, true);
146
+ if (rightDivider) resize(rightDivider, optionsPane, false);
147
+ }
148
+
149
+ /**
150
+ * Displays the loading indicator.
151
+ */
152
+ export function showLoadingIndicator() {
153
+ const loadingIndicator = document.getElementById("loadingIndicator");
154
+ if (loadingIndicator) {
155
+ loadingIndicator.style.display = 'flex';
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Hides the loading indicator.
161
+ */
162
+ export function hideLoadingIndicator() {
163
+ const loadingIndicator = document.getElementById("loadingIndicator");
164
+ if (loadingIndicator) {
165
+ loadingIndicator.style.display = 'none';
166
+ loadingIndicator.innerHTML = '';
167
+ }
168
+ }
169
+
170
+
171
+ /**
172
+ * Attaches sliding toolbar behavior to messages and adjusts container height.
173
+ * @param {HTMLElement} messageElement - The message element to attach the toolbar logic.
174
+ * @param {Object} options - Configuration for the toolbar behavior.
175
+ * @param {number} options.toolbarHeight - The height of the toolbar when visible (default: 50).
176
+ */
177
+ export function enableSlidingToolbar(
178
+ messageElement,
179
+ { toolbarHeight = 50 } = {}
180
+ ) {
181
+ const toolbar = messageElement.querySelector('.message-toolbar');
182
+ if (!toolbar) return;
183
+
184
+ // Apply initial styles
185
+ toolbar.style.height = '0px';
186
+ toolbar.style.opacity = '0';
187
+ toolbar.style.transition = 'height 0.3s ease, opacity 0.3s ease';
188
+
189
+ messageElement.style.transition = 'height 0.3s ease';
190
+
191
+ messageElement.addEventListener('mouseenter', () => {
192
+ toolbar.style.height = `${toolbarHeight}px`;
193
+ toolbar.style.opacity = '1';
194
+
195
+ // Adjust message height to accommodate the toolbar
196
+ messageElement.style.height = `${messageElement.scrollHeight + toolbarHeight}px`;
197
+ });
198
+
199
+ messageElement.addEventListener('mouseleave', () => {
200
+ toolbar.style.height = '0px';
201
+ toolbar.style.opacity = '0';
202
+
203
+ // Reset message height when toolbar is hidden
204
+ messageElement.style.height = '';
205
+ });
206
+ }
207
+
208
+ // TODO find home for this dropdown black text workaround...
209
+ document.addEventListener('DOMContentLoaded', function() {
210
+ const blueprintDropdown = document.getElementById('blueprintDropdown');
211
+
212
+ // Function to style all options
213
+ function styleOptions() {
214
+ const options = blueprintDropdown?.options;
215
+ if (options) {
216
+ for (let i = 0; i < options.length; i++) {
217
+ options[i].style.color = 'black';
218
+ }
219
+ }
220
+ }
221
+
222
+ // Style options initially
223
+ styleOptions();
224
+
225
+ if (blueprintDropdown) {
226
+ // Style options whenever the dropdown is opened
227
+ blueprintDropdown.addEventListener('mousedown', function() {
228
+ styleOptions();
229
+ });
230
+
231
+ // Style options whenever the dropdown is changed
232
+ blueprintDropdown.addEventListener('change', function() {
233
+ styleOptions();
234
+ });
235
+ }
236
+ });
237
+
238
+
239
+ /**
240
+ * Initializes all UI components and event listeners.
241
+ */
242
+ export function initializeUI() {
243
+ if (window.isUIInitialized) {
244
+ console.warn("UI is already initialized.");
245
+ return;
246
+ }
247
+
248
+ showSplashPage(); // Show the splash page on load
249
+ renderQuickPrompts(); // Render quick prompts on load
250
+
251
+ // Integrate other initialization logic
252
+ initializeSidebar();
253
+ setupChatHistoryPane();
254
+ initializeChatLogic();
255
+ // setupSettingsToggleButton();
256
+ setupResizableSidebars();
257
+ initializeTheme();
258
+
259
+ // Hide the splash screen after initialization
260
+ setTimeout(hideSplashPage, 2000); // Example delay for effect
261
+
262
+ window.isUIInitialized = true;
263
+ }
264
+
265
+