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
@@ -1,270 +0,0 @@
|
|
1
|
-
# DEPRECATED: This blueprint is superseded by Zeus. All logic and tests should be migrated to ZeusBlueprint. File retained for legacy reference only.
|
2
|
-
|
3
|
-
import asyncio
|
4
|
-
import time
|
5
|
-
from typing import Any
|
6
|
-
|
7
|
-
from swarm.core.blueprint_base import BlueprintBase
|
8
|
-
from swarm.core.output_utils import get_spinner_state, print_search_progress_box
|
9
|
-
|
10
|
-
|
11
|
-
class DivineCodeBlueprint(BlueprintBase):
|
12
|
-
"""
|
13
|
-
A blueprint for divine code inspiration. Demonstrates unified UX: spinner, ANSI/emoji output, and progress updates.
|
14
|
-
"""
|
15
|
-
coordinator = None # Dummy attribute for test compliance
|
16
|
-
|
17
|
-
def __init__(self, blueprint_id: str, config_path: str | None = None, **kwargs):
|
18
|
-
super().__init__(blueprint_id, config_path=config_path, **kwargs)
|
19
|
-
|
20
|
-
@staticmethod
|
21
|
-
def print_search_progress_box(*args, **kwargs):
|
22
|
-
from swarm.core.output_utils import (
|
23
|
-
print_search_progress_box as _real_print_search_progress_box,
|
24
|
-
)
|
25
|
-
return _real_print_search_progress_box(*args, **kwargs)
|
26
|
-
|
27
|
-
async def run(self, messages: list[dict[str, Any]], **kwargs: Any):
|
28
|
-
import os
|
29
|
-
op_start = time.monotonic()
|
30
|
-
instruction = messages[-1]["content"] if messages else ""
|
31
|
-
if os.environ.get('SWARM_TEST_MODE'):
|
32
|
-
instruction = messages[-1].get("content", "") if messages else ""
|
33
|
-
spinner_lines = [
|
34
|
-
"Generating.",
|
35
|
-
"Generating..",
|
36
|
-
"Generating...",
|
37
|
-
"Running..."
|
38
|
-
]
|
39
|
-
DivineCodeBlueprint.print_search_progress_box(
|
40
|
-
op_type="Divine Code Spinner",
|
41
|
-
results=[
|
42
|
-
"Divine Code Inspiration",
|
43
|
-
f"Seeking divine code for '{instruction}'",
|
44
|
-
*spinner_lines,
|
45
|
-
"Results: 2",
|
46
|
-
"Processed",
|
47
|
-
"✨"
|
48
|
-
],
|
49
|
-
params=None,
|
50
|
-
result_type="divine_code",
|
51
|
-
summary=f"Seeking divine code for: '{instruction}'",
|
52
|
-
progress_line=None,
|
53
|
-
spinner_state="Generating... Taking longer than expected",
|
54
|
-
operation_type="Divine Code Spinner",
|
55
|
-
search_mode=None,
|
56
|
-
total_lines=None,
|
57
|
-
emoji='✨',
|
58
|
-
border='╔'
|
59
|
-
)
|
60
|
-
for i, spinner_state in enumerate(spinner_lines + ["Generating... Taking longer than expected"], 1):
|
61
|
-
progress_line = f"Spinner {i}/{len(spinner_lines) + 1}"
|
62
|
-
DivineCodeBlueprint.print_search_progress_box(
|
63
|
-
op_type="Divine Code Spinner",
|
64
|
-
results=[f"Divine Code Spinner State: {spinner_state}"],
|
65
|
-
params=None,
|
66
|
-
result_type="divine_code",
|
67
|
-
summary=f"Spinner progress for: '{instruction}'",
|
68
|
-
progress_line=progress_line,
|
69
|
-
spinner_state=spinner_state,
|
70
|
-
operation_type="Divine Code Spinner",
|
71
|
-
search_mode=None,
|
72
|
-
total_lines=None,
|
73
|
-
emoji='✨',
|
74
|
-
border='╔'
|
75
|
-
)
|
76
|
-
import asyncio; await asyncio.sleep(0.01)
|
77
|
-
DivineCodeBlueprint.print_search_progress_box(
|
78
|
-
op_type="Divine Code Results",
|
79
|
-
results=[f"DivineCode agent response for: '{instruction}'", "Found 2 results.", "Processed"],
|
80
|
-
params=None,
|
81
|
-
result_type="divine_code",
|
82
|
-
summary=f"DivineCode agent response for: '{instruction}'",
|
83
|
-
progress_line="Processed",
|
84
|
-
spinner_state="Done",
|
85
|
-
operation_type="Divine Code Results",
|
86
|
-
search_mode=None,
|
87
|
-
total_lines=None,
|
88
|
-
emoji='✨',
|
89
|
-
border='╔'
|
90
|
-
)
|
91
|
-
message = f"Inspiration complete for: '{instruction}'"
|
92
|
-
yield {
|
93
|
-
"choices": [{"role": "assistant", "content": message}],
|
94
|
-
"message": {"role": "assistant", "content": message}
|
95
|
-
}
|
96
|
-
return
|
97
|
-
query = messages[-1]["content"] if messages else ""
|
98
|
-
params = {"query": query}
|
99
|
-
total_steps = 18
|
100
|
-
spinner_states = ["Generating.", "Generating..", "Generating...", "Running..."]
|
101
|
-
summary = f"Divine code inspiration for: '{query}'"
|
102
|
-
# Spinner/UX enhancement: cycle through spinner states and show 'Taking longer than expected'
|
103
|
-
for i, spinner_state in enumerate(spinner_states, 1):
|
104
|
-
progress_line = f"Step {i}/{total_steps}"
|
105
|
-
self.print_search_progress_box(
|
106
|
-
op_type="Divine Code Inspiration",
|
107
|
-
results=[f"Seeking divine code for '{query}'..."],
|
108
|
-
params=params,
|
109
|
-
result_type="inspiration",
|
110
|
-
summary=summary,
|
111
|
-
progress_line=progress_line,
|
112
|
-
spinner_state=spinner_state,
|
113
|
-
operation_type="Divine Inspiration",
|
114
|
-
search_mode=None,
|
115
|
-
total_lines=total_steps,
|
116
|
-
emoji='✨',
|
117
|
-
border='╔'
|
118
|
-
)
|
119
|
-
await asyncio.sleep(0.05)
|
120
|
-
for step in range(4, total_steps):
|
121
|
-
spinner_state = get_spinner_state(op_start)
|
122
|
-
progress_line = f"Step {step+1}/{total_steps}"
|
123
|
-
self.print_search_progress_box(
|
124
|
-
op_type="Divine Code Inspiration",
|
125
|
-
results=[f"Seeking divine code for '{query}'..."],
|
126
|
-
params=params,
|
127
|
-
result_type="inspiration",
|
128
|
-
summary=summary,
|
129
|
-
progress_line=progress_line,
|
130
|
-
spinner_state=spinner_state,
|
131
|
-
operation_type="Divine Inspiration",
|
132
|
-
search_mode=None,
|
133
|
-
total_lines=total_steps,
|
134
|
-
emoji='✨',
|
135
|
-
border='╔'
|
136
|
-
)
|
137
|
-
await asyncio.sleep(0.13)
|
138
|
-
self.print_search_progress_box(
|
139
|
-
op_type="Divine Code Inspiration",
|
140
|
-
results=[f"Seeking divine code for '{query}'...", "Taking longer than expected"],
|
141
|
-
params=params,
|
142
|
-
result_type="inspiration",
|
143
|
-
summary=summary,
|
144
|
-
progress_line=f"Step {total_steps}/{total_steps}",
|
145
|
-
spinner_state="Generating... Taking longer than expected",
|
146
|
-
operation_type="Divine Inspiration",
|
147
|
-
search_mode=None,
|
148
|
-
total_lines=total_steps,
|
149
|
-
emoji='✨',
|
150
|
-
border='╔'
|
151
|
-
)
|
152
|
-
await asyncio.sleep(0.1)
|
153
|
-
# Actually run the agent and get the LLM response
|
154
|
-
agent = self.coordinator
|
155
|
-
llm_response = ""
|
156
|
-
try:
|
157
|
-
from agents import Runner
|
158
|
-
response = await Runner.run(agent, query)
|
159
|
-
llm_response = getattr(response, 'final_output', str(response))
|
160
|
-
results = [llm_response.strip() or "(No response from LLM)"]
|
161
|
-
except Exception as e:
|
162
|
-
results = [f"[LLM ERROR] {e}"]
|
163
|
-
|
164
|
-
search_mode = kwargs.get('search_mode', 'semantic')
|
165
|
-
if search_mode in ("semantic", "code"):
|
166
|
-
op_type = "DivineCode Semantic Search" if search_mode == "semantic" else "DivineCode Code Search"
|
167
|
-
emoji = "🔎" if search_mode == "semantic" else "🧬"
|
168
|
-
summary = f"Analyzed ({search_mode}) for: '{query}'"
|
169
|
-
params = {"instruction": query}
|
170
|
-
# Simulate progressive search with line numbers and results
|
171
|
-
for i in range(1, 6):
|
172
|
-
match_count = i * 14
|
173
|
-
self.print_search_progress_box(
|
174
|
-
op_type=op_type,
|
175
|
-
results=[
|
176
|
-
f"DivineCode agent response for: '{query}'",
|
177
|
-
f"Search mode: {search_mode}",
|
178
|
-
f"Parameters: {params}",
|
179
|
-
f"Matches so far: {match_count}",
|
180
|
-
f"Line: {i*130}/650",
|
181
|
-
f"Searching {'.' * i}",
|
182
|
-
],
|
183
|
-
params=params,
|
184
|
-
result_type=search_mode,
|
185
|
-
summary=f"DivineCode {search_mode} search for: '{query}'",
|
186
|
-
progress_line=f"Processed {i*130} lines",
|
187
|
-
spinner_state=f"Generating... Taking longer than expected" if i > 3 else f"Searching {'.' * i}",
|
188
|
-
operation_type=op_type,
|
189
|
-
search_mode=search_mode,
|
190
|
-
total_lines=650,
|
191
|
-
emoji=emoji,
|
192
|
-
border='╔'
|
193
|
-
)
|
194
|
-
await asyncio.sleep(0.05)
|
195
|
-
self.print_search_progress_box(
|
196
|
-
op_type=op_type,
|
197
|
-
results=[
|
198
|
-
f"Searched for: '{query}'",
|
199
|
-
f"Search mode: {search_mode}",
|
200
|
-
f"Parameters: {params}",
|
201
|
-
f"Found 70 matches.",
|
202
|
-
f"Processed 650 lines.",
|
203
|
-
"Processed",
|
204
|
-
],
|
205
|
-
params=params,
|
206
|
-
result_type="search_results",
|
207
|
-
summary=f"DivineCode {search_mode} search complete for: '{query}'",
|
208
|
-
progress_line="Processed 650 lines",
|
209
|
-
spinner_state="Done",
|
210
|
-
operation_type=op_type,
|
211
|
-
search_mode=search_mode,
|
212
|
-
total_lines=650,
|
213
|
-
emoji=emoji,
|
214
|
-
border='╔'
|
215
|
-
)
|
216
|
-
yield {"messages": [{"role": "assistant", "content": f"{search_mode.title()} search complete. Found 70 results for '{query}'."}]}
|
217
|
-
return
|
218
|
-
self.print_search_progress_box(
|
219
|
-
op_type="DivineCode Final Results",
|
220
|
-
results=[
|
221
|
-
f"Search mode: {search_mode}",
|
222
|
-
f"Parameters: {params}",
|
223
|
-
f"Found 70 matches.",
|
224
|
-
f"Processed 650 lines.",
|
225
|
-
"Operation complete.",
|
226
|
-
],
|
227
|
-
params=params,
|
228
|
-
result_type="final_results",
|
229
|
-
summary=f"DivineCode operation complete for: '{query}'",
|
230
|
-
progress_line="Processed 650 lines",
|
231
|
-
spinner_state="Done",
|
232
|
-
operation_type="DivineCode Final Results",
|
233
|
-
search_mode=search_mode,
|
234
|
-
total_lines=650,
|
235
|
-
emoji=emoji,
|
236
|
-
border='╔'
|
237
|
-
)
|
238
|
-
# After LLM/agent run, show a creative output box with the main result
|
239
|
-
results = [llm_response]
|
240
|
-
self.print_search_progress_box(
|
241
|
-
op_type="DivineCode Creative",
|
242
|
-
results=results,
|
243
|
-
params=None,
|
244
|
-
result_type="creative",
|
245
|
-
summary=f"Creative generation complete for: '{query}'",
|
246
|
-
progress_line=None,
|
247
|
-
spinner_state=None,
|
248
|
-
operation_type="DivineCode Creative",
|
249
|
-
search_mode=None,
|
250
|
-
total_lines=None,
|
251
|
-
emoji='🧬',
|
252
|
-
border='╔'
|
253
|
-
)
|
254
|
-
yield {"messages": [{"role": "assistant", "content": results[0]}]}
|
255
|
-
return
|
256
|
-
|
257
|
-
if __name__ == "__main__":
|
258
|
-
import json
|
259
|
-
import sys
|
260
|
-
# print("\033[1;36m\n╔══════════════════════════════════════════════════════════════╗\n║ ✨ DIVINE CODE BLUEPRINT ║\n╠══════════════════════════════════════════════════════════════╣\n║ This blueprint seeks divine inspiration for your code. ║\n║ Try running: python blueprint_divine_code.py 'Find a bug!' ║\n╚══════════════════════════════════════════════════════════════╝\033[0m")
|
261
|
-
user_input = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Inspire me!"
|
262
|
-
messages = [
|
263
|
-
{"role": "user", "content": user_input}
|
264
|
-
]
|
265
|
-
blueprint = DivineCodeBlueprint(blueprint_id="demo-divine-code")
|
266
|
-
async def run_and_print():
|
267
|
-
async for response in blueprint.run(messages):
|
268
|
-
# print(json.dumps(response, indent=2))
|
269
|
-
pass
|
270
|
-
asyncio.run(run_and_print())
|
@@ -1,268 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Django Chat Blueprint
|
3
|
-
|
4
|
-
A blueprint providing a web-based chat interface with conversation history management.
|
5
|
-
HTTP-only; not intended for CLI use.
|
6
|
-
"""
|
7
|
-
|
8
|
-
import logging
|
9
|
-
import sys
|
10
|
-
import os
|
11
|
-
from typing import Dict, Any, List
|
12
|
-
from swarm.blueprints.common.operation_box_utils import display_operation_box
|
13
|
-
from swarm.core.blueprint_ux import BlueprintUXImproved
|
14
|
-
import time
|
15
|
-
|
16
|
-
# --- Logging Setup ---
|
17
|
-
def setup_logging():
|
18
|
-
import argparse
|
19
|
-
parser = argparse.ArgumentParser(add_help=False)
|
20
|
-
parser.add_argument('--debug', action='store_true', help='Enable debug logging')
|
21
|
-
args, _ = parser.parse_known_args()
|
22
|
-
loglevel = os.environ.get('LOGLEVEL', None)
|
23
|
-
if args.debug or os.environ.get('SWARM_DEBUG', '0') == '1' or (loglevel and loglevel.upper() == 'DEBUG'):
|
24
|
-
logging.basicConfig(level=logging.DEBUG)
|
25
|
-
else:
|
26
|
-
logging.basicConfig(level=logging.INFO)
|
27
|
-
return args
|
28
|
-
|
29
|
-
args = setup_logging()
|
30
|
-
|
31
|
-
logger = logging.getLogger(__name__)
|
32
|
-
|
33
|
-
# Reject CLI execution immediately
|
34
|
-
if __name__ == "__main__":
|
35
|
-
logger.info("DjangoChatBlueprint is an HTTP-only service. Access it via the web interface at /django_chat/.")
|
36
|
-
print("This blueprint is designed for HTTP use only. Please access it via the web server at /django_chat/", file=sys.stderr)
|
37
|
-
sys.stderr.flush()
|
38
|
-
sys.exit(1)
|
39
|
-
|
40
|
-
# Django imports after CLI rejection
|
41
|
-
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "swarm.settings")
|
42
|
-
import django
|
43
|
-
django.setup()
|
44
|
-
|
45
|
-
from django.shortcuts import render
|
46
|
-
from django.contrib.auth.decorators import login_required
|
47
|
-
from django.views.decorators.csrf import csrf_exempt
|
48
|
-
from django.contrib.auth.models import User
|
49
|
-
from swarm.models import ChatConversation, ChatMessage
|
50
|
-
from swarm.core.blueprint_base import BlueprintBase as Blueprint
|
51
|
-
from swarm.utils.logger_setup import setup_logger
|
52
|
-
|
53
|
-
logger = setup_logger(__name__)
|
54
|
-
|
55
|
-
# --- Spinner and ANSI/emoji operation box for unified UX (for CLI/dev runs) ---
|
56
|
-
from swarm.ux.ansi_box import ansi_box
|
57
|
-
from rich.console import Console
|
58
|
-
from rich.style import Style
|
59
|
-
from rich.text import Text
|
60
|
-
import threading
|
61
|
-
import time
|
62
|
-
|
63
|
-
class DjangoChatSpinner:
|
64
|
-
FRAMES = [
|
65
|
-
"Generating.", "Generating..", "Generating...", "Running...",
|
66
|
-
"⠋ Generating...", "⠙ Generating...", "⠹ Generating...", "⠸ Generating...",
|
67
|
-
"⠼ Generating...", "⠴ Generating...", "⠦ Generating...", "⠧ Generating...",
|
68
|
-
"⠇ Generating...", "⠏ Generating...", "🤖 Generating...", "💡 Generating...", "✨ Generating..."
|
69
|
-
]
|
70
|
-
SLOW_FRAME = "Generating... Taking longer than expected"
|
71
|
-
INTERVAL = 0.12
|
72
|
-
SLOW_THRESHOLD = 10 # seconds
|
73
|
-
|
74
|
-
def __init__(self):
|
75
|
-
self._stop_event = threading.Event()
|
76
|
-
self._thread = None
|
77
|
-
self._start_time = None
|
78
|
-
self.console = Console()
|
79
|
-
self._last_frame = None
|
80
|
-
self._last_slow = False
|
81
|
-
|
82
|
-
def start(self):
|
83
|
-
self._stop_event.clear()
|
84
|
-
self._start_time = time.time()
|
85
|
-
self._thread = threading.Thread(target=self._spin, daemon=True)
|
86
|
-
self._thread.start()
|
87
|
-
|
88
|
-
def _spin(self):
|
89
|
-
idx = 0
|
90
|
-
while not self._stop_event.is_set():
|
91
|
-
elapsed = time.time() - self._start_time
|
92
|
-
if elapsed > self.SLOW_THRESHOLD:
|
93
|
-
txt = Text(self.SLOW_FRAME, style=Style(color="yellow", bold=True))
|
94
|
-
self._last_frame = self.SLOW_FRAME
|
95
|
-
self._last_slow = True
|
96
|
-
else:
|
97
|
-
frame = self.FRAMES[idx % len(self.FRAMES)]
|
98
|
-
txt = Text(frame, style=Style(color="cyan", bold=True))
|
99
|
-
self._last_frame = frame
|
100
|
-
self._last_slow = False
|
101
|
-
self.console.print(txt, end="\r", soft_wrap=True, highlight=False)
|
102
|
-
time.sleep(self.INTERVAL)
|
103
|
-
idx += 1
|
104
|
-
self.console.print(" " * 40, end="\r") # Clear line
|
105
|
-
|
106
|
-
def stop(self, final_message="Done!"):
|
107
|
-
self._stop_event.set()
|
108
|
-
if self._thread:
|
109
|
-
self._thread.join()
|
110
|
-
self.console.print(Text(final_message, style=Style(color="green", bold=True)))
|
111
|
-
|
112
|
-
def current_spinner_state(self):
|
113
|
-
if self._last_slow:
|
114
|
-
return self.SLOW_FRAME
|
115
|
-
return self._last_frame or self.FRAMES[0]
|
116
|
-
|
117
|
-
|
118
|
-
class DjangoChatBlueprint(Blueprint):
|
119
|
-
def __init__(self, blueprint_id: str = "django_chat", config=None, config_path=None, **kwargs):
|
120
|
-
super().__init__(blueprint_id, config=config, config_path=config_path, **kwargs)
|
121
|
-
self.blueprint_id = blueprint_id
|
122
|
-
self.config_path = config_path
|
123
|
-
self._config = config if config is not None else None
|
124
|
-
self._llm_profile_name = None
|
125
|
-
self._llm_profile_data = None
|
126
|
-
self._markdown_output = None
|
127
|
-
class DummyLLM:
|
128
|
-
def chat_completion_stream(self, messages, **_):
|
129
|
-
class DummyStream:
|
130
|
-
def __aiter__(self): return self
|
131
|
-
async def __anext__(self):
|
132
|
-
raise StopAsyncIteration
|
133
|
-
return DummyStream()
|
134
|
-
self.llm = DummyLLM()
|
135
|
-
|
136
|
-
@property
|
137
|
-
def metadata(self) -> Dict[str, Any]:
|
138
|
-
logger.debug("Fetching metadata")
|
139
|
-
return {
|
140
|
-
"title": "Django Chat Interface",
|
141
|
-
"description": "A web-based chat interface with conversation history management. HTTP-only.",
|
142
|
-
"cli_name": "django_chat",
|
143
|
-
"env_vars": [],
|
144
|
-
"urls_module": "blueprints.django_chat.urls",
|
145
|
-
"url_prefix": "django_chat/"
|
146
|
-
}
|
147
|
-
|
148
|
-
def get_or_create_default_user(self):
|
149
|
-
"""Create or retrieve a default 'testuser' for development purposes."""
|
150
|
-
username = "testuser"
|
151
|
-
try:
|
152
|
-
user = User.objects.get(username=username)
|
153
|
-
except User.DoesNotExist:
|
154
|
-
user = User.objects.create_user(username=username, password="testpass")
|
155
|
-
logger.info(f"Created default user: {username}")
|
156
|
-
return user
|
157
|
-
|
158
|
-
@csrf_exempt
|
159
|
-
@login_required
|
160
|
-
def django_chat(self, request):
|
161
|
-
"""Render the django_chat UI with user-specific conversation history."""
|
162
|
-
logger.debug("Rendering django_chat web UI")
|
163
|
-
user = request.user if request.user.is_authenticated else self.get_or_create_default_user()
|
164
|
-
conversations = ChatConversation.objects.filter(student=user).order_by('-created_at')
|
165
|
-
context = {
|
166
|
-
"dark_mode": request.session.get('dark_mode', True),
|
167
|
-
"is_chatbot": False,
|
168
|
-
"conversations": conversations
|
169
|
-
}
|
170
|
-
return render(request, "django_chat/django_chat_webpage.html", context)
|
171
|
-
|
172
|
-
def render_prompt(self, template_name: str, context: dict) -> str:
|
173
|
-
return f"User request: {context.get('user_request', '')}\nHistory: {context.get('history', '')}\nAvailable tools: {', '.join(context.get('available_tools', []))}"
|
174
|
-
|
175
|
-
async def run(self, messages: List[Dict[str, str]]):
|
176
|
-
"""Main execution entry point for the DjangoChat blueprint."""
|
177
|
-
logger.info("DjangoChatBlueprint run method called.")
|
178
|
-
instruction = messages[-1].get("content", "") if messages else ""
|
179
|
-
ux = BlueprintUXImproved(style="serious")
|
180
|
-
spinner_idx = 0
|
181
|
-
start_time = time.time()
|
182
|
-
spinner_yield_interval = 1.0 # seconds
|
183
|
-
last_spinner_time = start_time
|
184
|
-
yielded_spinner = False
|
185
|
-
result_chunks = []
|
186
|
-
try:
|
187
|
-
# Simulate agent runner pattern (replace with actual agent logic if available)
|
188
|
-
prompt_context = {
|
189
|
-
"user_request": instruction,
|
190
|
-
"history": messages[:-1],
|
191
|
-
"available_tools": ["django_chat"]
|
192
|
-
}
|
193
|
-
rendered_prompt = self.render_prompt("django_chat_prompt.j2", prompt_context)
|
194
|
-
# Simulate progressive spinner for a few cycles
|
195
|
-
for _ in range(3):
|
196
|
-
now = time.time()
|
197
|
-
if now - last_spinner_time >= spinner_yield_interval:
|
198
|
-
taking_long = (now - start_time > 10)
|
199
|
-
spinner_msg = ux.spinner(spinner_idx, taking_long=taking_long)
|
200
|
-
yield {"messages": [{"role": "assistant", "content": spinner_msg}]}
|
201
|
-
spinner_idx += 1
|
202
|
-
last_spinner_time = now
|
203
|
-
yielded_spinner = True
|
204
|
-
await asyncio.sleep(0.2)
|
205
|
-
# Final result
|
206
|
-
summary = ux.summary("Operation", 1, {"instruction": instruction[:40]})
|
207
|
-
box = ux.ansi_emoji_box(
|
208
|
-
title="DjangoChat Result",
|
209
|
-
content=f"[DjangoChat LLM] Would respond to: {rendered_prompt}",
|
210
|
-
summary=summary,
|
211
|
-
params={"instruction": instruction[:40]},
|
212
|
-
result_count=1,
|
213
|
-
op_type="run",
|
214
|
-
status="success"
|
215
|
-
)
|
216
|
-
yield {"messages": [{"role": "assistant", "content": box}]}
|
217
|
-
except Exception as e:
|
218
|
-
logger.error(f"Error during DjangoChat run: {e}", exc_info=True)
|
219
|
-
yield {"messages": [{"role": "assistant", "content": f"An error occurred: {e}"}]}
|
220
|
-
|
221
|
-
def run_with_context(self, messages: List[Dict[str, str]], context_variables: dict) -> dict:
|
222
|
-
"""Minimal implementation for CLI compatibility without agents."""
|
223
|
-
logger.debug("Running with context (UI-focused implementation)")
|
224
|
-
return {
|
225
|
-
"response": {"messages": [{"role": "assistant", "content": "Django Chat UI active via web interface at /django_chat/"}]},
|
226
|
-
"context_variables": context_variables
|
227
|
-
}
|
228
|
-
|
229
|
-
if __name__ == "__main__":
|
230
|
-
import asyncio
|
231
|
-
import json
|
232
|
-
messages = [
|
233
|
-
{"role": "user", "content": "Start a chat session about Django."}
|
234
|
-
]
|
235
|
-
blueprint = DjangoChatBlueprint(blueprint_id="demo-1")
|
236
|
-
async def run_and_print():
|
237
|
-
spinner = DjangoChatSpinner()
|
238
|
-
spinner.start()
|
239
|
-
try:
|
240
|
-
all_results = []
|
241
|
-
async for response in blueprint.run(messages):
|
242
|
-
content = response["messages"][0]["content"] if (isinstance(response, dict) and "messages" in response and response["messages"]) else str(response)
|
243
|
-
all_results.append(content)
|
244
|
-
# Enhanced progressive output
|
245
|
-
if isinstance(response, dict) and (response.get("progress") or response.get("matches")):
|
246
|
-
display_operation_box(
|
247
|
-
title="Progressive Operation",
|
248
|
-
content="\n".join(response.get("matches", [])),
|
249
|
-
style="bold cyan" if response.get("type") == "code_search" else "bold magenta",
|
250
|
-
result_count=len(response.get("matches", [])) if response.get("matches") is not None else None,
|
251
|
-
params={k: v for k, v in response.items() if k not in {'matches', 'progress', 'total', 'truncated', 'done'}},
|
252
|
-
progress_line=response.get('progress'),
|
253
|
-
total_lines=response.get('total'),
|
254
|
-
spinner_state=spinner.current_spinner_state() if hasattr(spinner, 'current_spinner_state') else None,
|
255
|
-
op_type=response.get("type", "search"),
|
256
|
-
emoji="🔍" if response.get("type") == "code_search" else "🧠"
|
257
|
-
)
|
258
|
-
finally:
|
259
|
-
spinner.stop()
|
260
|
-
display_operation_box(
|
261
|
-
title="DjangoChat Output",
|
262
|
-
content="\n".join(all_results),
|
263
|
-
style="bold green",
|
264
|
-
result_count=len(all_results),
|
265
|
-
params={"prompt": messages[0]["content"]},
|
266
|
-
op_type="django_chat"
|
267
|
-
)
|
268
|
-
asyncio.run(run_and_print())
|
@@ -1,37 +0,0 @@
|
|
1
|
-
<div x-data="{ open: false, selectedModel: '', models: [] }" class="relative w-72 mx-auto mt-5">
|
2
|
-
<!-- Dropdown Trigger -->
|
3
|
-
<button
|
4
|
-
@click="open = !open"
|
5
|
-
class="w-full px-4 py-2 text-left bg-white border border-gray-300 rounded-md shadow-sm focus:ring focus:ring-blue-500"
|
6
|
-
>
|
7
|
-
<span x-text="selectedModel ? selectedModel : 'Select a Model'"></span>
|
8
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 inline float-right" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
9
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
10
|
-
</svg>
|
11
|
-
</button>
|
12
|
-
|
13
|
-
<!-- Dropdown Options -->
|
14
|
-
<div
|
15
|
-
x-show="open"
|
16
|
-
@click.outside="open = false"
|
17
|
-
class="absolute z-10 w-full mt-2 bg-white border border-gray-300 rounded-md shadow-lg max-h-60 overflow-auto"
|
18
|
-
>
|
19
|
-
<!-- Fetch models with HTMX -->
|
20
|
-
<div hx-get="/v1/models" hx-trigger="load" hx-target="#model-list" hx-swap="innerHTML">
|
21
|
-
<p class="px-4 py-2 text-gray-500">Loading models...</p>
|
22
|
-
</div>
|
23
|
-
|
24
|
-
<!-- Render Models -->
|
25
|
-
<div id="model-list">
|
26
|
-
<template x-for="model in models" :key="model.id">
|
27
|
-
<div
|
28
|
-
@click="selectedModel = model.name; open = false"
|
29
|
-
class="px-4 py-2 cursor-pointer hover:bg-blue-100"
|
30
|
-
>
|
31
|
-
<p class="text-sm font-medium" x-text="model.name"></p>
|
32
|
-
<p class="text-xs text-gray-500" x-text="model.description"></p>
|
33
|
-
</div>
|
34
|
-
</template>
|
35
|
-
</div>
|
36
|
-
</div>
|
37
|
-
</div>
|
@@ -1,32 +0,0 @@
|
|
1
|
-
from django.shortcuts import render
|
2
|
-
from django.contrib.auth.decorators import login_required
|
3
|
-
from django.views.decorators.csrf import csrf_exempt
|
4
|
-
from django.contrib.auth.models import User
|
5
|
-
from swarm.models import ChatConversation, ChatMessage
|
6
|
-
from swarm.utils.logger_setup import setup_logger
|
7
|
-
|
8
|
-
logger = setup_logger(__name__)
|
9
|
-
|
10
|
-
def get_or_create_default_user():
|
11
|
-
"""Create or retrieve a default 'testuser' for development purposes."""
|
12
|
-
username = "testuser"
|
13
|
-
try:
|
14
|
-
user = User.objects.get(username=username)
|
15
|
-
except User.DoesNotExist:
|
16
|
-
user = User.objects.create_user(username=username, password="testpass")
|
17
|
-
logger.info(f"Created default user: {username}")
|
18
|
-
return user
|
19
|
-
|
20
|
-
@csrf_exempt
|
21
|
-
@login_required
|
22
|
-
def django_chat(request):
|
23
|
-
"""Render the django_chat UI with user-specific conversation history."""
|
24
|
-
logger.debug("Rendering django_chat web UI")
|
25
|
-
user = request.user if request.user.is_authenticated else get_or_create_default_user()
|
26
|
-
conversations = ChatConversation.objects.filter(student=user).order_by('-created_at')
|
27
|
-
context = {
|
28
|
-
"dark_mode": request.session.get('dark_mode', True),
|
29
|
-
"is_chatbot": False,
|
30
|
-
"conversations": conversations
|
31
|
-
}
|
32
|
-
return render(request, "django_chat/django_chat_webpage.html", context)
|