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.
- open_swarm-0.1.1743364176.dist-info/METADATA +286 -0
- open_swarm-0.1.1743364176.dist-info/RECORD +260 -0
- {open_swarm-0.1.1743070217.dist-info → open_swarm-0.1.1743364176.dist-info}/WHEEL +1 -2
- open_swarm-0.1.1743364176.dist-info/entry_points.txt +2 -0
- swarm/__init__.py +0 -2
- swarm/auth.py +53 -49
- swarm/blueprints/README.md +67 -0
- swarm/blueprints/burnt_noodles/blueprint_burnt_noodles.py +412 -0
- swarm/blueprints/chatbot/blueprint_chatbot.py +98 -0
- swarm/blueprints/chatbot/templates/chatbot/chatbot.html +33 -0
- swarm/blueprints/digitalbutlers/blueprint_digitalbutlers.py +183 -0
- swarm/blueprints/dilbot_universe/blueprint_dilbot_universe.py +285 -0
- swarm/blueprints/divine_code/__init__.py +0 -0
- swarm/blueprints/divine_code/apps.py +11 -0
- swarm/blueprints/divine_code/blueprint_divine_code.py +219 -0
- swarm/blueprints/django_chat/apps.py +6 -0
- swarm/blueprints/django_chat/blueprint_django_chat.py +84 -0
- swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html +37 -0
- swarm/blueprints/django_chat/urls.py +8 -0
- swarm/blueprints/django_chat/views.py +32 -0
- swarm/blueprints/echocraft/blueprint_echocraft.py +44 -0
- swarm/blueprints/family_ties/apps.py +11 -0
- swarm/blueprints/family_ties/blueprint_family_ties.py +152 -0
- swarm/blueprints/family_ties/models.py +19 -0
- swarm/blueprints/family_ties/serializers.py +7 -0
- swarm/blueprints/family_ties/settings.py +16 -0
- swarm/blueprints/family_ties/urls.py +10 -0
- swarm/blueprints/family_ties/views.py +26 -0
- swarm/blueprints/flock/__init__.py +0 -0
- swarm/blueprints/gaggle/blueprint_gaggle.py +184 -0
- swarm/blueprints/gotchaman/blueprint_gotchaman.py +232 -0
- swarm/blueprints/mcp_demo/blueprint_mcp_demo.py +133 -0
- swarm/blueprints/messenger/templates/messenger/messenger.html +46 -0
- swarm/blueprints/mission_improbable/blueprint_mission_improbable.py +234 -0
- swarm/blueprints/monkai_magic/blueprint_monkai_magic.py +248 -0
- swarm/blueprints/nebula_shellz/blueprint_nebula_shellz.py +156 -0
- swarm/blueprints/omniplex/blueprint_omniplex.py +221 -0
- swarm/blueprints/rue_code/__init__.py +0 -0
- swarm/blueprints/rue_code/blueprint_rue_code.py +291 -0
- swarm/blueprints/suggestion/blueprint_suggestion.py +110 -0
- swarm/blueprints/unapologetic_press/blueprint_unapologetic_press.py +298 -0
- swarm/blueprints/whiskeytango_foxtrot/__init__.py +0 -0
- swarm/blueprints/whiskeytango_foxtrot/apps.py +11 -0
- swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py +256 -0
- swarm/extensions/blueprint/__init__.py +30 -15
- swarm/extensions/blueprint/agent_utils.py +16 -40
- swarm/extensions/blueprint/blueprint_base.py +141 -543
- swarm/extensions/blueprint/blueprint_discovery.py +112 -98
- swarm/extensions/blueprint/cli_handler.py +185 -0
- swarm/extensions/blueprint/config_loader.py +122 -0
- swarm/extensions/blueprint/django_utils.py +181 -79
- swarm/extensions/blueprint/interactive_mode.py +1 -1
- swarm/extensions/config/config_loader.py +83 -200
- swarm/extensions/launchers/build_swarm_wrapper.py +0 -0
- swarm/extensions/launchers/swarm_cli.py +199 -287
- swarm/llm/chat_completion.py +26 -55
- swarm/management/__init__.py +0 -0
- swarm/management/commands/__init__.py +0 -0
- swarm/management/commands/runserver.py +58 -0
- swarm/permissions.py +38 -0
- swarm/serializers.py +96 -5
- swarm/settings.py +95 -110
- swarm/static/contrib/fonts/fontawesome-webfont.ttf +7 -0
- swarm/static/contrib/fonts/fontawesome-webfont.woff +7 -0
- swarm/static/contrib/fonts/fontawesome-webfont.woff2 +7 -0
- swarm/static/contrib/markedjs/marked.min.js +6 -0
- swarm/static/contrib/tabler-icons/adjustments-horizontal.svg +27 -0
- swarm/static/contrib/tabler-icons/alert-triangle.svg +21 -0
- swarm/static/contrib/tabler-icons/archive.svg +21 -0
- swarm/static/contrib/tabler-icons/artboard.svg +27 -0
- swarm/static/contrib/tabler-icons/automatic-gearbox.svg +23 -0
- swarm/static/contrib/tabler-icons/box-multiple.svg +19 -0
- swarm/static/contrib/tabler-icons/carambola.svg +19 -0
- swarm/static/contrib/tabler-icons/copy.svg +20 -0
- swarm/static/contrib/tabler-icons/download.svg +21 -0
- swarm/static/contrib/tabler-icons/edit.svg +21 -0
- swarm/static/contrib/tabler-icons/filled/carambola.svg +13 -0
- swarm/static/contrib/tabler-icons/filled/paint.svg +13 -0
- swarm/static/contrib/tabler-icons/headset.svg +22 -0
- swarm/static/contrib/tabler-icons/layout-sidebar-left-collapse.svg +21 -0
- swarm/static/contrib/tabler-icons/layout-sidebar-left-expand.svg +21 -0
- swarm/static/contrib/tabler-icons/layout-sidebar-right-collapse.svg +21 -0
- swarm/static/contrib/tabler-icons/layout-sidebar-right-expand.svg +21 -0
- swarm/static/contrib/tabler-icons/message-chatbot.svg +22 -0
- swarm/static/contrib/tabler-icons/message-star.svg +22 -0
- swarm/static/contrib/tabler-icons/message-x.svg +23 -0
- swarm/static/contrib/tabler-icons/message.svg +21 -0
- swarm/static/contrib/tabler-icons/paperclip.svg +18 -0
- swarm/static/contrib/tabler-icons/playlist-add.svg +22 -0
- swarm/static/contrib/tabler-icons/robot.svg +26 -0
- swarm/static/contrib/tabler-icons/search.svg +19 -0
- swarm/static/contrib/tabler-icons/settings.svg +20 -0
- swarm/static/contrib/tabler-icons/thumb-down.svg +19 -0
- swarm/static/contrib/tabler-icons/thumb-up.svg +19 -0
- swarm/static/css/dropdown.css +22 -0
- swarm/static/htmx/htmx.min.js +0 -0
- swarm/static/js/dropdown.js +23 -0
- swarm/static/rest_mode/css/base.css +470 -0
- swarm/static/rest_mode/css/chat-history.css +286 -0
- swarm/static/rest_mode/css/chat.css +251 -0
- swarm/static/rest_mode/css/chatbot.css +74 -0
- swarm/static/rest_mode/css/chatgpt.css +62 -0
- swarm/static/rest_mode/css/colors/corporate.css +74 -0
- swarm/static/rest_mode/css/colors/pastel.css +81 -0
- swarm/static/rest_mode/css/colors/tropical.css +82 -0
- swarm/static/rest_mode/css/general.css +142 -0
- swarm/static/rest_mode/css/layout.css +167 -0
- swarm/static/rest_mode/css/layouts/messenger-layout.css +17 -0
- swarm/static/rest_mode/css/layouts/minimalist-layout.css +57 -0
- swarm/static/rest_mode/css/layouts/mobile-layout.css +8 -0
- swarm/static/rest_mode/css/messages.css +84 -0
- swarm/static/rest_mode/css/messenger.css +135 -0
- swarm/static/rest_mode/css/settings.css +91 -0
- swarm/static/rest_mode/css/simple.css +44 -0
- swarm/static/rest_mode/css/slack.css +58 -0
- swarm/static/rest_mode/css/style.css +156 -0
- swarm/static/rest_mode/css/theme.css +30 -0
- swarm/static/rest_mode/css/toast.css +40 -0
- swarm/static/rest_mode/js/auth.js +9 -0
- swarm/static/rest_mode/js/blueprint.js +41 -0
- swarm/static/rest_mode/js/blueprintUtils.js +12 -0
- swarm/static/rest_mode/js/chatLogic.js +79 -0
- swarm/static/rest_mode/js/debug.js +63 -0
- swarm/static/rest_mode/js/events.js +98 -0
- swarm/static/rest_mode/js/main.js +19 -0
- swarm/static/rest_mode/js/messages.js +264 -0
- swarm/static/rest_mode/js/messengerLogic.js +355 -0
- swarm/static/rest_mode/js/modules/apiService.js +84 -0
- swarm/static/rest_mode/js/modules/blueprintManager.js +162 -0
- swarm/static/rest_mode/js/modules/chatHistory.js +110 -0
- swarm/static/rest_mode/js/modules/debugLogger.js +14 -0
- swarm/static/rest_mode/js/modules/eventHandlers.js +107 -0
- swarm/static/rest_mode/js/modules/messageProcessor.js +120 -0
- swarm/static/rest_mode/js/modules/state.js +7 -0
- swarm/static/rest_mode/js/modules/userInteractions.js +29 -0
- swarm/static/rest_mode/js/modules/validation.js +23 -0
- swarm/static/rest_mode/js/rendering.js +119 -0
- swarm/static/rest_mode/js/settings.js +130 -0
- swarm/static/rest_mode/js/sidebar.js +94 -0
- swarm/static/rest_mode/js/simpleLogic.js +37 -0
- swarm/static/rest_mode/js/slackLogic.js +66 -0
- swarm/static/rest_mode/js/splash.js +76 -0
- swarm/static/rest_mode/js/theme.js +111 -0
- swarm/static/rest_mode/js/toast.js +36 -0
- swarm/static/rest_mode/js/ui.js +265 -0
- swarm/static/rest_mode/js/validation.js +57 -0
- swarm/static/rest_mode/svg/animated_spinner.svg +12 -0
- swarm/static/rest_mode/svg/arrow_down.svg +5 -0
- swarm/static/rest_mode/svg/arrow_left.svg +5 -0
- swarm/static/rest_mode/svg/arrow_right.svg +5 -0
- swarm/static/rest_mode/svg/arrow_up.svg +5 -0
- swarm/static/rest_mode/svg/attach.svg +8 -0
- swarm/static/rest_mode/svg/avatar.svg +7 -0
- swarm/static/rest_mode/svg/canvas.svg +6 -0
- swarm/static/rest_mode/svg/chat_history.svg +4 -0
- swarm/static/rest_mode/svg/close.svg +5 -0
- swarm/static/rest_mode/svg/copy.svg +4 -0
- swarm/static/rest_mode/svg/dark_mode.svg +3 -0
- swarm/static/rest_mode/svg/edit.svg +5 -0
- swarm/static/rest_mode/svg/layout.svg +9 -0
- swarm/static/rest_mode/svg/logo.svg +29 -0
- swarm/static/rest_mode/svg/logout.svg +5 -0
- swarm/static/rest_mode/svg/mobile.svg +5 -0
- swarm/static/rest_mode/svg/new_chat.svg +4 -0
- swarm/static/rest_mode/svg/not_visible.svg +5 -0
- swarm/static/rest_mode/svg/plus.svg +7 -0
- swarm/static/rest_mode/svg/run_code.svg +6 -0
- swarm/static/rest_mode/svg/save.svg +4 -0
- swarm/static/rest_mode/svg/search.svg +6 -0
- swarm/static/rest_mode/svg/settings.svg +4 -0
- swarm/static/rest_mode/svg/speaker.svg +5 -0
- swarm/static/rest_mode/svg/stop.svg +6 -0
- swarm/static/rest_mode/svg/thumbs_down.svg +3 -0
- swarm/static/rest_mode/svg/thumbs_up.svg +3 -0
- swarm/static/rest_mode/svg/toggle_off.svg +6 -0
- swarm/static/rest_mode/svg/toggle_on.svg +6 -0
- swarm/static/rest_mode/svg/trash.svg +10 -0
- swarm/static/rest_mode/svg/undo.svg +3 -0
- swarm/static/rest_mode/svg/visible.svg +8 -0
- swarm/static/rest_mode/svg/voice.svg +10 -0
- swarm/templates/account/login.html +22 -0
- swarm/templates/account/signup.html +32 -0
- swarm/templates/base.html +30 -0
- swarm/templates/chat.html +43 -0
- swarm/templates/index.html +35 -0
- swarm/templates/rest_mode/components/chat_sidebar.html +55 -0
- swarm/templates/rest_mode/components/header.html +45 -0
- swarm/templates/rest_mode/components/main_chat_pane.html +41 -0
- swarm/templates/rest_mode/components/settings_dialog.html +97 -0
- swarm/templates/rest_mode/components/splash_screen.html +7 -0
- swarm/templates/rest_mode/components/top_bar.html +28 -0
- swarm/templates/rest_mode/message_ui.html +50 -0
- swarm/templates/rest_mode/slackbot.html +30 -0
- swarm/templates/simple_blueprint_page.html +24 -0
- swarm/templates/websocket_partials/final_system_message.html +3 -0
- swarm/templates/websocket_partials/system_message.html +4 -0
- swarm/templates/websocket_partials/user_message.html +5 -0
- swarm/urls.py +57 -74
- swarm/utils/log_utils.py +63 -0
- swarm/views/api_views.py +48 -39
- swarm/views/chat_views.py +156 -70
- swarm/views/core_views.py +85 -90
- swarm/views/model_views.py +64 -121
- swarm/views/utils.py +65 -441
- open_swarm-0.1.1743070217.dist-info/METADATA +0 -258
- open_swarm-0.1.1743070217.dist-info/RECORD +0 -89
- open_swarm-0.1.1743070217.dist-info/entry_points.txt +0 -3
- open_swarm-0.1.1743070217.dist-info/top_level.txt +0 -1
- swarm/agent/agent.py +0 -49
- swarm/core.py +0 -326
- swarm/extensions/mcp/__init__.py +0 -1
- swarm/extensions/mcp/cache_utils.py +0 -36
- swarm/extensions/mcp/mcp_client.py +0 -341
- swarm/extensions/mcp/mcp_constants.py +0 -7
- swarm/extensions/mcp/mcp_tool_provider.py +0 -110
- swarm/types.py +0 -126
- {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">×</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
|
+
|