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,298 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import os
|
3
|
-
import sys
|
4
|
-
import shlex
|
5
|
-
from typing import Dict, Any, List, ClassVar, Optional
|
6
|
-
import time
|
7
|
-
|
8
|
-
# Ensure src is in path for BlueprintBase import
|
9
|
-
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
10
|
-
src_path = os.path.join(project_root, 'src')
|
11
|
-
if src_path not in sys.path: sys.path.insert(0, src_path)
|
12
|
-
|
13
|
-
try:
|
14
|
-
from agents import Agent, Tool, function_tool, Runner
|
15
|
-
from agents.mcp import MCPServer
|
16
|
-
from agents.models.interface import Model
|
17
|
-
from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel
|
18
|
-
from openai import AsyncOpenAI
|
19
|
-
from swarm.core.blueprint_base import BlueprintBase
|
20
|
-
from swarm.core.blueprint_ux import BlueprintUXImproved
|
21
|
-
except ImportError as e:
|
22
|
-
print(f"ERROR: Import failed in OmniplexBlueprint: {e}. Check dependencies.")
|
23
|
-
print(f"sys.path: {sys.path}")
|
24
|
-
sys.exit(1)
|
25
|
-
|
26
|
-
logger = logging.getLogger(__name__)
|
27
|
-
|
28
|
-
# --- Agent Instructions ---
|
29
|
-
|
30
|
-
amazo_instructions = """
|
31
|
-
You are Amazo, master of 'npx'-based MCP tools.
|
32
|
-
Receive task instructions from the Coordinator.
|
33
|
-
Identify the BEST available 'npx' MCP tool from your assigned list to accomplish the task.
|
34
|
-
Execute the chosen MCP tool with the necessary parameters provided by the Coordinator.
|
35
|
-
Report the results clearly back to the Coordinator.
|
36
|
-
"""
|
37
|
-
|
38
|
-
rogue_instructions = """
|
39
|
-
You are Rogue, master of 'uvx'-based MCP tools.
|
40
|
-
Receive task instructions from the Coordinator.
|
41
|
-
Identify the BEST available 'uvx' MCP tool from your assigned list.
|
42
|
-
Execute the chosen MCP tool with parameters from the Coordinator.
|
43
|
-
Report the results clearly back to the Coordinator.
|
44
|
-
"""
|
45
|
-
|
46
|
-
sylar_instructions = """
|
47
|
-
You are Sylar, master of miscellaneous MCP tools (non-npx, non-uvx).
|
48
|
-
Receive task instructions from the Coordinator.
|
49
|
-
Identify the BEST available MCP tool from your assigned list.
|
50
|
-
Execute the chosen MCP tool with parameters from the Coordinator.
|
51
|
-
Report the results clearly back to the Coordinator.
|
52
|
-
"""
|
53
|
-
|
54
|
-
coordinator_instructions = """
|
55
|
-
You are the Omniplex Coordinator. Your role is to understand the user request and delegate it to the agent best suited based on the required MCP tool's execution type (npx, uvx, or other).
|
56
|
-
Team & Tool Categories:
|
57
|
-
- Amazo (Agent Tool `Amazo`): Handles tasks requiring `npx`-based MCP servers (e.g., @modelcontextprotocol/*, mcp-shell, mcp-flowise). Pass the specific tool name and parameters needed.
|
58
|
-
- Rogue (Agent Tool `Rogue`): Handles tasks requiring `uvx`-based MCP servers (if any configured). Pass the specific tool name and parameters needed.
|
59
|
-
- Sylar (Agent Tool `Sylar`): Handles tasks requiring other/miscellaneous MCP servers (e.g., direct python scripts, other executables). Pass the specific tool name and parameters needed.
|
60
|
-
Analyze the user's request, determine if an `npx`, `uvx`, or `other` tool is likely needed, and delegate using the corresponding agent tool (`Amazo`, `Rogue`, or `Sylar`). Provide the *full context* of the user request to the chosen agent. Synthesize the final response based on the specialist agent's report.
|
61
|
-
"""
|
62
|
-
|
63
|
-
# --- Define the Blueprint ---
|
64
|
-
class OmniplexBlueprint(BlueprintBase):
|
65
|
-
"""Dynamically routes tasks to agents based on the execution type (npx, uvx, other) of the required MCP server."""
|
66
|
-
metadata: ClassVar[Dict[str, Any]] = {
|
67
|
-
"name": "OmniplexBlueprint",
|
68
|
-
"title": "Omniplex MCP Orchestrator",
|
69
|
-
"description": "Dynamically delegates tasks to agents (Amazo:npx, Rogue:uvx, Sylar:other) based on the command type of available MCP servers.",
|
70
|
-
"version": "1.1.0", # Refactored version
|
71
|
-
"author": "Open Swarm Team (Refactored)",
|
72
|
-
"tags": ["orchestration", "mcp", "dynamic", "multi-agent"],
|
73
|
-
# List common servers - BlueprintBase will try to start them if defined in config.
|
74
|
-
# The blueprint logic will then assign the *started* ones.
|
75
|
-
"required_mcp_servers": [
|
76
|
-
"memory", "filesystem", "mcp-shell", "brave-search", "sqlite",
|
77
|
-
"mcp-flowise", "sequential-thinking", # Add other common ones if needed
|
78
|
-
],
|
79
|
-
"env_vars": ["ALLOWED_PATH", "BRAVE_API_KEY", "SQLITE_DB_PATH", "FLOWISE_API_KEY"], # Informational
|
80
|
-
}
|
81
|
-
|
82
|
-
# Caches
|
83
|
-
_openai_client_cache: Dict[str, AsyncOpenAI] = {}
|
84
|
-
_model_instance_cache: Dict[str, Model] = {}
|
85
|
-
|
86
|
-
def __init__(self, blueprint_id: str = "omniplex", config=None, config_path=None, **kwargs):
|
87
|
-
super().__init__(blueprint_id=blueprint_id, config=config, config_path=config_path, **kwargs)
|
88
|
-
self.blueprint_id = blueprint_id
|
89
|
-
self.config_path = config_path
|
90
|
-
self._config = config if config is not None else None
|
91
|
-
self._llm_profile_name = None
|
92
|
-
self._llm_profile_data = None
|
93
|
-
self._markdown_output = None
|
94
|
-
# Add other attributes as needed for Omniplex
|
95
|
-
# ...
|
96
|
-
|
97
|
-
def _get_model_instance(self, profile_name: str) -> Model:
|
98
|
-
"""Retrieves or creates an LLM Model instance."""
|
99
|
-
# ... (Implementation is the same as in previous refactors) ...
|
100
|
-
if profile_name in self._model_instance_cache:
|
101
|
-
logger.debug(f"Using cached Model instance for profile '{profile_name}'.")
|
102
|
-
return self._model_instance_cache[profile_name]
|
103
|
-
logger.debug(f"Creating new Model instance for profile '{profile_name}'.")
|
104
|
-
profile_data = self.get_llm_profile(profile_name)
|
105
|
-
if not profile_data:
|
106
|
-
logger.critical(f"LLM profile '{profile_name}' (or 'default') not found.")
|
107
|
-
raise ValueError(f"Missing LLM profile configuration for '{profile_name}' or 'default'.")
|
108
|
-
provider = profile_data.get("provider", "openai").lower()
|
109
|
-
model_name = profile_data.get("model")
|
110
|
-
if not model_name:
|
111
|
-
logger.critical(f"LLM profile '{profile_name}' missing 'model' key.")
|
112
|
-
raise ValueError(f"Missing 'model' key in LLM profile '{profile_name}'.")
|
113
|
-
if provider != "openai":
|
114
|
-
logger.error(f"Unsupported LLM provider '{provider}'.")
|
115
|
-
raise ValueError(f"Unsupported LLM provider: {provider}")
|
116
|
-
client_cache_key = f"{provider}_{profile_data.get('base_url')}"
|
117
|
-
if client_cache_key not in self._openai_client_cache:
|
118
|
-
client_kwargs = { "api_key": profile_data.get("api_key"), "base_url": profile_data.get("base_url") }
|
119
|
-
filtered_kwargs = {k: v for k, v in client_kwargs.items() if v is not None}
|
120
|
-
log_kwargs = {k:v for k,v in filtered_kwargs.items() if k != 'api_key'}
|
121
|
-
logger.debug(f"Creating new AsyncOpenAI client for '{profile_name}': {log_kwargs}")
|
122
|
-
try: self._openai_client_cache[client_cache_key] = AsyncOpenAI(**filtered_kwargs)
|
123
|
-
except Exception as e: raise ValueError(f"Failed to init OpenAI client: {e}") from e
|
124
|
-
client = self._openai_client_cache[client_cache_key]
|
125
|
-
logger.debug(f"Instantiating OpenAIChatCompletionsModel(model='{model_name}') for '{profile_name}'.")
|
126
|
-
try:
|
127
|
-
model_instance = OpenAIChatCompletionsModel(model=model_name, openai_client=client)
|
128
|
-
self._model_instance_cache[profile_name] = model_instance
|
129
|
-
return model_instance
|
130
|
-
except Exception as e: raise ValueError(f"Failed to init LLM provider: {e}") from e
|
131
|
-
|
132
|
-
def render_prompt(self, template_name: str, context: dict) -> str:
|
133
|
-
return f"User request: {context.get('user_request', '')}\nHistory: {context.get('history', '')}\nAvailable tools: {', '.join(context.get('available_tools', []))}"
|
134
|
-
|
135
|
-
# --- Agent Creation ---
|
136
|
-
def create_starting_agent(self, mcp_servers: List[MCPServer]) -> Agent:
|
137
|
-
"""Creates the Omniplex agent team based on available started MCP servers."""
|
138
|
-
logger.debug("Dynamically creating agents for OmniplexBlueprint...")
|
139
|
-
self._model_instance_cache = {}
|
140
|
-
self._openai_client_cache = {}
|
141
|
-
|
142
|
-
default_profile_name = self.config.get("llm_profile", "default")
|
143
|
-
logger.debug(f"Using LLM profile '{default_profile_name}' for Omniplex agents.")
|
144
|
-
model_instance = self._get_model_instance(default_profile_name)
|
145
|
-
|
146
|
-
# Categorize the *started* MCP servers passed to this method
|
147
|
-
npx_started_servers: List[MCPServer] = []
|
148
|
-
uvx_started_servers: List[MCPServer] = [] # Assuming 'uvx' might be a command name
|
149
|
-
other_started_servers: List[MCPServer] = []
|
150
|
-
|
151
|
-
for server in mcp_servers:
|
152
|
-
server_config = self.mcp_server_configs.get(server.name, {})
|
153
|
-
command_def = server_config.get("command", "")
|
154
|
-
command_name = ""
|
155
|
-
if isinstance(command_def, list) and command_def:
|
156
|
-
command_name = os.path.basename(command_def[0]).lower()
|
157
|
-
elif isinstance(command_def, str):
|
158
|
-
# Simple case: command is just the executable name
|
159
|
-
command_name = os.path.basename(shlex.split(command_def)[0]).lower() if command_def else ""
|
160
|
-
|
161
|
-
|
162
|
-
if "npx" in command_name:
|
163
|
-
npx_started_servers.append(server)
|
164
|
-
elif "uvx" in command_name: # Placeholder for uvx logic
|
165
|
-
uvx_started_servers.append(server)
|
166
|
-
else:
|
167
|
-
other_started_servers.append(server)
|
168
|
-
|
169
|
-
logger.debug(f"Categorized MCPs - NPX: {[s.name for s in npx_started_servers]}, UVX: {[s.name for s in uvx_started_servers]}, Other: {[s.name for s in other_started_servers]}")
|
170
|
-
|
171
|
-
# Create agents for each category *only if* they have servers assigned
|
172
|
-
amazo_agent = rogue_agent = sylar_agent = None
|
173
|
-
team_tools: List[Tool] = []
|
174
|
-
|
175
|
-
if npx_started_servers:
|
176
|
-
logger.info(f"Creating Amazo for npx servers: {[s.name for s in npx_started_servers]}")
|
177
|
-
amazo_agent = Agent(
|
178
|
-
name="Amazo",
|
179
|
-
model=model_instance,
|
180
|
-
instructions=amazo_instructions,
|
181
|
-
tools=[], # Uses MCPs
|
182
|
-
mcp_servers=npx_started_servers
|
183
|
-
)
|
184
|
-
team_tools.append(amazo_agent.as_tool(
|
185
|
-
tool_name="Amazo",
|
186
|
-
tool_description=f"Delegate tasks requiring npx-based MCP servers (e.g., {', '.join(s.name for s in npx_started_servers)})."
|
187
|
-
))
|
188
|
-
else:
|
189
|
-
logger.info("No started npx servers found for Amazo.")
|
190
|
-
|
191
|
-
if uvx_started_servers:
|
192
|
-
logger.info(f"Creating Rogue for uvx servers: {[s.name for s in uvx_started_servers]}")
|
193
|
-
rogue_agent = Agent(
|
194
|
-
name="Rogue",
|
195
|
-
model=model_instance,
|
196
|
-
instructions=rogue_instructions,
|
197
|
-
tools=[], # Uses MCPs
|
198
|
-
mcp_servers=uvx_started_servers
|
199
|
-
)
|
200
|
-
team_tools.append(rogue_agent.as_tool(
|
201
|
-
tool_name="Rogue",
|
202
|
-
tool_description=f"Delegate tasks requiring uvx-based MCP servers (e.g., {', '.join(s.name for s in uvx_started_servers)})."
|
203
|
-
))
|
204
|
-
else:
|
205
|
-
logger.info("No started uvx servers found for Rogue.")
|
206
|
-
|
207
|
-
if other_started_servers:
|
208
|
-
logger.info(f"Creating Sylar for other servers: {[s.name for s in other_started_servers]}")
|
209
|
-
sylar_agent = Agent(
|
210
|
-
name="Sylar",
|
211
|
-
model=model_instance,
|
212
|
-
instructions=sylar_instructions,
|
213
|
-
tools=[], # Uses MCPs
|
214
|
-
mcp_servers=other_started_servers
|
215
|
-
)
|
216
|
-
team_tools.append(sylar_agent.as_tool(
|
217
|
-
tool_name="Sylar",
|
218
|
-
tool_description=f"Delegate tasks requiring miscellaneous MCP servers (e.g., {', '.join(s.name for s in other_started_servers)})."
|
219
|
-
))
|
220
|
-
else:
|
221
|
-
logger.info("No other started servers found for Sylar.")
|
222
|
-
|
223
|
-
# Create Coordinator and pass the tools for the agents that were created
|
224
|
-
coordinator_agent = Agent(
|
225
|
-
name="OmniplexCoordinator",
|
226
|
-
model=model_instance,
|
227
|
-
instructions=coordinator_instructions,
|
228
|
-
tools=team_tools,
|
229
|
-
mcp_servers=[] # Coordinator likely doesn't use MCPs directly
|
230
|
-
)
|
231
|
-
|
232
|
-
logger.info(f"Omniplex Coordinator created with tools for: {[t.name for t in team_tools]}")
|
233
|
-
return coordinator_agent
|
234
|
-
|
235
|
-
async def run(self, messages: List[Dict[str, Any]], **kwargs):
|
236
|
-
"""Main execution entry point for the Omniplex blueprint."""
|
237
|
-
logger.info("OmniplexBlueprint run method called.")
|
238
|
-
instruction = messages[-1].get("content", "") if messages else ""
|
239
|
-
from agents import Runner
|
240
|
-
ux = BlueprintUXImproved(style="serious")
|
241
|
-
spinner_idx = 0
|
242
|
-
start_time = time.time()
|
243
|
-
spinner_yield_interval = 1.0 # seconds
|
244
|
-
last_spinner_time = start_time
|
245
|
-
yielded_spinner = False
|
246
|
-
result_chunks = []
|
247
|
-
try:
|
248
|
-
runner_gen = Runner.run(self.create_starting_agent([]), instruction)
|
249
|
-
while True:
|
250
|
-
now = time.time()
|
251
|
-
try:
|
252
|
-
chunk = next(runner_gen)
|
253
|
-
result_chunks.append(chunk)
|
254
|
-
# If chunk is a final result, wrap and yield
|
255
|
-
if chunk and isinstance(chunk, dict) and "messages" in chunk:
|
256
|
-
content = chunk["messages"][0]["content"] if chunk["messages"] else ""
|
257
|
-
summary = ux.summary("Operation", len(result_chunks), {"instruction": instruction[:40]})
|
258
|
-
box = ux.ansi_emoji_box(
|
259
|
-
title="Omniplex Result",
|
260
|
-
content=content,
|
261
|
-
summary=summary,
|
262
|
-
params={"instruction": instruction[:40]},
|
263
|
-
result_count=len(result_chunks),
|
264
|
-
op_type="run",
|
265
|
-
status="success"
|
266
|
-
)
|
267
|
-
yield {"messages": [{"role": "assistant", "content": box}]}
|
268
|
-
else:
|
269
|
-
yield chunk
|
270
|
-
yielded_spinner = False
|
271
|
-
except StopIteration:
|
272
|
-
break
|
273
|
-
except Exception:
|
274
|
-
if now - last_spinner_time >= spinner_yield_interval:
|
275
|
-
taking_long = (now - start_time > 10)
|
276
|
-
spinner_msg = ux.spinner(spinner_idx, taking_long=taking_long)
|
277
|
-
yield {"messages": [{"role": "assistant", "content": spinner_msg}]}
|
278
|
-
spinner_idx += 1
|
279
|
-
last_spinner_time = now
|
280
|
-
yielded_spinner = True
|
281
|
-
if not result_chunks and not yielded_spinner:
|
282
|
-
yield {"messages": [{"role": "assistant", "content": ux.spinner(0)}]}
|
283
|
-
except Exception as e:
|
284
|
-
logger.error(f"Error during Omniplex run: {e}", exc_info=True)
|
285
|
-
yield {"messages": [{"role": "assistant", "content": f"An error occurred: {e}"}]}
|
286
|
-
|
287
|
-
# Standard Python entry point
|
288
|
-
if __name__ == "__main__":
|
289
|
-
import asyncio
|
290
|
-
import json
|
291
|
-
messages = [
|
292
|
-
{"role": "user", "content": "Show me everything."}
|
293
|
-
]
|
294
|
-
blueprint = OmniplexBlueprint(blueprint_id="demo-1")
|
295
|
-
async def run_and_print():
|
296
|
-
async for response in blueprint.run(messages):
|
297
|
-
print(json.dumps(response, indent=2))
|
298
|
-
asyncio.run(run_and_print())
|