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,110 @@
1
+ // src/swarm/static/rest_mode/js/modules/chatHistory.js
2
+
3
+ import { showToast } from '../toast.js';
4
+ import { appendRawMessage } from '../messages.js';
5
+ import { deleteChat } from './apiService.js';
6
+ import { debugLog } from './debugLogger.js';
7
+ import { chatHistory, contextVariables } from './state.js';
8
+
9
+ /**
10
+ * Truncates long messages and adds a "more..." link if needed.
11
+ * @param {string} content - The message content to truncate.
12
+ * @param {number} maxLength - The maximum length before truncation.
13
+ * @returns {string} - The truncated message with a "more..." link if applicable.
14
+ */
15
+ function truncateMessage(content, maxLength = 50) {
16
+ if (content.length > maxLength) {
17
+ const truncated = content.slice(0, maxLength);
18
+ return `<span data-full-content="${content}">${truncated}... <a href="#" class="read-more">more</a></span>`;
19
+ }
20
+ return content;
21
+ }
22
+
23
+ /**
24
+ * Creates a new chat history entry in the sidebar.
25
+ * @param {string} firstMessage - The user's first message in the chat.
26
+ */
27
+ export function createChatHistoryEntry(chatName, firstMessage) {
28
+ const chatHistoryPane = document.getElementById('chatHistoryPane');
29
+ if (!chatHistoryPane) {
30
+ debugLog('Chat history pane element not found.');
31
+ return;
32
+ }
33
+
34
+ // Create new chat history item
35
+ const chatItem = document.createElement('li');
36
+ chatItem.className = 'chat-history-item';
37
+
38
+ // Generate truncated message with "more..." link if necessary
39
+ const truncatedMessage = truncateMessage(firstMessage);
40
+
41
+ // Populate the chat history item
42
+ chatItem.innerHTML = `
43
+ <details>
44
+ <summary>${chatName}</summary>
45
+ <p>${truncatedMessage}</p>
46
+ <span class="chat-item-time">${new Date().toLocaleString()}</span>
47
+ <div class="chat-item-tools">
48
+ <!-- Tag Buttons and Delete Button -->
49
+ <div class="chat-item-tags">
50
+ <button class="tag-button" aria-label="Filter by General">General</button>
51
+ <button class="tag-button" aria-label="Filter by Introduction">Introduction</button>
52
+ <button class="tag-button" aria-label="Filter by Welcome">Welcome</button>
53
+ <button class="tag-button add-tag-btn" aria-label="Add Tag">+</button>
54
+ <!-- Delete Button -->
55
+ <button class="toolbar-btn delete-chat-btn" title="Delete Chat" aria-label="Delete Chat">
56
+ <img src="${window.STATIC_URLS.trashIcon}" alt="Delete Chat">
57
+ </button>
58
+ </div>
59
+ </div>
60
+ </details>
61
+ `;
62
+
63
+ // Add the new chat item to the top of the list
64
+ const chatList = chatHistoryPane.querySelector('.chat-history-list');
65
+ if (chatList) {
66
+ chatList.prepend(chatItem); // Insert at the top
67
+ debugLog('New chat history entry created and added to the list.', chatItem);
68
+ }
69
+
70
+ // Event listener for "more..." links
71
+ chatItem.querySelectorAll('.read-more').forEach(link => {
72
+ link.addEventListener('click', (event) => {
73
+ event.preventDefault();
74
+ const parent = link.parentElement;
75
+ if (parent) {
76
+ parent.innerHTML = parent.getAttribute('data-full-content'); // Reveal full content
77
+ }
78
+ });
79
+ });
80
+
81
+ // Event listener for delete button
82
+ const deleteBtn = chatItem.querySelector('.delete-chat-btn');
83
+ if (deleteBtn) {
84
+ deleteBtn.addEventListener('click', () => deleteChat(chatItem));
85
+ }
86
+
87
+ // Event listener for selecting the chat item
88
+ chatItem.addEventListener('click', (event) => {
89
+ // Prevent triggering when clicking on "more..." link or delete button
90
+ if (event.target.classList.contains('read-more') || event.target.closest('.delete-chat-btn')) {
91
+ return;
92
+ }
93
+ handleChatHistoryClick(chatItem);
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Handles chat history item click.
99
+ * @param {HTMLElement} item - The clicked chat history item.
100
+ */
101
+ export function handleChatHistoryClick(item) {
102
+ const chatName = item.querySelector('summary').textContent.trim();
103
+ showToast(`Selected: "${chatName}"`, 'info');
104
+
105
+ const chatHistoryItems = document.querySelectorAll('.chat-history-pane li');
106
+ chatHistoryItems.forEach((i) => i.classList.remove('active'));
107
+ item.classList.add('active');
108
+
109
+ // Additional logic to load the selected chat can be added here
110
+ }
@@ -0,0 +1,14 @@
1
+ // src/swarm/static/rest_mode/js/modules/debugLogger.js
2
+
3
+ const DEBUG_MODE = true;
4
+
5
+ /**
6
+ * Logs debug messages if debug mode is enabled.
7
+ * @param {string} message - The message to log.
8
+ * @param {any} data - Additional data to include in the log.
9
+ */
10
+ export function debugLog(message, data = null) {
11
+ if (DEBUG_MODE) {
12
+ console.log(`[DEBUG] ${message}`, data);
13
+ }
14
+ }
@@ -0,0 +1,107 @@
1
+ // src/swarm/static/rest_mode/js/modules/eventHandlers.js
2
+
3
+ import { handleLogout } from '../auth.js';
4
+ import { toggleDebugPane, handleTechSupport } from '../debug.js';
5
+ import { toggleSidebar } from '../sidebar.js';
6
+
7
+ import { handleChatHistoryClick } from './chatHistory.js';
8
+ import { deleteChat } from './apiService.js';
9
+ import { handleUpload, handleVoiceRecord } from './userInteractions.js';
10
+ import { fetchBlueprintMetadata } from './apiService.js';
11
+ import { handleSubmit } from './messageProcessor.js';
12
+ import { showToast } from '../toast.js';
13
+ import { debugLog } from './debugLogger.js';
14
+
15
+ /**
16
+ * Handles "Search" button click.
17
+ */
18
+ function handleSearch() {
19
+ showToast("🔍 Search feature is under development.", "info");
20
+ }
21
+
22
+ /**
23
+ * Handles "New Chat" button click.
24
+ */
25
+ function handleNewChat() {
26
+ showToast("📝 Starting a new chat...", "info");
27
+ // Implement new chat functionality as needed
28
+ }
29
+
30
+ /**
31
+ * Attaches event listeners to chat history items.
32
+ */
33
+ function setupChatHistoryListeners() {
34
+ const chatHistoryItems = document.querySelectorAll('.chat-history-pane li');
35
+ chatHistoryItems.forEach((item) => {
36
+ item.removeEventListener('click', () => handleChatHistoryClick(item));
37
+ item.addEventListener('click', () => handleChatHistoryClick(item));
38
+
39
+ const trashCan = item.querySelector('.trash-can');
40
+ if (trashCan) {
41
+ trashCan.addEventListener('click', (e) => {
42
+ e.stopPropagation();
43
+ deleteChat(item);
44
+ });
45
+ }
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Attaches event listeners to main application buttons and elements.
51
+ */
52
+ function setupGlobalEventListeners() {
53
+ // Sidebar toggles
54
+ document.getElementById("settingsToggleButton")?.removeEventListener('click', () => toggleSidebar('options', true));
55
+ document.getElementById("settingsToggleButton")?.addEventListener('click', () => toggleSidebar('options', true));
56
+ document.getElementById("optionsSidebarHideBtn")?.addEventListener('click', () => toggleSidebar('options', false));
57
+ // Removed event listeners for chatHistoryToggleButton and leftSidebarHideBtn
58
+
59
+ // Top buttons
60
+ // document.getElementById("searchButton")?.addEventListener('click', handleSearch);
61
+ document.getElementById("newChatButton")?.addEventListener('click', handleNewChat);
62
+
63
+ // Functional buttons
64
+ document.getElementById("logoutButton")?.addEventListener('click', handleLogout);
65
+ document.getElementById("uploadButton")?.addEventListener('click', handleUpload);
66
+ document.getElementById("voiceRecordButton")?.addEventListener('click', handleVoiceRecord);
67
+ document.getElementById("submitButton")?.addEventListener("click", handleSubmit); // Attached here
68
+
69
+ // User input submission with Enter key
70
+ const userInput = document.getElementById("userInput");
71
+ userInput?.addEventListener("keypress", (e) => {
72
+ if (e.key === "Enter") {
73
+ handleSubmit();
74
+ }
75
+ });
76
+
77
+ // Debug pane toggles
78
+ document.getElementById("debugButton")?.addEventListener('click', toggleDebugPane);
79
+ document.getElementById("techSupportButtonInsideDebug")?.addEventListener('click', handleTechSupport);
80
+ }
81
+
82
+ /**
83
+ * Sets up all event listeners for the application.
84
+ */
85
+ let eventListenersInitialized = false;
86
+
87
+ export function setupEventListeners() {
88
+ if (eventListenersInitialized) {
89
+ debugLog('Event listeners are already initialized.');
90
+ return;
91
+ }
92
+
93
+ setupGlobalEventListeners();
94
+ setupChatHistoryListeners();
95
+ debugLog('All event listeners have been set up.');
96
+ eventListenersInitialized = true;
97
+ }
98
+
99
+ /**
100
+ * Initialize the application.
101
+ */
102
+ export function initializeApplication() {
103
+ debugLog('[DEBUG] Initializing application...');
104
+ fetchBlueprintMetadata(); // Fetch blueprint metadata and display it
105
+ setupEventListeners(); // Set up event listeners
106
+ debugLog('[DEBUG] Application initialized.');
107
+ }
@@ -0,0 +1,120 @@
1
+ // src/swarm/static/rest_mode/js/modules/messageProcessor.js
2
+
3
+ import { showToast } from '../toast.js';
4
+ import { appendRawMessage } from '../messages.js';
5
+ import { showLoadingIndicator, hideLoadingIndicator } from '../ui.js';
6
+
7
+ import { submitMessage } from './apiService.js';
8
+ import { debugLog } from './debugLogger.js';
9
+ import { validateMessage } from './validation.js';
10
+ import { chatHistory, contextVariables } from './state.js'; // Assuming state.js manages shared state
11
+ import { createChatHistoryEntry } from './chatHistory.js';
12
+
13
+ /**
14
+ * Processes the assistant's response and updates context variables.
15
+ * @param {Object} data - The response data from the server.
16
+ * @param {Object} contextVariables - The current context variables.
17
+ */
18
+ export function processAssistantResponse(data, contextVariables) {
19
+ if (!data.choices || !Array.isArray(data.choices)) {
20
+ debugLog('Invalid response structure:', data);
21
+ showToast('⚠️ Invalid response from server.', 'error');
22
+ return;
23
+ }
24
+
25
+ data.choices.forEach((choice) => {
26
+ const rawMessage = { ...choice.message };
27
+
28
+ const role = rawMessage.role || 'assistant';
29
+ const content = rawMessage.content || 'No content';
30
+ const sender = rawMessage.sender || (role === 'user' ? 'User' : 'Assistant');
31
+
32
+ appendRawMessage(role, { content }, sender, rawMessage.metadata);
33
+ });
34
+
35
+ debugLog('Assistant response processed successfully.', data);
36
+ }
37
+
38
+ /**
39
+ * Handles user message submission.
40
+ * @returns {Promise<void>}
41
+ */
42
+ export async function handleSubmit() {
43
+ const userInput = document.getElementById("userInput");
44
+ if (!userInput) {
45
+ debugLog("User input element not found.");
46
+ return;
47
+ }
48
+
49
+ const userMessageContent = userInput.value.trim();
50
+ if (!userMessageContent) {
51
+ showToast("❌ You cannot send an empty message.", "error");
52
+ debugLog("Empty message submission blocked.");
53
+ return;
54
+ }
55
+
56
+ // Clear input field
57
+ userInput.value = "";
58
+
59
+ const userMessage = {
60
+ role: "user",
61
+ content: userMessageContent,
62
+ sender: "User",
63
+ metadata: {},
64
+ };
65
+ chatHistory.push(userMessage);
66
+ debugLog("User message added to chat history.", userMessage);
67
+
68
+ const isFirstUserMessage = chatHistory.filter((msg) => msg.role === "user").length === 1;
69
+
70
+ // Validate the message
71
+ const error = validateMessage(userMessage);
72
+ if (error) return;
73
+
74
+ // Render the user message in the UI
75
+ appendRawMessage(userMessage.role, { content: userMessage.content }, userMessage.sender, userMessage.metadata);
76
+
77
+ // If it's the first user message, update the persistent message and create a new chat history entry
78
+ if (isFirstUserMessage) {
79
+ const persistentMessageElement = document.getElementById('firstUserMessage');
80
+ if (persistentMessageElement) {
81
+ persistentMessageElement.innerHTML = `<b>Persist:</b><p>User: ${userMessageContent}</p>`;
82
+ debugLog("Persistent message updated with the first user message.");
83
+ }
84
+ createChatHistoryEntry("New Chat", userMessageContent);
85
+ }
86
+
87
+ showLoadingIndicator(); // Show loading spinner
88
+
89
+ try {
90
+ const urlPath = window.location.pathname;
91
+ const modelName = urlPath.split("/").filter(Boolean).pop() || "";
92
+ debugLog("Submitting message to model.", { modelName, message: userMessageContent });
93
+
94
+ const response = await fetch("/v1/chat/completions", {
95
+ method: "POST",
96
+ headers: {
97
+ "Content-Type": "application/json",
98
+ "X-CSRFToken": document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") || "",
99
+ },
100
+ body: JSON.stringify({
101
+ model: modelName,
102
+ messages: chatHistory,
103
+ context_variables: contextVariables,
104
+ }),
105
+ });
106
+
107
+ if (!response.ok) {
108
+ throw new Error(`HTTP Error: ${response.status}`);
109
+ }
110
+
111
+ const data = await response.json();
112
+ debugLog("Message successfully processed by the model.", data);
113
+ processAssistantResponse(data, contextVariables); // Ensure this matches your function signature
114
+ } catch (err) {
115
+ console.error("Error submitting message:", err);
116
+ showToast("⚠️ Error submitting message. Please try again.", "error");
117
+ } finally {
118
+ hideLoadingIndicator(); // Hide loading spinner
119
+ }
120
+ }
@@ -0,0 +1,7 @@
1
+ // src/swarm/static/rest_mode/js/modules/state.js
2
+
3
+ /**
4
+ * Shared state variables.
5
+ */
6
+ export let contextVariables = { active_agent_name: null };
7
+ export let chatHistory = [];
@@ -0,0 +1,29 @@
1
+ // src/swarm/static/rest_mode/js/modules/userInteractions.js
2
+
3
+ import { showToast } from '../toast.js';
4
+ import { debugLog } from './debugLogger.js';
5
+
6
+ /**
7
+ * Handles user logout.
8
+ */
9
+ export function handleLogout() {
10
+ showToast('🚪 You have been logged out.', 'info');
11
+ debugLog('User initiated logout.');
12
+ window.location.href = '/login';
13
+ }
14
+
15
+ /**
16
+ * Handles file upload.
17
+ */
18
+ export function handleUpload() {
19
+ showToast('➕ Upload feature is under development.', 'info');
20
+ debugLog('User attempted to upload a file.');
21
+ }
22
+
23
+ /**
24
+ * Handles voice recording.
25
+ */
26
+ export function handleVoiceRecord() {
27
+ showToast('🎤 Voice recording is under development.', 'info');
28
+ debugLog('User attempted to record voice.');
29
+ }
@@ -0,0 +1,23 @@
1
+ // src/swarm/static/rest_mode/js/modules/validation.js
2
+
3
+ import { showToast } from '../toast.js';
4
+ import { debugLog } from './debugLogger.js';
5
+
6
+ /**
7
+ * Validates the user message.
8
+ * @param {Object} message - The message object to validate.
9
+ * @returns {string|null} - Error message if invalid, or null if valid.
10
+ */
11
+ export function validateMessage(message) {
12
+ if (!message.content || message.content.trim() === '') {
13
+ showToast('❌ Message cannot be empty.', 'error');
14
+ debugLog('Validation failed: Message is empty.');
15
+ return 'Message cannot be empty.';
16
+ }
17
+ if (message.content.length > 5000) {
18
+ showToast('❌ Message too long. Please limit to 5000 characters.', 'error');
19
+ debugLog('Validation failed: Message too long.');
20
+ return 'Message too long.';
21
+ }
22
+ return null; // Valid message
23
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * rendering.js - Contains functions for rendering messages in the chat area,
3
+ * and appending raw messages to the debug panel.
4
+ */
5
+ const messageContainerId = "messageHistory";
6
+ const rawMessagesContainerId = "rawMessagesContent";
7
+
8
+ /**
9
+ * Retrieves the current style theme.
10
+ * @returns {string} - The current style theme ('pastel', 'tropical', 'corporate').
11
+ */
12
+ function getCurrentStyleTheme() {
13
+ const container = document.querySelector('.container');
14
+ return container?.getAttribute('data-theme-color') || 'pastel';
15
+ }
16
+
17
+ /**
18
+ * Renders a single message in the chat.
19
+ */
20
+ export function renderMessage(role, message, sender = "", metadata = {}, isFirstUser = false) {
21
+ const messageHistory = document.getElementById(messageContainerId);
22
+ if (!messageHistory) return;
23
+
24
+ const containerDiv = document.createElement("div");
25
+ containerDiv.classList.add("message", role);
26
+ if (isFirstUser) containerDiv.classList.add("first-user");
27
+
28
+ // For our special "plus" icon on hover (to persist the message), we wrap the messageContent in a container
29
+ // Then on hover, show a small plus icon in the top-right corner
30
+ let messageContent = `<strong>${sender}:</strong> ${message.content}`;
31
+
32
+ // If role === "assistant" and layout is "minimalist", remove boxes, etc.
33
+ const containerElement = document.querySelector('.container');
34
+ if (role === "assistant" && containerElement?.getAttribute('data-theme-layout') === 'minimalist-layout') {
35
+ messageContent = message.content;
36
+ }
37
+
38
+ // Determine trash can icon based on current style
39
+ const currentStyle = getCurrentStyleTheme();
40
+ let trashCanIcon = '';
41
+ if (currentStyle === 'corporate') {
42
+ trashCanIcon = '✖️'; // X icon
43
+ } else if (currentStyle === 'tropical') {
44
+ trashCanIcon = '🗑️'; // Emoji trashcan
45
+ } else { // pastel
46
+ trashCanIcon = '🗑️'; // Smaller slim trash can could use a different emoji or a custom SVG
47
+ }
48
+
49
+ containerDiv.innerHTML = `
50
+ <div class="message-text">
51
+ ${messageContent}
52
+ </div>
53
+ <span class="persist-icon" title="Persist this message to the pinned area">➕</span>
54
+ <span class="trash-can" title="Delete Chat">${trashCanIcon}</span>
55
+ `;
56
+
57
+ // Add event listener on the plus icon
58
+ const plusIcon = containerDiv.querySelector('.persist-icon');
59
+ plusIcon?.addEventListener('click', (event) => {
60
+ event.stopPropagation();
61
+ persistMessage(role, message, sender);
62
+ });
63
+
64
+ // Add event listener on the trash can
65
+ const trashCan = containerDiv.querySelector('.trash-can');
66
+ trashCan?.addEventListener('click', (event) => {
67
+ event.stopPropagation();
68
+ // Implement deletion logic if necessary
69
+ showToast("��️ Delete feature is under development.", "info");
70
+ });
71
+
72
+ messageHistory.appendChild(containerDiv);
73
+ messageHistory.scrollTop = messageHistory.scrollHeight;
74
+ }
75
+
76
+ /**
77
+ * Persists a message in the "first user message" container,
78
+ * along with any other pinned messages.
79
+ */
80
+ function persistMessage(role, message, sender = "") {
81
+ const firstUserMessageDiv = document.getElementById("firstUserMessage");
82
+ if (!firstUserMessageDiv) return;
83
+
84
+ // We'll allow multiple pinned messages by just appending
85
+ const pinned = document.createElement("div");
86
+ pinned.classList.add("pinned-message");
87
+ pinned.innerHTML = `<small>${sender}:</small> ${message.content}`;
88
+
89
+ firstUserMessageDiv.style.display = "block";
90
+ firstUserMessageDiv.appendChild(pinned);
91
+ }
92
+
93
+ /**
94
+ * Appends raw message data to the Raw Messages pane.
95
+ * @param {string} role - The role of the sender.
96
+ * @param {object} content - The message content.
97
+ * @param {string} sender - The display name of the sender.
98
+ * @param {object} metadata - The metadata associated with the message.
99
+ */
100
+ export function appendRawMessage(role, content, sender, metadata) {
101
+ const rawMessage = document.createElement("div");
102
+ rawMessage.className = "raw-message";
103
+
104
+ const rawData = {
105
+ role: role,
106
+ sender: sender || "Unknown",
107
+ content: content.content || "No content provided.",
108
+ metadata: metadata // Retain full metadata for backend processing
109
+ };
110
+
111
+ const pre = document.createElement("pre");
112
+ pre.textContent = JSON.stringify(rawData, null, 2);
113
+ rawMessage.appendChild(pre);
114
+
115
+ rawMessagesContent.appendChild(rawMessage);
116
+ rawMessagesContent.scrollTop = rawMessagesContent.scrollHeight;
117
+
118
+ console.log("Appended Raw Message:", rawData);
119
+ }
@@ -0,0 +1,130 @@
1
+ const DEBUG_MODE = true;
2
+
3
+ import { showToast } from './toast.js';
4
+
5
+ export let llmConfig = {};
6
+
7
+ /**
8
+ * Logs debug messages if debug mode is enabled.
9
+ * @param {string} message - The message to log.
10
+ * @param {any} data - Additional data to include in the log.
11
+ */
12
+ export function debugLog(message, data = null) {
13
+ if (DEBUG_MODE) {
14
+ console.log(`[DEBUG] ${message}`, data);
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Fetch and load LLM configuration.
20
+ */
21
+ export async function loadLLMConfig() {
22
+ debugLog("Attempting to load LLM configuration...");
23
+ try {
24
+ const response = await fetch('/config/swarm_config.json');
25
+ debugLog("Received response from LLM config fetch.", { status: response.status });
26
+
27
+ if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);
28
+ const config = await response.json();
29
+ debugLog("LLM configuration loaded successfully.", config);
30
+
31
+ llmConfig = config.llm || {};
32
+ updateLLMSettingsPane(llmConfig);
33
+ } catch (error) {
34
+ console.error("Error loading LLM config:", error);
35
+ showToast("⚠️ LLM settings could not be loaded. Please check the server.", "warning");
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Updates the settings pane with collapsible LLM modes and toggles.
41
+ * @param {Object} config - The LLM configuration object.
42
+ */
43
+ function updateLLMSettingsPane(config) {
44
+ debugLog("Updating LLM settings pane...", config);
45
+
46
+ const llmContainer = document.getElementById('llmConfiguration');
47
+ if (!llmContainer) {
48
+ console.warn("[DEBUG] LLM configuration container not found in the DOM.");
49
+ return;
50
+ }
51
+
52
+ llmContainer.innerHTML = Object.entries(config)
53
+ .map(([mode, details]) => {
54
+ const isDefault = mode === 'default';
55
+ const toggleHTML = `
56
+ <div class="svg-toggle ${isDefault ? 'disabled' : ''}" data-state="on" id="toggle-${mode}">
57
+ <img src="/static/rest_mode/svg/toggle_on.svg" alt="Toggle On">
58
+ </div>
59
+ `;
60
+
61
+ const fields = Object.entries(details)
62
+ .map(([key, value]) => `
63
+ <div class="llm-field">
64
+ <label>${key}:</label>
65
+ <input type="text" value="${value}" readonly>
66
+ </div>
67
+ `)
68
+ .join('');
69
+
70
+ return `
71
+ <div class="llm-mode collapsible">
72
+ <h4 class="collapsible-toggle">
73
+ ${toggleHTML} ${mode.charAt(0).toUpperCase() + mode.slice(1)} Mode
74
+ <span>▼</span>
75
+ </h4>
76
+ <div class="collapsible-content hidden">
77
+ ${fields}
78
+ </div>
79
+ </div>
80
+ `;
81
+ })
82
+ .join('');
83
+
84
+ initializeLLMModeToggles();
85
+ initializeCollapsibleSections();
86
+ }
87
+
88
+ /**
89
+ * Initialize toggles for LLM modes.
90
+ */
91
+ function initializeLLMModeToggles() {
92
+ Object.keys(llmConfig).forEach((mode) => {
93
+ const toggle = document.getElementById(`toggle-${mode}`);
94
+ if (toggle && mode !== 'default') {
95
+ toggle.addEventListener('click', (event) => {
96
+ event.stopPropagation();
97
+ const isOn = toggle.dataset.state === 'on';
98
+ toggle.dataset.state = isOn ? 'off' : 'on';
99
+ toggle.querySelector('img').src = isOn
100
+ ? '/static/rest_mode/svg/toggle_off.svg'
101
+ : '/static/rest_mode/svg/toggle_on.svg';
102
+ showToast(`${mode.charAt(0).toUpperCase() + mode.slice(1)} Mode ${isOn ? 'disabled' : 'enabled'}`);
103
+ });
104
+ }
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Initialize collapsible behavior for LLM modes and sections.
110
+ */
111
+ function initializeCollapsibleSections() {
112
+ document.querySelectorAll('.collapsible-toggle').forEach((toggle) => {
113
+ toggle.addEventListener('click', () => {
114
+ const content = toggle.nextElementSibling;
115
+ if (content) {
116
+ content.classList.toggle('hidden');
117
+ const isOpen = !content.classList.contains('hidden');
118
+ toggle.querySelector('span').textContent = isOpen ? '▲' : '▼';
119
+ }
120
+ });
121
+ });
122
+ }
123
+
124
+ /**
125
+ * Initialize settings logic.
126
+ */
127
+ document.addEventListener('DOMContentLoaded', () => {
128
+ debugLog("Settings page initialized.");
129
+ loadLLMConfig();
130
+ });