open-swarm 0.1.1743070217__py3-none-any.whl → 0.1.1743362777__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.1743362777.dist-info/METADATA +217 -0
- open_swarm-0.1.1743362777.dist-info/RECORD +260 -0
- {open_swarm-0.1.1743070217.dist-info → open_swarm-0.1.1743362777.dist-info}/WHEEL +1 -2
- open_swarm-0.1.1743362777.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.1743362777.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
// src/swarm/static/rest_mode/js/debug.js
|
2
|
+
|
3
|
+
import { showToast } from './toast.js';
|
4
|
+
import { chatHistory } from './modules/state.js';
|
5
|
+
import { contextVariables } from './modules/state.js';
|
6
|
+
export { debugLog } from './modules/debugLogger.js';
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Toggles the Debug pane.
|
10
|
+
* Displays raw messages and key info from the most recent message.
|
11
|
+
*/
|
12
|
+
export function toggleDebugPane() {
|
13
|
+
const debugPane = document.getElementById("debugPane");
|
14
|
+
if (!debugPane) return;
|
15
|
+
|
16
|
+
if (debugPane.style.display === "block") {
|
17
|
+
debugPane.style.display = "none";
|
18
|
+
showToast("🐞 Debug pane hidden.", "info");
|
19
|
+
} else {
|
20
|
+
debugPane.style.display = "block";
|
21
|
+
showToast("🐞 Debug pane shown.", "info");
|
22
|
+
renderRelevantDebugInfo();
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Handles Tech Support Button Click Inside Debug Pane
|
28
|
+
*/
|
29
|
+
export function handleTechSupport() {
|
30
|
+
showToast("🛠️ Tech Support feature coming soon!", "info");
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Renders relevant debug information from the most recent message in chatHistory.
|
35
|
+
*/
|
36
|
+
function renderRelevantDebugInfo() {
|
37
|
+
const debugContent = document.getElementById("debugContent");
|
38
|
+
if (!debugContent) return;
|
39
|
+
|
40
|
+
if (chatHistory.length === 0) {
|
41
|
+
debugContent.innerHTML = "<p>No messages yet.</p>";
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
|
45
|
+
const latestMessage = chatHistory[chatHistory.length - 1];
|
46
|
+
const { role, content, sender, metadata } = latestMessage;
|
47
|
+
|
48
|
+
debugContent.innerHTML = `
|
49
|
+
<p><strong>Role:</strong> ${role}</p>
|
50
|
+
<p><strong>Sender:</strong> ${sender}</p>
|
51
|
+
<p><strong>Content:</strong> ${content || "No content provided."}</p>
|
52
|
+
<p><strong>Metadata:</strong> <pre>${JSON.stringify(metadata || {}, null, 2)}</pre></p>
|
53
|
+
`;
|
54
|
+
|
55
|
+
if (contextVariables.active_agent_name) {
|
56
|
+
const activeAgentElement = document.createElement("div");
|
57
|
+
activeAgentElement.className = "debug-active-agent";
|
58
|
+
activeAgentElement.innerHTML = `<strong>Active Agent:</strong> ${contextVariables.active_agent_name}`;
|
59
|
+
debugContent.appendChild(activeAgentElement);
|
60
|
+
}
|
61
|
+
|
62
|
+
debugContent.scrollTop = debugContent.scrollHeight;
|
63
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
// src/swarm/static/rest_mode/js/events.js
|
2
|
+
|
3
|
+
import { toggleSidebar } from './sidebar.js';
|
4
|
+
import { handleChatHistoryClick } from './modules/chatHistory.js';
|
5
|
+
import { deleteChat } from './modules/apiService.js';
|
6
|
+
import { handleUpload, handleVoiceRecord } from './modules/userInteractions.js';
|
7
|
+
import { fetchBlueprintMetadata } from './modules/apiService.js';
|
8
|
+
import { handleSubmit } from './modules/messageProcessor.js';
|
9
|
+
import { toggleDebugPane, handleTechSupport } from './debug.js';
|
10
|
+
import { showToast } from './toast.js';
|
11
|
+
import { handleLogout } from './auth.js';
|
12
|
+
import { debugLog } from './modules/debugLogger.js';
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Handles "Search" button click.
|
16
|
+
*/
|
17
|
+
function handleSearch() {
|
18
|
+
showToast("🔍 Search feature is under development.", "info");
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Handles "New Chat" button click.
|
23
|
+
*/
|
24
|
+
function handleNewChat() {
|
25
|
+
showToast("📝 Starting a new chat...", "info");
|
26
|
+
// Implement new chat functionality as needed
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Attaches event listeners to chat history items.
|
31
|
+
*/
|
32
|
+
function setupChatHistoryListeners() {
|
33
|
+
const chatHistoryItems = document.querySelectorAll('.chat-history-pane li');
|
34
|
+
chatHistoryItems.forEach((item) => {
|
35
|
+
item.addEventListener('click', () => handleChatHistoryClick(item));
|
36
|
+
|
37
|
+
const trashCan = item.querySelector('.trash-can');
|
38
|
+
if (trashCan) {
|
39
|
+
trashCan.addEventListener('click', (e) => {
|
40
|
+
e.stopPropagation();
|
41
|
+
deleteChat(item);
|
42
|
+
});
|
43
|
+
}
|
44
|
+
});
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Attaches event listeners to main application buttons and elements.
|
49
|
+
*/
|
50
|
+
function setupGlobalEventListeners() {
|
51
|
+
// Sidebar toggles
|
52
|
+
document.getElementById("settingsToggleButton")?.addEventListener('click', () => toggleSidebar('options', true));
|
53
|
+
document.getElementById("optionsSidebarHideBtn")?.addEventListener('click', () => toggleSidebar('options', false));
|
54
|
+
document.getElementById("chatHistoryToggleButton")?.addEventListener('click', () => toggleSidebar('left', true));
|
55
|
+
document.getElementById("leftSidebarHideBtn")?.addEventListener('click', () => toggleSidebar('left', false));
|
56
|
+
|
57
|
+
// Top buttons
|
58
|
+
// document.getElementById("searchButton")?.addEventListener('click', handleSearch);
|
59
|
+
document.getElementById("newChatButton")?.addEventListener('click', handleNewChat);
|
60
|
+
|
61
|
+
// Functional buttons
|
62
|
+
document.getElementById("logoutButton")?.addEventListener('click', handleLogout);
|
63
|
+
document.getElementById("uploadButton")?.addEventListener('click', handleUpload);
|
64
|
+
document.getElementById("voiceRecordButton")?.addEventListener('click', handleVoiceRecord);
|
65
|
+
document.getElementById("submitButton")?.addEventListener("click", handleSubmit);
|
66
|
+
|
67
|
+
// User input submission with Enter key
|
68
|
+
const userInput = document.getElementById("userInput");
|
69
|
+
userInput?.addEventListener("keypress", (e) => {
|
70
|
+
if (e.key === "Enter") {
|
71
|
+
e.preventDefault();
|
72
|
+
handleSubmit();
|
73
|
+
}
|
74
|
+
});
|
75
|
+
|
76
|
+
// Debug pane toggles
|
77
|
+
document.getElementById("debugButton")?.addEventListener('click', toggleDebugPane);
|
78
|
+
document.getElementById("techSupportButtonInsideDebug")?.addEventListener('click', handleTechSupport);
|
79
|
+
}
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Sets up all event listeners for the application.
|
83
|
+
*/
|
84
|
+
export function setupEventListeners() {
|
85
|
+
setupGlobalEventListeners();
|
86
|
+
setupChatHistoryListeners();
|
87
|
+
debugLog('All event listeners have been set up.');
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Initialize the application.
|
92
|
+
*/
|
93
|
+
export function initializeApplication() {
|
94
|
+
debugLog('[DEBUG] Initializing application...');
|
95
|
+
fetchBlueprintMetadata(); // Fetch blueprint metadata and display it
|
96
|
+
setupEventListeners(); // Set up event listeners
|
97
|
+
debugLog('[DEBUG] Application initialized.');
|
98
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
// main.js - Main application entry point
|
2
|
+
|
3
|
+
import { initializeSplashScreen } from './splash.js';
|
4
|
+
import { initializeUI } from './ui.js';
|
5
|
+
import { debugLog } from './settings.js';
|
6
|
+
|
7
|
+
document.addEventListener('DOMContentLoaded', () => {
|
8
|
+
debugLog("DOM Content Loaded. Initializing application...");
|
9
|
+
|
10
|
+
try {
|
11
|
+
initializeSplashScreen();
|
12
|
+
debugLog("Splash screen initialization complete.");
|
13
|
+
|
14
|
+
initializeUI();
|
15
|
+
debugLog("UI initialization complete.");
|
16
|
+
} catch (error) {
|
17
|
+
debugLog(`Initialization failed: ${error.message}`, "error");
|
18
|
+
}
|
19
|
+
});
|
@@ -0,0 +1,264 @@
|
|
1
|
+
import { debugLog } from './debug.js';
|
2
|
+
import { enableSlidingToolbar } from './ui.js';
|
3
|
+
// import { marked } from '../../contrib/markedjs/marked.min.js';
|
4
|
+
import { marked } from "https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js";
|
5
|
+
|
6
|
+
let quickPrompts = ["What is Open-Swarm?", "Explain the architecture.", "How do I set up a new blueprint?"];
|
7
|
+
|
8
|
+
export function renderMessage(role, content, sender, metadata) {
|
9
|
+
debugLog('Rendering message...', { role, content, sender, metadata });
|
10
|
+
|
11
|
+
const messageContainer = document.getElementById('messageHistory');
|
12
|
+
if (!messageContainer) {
|
13
|
+
debugLog('Message container not found.');
|
14
|
+
return;
|
15
|
+
}
|
16
|
+
|
17
|
+
let messageContent = content.content || content.text || '';
|
18
|
+
|
19
|
+
// 🛑 Ignore empty messages immediately
|
20
|
+
if (!messageContent.trim()) {
|
21
|
+
debugLog('Skipping empty message.');
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
// 🔄 Detect assistant handoff JSON
|
26
|
+
let isHandoff = false;
|
27
|
+
try {
|
28
|
+
const parsedContent = JSON.parse(messageContent);
|
29
|
+
if (parsedContent.assistant && typeof parsedContent.assistant === 'string') {
|
30
|
+
messageContent = `<em>🔄 Handoff to <strong>${parsedContent.assistant}</strong></em>`;
|
31
|
+
role = 'system';
|
32
|
+
isHandoff = true;
|
33
|
+
}
|
34
|
+
} catch (e) {
|
35
|
+
// Not a JSON object, proceed
|
36
|
+
}
|
37
|
+
|
38
|
+
if (!isHandoff) {
|
39
|
+
messageContent = `<strong>${sender}:</strong> ${marked.parse(messageContent)}`;
|
40
|
+
}
|
41
|
+
|
42
|
+
// ❌ Prevent rendering assistant messages with "No content"
|
43
|
+
if (role === "assistant" && messageContent.includes("<p>No content</p>")) {
|
44
|
+
debugLog("Skipping assistant message with 'No content'.");
|
45
|
+
return; // 🛑 Stop execution here
|
46
|
+
}
|
47
|
+
|
48
|
+
// ✅ Create the message
|
49
|
+
const messageDiv = document.createElement('div');
|
50
|
+
messageDiv.className = `message ${role}`;
|
51
|
+
|
52
|
+
messageDiv.innerHTML = `
|
53
|
+
<div class="message-text">${messageContent}</div>
|
54
|
+
<div class="message-toolbar">
|
55
|
+
<button class="toolbar-btn" aria-label="Copy Message">
|
56
|
+
<img src="/static/rest_mode/svg/copy.svg" alt="Copy Icon" class="icon-svg" />
|
57
|
+
</button>
|
58
|
+
<button class="toolbar-btn" aria-label="Delete Message">
|
59
|
+
<img src="/static/rest_mode/svg/trash.svg" alt="Trash Icon" class="icon-svg" />
|
60
|
+
</button>
|
61
|
+
</div>
|
62
|
+
`;
|
63
|
+
|
64
|
+
messageContainer.appendChild(messageDiv);
|
65
|
+
debugLog('Message rendered successfully.');
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Appends a raw message object into the chat UI.
|
70
|
+
*/
|
71
|
+
let isAppendingMessage = false; // Prevent duplicate appending
|
72
|
+
|
73
|
+
export function appendRawMessage(role, content, sender, metadata) {
|
74
|
+
if (isAppendingMessage) {
|
75
|
+
debugLog('Duplicate appendRawMessage call detected. Skipping execution.', { role, content, sender, metadata });
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
|
79
|
+
isAppendingMessage = true; // Set the flag
|
80
|
+
debugLog('Appending raw message...', { role, content, sender, metadata });
|
81
|
+
|
82
|
+
renderMessage(role, content, sender, metadata);
|
83
|
+
|
84
|
+
const messageContainer = document.getElementById('messageHistory');
|
85
|
+
if (messageContainer) {
|
86
|
+
messageContainer.scrollTop = messageContainer.scrollHeight;
|
87
|
+
debugLog('Scrolled to the bottom of the message history.');
|
88
|
+
}
|
89
|
+
|
90
|
+
isAppendingMessage = false; // Reset the flag
|
91
|
+
}
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
/**
|
96
|
+
* Renders quick prompts in the UI.
|
97
|
+
*/
|
98
|
+
export function renderQuickPrompts() {
|
99
|
+
const quickPromptsContainer = document.getElementById('quickPrompts');
|
100
|
+
if (!quickPromptsContainer) {
|
101
|
+
debugLog('Quick prompts container not found.');
|
102
|
+
return;
|
103
|
+
}
|
104
|
+
|
105
|
+
quickPromptsContainer.innerHTML = quickPrompts
|
106
|
+
.map(
|
107
|
+
(prompt, index) => `
|
108
|
+
<button class="quick-prompt-button" data-index="${index}">
|
109
|
+
${prompt}
|
110
|
+
</button>`
|
111
|
+
)
|
112
|
+
.join('');
|
113
|
+
|
114
|
+
document.querySelectorAll('.quick-prompt-button').forEach((button) =>
|
115
|
+
button.addEventListener('click', (e) => handleQuickPromptSelection(e))
|
116
|
+
);
|
117
|
+
debugLog('Quick prompts rendered successfully.');
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Handles quick prompt selection.
|
122
|
+
*/
|
123
|
+
function handleQuickPromptSelection(event) {
|
124
|
+
const promptIndex = event.target.getAttribute('data-index');
|
125
|
+
const promptText = quickPrompts[promptIndex];
|
126
|
+
|
127
|
+
appendRawMessage('user', { content: promptText }, 'User', {});
|
128
|
+
clearQuickPrompts();
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Clears all quick prompts from the UI.
|
133
|
+
*/
|
134
|
+
function clearQuickPrompts() {
|
135
|
+
const quickPromptsContainer = document.getElementById('quickPrompts');
|
136
|
+
if (quickPromptsContainer) {
|
137
|
+
quickPromptsContainer.innerHTML = '';
|
138
|
+
debugLog('Quick prompts cleared.');
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
/**
|
143
|
+
* Allows adding a new quick prompt dynamically.
|
144
|
+
*/
|
145
|
+
export function addQuickPrompt(prompt) {
|
146
|
+
quickPrompts.push(prompt);
|
147
|
+
renderQuickPrompts();
|
148
|
+
debugLog('Quick prompt added.', { prompt });
|
149
|
+
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
* Removes a quick prompt by index.
|
153
|
+
*/
|
154
|
+
export function removeQuickPrompt(index) {
|
155
|
+
if (index < 0 || index >= quickPrompts.length) {
|
156
|
+
debugLog('Invalid quick prompt index.', { index });
|
157
|
+
return;
|
158
|
+
}
|
159
|
+
quickPrompts.splice(index, 1);
|
160
|
+
renderQuickPrompts();
|
161
|
+
debugLog('Quick prompt removed.', { index });
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
* Clears all messages from the chat history UI.
|
166
|
+
*/
|
167
|
+
export function clearMessages() {
|
168
|
+
debugLog('Clearing all messages from the chat history.');
|
169
|
+
|
170
|
+
const messageContainer = document.getElementById('messageHistory');
|
171
|
+
if (messageContainer) {
|
172
|
+
messageContainer.innerHTML = '';
|
173
|
+
debugLog('Chat history cleared successfully.');
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Attaches toolbar actions to a message element.
|
179
|
+
*/
|
180
|
+
function attachToolbarActions(messageDiv) {
|
181
|
+
const persistentMessage = document.getElementById("persistentMessage");
|
182
|
+
|
183
|
+
messageDiv.addEventListener("click", (event) => {
|
184
|
+
const target = event.target.closest('button');
|
185
|
+
if (!target) return;
|
186
|
+
|
187
|
+
const action = target.getAttribute('aria-label');
|
188
|
+
|
189
|
+
switch (action) {
|
190
|
+
case 'Thumbs Up':
|
191
|
+
debugLog('Thumbs up clicked.');
|
192
|
+
break;
|
193
|
+
case 'Thumbs Down':
|
194
|
+
debugLog('Thumbs down clicked.');
|
195
|
+
break;
|
196
|
+
case 'Append to Persistent Message':
|
197
|
+
appendToPersistentMessage(messageDiv, persistentMessage);
|
198
|
+
break;
|
199
|
+
case 'Edit Message':
|
200
|
+
editMessage(messageDiv);
|
201
|
+
break;
|
202
|
+
case 'Copy Message':
|
203
|
+
copyMessageToClipboard(messageDiv);
|
204
|
+
break;
|
205
|
+
case 'Delete Message':
|
206
|
+
deleteMessage(messageDiv);
|
207
|
+
break;
|
208
|
+
}
|
209
|
+
});
|
210
|
+
}
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Appends the content of a message to the persistent message area.
|
214
|
+
*/
|
215
|
+
function appendToPersistentMessage(messageDiv, persistentMessageElement) {
|
216
|
+
if (!persistentMessageElement) {
|
217
|
+
console.error("Persistent message element not found (firstUserMessage).");
|
218
|
+
return;
|
219
|
+
}
|
220
|
+
|
221
|
+
const content = messageDiv.querySelector('span')?.innerText || "No content";
|
222
|
+
const persistentMessageContent = persistentMessageElement.querySelector('.message span');
|
223
|
+
|
224
|
+
if (persistentMessageContent) {
|
225
|
+
persistentMessageContent.innerText = content;
|
226
|
+
debugLog('Message appended to persistent message area.', { content });
|
227
|
+
} else {
|
228
|
+
console.error("Persistent message content element not found.");
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* Allows the user to edit a message.
|
234
|
+
*/
|
235
|
+
function editMessage(messageDiv) {
|
236
|
+
const span = messageDiv.querySelector('span');
|
237
|
+
const content = span.innerText;
|
238
|
+
const newContent = prompt('Edit your message:', content);
|
239
|
+
if (newContent !== null) {
|
240
|
+
span.innerText = newContent;
|
241
|
+
debugLog('Message edited successfully.', { newContent });
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
/**
|
246
|
+
* Copies a message's content to the clipboard.
|
247
|
+
*/
|
248
|
+
function copyMessageToClipboard(messageDiv) {
|
249
|
+
const content = messageDiv.querySelector('span').innerText;
|
250
|
+
navigator.clipboard.writeText(content).then(() => {
|
251
|
+
alert('Message copied to clipboard!');
|
252
|
+
debugLog('Message copied to clipboard.', { content });
|
253
|
+
});
|
254
|
+
}
|
255
|
+
|
256
|
+
/**
|
257
|
+
* Deletes a message from the chat history.
|
258
|
+
*/
|
259
|
+
function deleteMessage(messageDiv) {
|
260
|
+
if (confirm('Are you sure you want to delete this message?')) {
|
261
|
+
messageDiv.remove();
|
262
|
+
debugLog('Message deleted successfully.');
|
263
|
+
}
|
264
|
+
}
|