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,355 @@
1
+ async function fetchBlueprints() {
2
+ console.log('Fetching blueprints from /v1/models/ at:', new Date().toISOString());
3
+ try {
4
+ const response = await fetch('/v1/models/');
5
+ if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
6
+ const data = await response.json();
7
+ console.log('Raw response from /v1/models/:', data); // Print the raw response
8
+ const blueprints = data.data.filter(model => model.object === 'model');
9
+ console.log('Filtered blueprints:', blueprints);
10
+ return blueprints;
11
+ } catch (error) {
12
+ console.error('Error fetching blueprints:', error);
13
+ return [];
14
+ }
15
+ }
16
+
17
+ function populateChannelList(blueprints) {
18
+ console.log('Populating channel list with blueprints:', blueprints);
19
+ const list = document.getElementById('channelList');
20
+ if (!list) {
21
+ console.error('Channel list element not found!');
22
+ return;
23
+ }
24
+ console.log('Channel list found, initial HTML:', list.innerHTML);
25
+ list.innerHTML = ''; // Clear to ensure test data
26
+ // Preserve or add pseudo-channel
27
+ const existingPseudo = list.querySelector('li[data-blueprint-id="welcome"]');
28
+ if (!existingPseudo) {
29
+ list.innerHTML += '<li data-blueprint-id="welcome">#Welcome to Open-Swarm</li>';
30
+ console.log('Added pseudo-channel');
31
+ }
32
+ // Force test data
33
+ const testData = [
34
+ { id: 'test1', title: 'Test Channel 1' },
35
+ { id: 'test2', title: 'Test Channel 2' }
36
+ ];
37
+ testData.forEach(bp => {
38
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
39
+ const li = document.createElement('li');
40
+ li.textContent = `# ${bp.title}`;
41
+ li.dataset.blueprintId = bp.id;
42
+ li.addEventListener('click', () => switchChannel(bp.id));
43
+ list.appendChild(li);
44
+ console.log('Added test channel:', bp.title);
45
+ }
46
+ });
47
+ blueprints.forEach(bp => {
48
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
49
+ const li = document.createElement('li');
50
+ li.textContent = `# ${bp.title}`;
51
+ li.dataset.blueprintId = bp.id;
52
+ li.addEventListener('click', () => switchChannel(bp.id));
53
+ list.appendChild(li);
54
+ console.log('Added blueprint:', bp.title);
55
+ }
56
+ });
57
+ console.log('Channel list updated:', list.innerHTML);
58
+ }
59
+
60
+ let currentBlueprint = null;
61
+ function switchChannel(blueprintId) {
62
+ currentBlueprint = blueprintId;
63
+ document.getElementById('messageHistory').innerHTML = '';
64
+ document.getElementById('blueprintTitle').textContent = blueprintId;
65
+ console.log(`Switched to channel: ${blueprintId}`);
66
+ }
67
+
68
+ async function handleSubmit(event) {
69
+ event.preventDefault();
70
+ const input = document.getElementById('userInput');
71
+ const message = input.value.trim();
72
+ if (!message || !currentBlueprint) {
73
+ console.log('No message or blueprint selected, skipping submission');
74
+ return;
75
+ }
76
+ input.value = '';
77
+ const history = document.getElementById('messageHistory');
78
+ history.innerHTML += `<div class="user-message">${message}</div>`;
79
+ try {
80
+ const response = await fetch('/v1/chat/completions/', {
81
+ method: 'POST',
82
+ headers: {
83
+ 'Content-Type': 'application/json',
84
+ 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').content
85
+ },
86
+ body: JSON.stringify({
87
+ model: currentBlueprint,
88
+ messages: [{ role: 'user', content: message }]
89
+ })
90
+ });
91
+ const data = await response.json();
92
+ history.innerHTML += `<div class="assistant-message">${data.choices[0].message.content}</div>`;
93
+ history.scrollTop = history.scrollHeight;
94
+ } catch (error) {
95
+ console.error('Error submitting message:', error);
96
+ history.innerHTML += `<div class="error-message">Error: ${error.message}</div>`;
97
+ }
98
+ }
99
+
100
+ document.addEventListener('DOMContentLoaded', () => {
101
+ console.log('DOM fully loaded, initializing Messenger at:', new Date().toISOString());
102
+ const blueprints = []; // Disable fetch to test DOM with test data
103
+ populateChannelList(blueprints);
104
+ if (blueprints.length > 0) {
105
+ switchChannel(blueprints[0].id);
106
+ } else {
107
+ console.log('No blueprints available, using test data at:', new Date().toISOString());
108
+ }
109
+ document.getElementById('sendButton').addEventListener('click', handleSubmit);
110
+ document.getElementById('userInput').addEventListener('keypress', (e) => {
111
+ if (e.key === 'Enter') handleSubmit(e);
112
+ });
113
+ });
114
+ // Append debugging and test data
115
+ console.log('Appending debug at:', new Date().toISOString());
116
+ const originalPopulate = populateChannelList;
117
+ populateChannelList = function(blueprints) {
118
+ console.log('Original populate called with:', blueprints);
119
+ originalPopulate(blueprints); // Call your original function
120
+ // Force test data
121
+ const testData = [
122
+ { id: 'test1', title: 'Test Channel 1' },
123
+ { id: 'test2', title: 'Test Channel 2' }
124
+ ];
125
+ const list = document.getElementById('channelList');
126
+ if (list) {
127
+ testData.forEach(bp => {
128
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
129
+ const li = document.createElement('li');
130
+ li.textContent = `# ${bp.title}`;
131
+ li.dataset.blueprintId = bp.id;
132
+ li.addEventListener('click', () => switchChannel(bp.id));
133
+ list.appendChild(li);
134
+ console.log('Added test channel:', bp.title, 'at:', new Date().toISOString());
135
+ }
136
+ });
137
+ console.log('Channel list updated with test data:', list.innerHTML);
138
+ } else {
139
+ console.error('Channel list not found during test data append!');
140
+ }
141
+ };
142
+ // Append debug and test data
143
+ console.log('Appending debug at:', new Date().toISOString());
144
+ const originalFetch = fetchBlueprints;
145
+ fetchBlueprints = async function() {
146
+ console.log('Fetching blueprints with debug at:', new Date().toISOString());
147
+ const blueprints = await originalFetch();
148
+ console.log('Fetch result:', blueprints);
149
+ return blueprints;
150
+ };
151
+ const originalPopulate = populateChannelList;
152
+ populateChannelList = function(blueprints) {
153
+ console.log('Populating with debug:', blueprints);
154
+ originalPopulate(blueprints);
155
+ if (blueprints.length === 0) {
156
+ const testData = [
157
+ { id: 'test1', title: 'Test Channel 1' },
158
+ { id: 'test2', title: 'Test Channel 2' }
159
+ ];
160
+ const list = document.getElementById('channelList');
161
+ if (list) {
162
+ testData.forEach(bp => {
163
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
164
+ const li = document.createElement('li');
165
+ li.textContent = `# ${bp.title}`;
166
+ li.dataset.blueprintId = bp.id;
167
+ li.addEventListener('click', () => switchChannel(bp.id));
168
+ list.appendChild(li);
169
+ console.log('Added test channel:', bp.title);
170
+ }
171
+ });
172
+ console.log('Updated with test data:', list.innerHTML);
173
+ }
174
+ }
175
+ };
176
+ // Append debug and test data
177
+ console.log('Debug append at:', new Date().toISOString());
178
+ const originalPopulate = populateChannelList;
179
+ populateChannelList = function(blueprints) {
180
+ console.log('Populating with:', blueprints);
181
+ originalPopulate(blueprints);
182
+ const testData = [
183
+ { id: 'test1', title: 'Test Channel 1' },
184
+ { id: 'test2', title: 'Test Channel 2' }
185
+ ];
186
+ const list = document.getElementById('channelList');
187
+ if (list) {
188
+ testData.forEach(bp => {
189
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
190
+ const li = document.createElement('li');
191
+ li.textContent = `# ${bp.title}`;
192
+ li.dataset.blueprintId = bp.id;
193
+ li.addEventListener('click', () => switchChannel(bp.id));
194
+ list.appendChild(li);
195
+ console.log('Added test:', bp.title);
196
+ }
197
+ });
198
+ console.log('List after test:', list.innerHTML);
199
+ } else {
200
+ console.error('No channel list found!');
201
+ }
202
+ };
203
+ // Append debug and test data
204
+ console.log('MessengerLogic debug append at:', new Date().toISOString());
205
+ const originalFetch = fetchBlueprints;
206
+ fetchBlueprints = async function() {
207
+ console.log('Executing fetchBlueprints at:', new Date().toISOString());
208
+ const response = await originalFetch();
209
+ console.log('Fetch result from /v1/models/:', response);
210
+ return response;
211
+ };
212
+ const originalPopulate = populateChannelList;
213
+ populateChannelList = function(blueprints) {
214
+ console.log('Executing populateChannelList with:', blueprints);
215
+ originalPopulate(blueprints);
216
+ if (blueprints.length === 0 || !blueprints) {
217
+ console.log('No blueprints, forcing test data at:', new Date().toISOString());
218
+ const testData = [
219
+ { id: 'test1', title: 'Test Channel 1' },
220
+ { id: 'test2', title: 'Test Channel 2' }
221
+ ];
222
+ const list = document.getElementById('channelList');
223
+ if (list) {
224
+ testData.forEach(bp => {
225
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
226
+ const li = document.createElement('li');
227
+ li.textContent = `# ${bp.title}`;
228
+ li.dataset.blueprintId = bp.id;
229
+ li.addEventListener('click', () => switchChannel(bp.id));
230
+ list.appendChild(li);
231
+ console.log('Populated test channel:', bp.title);
232
+ }
233
+ });
234
+ console.log('Channel list after population:', list.innerHTML);
235
+ } else {
236
+ console.error('Channel list not found!');
237
+ }
238
+ }
239
+ };
240
+ // Append debug and test data
241
+ console.log('MessengerLogic debug append at:', new Date().toISOString());
242
+ const originalFetch = fetchBlueprints;
243
+ fetchBlueprints = async function() {
244
+ console.log('Executing fetchBlueprints at:', new Date().toISOString());
245
+ const response = await originalFetch();
246
+ console.log('Fetch result from /v1/models/:', response);
247
+ return response;
248
+ };
249
+ const originalPopulate = populateChannelList;
250
+ populateChannelList = function(blueprints) {
251
+ console.log('Executing populateChannelList with:', blueprints);
252
+ originalPopulate(blueprints);
253
+ if (blueprints.length === 0 || !blueprints) {
254
+ console.log('No blueprints, forcing test data at:', new Date().toISOString());
255
+ const testData = [
256
+ { id: 'test1', title: 'Test Channel 1' },
257
+ { id: 'test2', title: 'Test Channel 2' }
258
+ ];
259
+ const list = document.getElementById('channelList');
260
+ if (list) {
261
+ testData.forEach(bp => {
262
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
263
+ const li = document.createElement('li');
264
+ li.textContent = `# ${bp.title}`;
265
+ li.dataset.blueprintId = bp.id;
266
+ li.addEventListener('click', () => switchChannel(bp.id));
267
+ list.appendChild(li);
268
+ console.log('Populated test channel:', bp.title);
269
+ }
270
+ });
271
+ console.log('Channel list after population:', list.innerHTML);
272
+ } else {
273
+ console.error('Channel list not found!');
274
+ }
275
+ }
276
+ };
277
+ // Append load check and test data
278
+ console.log('MessengerLogic loaded at:', new Date().toISOString());
279
+ const originalPopulate = populateChannelList;
280
+ populateChannelList = function(blueprints) {
281
+ console.log('Populating with blueprints at:', new Date().toISOString(), blueprints);
282
+ originalPopulate(blueprints);
283
+ if (!blueprints || blueprints.length === 0) {
284
+ console.log('No blueprints, adding test data at:', new Date().toISOString());
285
+ const testData = [
286
+ { id: 'test1', title: 'Test Channel 1' },
287
+ { id: 'test2', title: 'Test Channel 2' }
288
+ ];
289
+ const list = document.getElementById('channelList');
290
+ if (list) {
291
+ testData.forEach(bp => {
292
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
293
+ const li = document.createElement('li');
294
+ li.textContent = `# ${bp.title}`;
295
+ li.dataset.blueprintId = bp.id;
296
+ li.addEventListener('click', () => switchChannel(bp.id));
297
+ list.appendChild(li);
298
+ console.log('Added test channel:', bp.title);
299
+ }
300
+ });
301
+ console.log('Channel list updated:', list.innerHTML);
302
+ } else {
303
+ console.error('Channel list not found!');
304
+ }
305
+ }
306
+ };
307
+ // Append debug and combine ideas
308
+ console.log('Debug append at:', new Date().toISOString());
309
+ const originalFetch = fetchBlueprints;
310
+ fetchBlueprints = async function() {
311
+ console.log('Fetching blueprints like dropdown at:', new Date().toISOString());
312
+ const blueprints = await originalFetch();
313
+ console.log('Fetch result (like Chatbot dropdown):', blueprints);
314
+ return blueprints;
315
+ };
316
+ const originalPopulate = populateChannelList;
317
+ populateChannelList = function(blueprints) {
318
+ console.log('Populating like pseudo-channel with:', blueprints);
319
+ originalPopulate(blueprints); // Your logic
320
+ if (!blueprints || blueprints.length === 0) {
321
+ console.log('No blueprints, adding test channels at:', new Date().toISOString());
322
+ const testData = [
323
+ { id: 'test1', title: 'Test Channel 1' },
324
+ { id: 'test2', title: 'Test Channel 2' }
325
+ ];
326
+ const list = document.getElementById('channelList');
327
+ if (list) {
328
+ testData.forEach(bp => {
329
+ if (!list.querySelector(`li[data-blueprint-id="${bp.id}"]`)) {
330
+ const li = document.createElement('li');
331
+ li.textContent = `# ${bp.title}`;
332
+ li.dataset.blueprintId = bp.id;
333
+ li.addEventListener('click', () => switchChannel(bp.id));
334
+ list.appendChild(li);
335
+ console.log('Added test channel (like pseudo):', bp.title);
336
+ }
337
+ });
338
+ console.log('Channel list updated:', list.innerHTML);
339
+ }
340
+ }
341
+ };
342
+ // Append fetch debug
343
+ console.log('Debug append at:', new Date().toISOString());
344
+ const originalFetch = fetchBlueprints;
345
+ fetchBlueprints = async function() {
346
+ console.log('Fetching blueprints at:', new Date().toISOString());
347
+ try {
348
+ const response = await originalFetch();
349
+ console.log('Fetch result from /v1/models/:', response);
350
+ return response;
351
+ } catch (error) {
352
+ console.error('Fetch error:', error);
353
+ return [];
354
+ }
355
+ };
@@ -0,0 +1,84 @@
1
+ // src/swarm/static/rest_mode/js/modules/apiService.js
2
+
3
+ import { showToast } from '../toast.js';
4
+ import { debugLog } from './debugLogger.js';
5
+
6
+ /**
7
+ * Handles all API interactions.
8
+ */
9
+
10
+ /**
11
+ * Fetches blueprint metadata from the server.
12
+ * @returns {Promise<Array>} - Returns a promise that resolves to the list of blueprints.
13
+ */
14
+ export async function fetchBlueprintMetadata() {
15
+ try {
16
+ const response = await fetch('/v1/models/');
17
+ if (!response.ok) throw new Error('Failed to fetch metadata.');
18
+
19
+ const data = await response.json();
20
+ showToast('Retrieved blueprint metadata.', 'info');
21
+ return data.data || [];
22
+ } catch (error) {
23
+ debugLog('Error fetching blueprint metadata:', error);
24
+ showToast('❌ Could not retrieve blueprint metadata.', 'error');
25
+ return [];
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Submits a user message to the server and retrieves the assistant's response.
31
+ * @param {string} modelName - The model to use for generating responses.
32
+ * @param {Array} messages - The chat history messages.
33
+ * @param {Object} contextVariables - Context variables for the chat.
34
+ * @returns {Promise<Object>} - Returns a promise that resolves to the server's response.
35
+ */
36
+ export async function submitMessage(modelName, messages, contextVariables) {
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"]')?.getAttribute('content') || '',
43
+ },
44
+ body: JSON.stringify({
45
+ model: modelName,
46
+ messages: messages,
47
+ context_variables: contextVariables,
48
+ }),
49
+ });
50
+
51
+ if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);
52
+
53
+ const data = await response.json();
54
+ return data;
55
+ } catch (error) {
56
+ debugLog('Error submitting message:', error);
57
+ showToast('⚠️ Error submitting message. Please try again.', 'error');
58
+ throw error;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Deletes a chat by its ID.
64
+ * @param {string} chatId - The ID of the chat to delete.
65
+ * @returns {Promise<boolean>} - Returns true if deletion was successful.
66
+ */
67
+ export async function deleteChat(chatId) {
68
+ try {
69
+ const response = await fetch(`/v1/chat/delete/${chatId}`, {
70
+ method: 'DELETE',
71
+ headers: {
72
+ 'Content-Type': 'application/json',
73
+ 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
74
+ },
75
+ });
76
+
77
+ if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);
78
+ return true;
79
+ } catch (error) {
80
+ debugLog('Error deleting chat:', error);
81
+ showToast('❌ Error deleting chat. Please try again.', 'error');
82
+ return false;
83
+ }
84
+ }
@@ -0,0 +1,162 @@
1
+ // src/swarm/static/rest_mode/js/modules/blueprintManager.js
2
+
3
+ import { fetchBlueprintMetadata as fetchMetadataAPI } from './apiService.js';
4
+ import { showToast } from '../toast.js';
5
+ import { appendRawMessage } from '../messages.js';
6
+ import { debugLog } from './debugLogger.js';
7
+ import { createChatHistoryEntry } from './chatHistory.js';
8
+
9
+ /**
10
+ * Populates the blueprint selection dialog and dropdown.
11
+ * @param {Array} blueprints - The list of blueprints fetched from the API.
12
+ */
13
+ function populateBlueprintDialog(blueprints) {
14
+ const blueprintDialogElement = document.getElementById('blueprintDialog');
15
+ const blueprintDropdown = document.getElementById('blueprintDropdown');
16
+ const currentPath = window.location.pathname; // Get the current URL path
17
+
18
+ if (!blueprintDialogElement) {
19
+ debugLog('Blueprint dialog not found.');
20
+ return;
21
+ }
22
+
23
+ // Populate dialog
24
+ blueprintDialogElement.innerHTML = blueprints
25
+ .map(
26
+ (bp) => `
27
+ <div class="blueprint-option" data-id="${bp.id}">
28
+ <p class="blueprint-title">${bp.title}</p>
29
+ <p class="blueprint-description">${bp.description}</p>
30
+ </div>`
31
+ )
32
+ .join('');
33
+
34
+ if (!blueprintDropdown) {
35
+ debugLog('Blueprint dropdown element not found.');
36
+ return;
37
+ }
38
+
39
+ // Populate dropdown
40
+ blueprintDropdown.innerHTML = blueprints
41
+ .map(
42
+ (bp) => `
43
+ <option value="${bp.id}">${bp.title}</option>`
44
+ )
45
+ .join('');
46
+
47
+ // Add click event for each dialog option
48
+ blueprintDialogElement.querySelectorAll('.blueprint-option').forEach((option) => {
49
+ option.addEventListener('click', () => {
50
+ const selectedId = option.getAttribute('data-id');
51
+ const selectedBlueprint = blueprints.find((bp) => bp.id === selectedId);
52
+ if (selectedBlueprint) {
53
+ selectBlueprint(selectedBlueprint, true); // User-initiated selection
54
+ }
55
+ });
56
+ });
57
+
58
+ // Add change event for dropdown
59
+ blueprintDropdown.addEventListener('change', (event) => {
60
+ const selectedId = event.target.value;
61
+ const selectedBlueprint = blueprints.find((bp) => bp.id === selectedId);
62
+ if (selectedBlueprint) {
63
+ selectBlueprint(selectedBlueprint, true); // User-initiated selection
64
+ }
65
+ });
66
+ }
67
+
68
+ /**
69
+ * Updates the UI and metadata when a blueprint is selected.
70
+ * @param {Object} blueprint - The selected blueprint.
71
+ * @param {boolean} isUserInitiated - Indicates if the selection was made by the user.
72
+ */
73
+ export function selectBlueprint(blueprint, isUserInitiated = false) {
74
+ const blueprintMetadataElement = document.getElementById('blueprintMetadata');
75
+ const blueprintTitleElement = document.getElementById('blueprintTitle');
76
+ const blueprintDialogElement = document.getElementById('blueprintDialog');
77
+ const blueprintDropdown = document.getElementById('blueprintDropdown');
78
+
79
+ if (!blueprintMetadataElement || !blueprintTitleElement || !blueprintDropdown) {
80
+ debugLog('Required elements for blueprint selection not found.');
81
+ return;
82
+ }
83
+
84
+ const blueprintName = blueprint.title;
85
+ const blueprintDescription = blueprint.description;
86
+
87
+ // Update UI
88
+ blueprintMetadataElement.innerHTML = `<h2>${blueprintName}</h2><p>${blueprintDescription}</p>`;
89
+ blueprintTitleElement.textContent = blueprintName;
90
+
91
+ // Update Dropdown Value
92
+ blueprintDropdown.value = blueprint.id;
93
+
94
+ // Hide the blueprint dialog
95
+ if (blueprintDialogElement) {
96
+ blueprintDialogElement.classList.add('hidden');
97
+ }
98
+
99
+ // Optionally, show the dropdown if in advanced mode
100
+ // For simple chat mode, keep it hidden
101
+ // blueprintDropdown.classList.remove('hidden'); // Uncomment if needed
102
+
103
+ // Notify user about blueprint change only if it's user-initiated
104
+ if (isUserInitiated) {
105
+ appendRawMessage(
106
+ 'assistant',
107
+ {
108
+ content: `Blueprint loaded: ${blueprintName}`,
109
+ },
110
+ 'Assistant'
111
+ );
112
+ }
113
+
114
+ debugLog('Blueprint selected and UI updated.', blueprint);
115
+ }
116
+
117
+ /**
118
+ * Initializes blueprint management by fetching metadata and populating the UI.
119
+ */
120
+ export async function initializeBlueprints() {
121
+ debugLog('Initializing blueprint management.');
122
+ try {
123
+ const blueprints = await fetchMetadataAPI();
124
+ if (blueprints.length === 0) throw new Error('No blueprints available.');
125
+
126
+ // Populate blueprint dialog and dropdown
127
+ populateBlueprintDialog(blueprints);
128
+
129
+ // Extract blueprint ID from the current path
130
+ const currentPath = window.location.pathname;
131
+ const pathSegments = currentPath.split('/').filter(segment => segment.length > 0);
132
+ const blueprintId = pathSegments.length > 0 ? pathSegments[pathSegments.length - 1] : null;
133
+
134
+ debugLog('Current Path:', currentPath);
135
+ debugLog('Extracted Blueprint ID:', blueprintId);
136
+
137
+ // Find the blueprint with the extracted ID
138
+ const matchedBlueprint = blueprints.find(bp => bp.id === blueprintId);
139
+
140
+ if (matchedBlueprint) {
141
+ debugLog('Matched Blueprint:', matchedBlueprint);
142
+ selectBlueprint(matchedBlueprint, false); // Programmatic selection
143
+ } else {
144
+ debugLog('No matched blueprint found. Selecting default blueprint:', blueprints[0]);
145
+ // If no matching blueprint, select the first blueprint as default
146
+ const defaultBlueprint = blueprints[0];
147
+ selectBlueprint(defaultBlueprint, false); // Programmatic selection
148
+ }
149
+ } catch (error) {
150
+ debugLog('Error fetching blueprint metadata:', error);
151
+ console.error('Error initializing blueprints:', error);
152
+
153
+ appendRawMessage(
154
+ 'assistant',
155
+ {
156
+ content:
157
+ 'Could not retrieve blueprint metadata. Check out the troubleshooting guide at <a href="https://github.com/matthewhand/open-swarm/TROUBLESHOOTING.md">Troubleshooting Guide</a>.',
158
+ },
159
+ 'Assistant'
160
+ );
161
+ }
162
+ }