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.
Files changed (307) hide show
  1. open_swarm-0.1.1748636295.dist-info/METADATA +257 -0
  2. open_swarm-0.1.1748636295.dist-info/RECORD +89 -0
  3. {open_swarm-0.1.1745275181.dist-info → open_swarm-0.1.1748636295.dist-info}/WHEEL +2 -1
  4. open_swarm-0.1.1748636295.dist-info/entry_points.txt +3 -0
  5. open_swarm-0.1.1748636295.dist-info/top_level.txt +1 -0
  6. swarm/__init__.py +2 -0
  7. swarm/agent/agent.py +49 -0
  8. swarm/auth.py +48 -113
  9. swarm/consumers.py +0 -19
  10. swarm/core.py +411 -0
  11. swarm/extensions/blueprint/__init__.py +16 -30
  12. swarm/extensions/blueprint/agent_utils.py +45 -0
  13. swarm/extensions/blueprint/blueprint_base.py +562 -0
  14. swarm/extensions/blueprint/blueprint_discovery.py +112 -0
  15. swarm/extensions/blueprint/django_utils.py +79 -181
  16. swarm/extensions/blueprint/interactive_mode.py +72 -67
  17. swarm/extensions/blueprint/output_utils.py +82 -0
  18. swarm/{core → extensions/blueprint}/spinner.py +21 -30
  19. swarm/extensions/cli/cli_args.py +0 -6
  20. swarm/extensions/cli/commands/blueprint_management.py +9 -47
  21. swarm/extensions/cli/commands/config_management.py +6 -5
  22. swarm/extensions/cli/commands/edit_config.py +7 -16
  23. swarm/extensions/cli/commands/list_blueprints.py +1 -1
  24. swarm/extensions/cli/commands/validate_env.py +4 -11
  25. swarm/extensions/cli/commands/validate_envvars.py +6 -6
  26. swarm/extensions/cli/interactive_shell.py +2 -16
  27. swarm/extensions/config/config_loader.py +345 -107
  28. swarm/{core → extensions/config}/config_manager.py +38 -50
  29. swarm/{core → extensions/config}/server_config.py +0 -32
  30. swarm/extensions/launchers/build_launchers.py +14 -0
  31. swarm/{core → extensions/launchers}/build_swarm_wrapper.py +0 -0
  32. swarm/extensions/launchers/swarm_api.py +64 -8
  33. swarm/extensions/launchers/swarm_cli.py +300 -8
  34. swarm/extensions/mcp/__init__.py +1 -0
  35. swarm/extensions/mcp/cache_utils.py +32 -0
  36. swarm/extensions/mcp/mcp_client.py +233 -0
  37. swarm/extensions/mcp/mcp_tool_provider.py +135 -0
  38. swarm/extensions/mcp/mcp_utils.py +260 -0
  39. swarm/llm/chat_completion.py +166 -0
  40. swarm/serializers.py +5 -96
  41. swarm/settings.py +133 -85
  42. swarm/types.py +91 -0
  43. swarm/urls.py +74 -57
  44. swarm/utils/context_utils.py +4 -10
  45. swarm/utils/general_utils.py +0 -21
  46. swarm/utils/redact.py +36 -23
  47. swarm/views/api_views.py +39 -48
  48. swarm/views/chat_views.py +76 -236
  49. swarm/views/core_views.py +87 -80
  50. swarm/views/model_views.py +121 -64
  51. swarm/views/utils.py +439 -65
  52. swarm/views/web_views.py +2 -2
  53. open_swarm-0.1.1745275181.dist-info/METADATA +0 -874
  54. open_swarm-0.1.1745275181.dist-info/RECORD +0 -319
  55. open_swarm-0.1.1745275181.dist-info/entry_points.txt +0 -4
  56. swarm/blueprints/README.md +0 -68
  57. swarm/blueprints/blueprint_audit_status.json +0 -27
  58. swarm/blueprints/chatbot/README.md +0 -40
  59. swarm/blueprints/chatbot/blueprint_chatbot.py +0 -471
  60. swarm/blueprints/chatbot/metadata.json +0 -23
  61. swarm/blueprints/chatbot/templates/chatbot/chatbot.html +0 -33
  62. swarm/blueprints/chucks_angels/README.md +0 -11
  63. swarm/blueprints/chucks_angels/blueprint_chucks_angels.py +0 -7
  64. swarm/blueprints/chucks_angels/test_basic.py +0 -3
  65. swarm/blueprints/codey/CODEY.md +0 -15
  66. swarm/blueprints/codey/README.md +0 -115
  67. swarm/blueprints/codey/blueprint_codey.py +0 -1072
  68. swarm/blueprints/codey/codey_cli.py +0 -373
  69. swarm/blueprints/codey/instructions.md +0 -17
  70. swarm/blueprints/codey/metadata.json +0 -23
  71. swarm/blueprints/common/operation_box_utils.py +0 -83
  72. swarm/blueprints/digitalbutlers/README.md +0 -11
  73. swarm/blueprints/digitalbutlers/__init__.py +0 -1
  74. swarm/blueprints/digitalbutlers/blueprint_digitalbutlers.py +0 -7
  75. swarm/blueprints/digitalbutlers/test_basic.py +0 -3
  76. swarm/blueprints/divine_code/README.md +0 -3
  77. swarm/blueprints/divine_code/__init__.py +0 -10
  78. swarm/blueprints/divine_code/apps.py +0 -11
  79. swarm/blueprints/divine_code/blueprint_divine_code.py +0 -270
  80. swarm/blueprints/django_chat/apps.py +0 -6
  81. swarm/blueprints/django_chat/blueprint_django_chat.py +0 -268
  82. swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html +0 -37
  83. swarm/blueprints/django_chat/urls.py +0 -8
  84. swarm/blueprints/django_chat/views.py +0 -32
  85. swarm/blueprints/echocraft/blueprint_echocraft.py +0 -384
  86. swarm/blueprints/flock/README.md +0 -11
  87. swarm/blueprints/flock/__init__.py +0 -8
  88. swarm/blueprints/flock/blueprint_flock.py +0 -7
  89. swarm/blueprints/flock/test_basic.py +0 -3
  90. swarm/blueprints/geese/README.md +0 -10
  91. swarm/blueprints/geese/__init__.py +0 -8
  92. swarm/blueprints/geese/blueprint_geese.py +0 -384
  93. swarm/blueprints/geese/geese_cli.py +0 -102
  94. swarm/blueprints/jeeves/README.md +0 -41
  95. swarm/blueprints/jeeves/blueprint_jeeves.py +0 -722
  96. swarm/blueprints/jeeves/jeeves_cli.py +0 -55
  97. swarm/blueprints/jeeves/metadata.json +0 -24
  98. swarm/blueprints/mcp_demo/blueprint_mcp_demo.py +0 -473
  99. swarm/blueprints/messenger/templates/messenger/messenger.html +0 -46
  100. swarm/blueprints/mission_improbable/blueprint_mission_improbable.py +0 -423
  101. swarm/blueprints/monkai_magic/blueprint_monkai_magic.py +0 -340
  102. swarm/blueprints/nebula_shellz/blueprint_nebula_shellz.py +0 -265
  103. swarm/blueprints/omniplex/blueprint_omniplex.py +0 -298
  104. swarm/blueprints/poets/blueprint_poets.py +0 -546
  105. swarm/blueprints/poets/poets_cli.py +0 -23
  106. swarm/blueprints/rue_code/README.md +0 -8
  107. swarm/blueprints/rue_code/blueprint_rue_code.py +0 -448
  108. swarm/blueprints/rue_code/rue_code_cli.py +0 -43
  109. swarm/blueprints/stewie/apps.py +0 -12
  110. swarm/blueprints/stewie/blueprint_family_ties.py +0 -349
  111. swarm/blueprints/stewie/models.py +0 -19
  112. swarm/blueprints/stewie/serializers.py +0 -10
  113. swarm/blueprints/stewie/settings.py +0 -17
  114. swarm/blueprints/stewie/urls.py +0 -11
  115. swarm/blueprints/stewie/views.py +0 -26
  116. swarm/blueprints/suggestion/blueprint_suggestion.py +0 -222
  117. swarm/blueprints/whinge_surf/README.md +0 -22
  118. swarm/blueprints/whinge_surf/__init__.py +0 -1
  119. swarm/blueprints/whinge_surf/blueprint_whinge_surf.py +0 -565
  120. swarm/blueprints/whinge_surf/whinge_surf_cli.py +0 -99
  121. swarm/blueprints/whiskeytango_foxtrot/__init__.py +0 -0
  122. swarm/blueprints/whiskeytango_foxtrot/apps.py +0 -11
  123. swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py +0 -339
  124. swarm/blueprints/zeus/__init__.py +0 -2
  125. swarm/blueprints/zeus/apps.py +0 -4
  126. swarm/blueprints/zeus/blueprint_zeus.py +0 -270
  127. swarm/blueprints/zeus/zeus_cli.py +0 -13
  128. swarm/cli/async_input.py +0 -65
  129. swarm/cli/async_input_demo.py +0 -32
  130. swarm/core/agent_utils.py +0 -21
  131. swarm/core/blueprint_base.py +0 -769
  132. swarm/core/blueprint_discovery.py +0 -125
  133. swarm/core/blueprint_runner.py +0 -59
  134. swarm/core/blueprint_ux.py +0 -109
  135. swarm/core/build_launchers.py +0 -15
  136. swarm/core/cli/__init__.py +0 -1
  137. swarm/core/cli/commands/__init__.py +0 -1
  138. swarm/core/cli/commands/blueprint_management.py +0 -7
  139. swarm/core/cli/interactive_shell.py +0 -14
  140. swarm/core/cli/main.py +0 -50
  141. swarm/core/cli/utils/__init__.py +0 -1
  142. swarm/core/cli/utils/discover_commands.py +0 -18
  143. swarm/core/config_loader.py +0 -122
  144. swarm/core/output_utils.py +0 -193
  145. swarm/core/session_logger.py +0 -42
  146. swarm/core/slash_commands.py +0 -89
  147. swarm/core/swarm_api.py +0 -68
  148. swarm/core/swarm_cli.py +0 -216
  149. swarm/core/utils/__init__.py +0 -0
  150. swarm/extensions/blueprint/cli_handler.py +0 -197
  151. swarm/extensions/blueprint/runnable_blueprint.py +0 -42
  152. swarm/extensions/cli/utils/__init__.py +0 -1
  153. swarm/extensions/cli/utils/async_input.py +0 -46
  154. swarm/extensions/cli/utils/prompt_user.py +0 -3
  155. swarm/management/__init__.py +0 -0
  156. swarm/management/commands/__init__.py +0 -0
  157. swarm/management/commands/runserver.py +0 -58
  158. swarm/middleware.py +0 -65
  159. swarm/permissions.py +0 -38
  160. swarm/static/contrib/fonts/fontawesome-webfont.ttf +0 -7
  161. swarm/static/contrib/fonts/fontawesome-webfont.woff +0 -7
  162. swarm/static/contrib/fonts/fontawesome-webfont.woff2 +0 -7
  163. swarm/static/contrib/markedjs/marked.min.js +0 -6
  164. swarm/static/contrib/tabler-icons/adjustments-horizontal.svg +0 -27
  165. swarm/static/contrib/tabler-icons/alert-triangle.svg +0 -21
  166. swarm/static/contrib/tabler-icons/archive.svg +0 -21
  167. swarm/static/contrib/tabler-icons/artboard.svg +0 -27
  168. swarm/static/contrib/tabler-icons/automatic-gearbox.svg +0 -23
  169. swarm/static/contrib/tabler-icons/box-multiple.svg +0 -19
  170. swarm/static/contrib/tabler-icons/carambola.svg +0 -19
  171. swarm/static/contrib/tabler-icons/copy.svg +0 -20
  172. swarm/static/contrib/tabler-icons/download.svg +0 -21
  173. swarm/static/contrib/tabler-icons/edit.svg +0 -21
  174. swarm/static/contrib/tabler-icons/filled/carambola.svg +0 -13
  175. swarm/static/contrib/tabler-icons/filled/paint.svg +0 -13
  176. swarm/static/contrib/tabler-icons/headset.svg +0 -22
  177. swarm/static/contrib/tabler-icons/layout-sidebar-left-collapse.svg +0 -21
  178. swarm/static/contrib/tabler-icons/layout-sidebar-left-expand.svg +0 -21
  179. swarm/static/contrib/tabler-icons/layout-sidebar-right-collapse.svg +0 -21
  180. swarm/static/contrib/tabler-icons/layout-sidebar-right-expand.svg +0 -21
  181. swarm/static/contrib/tabler-icons/message-chatbot.svg +0 -22
  182. swarm/static/contrib/tabler-icons/message-star.svg +0 -22
  183. swarm/static/contrib/tabler-icons/message-x.svg +0 -23
  184. swarm/static/contrib/tabler-icons/message.svg +0 -21
  185. swarm/static/contrib/tabler-icons/paperclip.svg +0 -18
  186. swarm/static/contrib/tabler-icons/playlist-add.svg +0 -22
  187. swarm/static/contrib/tabler-icons/robot.svg +0 -26
  188. swarm/static/contrib/tabler-icons/search.svg +0 -19
  189. swarm/static/contrib/tabler-icons/settings.svg +0 -20
  190. swarm/static/contrib/tabler-icons/thumb-down.svg +0 -19
  191. swarm/static/contrib/tabler-icons/thumb-up.svg +0 -19
  192. swarm/static/css/dropdown.css +0 -22
  193. swarm/static/htmx/htmx.min.js +0 -0
  194. swarm/static/js/dropdown.js +0 -23
  195. swarm/static/rest_mode/css/base.css +0 -470
  196. swarm/static/rest_mode/css/chat-history.css +0 -286
  197. swarm/static/rest_mode/css/chat.css +0 -251
  198. swarm/static/rest_mode/css/chatbot.css +0 -74
  199. swarm/static/rest_mode/css/chatgpt.css +0 -62
  200. swarm/static/rest_mode/css/colors/corporate.css +0 -74
  201. swarm/static/rest_mode/css/colors/pastel.css +0 -81
  202. swarm/static/rest_mode/css/colors/tropical.css +0 -82
  203. swarm/static/rest_mode/css/general.css +0 -142
  204. swarm/static/rest_mode/css/layout.css +0 -167
  205. swarm/static/rest_mode/css/layouts/messenger-layout.css +0 -17
  206. swarm/static/rest_mode/css/layouts/minimalist-layout.css +0 -57
  207. swarm/static/rest_mode/css/layouts/mobile-layout.css +0 -8
  208. swarm/static/rest_mode/css/messages.css +0 -84
  209. swarm/static/rest_mode/css/messenger.css +0 -135
  210. swarm/static/rest_mode/css/settings.css +0 -91
  211. swarm/static/rest_mode/css/simple.css +0 -44
  212. swarm/static/rest_mode/css/slack.css +0 -58
  213. swarm/static/rest_mode/css/style.css +0 -156
  214. swarm/static/rest_mode/css/theme.css +0 -30
  215. swarm/static/rest_mode/css/toast.css +0 -40
  216. swarm/static/rest_mode/js/auth.js +0 -9
  217. swarm/static/rest_mode/js/blueprint.js +0 -41
  218. swarm/static/rest_mode/js/blueprintUtils.js +0 -12
  219. swarm/static/rest_mode/js/chatLogic.js +0 -79
  220. swarm/static/rest_mode/js/debug.js +0 -63
  221. swarm/static/rest_mode/js/events.js +0 -98
  222. swarm/static/rest_mode/js/main.js +0 -19
  223. swarm/static/rest_mode/js/messages.js +0 -264
  224. swarm/static/rest_mode/js/messengerLogic.js +0 -355
  225. swarm/static/rest_mode/js/modules/apiService.js +0 -84
  226. swarm/static/rest_mode/js/modules/blueprintManager.js +0 -162
  227. swarm/static/rest_mode/js/modules/chatHistory.js +0 -110
  228. swarm/static/rest_mode/js/modules/debugLogger.js +0 -14
  229. swarm/static/rest_mode/js/modules/eventHandlers.js +0 -107
  230. swarm/static/rest_mode/js/modules/messageProcessor.js +0 -120
  231. swarm/static/rest_mode/js/modules/state.js +0 -7
  232. swarm/static/rest_mode/js/modules/userInteractions.js +0 -29
  233. swarm/static/rest_mode/js/modules/validation.js +0 -23
  234. swarm/static/rest_mode/js/rendering.js +0 -119
  235. swarm/static/rest_mode/js/settings.js +0 -130
  236. swarm/static/rest_mode/js/sidebar.js +0 -94
  237. swarm/static/rest_mode/js/simpleLogic.js +0 -37
  238. swarm/static/rest_mode/js/slackLogic.js +0 -66
  239. swarm/static/rest_mode/js/splash.js +0 -76
  240. swarm/static/rest_mode/js/theme.js +0 -111
  241. swarm/static/rest_mode/js/toast.js +0 -36
  242. swarm/static/rest_mode/js/ui.js +0 -265
  243. swarm/static/rest_mode/js/validation.js +0 -57
  244. swarm/static/rest_mode/svg/animated_spinner.svg +0 -12
  245. swarm/static/rest_mode/svg/arrow_down.svg +0 -5
  246. swarm/static/rest_mode/svg/arrow_left.svg +0 -5
  247. swarm/static/rest_mode/svg/arrow_right.svg +0 -5
  248. swarm/static/rest_mode/svg/arrow_up.svg +0 -5
  249. swarm/static/rest_mode/svg/attach.svg +0 -8
  250. swarm/static/rest_mode/svg/avatar.svg +0 -7
  251. swarm/static/rest_mode/svg/canvas.svg +0 -6
  252. swarm/static/rest_mode/svg/chat_history.svg +0 -4
  253. swarm/static/rest_mode/svg/close.svg +0 -5
  254. swarm/static/rest_mode/svg/copy.svg +0 -4
  255. swarm/static/rest_mode/svg/dark_mode.svg +0 -3
  256. swarm/static/rest_mode/svg/edit.svg +0 -5
  257. swarm/static/rest_mode/svg/layout.svg +0 -9
  258. swarm/static/rest_mode/svg/logo.svg +0 -29
  259. swarm/static/rest_mode/svg/logout.svg +0 -5
  260. swarm/static/rest_mode/svg/mobile.svg +0 -5
  261. swarm/static/rest_mode/svg/new_chat.svg +0 -4
  262. swarm/static/rest_mode/svg/not_visible.svg +0 -5
  263. swarm/static/rest_mode/svg/plus.svg +0 -7
  264. swarm/static/rest_mode/svg/run_code.svg +0 -6
  265. swarm/static/rest_mode/svg/save.svg +0 -4
  266. swarm/static/rest_mode/svg/search.svg +0 -6
  267. swarm/static/rest_mode/svg/settings.svg +0 -4
  268. swarm/static/rest_mode/svg/speaker.svg +0 -5
  269. swarm/static/rest_mode/svg/stop.svg +0 -6
  270. swarm/static/rest_mode/svg/thumbs_down.svg +0 -3
  271. swarm/static/rest_mode/svg/thumbs_up.svg +0 -3
  272. swarm/static/rest_mode/svg/toggle_off.svg +0 -6
  273. swarm/static/rest_mode/svg/toggle_on.svg +0 -6
  274. swarm/static/rest_mode/svg/trash.svg +0 -10
  275. swarm/static/rest_mode/svg/undo.svg +0 -3
  276. swarm/static/rest_mode/svg/visible.svg +0 -8
  277. swarm/static/rest_mode/svg/voice.svg +0 -10
  278. swarm/templates/account/login.html +0 -22
  279. swarm/templates/account/signup.html +0 -32
  280. swarm/templates/base.html +0 -30
  281. swarm/templates/chat.html +0 -43
  282. swarm/templates/index.html +0 -35
  283. swarm/templates/rest_mode/components/chat_sidebar.html +0 -55
  284. swarm/templates/rest_mode/components/header.html +0 -45
  285. swarm/templates/rest_mode/components/main_chat_pane.html +0 -41
  286. swarm/templates/rest_mode/components/settings_dialog.html +0 -97
  287. swarm/templates/rest_mode/components/splash_screen.html +0 -7
  288. swarm/templates/rest_mode/components/top_bar.html +0 -28
  289. swarm/templates/rest_mode/message_ui.html +0 -50
  290. swarm/templates/rest_mode/slackbot.html +0 -30
  291. swarm/templates/simple_blueprint_page.html +0 -24
  292. swarm/templates/websocket_partials/final_system_message.html +0 -3
  293. swarm/templates/websocket_partials/system_message.html +0 -4
  294. swarm/templates/websocket_partials/user_message.html +0 -5
  295. swarm/utils/ansi_box.py +0 -34
  296. swarm/utils/disable_tracing.py +0 -38
  297. swarm/utils/log_utils.py +0 -63
  298. swarm/utils/openai_patch.py +0 -33
  299. swarm/ux/ansi_box.py +0 -43
  300. swarm/ux/spinner.py +0 -53
  301. {open_swarm-0.1.1745275181.dist-info → open_swarm-0.1.1748636295.dist-info}/licenses/LICENSE +0 -0
  302. /swarm/{core → extensions/blueprint}/blueprint_utils.py +0 -0
  303. /swarm/{core → extensions/blueprint}/common_utils.py +0 -0
  304. /swarm/{core → extensions/config}/setup_wizard.py +0 -0
  305. /swarm/{blueprints/rue_code → extensions/config/utils}/__init__.py +0 -0
  306. /swarm/{core → extensions/config}/utils/logger.py +0 -0
  307. /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())