open-swarm 0.1.1745275181__py3-none-any.whl → 0.1.1748636295__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.1748636295.dist-info/METADATA +257 -0
- open_swarm-0.1.1748636295.dist-info/RECORD +89 -0
- {open_swarm-0.1.1745275181.dist-info → open_swarm-0.1.1748636295.dist-info}/WHEEL +2 -1
- open_swarm-0.1.1748636295.dist-info/entry_points.txt +3 -0
- open_swarm-0.1.1748636295.dist-info/top_level.txt +1 -0
- swarm/__init__.py +2 -0
- swarm/agent/agent.py +49 -0
- swarm/auth.py +48 -113
- swarm/consumers.py +0 -19
- swarm/core.py +411 -0
- swarm/extensions/blueprint/__init__.py +16 -30
- swarm/extensions/blueprint/agent_utils.py +45 -0
- swarm/extensions/blueprint/blueprint_base.py +562 -0
- swarm/extensions/blueprint/blueprint_discovery.py +112 -0
- swarm/extensions/blueprint/django_utils.py +79 -181
- swarm/extensions/blueprint/interactive_mode.py +72 -67
- swarm/extensions/blueprint/output_utils.py +82 -0
- swarm/{core → extensions/blueprint}/spinner.py +21 -30
- swarm/extensions/cli/cli_args.py +0 -6
- swarm/extensions/cli/commands/blueprint_management.py +9 -47
- swarm/extensions/cli/commands/config_management.py +6 -5
- swarm/extensions/cli/commands/edit_config.py +7 -16
- swarm/extensions/cli/commands/list_blueprints.py +1 -1
- swarm/extensions/cli/commands/validate_env.py +4 -11
- swarm/extensions/cli/commands/validate_envvars.py +6 -6
- swarm/extensions/cli/interactive_shell.py +2 -16
- swarm/extensions/config/config_loader.py +345 -107
- swarm/{core → extensions/config}/config_manager.py +38 -50
- swarm/{core → extensions/config}/server_config.py +0 -32
- swarm/extensions/launchers/build_launchers.py +14 -0
- swarm/{core → extensions/launchers}/build_swarm_wrapper.py +0 -0
- swarm/extensions/launchers/swarm_api.py +64 -8
- swarm/extensions/launchers/swarm_cli.py +300 -8
- swarm/extensions/mcp/__init__.py +1 -0
- swarm/extensions/mcp/cache_utils.py +32 -0
- swarm/extensions/mcp/mcp_client.py +233 -0
- swarm/extensions/mcp/mcp_tool_provider.py +135 -0
- swarm/extensions/mcp/mcp_utils.py +260 -0
- swarm/llm/chat_completion.py +166 -0
- swarm/serializers.py +5 -96
- swarm/settings.py +133 -85
- swarm/types.py +91 -0
- swarm/urls.py +74 -57
- swarm/utils/context_utils.py +4 -10
- swarm/utils/general_utils.py +0 -21
- swarm/utils/redact.py +36 -23
- swarm/views/api_views.py +39 -48
- swarm/views/chat_views.py +76 -236
- swarm/views/core_views.py +87 -80
- swarm/views/model_views.py +121 -64
- swarm/views/utils.py +439 -65
- swarm/views/web_views.py +2 -2
- open_swarm-0.1.1745275181.dist-info/METADATA +0 -874
- open_swarm-0.1.1745275181.dist-info/RECORD +0 -319
- open_swarm-0.1.1745275181.dist-info/entry_points.txt +0 -4
- swarm/blueprints/README.md +0 -68
- swarm/blueprints/blueprint_audit_status.json +0 -27
- swarm/blueprints/chatbot/README.md +0 -40
- swarm/blueprints/chatbot/blueprint_chatbot.py +0 -471
- swarm/blueprints/chatbot/metadata.json +0 -23
- swarm/blueprints/chatbot/templates/chatbot/chatbot.html +0 -33
- swarm/blueprints/chucks_angels/README.md +0 -11
- swarm/blueprints/chucks_angels/blueprint_chucks_angels.py +0 -7
- swarm/blueprints/chucks_angels/test_basic.py +0 -3
- swarm/blueprints/codey/CODEY.md +0 -15
- swarm/blueprints/codey/README.md +0 -115
- swarm/blueprints/codey/blueprint_codey.py +0 -1072
- swarm/blueprints/codey/codey_cli.py +0 -373
- swarm/blueprints/codey/instructions.md +0 -17
- swarm/blueprints/codey/metadata.json +0 -23
- swarm/blueprints/common/operation_box_utils.py +0 -83
- swarm/blueprints/digitalbutlers/README.md +0 -11
- swarm/blueprints/digitalbutlers/__init__.py +0 -1
- swarm/blueprints/digitalbutlers/blueprint_digitalbutlers.py +0 -7
- swarm/blueprints/digitalbutlers/test_basic.py +0 -3
- swarm/blueprints/divine_code/README.md +0 -3
- swarm/blueprints/divine_code/__init__.py +0 -10
- swarm/blueprints/divine_code/apps.py +0 -11
- swarm/blueprints/divine_code/blueprint_divine_code.py +0 -270
- swarm/blueprints/django_chat/apps.py +0 -6
- swarm/blueprints/django_chat/blueprint_django_chat.py +0 -268
- swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html +0 -37
- swarm/blueprints/django_chat/urls.py +0 -8
- swarm/blueprints/django_chat/views.py +0 -32
- swarm/blueprints/echocraft/blueprint_echocraft.py +0 -384
- swarm/blueprints/flock/README.md +0 -11
- swarm/blueprints/flock/__init__.py +0 -8
- swarm/blueprints/flock/blueprint_flock.py +0 -7
- swarm/blueprints/flock/test_basic.py +0 -3
- swarm/blueprints/geese/README.md +0 -10
- swarm/blueprints/geese/__init__.py +0 -8
- swarm/blueprints/geese/blueprint_geese.py +0 -384
- swarm/blueprints/geese/geese_cli.py +0 -102
- swarm/blueprints/jeeves/README.md +0 -41
- swarm/blueprints/jeeves/blueprint_jeeves.py +0 -722
- swarm/blueprints/jeeves/jeeves_cli.py +0 -55
- swarm/blueprints/jeeves/metadata.json +0 -24
- swarm/blueprints/mcp_demo/blueprint_mcp_demo.py +0 -473
- swarm/blueprints/messenger/templates/messenger/messenger.html +0 -46
- swarm/blueprints/mission_improbable/blueprint_mission_improbable.py +0 -423
- swarm/blueprints/monkai_magic/blueprint_monkai_magic.py +0 -340
- swarm/blueprints/nebula_shellz/blueprint_nebula_shellz.py +0 -265
- swarm/blueprints/omniplex/blueprint_omniplex.py +0 -298
- swarm/blueprints/poets/blueprint_poets.py +0 -546
- swarm/blueprints/poets/poets_cli.py +0 -23
- swarm/blueprints/rue_code/README.md +0 -8
- swarm/blueprints/rue_code/blueprint_rue_code.py +0 -448
- swarm/blueprints/rue_code/rue_code_cli.py +0 -43
- swarm/blueprints/stewie/apps.py +0 -12
- swarm/blueprints/stewie/blueprint_family_ties.py +0 -349
- swarm/blueprints/stewie/models.py +0 -19
- swarm/blueprints/stewie/serializers.py +0 -10
- swarm/blueprints/stewie/settings.py +0 -17
- swarm/blueprints/stewie/urls.py +0 -11
- swarm/blueprints/stewie/views.py +0 -26
- swarm/blueprints/suggestion/blueprint_suggestion.py +0 -222
- swarm/blueprints/whinge_surf/README.md +0 -22
- swarm/blueprints/whinge_surf/__init__.py +0 -1
- swarm/blueprints/whinge_surf/blueprint_whinge_surf.py +0 -565
- swarm/blueprints/whinge_surf/whinge_surf_cli.py +0 -99
- swarm/blueprints/whiskeytango_foxtrot/__init__.py +0 -0
- swarm/blueprints/whiskeytango_foxtrot/apps.py +0 -11
- swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py +0 -339
- swarm/blueprints/zeus/__init__.py +0 -2
- swarm/blueprints/zeus/apps.py +0 -4
- swarm/blueprints/zeus/blueprint_zeus.py +0 -270
- swarm/blueprints/zeus/zeus_cli.py +0 -13
- swarm/cli/async_input.py +0 -65
- swarm/cli/async_input_demo.py +0 -32
- swarm/core/agent_utils.py +0 -21
- swarm/core/blueprint_base.py +0 -769
- swarm/core/blueprint_discovery.py +0 -125
- swarm/core/blueprint_runner.py +0 -59
- swarm/core/blueprint_ux.py +0 -109
- swarm/core/build_launchers.py +0 -15
- swarm/core/cli/__init__.py +0 -1
- swarm/core/cli/commands/__init__.py +0 -1
- swarm/core/cli/commands/blueprint_management.py +0 -7
- swarm/core/cli/interactive_shell.py +0 -14
- swarm/core/cli/main.py +0 -50
- swarm/core/cli/utils/__init__.py +0 -1
- swarm/core/cli/utils/discover_commands.py +0 -18
- swarm/core/config_loader.py +0 -122
- swarm/core/output_utils.py +0 -193
- swarm/core/session_logger.py +0 -42
- swarm/core/slash_commands.py +0 -89
- swarm/core/swarm_api.py +0 -68
- swarm/core/swarm_cli.py +0 -216
- swarm/core/utils/__init__.py +0 -0
- swarm/extensions/blueprint/cli_handler.py +0 -197
- swarm/extensions/blueprint/runnable_blueprint.py +0 -42
- swarm/extensions/cli/utils/__init__.py +0 -1
- swarm/extensions/cli/utils/async_input.py +0 -46
- swarm/extensions/cli/utils/prompt_user.py +0 -3
- swarm/management/__init__.py +0 -0
- swarm/management/commands/__init__.py +0 -0
- swarm/management/commands/runserver.py +0 -58
- swarm/middleware.py +0 -65
- swarm/permissions.py +0 -38
- swarm/static/contrib/fonts/fontawesome-webfont.ttf +0 -7
- swarm/static/contrib/fonts/fontawesome-webfont.woff +0 -7
- swarm/static/contrib/fonts/fontawesome-webfont.woff2 +0 -7
- swarm/static/contrib/markedjs/marked.min.js +0 -6
- swarm/static/contrib/tabler-icons/adjustments-horizontal.svg +0 -27
- swarm/static/contrib/tabler-icons/alert-triangle.svg +0 -21
- swarm/static/contrib/tabler-icons/archive.svg +0 -21
- swarm/static/contrib/tabler-icons/artboard.svg +0 -27
- swarm/static/contrib/tabler-icons/automatic-gearbox.svg +0 -23
- swarm/static/contrib/tabler-icons/box-multiple.svg +0 -19
- swarm/static/contrib/tabler-icons/carambola.svg +0 -19
- swarm/static/contrib/tabler-icons/copy.svg +0 -20
- swarm/static/contrib/tabler-icons/download.svg +0 -21
- swarm/static/contrib/tabler-icons/edit.svg +0 -21
- swarm/static/contrib/tabler-icons/filled/carambola.svg +0 -13
- swarm/static/contrib/tabler-icons/filled/paint.svg +0 -13
- swarm/static/contrib/tabler-icons/headset.svg +0 -22
- swarm/static/contrib/tabler-icons/layout-sidebar-left-collapse.svg +0 -21
- swarm/static/contrib/tabler-icons/layout-sidebar-left-expand.svg +0 -21
- swarm/static/contrib/tabler-icons/layout-sidebar-right-collapse.svg +0 -21
- swarm/static/contrib/tabler-icons/layout-sidebar-right-expand.svg +0 -21
- swarm/static/contrib/tabler-icons/message-chatbot.svg +0 -22
- swarm/static/contrib/tabler-icons/message-star.svg +0 -22
- swarm/static/contrib/tabler-icons/message-x.svg +0 -23
- swarm/static/contrib/tabler-icons/message.svg +0 -21
- swarm/static/contrib/tabler-icons/paperclip.svg +0 -18
- swarm/static/contrib/tabler-icons/playlist-add.svg +0 -22
- swarm/static/contrib/tabler-icons/robot.svg +0 -26
- swarm/static/contrib/tabler-icons/search.svg +0 -19
- swarm/static/contrib/tabler-icons/settings.svg +0 -20
- swarm/static/contrib/tabler-icons/thumb-down.svg +0 -19
- swarm/static/contrib/tabler-icons/thumb-up.svg +0 -19
- swarm/static/css/dropdown.css +0 -22
- swarm/static/htmx/htmx.min.js +0 -0
- swarm/static/js/dropdown.js +0 -23
- swarm/static/rest_mode/css/base.css +0 -470
- swarm/static/rest_mode/css/chat-history.css +0 -286
- swarm/static/rest_mode/css/chat.css +0 -251
- swarm/static/rest_mode/css/chatbot.css +0 -74
- swarm/static/rest_mode/css/chatgpt.css +0 -62
- swarm/static/rest_mode/css/colors/corporate.css +0 -74
- swarm/static/rest_mode/css/colors/pastel.css +0 -81
- swarm/static/rest_mode/css/colors/tropical.css +0 -82
- swarm/static/rest_mode/css/general.css +0 -142
- swarm/static/rest_mode/css/layout.css +0 -167
- swarm/static/rest_mode/css/layouts/messenger-layout.css +0 -17
- swarm/static/rest_mode/css/layouts/minimalist-layout.css +0 -57
- swarm/static/rest_mode/css/layouts/mobile-layout.css +0 -8
- swarm/static/rest_mode/css/messages.css +0 -84
- swarm/static/rest_mode/css/messenger.css +0 -135
- swarm/static/rest_mode/css/settings.css +0 -91
- swarm/static/rest_mode/css/simple.css +0 -44
- swarm/static/rest_mode/css/slack.css +0 -58
- swarm/static/rest_mode/css/style.css +0 -156
- swarm/static/rest_mode/css/theme.css +0 -30
- swarm/static/rest_mode/css/toast.css +0 -40
- swarm/static/rest_mode/js/auth.js +0 -9
- swarm/static/rest_mode/js/blueprint.js +0 -41
- swarm/static/rest_mode/js/blueprintUtils.js +0 -12
- swarm/static/rest_mode/js/chatLogic.js +0 -79
- swarm/static/rest_mode/js/debug.js +0 -63
- swarm/static/rest_mode/js/events.js +0 -98
- swarm/static/rest_mode/js/main.js +0 -19
- swarm/static/rest_mode/js/messages.js +0 -264
- swarm/static/rest_mode/js/messengerLogic.js +0 -355
- swarm/static/rest_mode/js/modules/apiService.js +0 -84
- swarm/static/rest_mode/js/modules/blueprintManager.js +0 -162
- swarm/static/rest_mode/js/modules/chatHistory.js +0 -110
- swarm/static/rest_mode/js/modules/debugLogger.js +0 -14
- swarm/static/rest_mode/js/modules/eventHandlers.js +0 -107
- swarm/static/rest_mode/js/modules/messageProcessor.js +0 -120
- swarm/static/rest_mode/js/modules/state.js +0 -7
- swarm/static/rest_mode/js/modules/userInteractions.js +0 -29
- swarm/static/rest_mode/js/modules/validation.js +0 -23
- swarm/static/rest_mode/js/rendering.js +0 -119
- swarm/static/rest_mode/js/settings.js +0 -130
- swarm/static/rest_mode/js/sidebar.js +0 -94
- swarm/static/rest_mode/js/simpleLogic.js +0 -37
- swarm/static/rest_mode/js/slackLogic.js +0 -66
- swarm/static/rest_mode/js/splash.js +0 -76
- swarm/static/rest_mode/js/theme.js +0 -111
- swarm/static/rest_mode/js/toast.js +0 -36
- swarm/static/rest_mode/js/ui.js +0 -265
- swarm/static/rest_mode/js/validation.js +0 -57
- swarm/static/rest_mode/svg/animated_spinner.svg +0 -12
- swarm/static/rest_mode/svg/arrow_down.svg +0 -5
- swarm/static/rest_mode/svg/arrow_left.svg +0 -5
- swarm/static/rest_mode/svg/arrow_right.svg +0 -5
- swarm/static/rest_mode/svg/arrow_up.svg +0 -5
- swarm/static/rest_mode/svg/attach.svg +0 -8
- swarm/static/rest_mode/svg/avatar.svg +0 -7
- swarm/static/rest_mode/svg/canvas.svg +0 -6
- swarm/static/rest_mode/svg/chat_history.svg +0 -4
- swarm/static/rest_mode/svg/close.svg +0 -5
- swarm/static/rest_mode/svg/copy.svg +0 -4
- swarm/static/rest_mode/svg/dark_mode.svg +0 -3
- swarm/static/rest_mode/svg/edit.svg +0 -5
- swarm/static/rest_mode/svg/layout.svg +0 -9
- swarm/static/rest_mode/svg/logo.svg +0 -29
- swarm/static/rest_mode/svg/logout.svg +0 -5
- swarm/static/rest_mode/svg/mobile.svg +0 -5
- swarm/static/rest_mode/svg/new_chat.svg +0 -4
- swarm/static/rest_mode/svg/not_visible.svg +0 -5
- swarm/static/rest_mode/svg/plus.svg +0 -7
- swarm/static/rest_mode/svg/run_code.svg +0 -6
- swarm/static/rest_mode/svg/save.svg +0 -4
- swarm/static/rest_mode/svg/search.svg +0 -6
- swarm/static/rest_mode/svg/settings.svg +0 -4
- swarm/static/rest_mode/svg/speaker.svg +0 -5
- swarm/static/rest_mode/svg/stop.svg +0 -6
- swarm/static/rest_mode/svg/thumbs_down.svg +0 -3
- swarm/static/rest_mode/svg/thumbs_up.svg +0 -3
- swarm/static/rest_mode/svg/toggle_off.svg +0 -6
- swarm/static/rest_mode/svg/toggle_on.svg +0 -6
- swarm/static/rest_mode/svg/trash.svg +0 -10
- swarm/static/rest_mode/svg/undo.svg +0 -3
- swarm/static/rest_mode/svg/visible.svg +0 -8
- swarm/static/rest_mode/svg/voice.svg +0 -10
- swarm/templates/account/login.html +0 -22
- swarm/templates/account/signup.html +0 -32
- swarm/templates/base.html +0 -30
- swarm/templates/chat.html +0 -43
- swarm/templates/index.html +0 -35
- swarm/templates/rest_mode/components/chat_sidebar.html +0 -55
- swarm/templates/rest_mode/components/header.html +0 -45
- swarm/templates/rest_mode/components/main_chat_pane.html +0 -41
- swarm/templates/rest_mode/components/settings_dialog.html +0 -97
- swarm/templates/rest_mode/components/splash_screen.html +0 -7
- swarm/templates/rest_mode/components/top_bar.html +0 -28
- swarm/templates/rest_mode/message_ui.html +0 -50
- swarm/templates/rest_mode/slackbot.html +0 -30
- swarm/templates/simple_blueprint_page.html +0 -24
- swarm/templates/websocket_partials/final_system_message.html +0 -3
- swarm/templates/websocket_partials/system_message.html +0 -4
- swarm/templates/websocket_partials/user_message.html +0 -5
- swarm/utils/ansi_box.py +0 -34
- swarm/utils/disable_tracing.py +0 -38
- swarm/utils/log_utils.py +0 -63
- swarm/utils/openai_patch.py +0 -33
- swarm/ux/ansi_box.py +0 -43
- swarm/ux/spinner.py +0 -53
- {open_swarm-0.1.1745275181.dist-info → open_swarm-0.1.1748636295.dist-info}/licenses/LICENSE +0 -0
- /swarm/{core → extensions/blueprint}/blueprint_utils.py +0 -0
- /swarm/{core → extensions/blueprint}/common_utils.py +0 -0
- /swarm/{core → extensions/config}/setup_wizard.py +0 -0
- /swarm/{blueprints/rue_code → extensions/config/utils}/__init__.py +0 -0
- /swarm/{core → extensions/config}/utils/logger.py +0 -0
- /swarm/{core → extensions/launchers}/swarm_wrapper.py +0 -0
swarm/urls.py
CHANGED
@@ -1,72 +1,89 @@
|
|
1
|
-
"""
|
2
|
-
Swarm URL Configuration
|
3
|
-
"""
|
4
|
-
import logging
|
5
1
|
from django.contrib import admin
|
6
|
-
from django.urls import path,
|
2
|
+
from django.urls import path, re_path, include
|
3
|
+
from django.http import HttpResponse
|
7
4
|
from django.conf import settings
|
8
|
-
from django.
|
9
|
-
|
10
|
-
|
11
|
-
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
|
5
|
+
from django.conf.urls.static import static
|
6
|
+
import os
|
7
|
+
import logging
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
from swarm.views.
|
16
|
-
|
9
|
+
# Import specific views from their modules
|
10
|
+
from swarm.views.core_views import index as core_index_view, serve_swarm_config, custom_login
|
11
|
+
from swarm.views.chat_views import chat_completions
|
12
|
+
from swarm.views.model_views import list_models
|
13
|
+
from swarm.views.message_views import ChatMessageViewSet
|
14
|
+
from drf_spectacular.views import SpectacularSwaggerView, SpectacularAPIView as HiddenSpectacularAPIView
|
15
|
+
from rest_framework.routers import DefaultRouter
|
17
16
|
|
18
17
|
logger = logging.getLogger(__name__)
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
]
|
30
|
-
|
31
|
-
# ==============================================================================
|
32
|
-
# Schema URL Patterns
|
33
|
-
# ==============================================================================
|
34
|
-
schema_urlpatterns = [
|
35
|
-
path('schema/', SpectacularAPIView.as_view(), name='schema'),
|
36
|
-
path('schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
|
37
|
-
path('schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
|
38
|
-
]
|
19
|
+
def favicon(request):
|
20
|
+
favicon_path = settings.BASE_DIR / 'assets' / 'images' / 'favicon.ico'
|
21
|
+
try:
|
22
|
+
with open(favicon_path, 'rb') as f:
|
23
|
+
favicon_data = f.read()
|
24
|
+
return HttpResponse(favicon_data, content_type="image/x-icon")
|
25
|
+
except FileNotFoundError:
|
26
|
+
logger.warning("Favicon not found.")
|
27
|
+
return HttpResponse(status=404)
|
39
28
|
|
40
|
-
|
41
|
-
|
42
|
-
# ==============================================================================
|
43
|
-
urlpatterns = [
|
44
|
-
# Redirect root based on DEBUG setting
|
45
|
-
path('', RedirectView.as_view(pattern_name='swagger-ui', permanent=False) if settings.DEBUG else RedirectView.as_view(pattern_name='login', permanent=False)),
|
29
|
+
ENABLE_ADMIN = os.getenv("ENABLE_ADMIN", "false").lower() in ("true", "1", "t")
|
30
|
+
ENABLE_WEBUI = os.getenv("ENABLE_WEBUI", "true").lower() in ("true", "1", "t")
|
46
31
|
|
47
|
-
|
48
|
-
|
32
|
+
logger.debug(f"ENABLE_WEBUI={'true' if ENABLE_WEBUI else 'false'}")
|
33
|
+
logger.debug(f"ENABLE_ADMIN={'true' if ENABLE_ADMIN else 'false'}")
|
49
34
|
|
50
|
-
|
51
|
-
|
35
|
+
router = DefaultRouter()
|
36
|
+
# Ensure ChatMessageViewSet is available before registering
|
37
|
+
if ChatMessageViewSet:
|
38
|
+
router.register(r'v1/chat/messages', ChatMessageViewSet, basename='chatmessage')
|
39
|
+
else:
|
40
|
+
logger.warning("ChatMessageViewSet not imported correctly, skipping API registration.")
|
52
41
|
|
53
|
-
|
54
|
-
|
42
|
+
# Base URL patterns required by Swarm core
|
43
|
+
# Use the imported view functions directly
|
44
|
+
base_urlpatterns = [
|
45
|
+
re_path(r'^health/?$', lambda request: HttpResponse("OK"), name='health_check'),
|
46
|
+
re_path(r'^v1/chat/completions/?$', chat_completions, name='chat_completions'),
|
47
|
+
re_path(r'^v1/models/?$', list_models, name='list_models'),
|
48
|
+
re_path(r'^schema/?$', HiddenSpectacularAPIView.as_view(), name='schema'),
|
49
|
+
re_path(r'^swagger-ui/?$', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
|
50
|
+
]
|
55
51
|
|
56
|
-
|
57
|
-
|
58
|
-
path('logout/', auth_views.LogoutView.as_view(next_page=reverse_lazy('login')), name='logout'),
|
52
|
+
# Optional Admin URLs
|
53
|
+
admin_urlpatterns = [path('admin/', admin.site.urls)] if ENABLE_ADMIN else []
|
59
54
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
55
|
+
# Optional Web UI URLs
|
56
|
+
webui_urlpatterns = []
|
57
|
+
if ENABLE_WEBUI:
|
58
|
+
webui_urlpatterns = [
|
59
|
+
path('', core_index_view, name='index'),
|
60
|
+
path('favicon.ico', favicon, name='favicon'),
|
61
|
+
path('config/swarm_config.json', serve_swarm_config, name='serve_swarm_config'),
|
62
|
+
path('accounts/login/', custom_login, name='custom_login'),
|
63
|
+
]
|
64
|
+
if settings.DEBUG:
|
65
|
+
if settings.STATIC_URL and settings.STATIC_ROOT:
|
66
|
+
webui_urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
67
|
+
else:
|
68
|
+
logger.warning("STATIC_URL or STATIC_ROOT not configured, static files may not serve correctly in DEBUG mode.")
|
64
69
|
|
65
|
-
#
|
66
|
-
|
67
|
-
logger.debug(f"ENABLE_WEBUI={getattr(settings, 'ENABLE_WEBUI', False)}")
|
70
|
+
# --- Blueprint URLs are now added dynamically via blueprint_base.py -> django_utils.py ---
|
71
|
+
blueprint_urlpatterns = [] # Start with empty list, populated by utils
|
68
72
|
|
69
|
-
#
|
70
|
-
|
71
|
-
# urlpatterns.append(path('something/', include('something.urls')))
|
73
|
+
# Combine all URL patterns
|
74
|
+
urlpatterns = webui_urlpatterns + admin_urlpatterns + base_urlpatterns + blueprint_urlpatterns + router.urls
|
72
75
|
|
76
|
+
# Log final URL patterns (consider moving this to where patterns are finalized if issues persist)
|
77
|
+
if settings.DEBUG:
|
78
|
+
try:
|
79
|
+
from django.urls import get_resolver
|
80
|
+
# Note: get_resolver(None) might not reflect dynamically added URLs perfectly here.
|
81
|
+
# Logging within django_utils might be more accurate for dynamic additions.
|
82
|
+
final_patterns = get_resolver(None).url_patterns
|
83
|
+
logger.debug(f"Initial resolved URL patterns ({len(final_patterns)} total):")
|
84
|
+
# for pattern in final_patterns:
|
85
|
+
# try: pattern_repr = str(pattern)
|
86
|
+
# except: pattern_repr = f"[Pattern for {getattr(pattern, 'name', 'unnamed')}]"
|
87
|
+
# logger.debug(f" {pattern_repr}")
|
88
|
+
except Exception as e:
|
89
|
+
logger.error(f"Could not log initial URL patterns: {e}")
|
swarm/utils/context_utils.py
CHANGED
@@ -23,16 +23,10 @@ def _is_valid_message(msg: Any) -> bool:
|
|
23
23
|
role = msg.get("role")
|
24
24
|
if not role or not isinstance(role, str): logger.warning(f"Skipping msg missing role: {str(msg)[:150]}"); return False
|
25
25
|
content = msg.get("content"); tool_calls = msg.get("tool_calls"); tool_call_id = msg.get("tool_call_id")
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
elif role == "
|
30
|
-
is_valid = isinstance(content, str)
|
31
|
-
elif role == "assistant":
|
32
|
-
# Assistant valid if it has string content or at least one tool call
|
33
|
-
is_valid = isinstance(content, str) or (isinstance(tool_calls, list) and len(tool_calls) > 0)
|
34
|
-
elif role == "tool":
|
35
|
-
is_valid = isinstance(content, str) and tool_call_id is not None
|
26
|
+
if role == "system": is_valid = content is not None
|
27
|
+
elif role == "user": is_valid = content is not None
|
28
|
+
elif role == "assistant": is_valid = content is not None or (isinstance(tool_calls, list) and len(tool_calls) > 0)
|
29
|
+
elif role == "tool": is_valid = content is not None and tool_call_id is not None
|
36
30
|
else: is_valid = False
|
37
31
|
if not is_valid: logger.warning(f"Skipping msg failing validity check for role '{role}': {str(msg)[:150]}")
|
38
32
|
return is_valid
|
swarm/utils/general_utils.py
CHANGED
@@ -118,27 +118,6 @@ def _search_and_process_jmespath(expression: str, payload: dict) -> str:
|
|
118
118
|
|
119
119
|
return str(chat_id) if chat_id is not None else ""
|
120
120
|
|
121
|
-
# ---------------------------------------------------------------------------
|
122
|
-
# Debug utilities
|
123
|
-
# ---------------------------------------------------------------------------
|
124
|
-
|
125
|
-
_DEBUG_ENV_VARS = ("SWARM_DEBUG", "DEBUG", "OPEN_SWARM_DEBUG")
|
126
|
-
|
127
|
-
|
128
|
-
def is_debug_enabled() -> bool:
|
129
|
-
"""Return True if any recognised debug environment variable is truthy.
|
130
|
-
|
131
|
-
A value is considered *truthy* when it is set and **not** one of
|
132
|
-
"0", "false", "off" (case‑insensitive).
|
133
|
-
"""
|
134
|
-
import os
|
135
|
-
|
136
|
-
for var in _DEBUG_ENV_VARS:
|
137
|
-
val = os.getenv(var)
|
138
|
-
if val and val.lower() not in ("0", "false", "off"):
|
139
|
-
return True
|
140
|
-
return False
|
141
|
-
|
142
121
|
|
143
122
|
def extract_chat_id(payload: dict) -> str:
|
144
123
|
"""
|
swarm/utils/redact.py
CHANGED
@@ -13,43 +13,56 @@ DEFAULT_SENSITIVE_KEYS = ["secret", "password", "api_key", "apikey", "token", "a
|
|
13
13
|
def redact_sensitive_data(
|
14
14
|
data: Union[str, Dict, List],
|
15
15
|
sensitive_keys: Optional[List[str]] = None,
|
16
|
-
reveal_chars: int =
|
16
|
+
reveal_chars: int = 4,
|
17
17
|
mask: str = "[REDACTED]"
|
18
18
|
) -> Union[str, Dict, List]:
|
19
19
|
"""
|
20
20
|
Recursively redact sensitive information from dictionaries or lists based on keys.
|
21
|
-
|
22
|
-
If reveal_chars > 0, partially masks (preserves reveal_chars at start/end).
|
23
|
-
If a custom mask is provided, always use it (for test compatibility).
|
21
|
+
Applies partial redaction to string values associated with sensitive keys.
|
24
22
|
Does NOT redact standalone strings.
|
23
|
+
|
24
|
+
Args:
|
25
|
+
data: Input data to redact (dict or list). Other types returned as is.
|
26
|
+
sensitive_keys: List of dictionary keys to treat as sensitive. Defaults to common keys.
|
27
|
+
reveal_chars: Number of initial/trailing characters to reveal (0 means full redaction).
|
28
|
+
mask: String used for redaction in the middle or for full redaction of strings.
|
29
|
+
|
30
|
+
Returns:
|
31
|
+
Redacted data structure of the same type as input.
|
25
32
|
"""
|
26
|
-
keys_to_redact =
|
27
|
-
|
28
|
-
|
29
|
-
return val
|
30
|
-
if mask != "[REDACTED]":
|
31
|
-
return mask
|
32
|
-
if reveal_chars == 0:
|
33
|
-
return mask
|
34
|
-
if len(val) >= 2 * reveal_chars + 1:
|
35
|
-
return val[:reveal_chars] + mask + val[-reveal_chars:]
|
36
|
-
return mask
|
33
|
+
keys_to_redact = sensitive_keys if sensitive_keys is not None else DEFAULT_SENSITIVE_KEYS
|
34
|
+
keys_to_redact_lower = {key.lower() for key in keys_to_redact}
|
35
|
+
|
37
36
|
if isinstance(data, dict):
|
38
37
|
redacted_dict = {}
|
39
|
-
for
|
40
|
-
if isinstance(
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
for key, value in data.items():
|
39
|
+
if isinstance(key, str) and key.lower() in keys_to_redact_lower:
|
40
|
+
if isinstance(value, str):
|
41
|
+
val_len = len(value)
|
42
|
+
if reveal_chars > 0 and val_len > reveal_chars * 2:
|
43
|
+
redacted_dict[key] = f"{value[:reveal_chars]}{mask}{value[-reveal_chars:]}"
|
44
|
+
elif val_len > 0:
|
45
|
+
# Use the provided mask string directly for full redaction
|
46
|
+
redacted_dict[key] = mask
|
47
|
+
else:
|
48
|
+
redacted_dict[key] = "" # Redact empty string as empty
|
49
|
+
else:
|
50
|
+
# Use specific placeholder for non-strings
|
51
|
+
redacted_dict[key] = "[REDACTED NON-STRING]"
|
44
52
|
else:
|
45
|
-
|
53
|
+
# Recursively redact nested structures if key is not sensitive
|
54
|
+
redacted_dict[key] = redact_sensitive_data(value, keys_to_redact, reveal_chars, mask)
|
46
55
|
return redacted_dict
|
56
|
+
|
47
57
|
elif isinstance(data, list):
|
58
|
+
# Recursively redact items in a list ONLY if they are dicts or lists themselves.
|
48
59
|
processed_list = []
|
49
60
|
for item in data:
|
50
61
|
if isinstance(item, (dict, list)):
|
51
|
-
processed_list.append(redact_sensitive_data(item,
|
62
|
+
processed_list.append(redact_sensitive_data(item, keys_to_redact, reveal_chars, mask))
|
52
63
|
else:
|
53
|
-
processed_list.append(item)
|
64
|
+
processed_list.append(item) # Keep non-dict/list items (like strings) unchanged
|
54
65
|
return processed_list
|
66
|
+
|
67
|
+
# Return data unchanged if it's not a dict or list (including standalone strings)
|
55
68
|
return data
|
swarm/views/api_views.py
CHANGED
@@ -1,55 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
from rest_framework.
|
5
|
-
from rest_framework import status
|
1
|
+
"""
|
2
|
+
API-specific views and viewsets for Open Swarm MCP Core.
|
3
|
+
"""
|
4
|
+
from rest_framework.viewsets import ModelViewSet
|
6
5
|
from rest_framework.permissions import AllowAny
|
7
|
-
|
8
|
-
from
|
6
|
+
from drf_spectacular.views import SpectacularAPIView as BaseSpectacularAPIView
|
7
|
+
from drf_spectacular.utils import extend_schema
|
8
|
+
from swarm.utils.logger_setup import setup_logger
|
9
|
+
from swarm.models import ChatMessage
|
10
|
+
from swarm.serializers import ChatMessageSerializer
|
9
11
|
|
10
|
-
|
12
|
+
logger = setup_logger(__name__)
|
11
13
|
|
12
|
-
|
14
|
+
class HiddenSpectacularAPIView(BaseSpectacularAPIView):
|
15
|
+
exclude_from_schema = True
|
13
16
|
|
14
|
-
class
|
15
|
-
"""
|
16
|
-
|
17
|
-
"""
|
17
|
+
class ChatMessageViewSet(ModelViewSet):
|
18
|
+
"""API viewset for managing chat messages."""
|
19
|
+
authentication_classes = []
|
18
20
|
permission_classes = [AllowAny]
|
21
|
+
queryset = ChatMessage.objects.all()
|
22
|
+
serializer_class = ChatMessageSerializer
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
available_blueprints = async_to_sync(get_available_blueprints)()
|
24
|
-
|
25
|
-
models_data = []
|
26
|
-
current_time = int(time.time())
|
27
|
-
if isinstance(available_blueprints, dict):
|
28
|
-
blueprint_ids = available_blueprints.keys()
|
29
|
-
elif isinstance(available_blueprints, list):
|
30
|
-
blueprint_ids = available_blueprints
|
31
|
-
else:
|
32
|
-
logger.error(f"Unexpected type from get_available_blueprints: {type(available_blueprints)}")
|
33
|
-
blueprint_ids = []
|
34
|
-
|
35
|
-
for blueprint_id in blueprint_ids:
|
36
|
-
models_data.append({
|
37
|
-
"id": blueprint_id,
|
38
|
-
"object": "model",
|
39
|
-
"created": current_time,
|
40
|
-
"owned_by": "open-swarm",
|
41
|
-
})
|
42
|
-
|
43
|
-
response_payload = {
|
44
|
-
"object": "list",
|
45
|
-
"data": models_data,
|
46
|
-
}
|
47
|
-
return Response(response_payload, status=status.HTTP_200_OK)
|
48
|
-
|
49
|
-
except Exception as e:
|
50
|
-
logger.exception("Error retrieving available models.")
|
51
|
-
return Response(
|
52
|
-
{"error": "Failed to retrieve models list."},
|
53
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
54
|
-
)
|
24
|
+
@extend_schema(summary="List all chat messages")
|
25
|
+
def list(self, request, *args, **kwargs):
|
26
|
+
return super().list(request, *args, **kwargs)
|
55
27
|
|
28
|
+
@extend_schema(summary="Retrieve a chat message by its unique id")
|
29
|
+
def retrieve(self, request, *args, **kwargs):
|
30
|
+
return super().retrieve(request, *args, **kwargs)
|
31
|
+
|
32
|
+
@extend_schema(summary="Create a new chat message")
|
33
|
+
def create(self, request, *args, **kwargs):
|
34
|
+
return super().create(request, *args, **kwargs)
|
35
|
+
|
36
|
+
@extend_schema(summary="Update an existing chat message")
|
37
|
+
def update(self, request, *args, **kwargs):
|
38
|
+
return super().update(request, *args, **kwargs)
|
39
|
+
|
40
|
+
@extend_schema(summary="Partially update a chat message")
|
41
|
+
def partial_update(self, request, *args, **kwargs):
|
42
|
+
return super().partial_update(request, *args, **kwargs)
|
43
|
+
|
44
|
+
@extend_schema(summary="Delete a chat message by its unique id")
|
45
|
+
def destroy(self, request, *args, **kwargs):
|
46
|
+
return super().destroy(request, *args, **kwargs)
|