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
File without changes
@@ -1,11 +0,0 @@
1
- from django.apps import AppConfig
2
- import logging
3
-
4
- logger = logging.getLogger(__name__)
5
-
6
- class WhiskeyTangoFoxtrotConfig(AppConfig):
7
- name = 'blueprints.whiskeytango_foxtrot' # Normalized name
8
- verbose_name = "Whiskey Tango Foxtrot Blueprint"
9
-
10
- def ready(self):
11
- logger.debug(f"Registering {self.name} via AppConfig")
@@ -1,339 +0,0 @@
1
- """
2
- WhiskeyTangoFoxtrot: Tracking Free Online Services
3
-
4
- A chaotic spy-themed blueprint with a multi-tiered agent hierarchy for tracking and managing free online services using SQLite and web search capabilities.
5
- Uses BlueprintBase and agent-as-tool delegation.
6
- """
7
-
8
- from agents.mcp import MCPServer
9
- import os
10
- from dotenv import load_dotenv; load_dotenv(override=True)
11
-
12
- import logging
13
- import sqlite3
14
- import sys
15
- from pathlib import Path
16
- from typing import Dict, Any, List, ClassVar, Optional
17
- import time
18
-
19
- # Ensure src is in path for BlueprintBase import
20
- project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
21
- src_path = os.path.join(project_root, 'src')
22
- if src_path not in sys.path: sys.path.insert(0, src_path)
23
-
24
- try:
25
- from agents import Agent, Tool, function_tool, Runner
26
- from agents.models.interface import Model
27
- from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel
28
- from openai import AsyncOpenAI
29
- from swarm.core.blueprint_ux import BlueprintUXImproved
30
- except ImportError as e:
31
- print(f"ERROR: Import failed in WhiskeyTangoFoxtrotBlueprint: {e}. Check dependencies.")
32
- print(f"sys.path: {sys.path}")
33
- sys.exit(1)
34
-
35
- logger = logging.getLogger(__name__)
36
-
37
- # --- Database Path ---
38
- # Defined here for clarity, sourced from env var via BlueprintBase config loading primarily
39
- SQLITE_DB_PATH_STR = os.getenv("SQLITE_DB_PATH", "./wtf_services.db") # Default if not set
40
- SQLITE_DB_PATH = Path(SQLITE_DB_PATH_STR).resolve()
41
-
42
- # --- Agent Instructions ---
43
-
44
- valory_instructions = """
45
- You are Valory, the top-tier coordinator for Operation Freebie Freedom.
46
- Your mission: Track and manage information about free online services based on user requests.
47
- Delegate tasks to your middle managers:
48
- - Tyril (DB Manager): Use the `Tyril` agent tool for tasks involving storing, retrieving, or updating service info in the database, or managing related files.
49
- - Tray (Web Manager): Use the `Tray` agent tool for tasks involving searching for new services, fetching details from the web, or processing web data.
50
- Synthesize reports from Tyril and Tray into a final response for the user.
51
- Available Agent Tools: Tyril, Tray.
52
- """
53
-
54
- tyril_instructions = """
55
- You are Tyril, middle manager for database and filesystem operations under Valory.
56
- Your mission: Manage the 'services' database and temporary files.
57
- Delegate specific tasks to your minions:
58
- - Larry (Filesystem): Use the `Larry` agent tool for creating, reading, or deleting temporary files related to service data.
59
- - Kriegs (DB Updates): Use the `Kriegs` agent tool for ALL interactions with the 'services' SQLite database (add, update, delete, query records).
60
- You have direct access to the `sqlite` MCP tool for read-only queries if needed, but prefer delegating writes/updates to Kriegs.
61
- Report results or completion status back to Valory.
62
- Available MCP Tools (Direct Use - Read Only Recommended): sqlite.
63
- Available Agent Tools: Larry, Kriegs.
64
- """
65
-
66
- tray_instructions = """
67
- You are Tray, middle manager for web data operations under Valory.
68
- Your mission: Find and process information about free online services from the web.
69
- Delegate specific tasks to your minions:
70
- - Vanna (Web Search/Fetch): Use the `Vanna` agent tool to find service URLs (via brave-search) and fetch content from those URLs (via mcp-npx-fetch).
71
- - Marcher (Data Processing): Use the `Marcher` agent tool to process raw fetched data (using mcp-doc-forge) into a structured format (name, type, url, api_key, usage_limits, documentation_link).
72
- Coordinate the flow: Task Vanna, receive results, task Marcher with Vanna's results, receive structured data.
73
- Report the final structured data back to Valory.
74
- Available Agent Tools: Vanna, Marcher.
75
- """
76
-
77
- larry_instructions = """
78
- You are Larry, filesystem minion under Tyril.
79
- Your mission: Manage temporary files using the `filesystem` MCP tool within the allowed path.
80
- Tasks include storing fetched web content temporarily, reading data for processing, or deleting temp files.
81
- Report success or failure of file operations back to Tyril.
82
- Available MCP Tools: filesystem.
83
- """
84
-
85
- kriegs_instructions = """
86
- You are Kriegs, database minion under Tyril.
87
- Your mission: Perform CRUD (Create, Read, Update, Delete) operations on the 'services' table in the SQLite database using the `sqlite` MCP tool.
88
- The table schema is: (id INTEGER PRIMARY KEY, name TEXT NOT NULL, type TEXT NOT NULL, url TEXT, api_key TEXT, usage_limits TEXT, documentation_link TEXT).
89
- Receive structured data (usually from Tyril, originating from Marcher) and perform the requested database action (INSERT, UPDATE, DELETE, SELECT).
90
- Report the outcome (e.g., "Successfully added Fly.io", "Error updating Grok entry", "Deleted service X", "Found 3 services of type AI") back to Tyril.
91
- Available MCP Tools: sqlite.
92
- """
93
-
94
- vanna_instructions = """
95
- You are Vanna, web search and fetch minion under Tray.
96
- Your mission: Find URLs for specified services and fetch content from those URLs.
97
- 1. Use the `brave-search` MCP tool to find the official website or documentation URL for a service name provided by Tray.
98
- 2. Use the `mcp-npx-fetch` MCP tool to retrieve the content (HTML or text) from the URL found.
99
- Report the fetched content (or any errors like URL not found/fetch failed) back to Tray.
100
- Available MCP Tools: brave-search, mcp-npx-fetch.
101
- """
102
-
103
- marcher_instructions = """
104
- You are Marcher, data processing minion under Tray.
105
- Your mission: Process raw web content (fetched by Vanna) into structured data using the `mcp-doc-forge` MCP tool.
106
- Receive raw text/HTML content and the original service name/type from Tray.
107
- Use `mcp-doc-forge` (likely its text extraction or summarization functions) to extract: name, type, url, api_key (if mentioned), usage_limits, documentation_link.
108
- Report the structured data (as JSON or a clear key-value format) back to Tray.
109
- Available MCP Tools: mcp-doc-forge.
110
- """
111
-
112
- # --- Define the Blueprint ---
113
- class WhiskeyTangoFoxtrotBlueprint(BlueprintUXImproved):
114
- """Tracks free online services with a hierarchical spy-inspired agent team using SQLite and web search."""
115
- metadata: ClassVar[Dict[str, Any]] = {
116
- "name": "WhiskeyTangoFoxtrotBlueprint",
117
- "title": "WhiskeyTangoFoxtrot Service Tracker",
118
- "description": "Tracks free online services with SQLite and web search using a multi-tiered agent hierarchy.",
119
- "version": "1.2.0", # Refactored version
120
- "author": "Open Swarm Team (Refactored)",
121
- "tags": ["web scraping", "database", "sqlite", "multi-agent", "hierarchy", "mcp"],
122
- "required_mcp_servers": ["sqlite", "brave-search", "mcp-npx-fetch", "mcp-doc-forge", "filesystem"],
123
- "env_vars": ["BRAVE_API_KEY", "SQLITE_DB_PATH", "ALLOWED_PATH"] # Actual required vars
124
- }
125
-
126
- # Caches
127
- _openai_client_cache: Dict[str, AsyncOpenAI] = {}
128
- _model_instance_cache: Dict[str, Model] = {}
129
-
130
- def __init__(self, blueprint_id: str = "whiskeytangofoxtrot", config=None, config_path=None, **kwargs):
131
- super().__init__(blueprint_id=blueprint_id, config=config, config_path=config_path, **kwargs)
132
- self.blueprint_id = blueprint_id
133
- self.config_path = config_path
134
- self._config = config if config is not None else None
135
- self._llm_profile_name = None
136
- self._llm_profile_data = None
137
- self._markdown_output = None
138
- # Add other attributes as needed for WhiskeyTangoFoxtrot
139
- # ...
140
-
141
- def initialize_db(self) -> None:
142
- """Initializes the SQLite database schema if not present."""
143
- db_path = SQLITE_DB_PATH
144
- logger.info(f"Ensuring database schema exists at: {db_path}")
145
- try:
146
- db_path.parent.mkdir(parents=True, exist_ok=True) # Ensure directory exists
147
- conn = sqlite3.connect(db_path)
148
- cursor = conn.cursor()
149
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='services';")
150
- if not cursor.fetchone():
151
- logger.info("Initializing 'services' table in SQLite database.")
152
- cursor.execute("""
153
- CREATE TABLE services (
154
- id INTEGER PRIMARY KEY AUTOINCREMENT,
155
- name TEXT NOT NULL UNIQUE,
156
- type TEXT NOT NULL,
157
- url TEXT,
158
- api_key TEXT,
159
- usage_limits TEXT,
160
- documentation_link TEXT,
161
- last_checked TEXT
162
- );
163
- """)
164
- conn.commit()
165
- logger.info("'services' table created.")
166
- else:
167
- logger.debug("'services' table already exists.")
168
- conn.close()
169
- except sqlite3.Error as e:
170
- logger.error(f"SQLite error during DB initialization: {e}", exc_info=True)
171
- # Depending on severity, you might want to raise this
172
- # raise RuntimeError(f"Failed to initialize database: {e}") from e
173
- except Exception as e:
174
- logger.error(f"Unexpected error during DB initialization: {e}", exc_info=True)
175
- # raise RuntimeError(f"Failed to initialize database: {e}") from e
176
-
177
-
178
- # --- Model Instantiation Helper --- (Standard helper)
179
- def _get_model_instance(self, profile_name: str) -> Model:
180
- """Retrieves or creates an LLM Model instance."""
181
- # ... (Implementation is the same as previous refactors) ...
182
- if profile_name in self._model_instance_cache:
183
- logger.debug(f"Using cached Model instance for profile '{profile_name}'.")
184
- return self._model_instance_cache[profile_name]
185
- logger.debug(f"Creating new Model instance for profile '{profile_name}'.")
186
- profile_data = self.get_llm_profile(profile_name)
187
- if not profile_data: raise ValueError(f"Missing LLM profile '{profile_name}'.")
188
- provider = profile_data.get("provider", "openai").lower()
189
- model_name = profile_data.get("model")
190
- if not model_name: raise ValueError(f"Missing 'model' in profile '{profile_name}'.")
191
- if provider != "openai": raise ValueError(f"Unsupported provider: {provider}")
192
- client_cache_key = f"{provider}_{profile_data.get('base_url')}"
193
- if client_cache_key not in self._openai_client_cache:
194
- client_kwargs = { "api_key": profile_data.get("api_key"), "base_url": profile_data.get("base_url") }
195
- filtered_kwargs = {k: v for k, v in client_kwargs.items() if v is not None}
196
- log_kwargs = {k:v for k,v in filtered_kwargs.items() if k != 'api_key'}
197
- logger.debug(f"Creating new AsyncOpenAI client for '{profile_name}': {log_kwargs}")
198
- try: self._openai_client_cache[client_cache_key] = AsyncOpenAI(**filtered_kwargs)
199
- except Exception as e: raise ValueError(f"Failed to init client: {e}") from e
200
- client = self._openai_client_cache[client_cache_key]
201
- logger.debug(f"Instantiating OpenAIChatCompletionsModel(model='{model_name}') for '{profile_name}'.")
202
- try:
203
- model_instance = OpenAIChatCompletionsModel(model=model_name, openai_client=client)
204
- self._model_instance_cache[profile_name] = model_instance
205
- return model_instance
206
- except Exception as e: raise ValueError(f"Failed to init LLM: {e}") from e
207
-
208
-
209
- def render_prompt(self, template_name: str, context: dict) -> str:
210
- return f"User request: {context.get('user_request', '')}\nHistory: {context.get('history', '')}\nAvailable tools: {', '.join(context.get('available_tools', []))}"
211
-
212
-
213
- async def run(self, messages: List[dict], **kwargs):
214
- """Main execution entry point for the WhiskeyTangoFoxtrot blueprint."""
215
- logger.info("WhiskeyTangoFoxtrotBlueprint run method called.")
216
- instruction = messages[-1].get("content", "") if messages else ""
217
- from agents import Runner
218
- ux = BlueprintUXImproved(style="serious")
219
- spinner_idx = 0
220
- start_time = time.time()
221
- spinner_yield_interval = 1.0 # seconds
222
- last_spinner_time = start_time
223
- yielded_spinner = False
224
- result_chunks = []
225
- try:
226
- runner_gen = Runner.run(self.create_starting_agent([]), instruction)
227
- while True:
228
- now = time.time()
229
- try:
230
- chunk = next(runner_gen)
231
- result_chunks.append(chunk)
232
- # If chunk is a final result, wrap and yield
233
- if chunk and isinstance(chunk, dict) and "messages" in chunk:
234
- content = chunk["messages"][0]["content"] if chunk["messages"] else ""
235
- summary = ux.summary("Operation", len(result_chunks), {"instruction": instruction[:40]})
236
- box = ux.ansi_emoji_box(
237
- title="WhiskeyTangoFoxtrot Result",
238
- content=content,
239
- summary=summary,
240
- params={"instruction": instruction[:40]},
241
- result_count=len(result_chunks),
242
- op_type="run",
243
- status="success"
244
- )
245
- yield {"messages": [{"role": "assistant", "content": box}]}
246
- else:
247
- yield chunk
248
- yielded_spinner = False
249
- except StopIteration:
250
- break
251
- except Exception:
252
- if now - last_spinner_time >= spinner_yield_interval:
253
- taking_long = (now - start_time > 10)
254
- spinner_msg = ux.spinner(spinner_idx, taking_long=taking_long)
255
- yield {"messages": [{"role": "assistant", "content": spinner_msg}]}
256
- spinner_idx += 1
257
- last_spinner_time = now
258
- yielded_spinner = True
259
- if not result_chunks and not yielded_spinner:
260
- yield {"messages": [{"role": "assistant", "content": ux.spinner(0)}]}
261
- except Exception as e:
262
- logger.error(f"Error during WhiskeyTangoFoxtrot run: {e}", exc_info=True)
263
- yield {"messages": [{"role": "assistant", "content": f"An error occurred: {e}"}]}
264
- return
265
-
266
-
267
- def create_starting_agent(self, mcp_servers: List[MCPServer]) -> Agent:
268
- """Creates the WTF agent hierarchy and returns Valory (Coordinator)."""
269
- # Ensure config is loaded (defensive fix for tests/patching)
270
- if self._config is None:
271
- self._load_configuration()
272
- self.initialize_db() # Ensure DB is ready
273
-
274
- logger.debug("Creating WhiskeyTangoFoxtrot agent team...")
275
- self._model_instance_cache = {}
276
- self._openai_client_cache = {}
277
-
278
- default_profile_name = self.config.get("llm_profile", "default")
279
- logger.debug(f"Using LLM profile '{default_profile_name}' for WTF agents.")
280
- model_instance = self._get_model_instance(default_profile_name)
281
-
282
- # Helper to filter started MCP servers
283
- def get_agent_mcps(names: List[str]) -> List[MCPServer]:
284
- started_names = {s.name for s in mcp_servers}
285
- required_found = [name for name in names if name in started_names]
286
- if len(required_found) != len(names):
287
- missing = set(names) - started_names
288
- logger.warning(f"Agent needing {names} is missing started MCP(s): {', '.join(missing)}")
289
- return [s for s in mcp_servers if s.name in required_found]
290
-
291
- # Instantiate all agents first
292
- agents: Dict[str, Agent] = {}
293
-
294
- agents["Larry"] = Agent(name="Larry", model=model_instance, instructions=larry_instructions, tools=[], mcp_servers=get_agent_mcps(["filesystem"]))
295
- agents["Kriegs"] = Agent(name="Kriegs", model=model_instance, instructions=kriegs_instructions, tools=[], mcp_servers=get_agent_mcps(["sqlite"]))
296
- agents["Vanna"] = Agent(name="Vanna", model=model_instance, instructions=vanna_instructions, tools=[], mcp_servers=get_agent_mcps(["brave-search", "mcp-npx-fetch"]))
297
- agents["Marcher"] = Agent(name="Marcher", model=model_instance, instructions=marcher_instructions, tools=[], mcp_servers=get_agent_mcps(["mcp-doc-forge"]))
298
-
299
- agents["Tyril"] = Agent(
300
- name="Tyril", model=model_instance, instructions=tyril_instructions,
301
- tools=[ # Tools for delegating to minions
302
- agents["Larry"].as_tool(tool_name="Larry", tool_description="Delegate filesystem tasks (temp files)."),
303
- agents["Kriegs"].as_tool(tool_name="Kriegs", tool_description="Delegate SQLite database operations (CRUD).")
304
- ],
305
- mcp_servers=get_agent_mcps(["sqlite"]) # Tyril might read DB directly
306
- )
307
- agents["Tray"] = Agent(
308
- name="Tray", model=model_instance, instructions=tray_instructions,
309
- tools=[ # Tools for delegating to minions
310
- agents["Vanna"].as_tool(tool_name="Vanna", tool_description="Delegate web search/fetch tasks."),
311
- agents["Marcher"].as_tool(tool_name="Marcher", tool_description="Delegate processing/structuring of fetched web data.")
312
- ],
313
- mcp_servers=[] # Tray coordinates web minions
314
- )
315
-
316
- agents["Valory"] = Agent(
317
- name="Valory", model=model_instance, instructions=valory_instructions,
318
- tools=[ # Tools for delegating to middle managers
319
- agents["Tyril"].as_tool(tool_name="Tyril", tool_description="Delegate database and filesystem management tasks."),
320
- agents["Tray"].as_tool(tool_name="Tray", tool_description="Delegate web data fetching and processing tasks.")
321
- ],
322
- mcp_servers=[] # Coordinator doesn't directly use MCPs
323
- )
324
-
325
- logger.debug("WhiskeyTangoFoxtrot agents created. Starting with Valory.")
326
- return agents["Valory"]
327
-
328
- # Standard Python entry point
329
- if __name__ == "__main__":
330
- import asyncio
331
- import json
332
- messages = [
333
- {"role": "user", "content": "WTF is going on?"}
334
- ]
335
- blueprint = WhiskeyTangoFoxtrotBlueprint(blueprint_id="demo-1")
336
- async def run_and_print():
337
- async for response in blueprint.run(messages):
338
- print(json.dumps(response, indent=2))
339
- asyncio.run(run_and_print())
@@ -1,2 +0,0 @@
1
- # __init__.py for zeus blueprint package
2
- # (Obsolete DivineAssistantBlueprint import removed)
@@ -1,4 +0,0 @@
1
- from django.apps import AppConfig
2
-
3
- class ZeusConfig(AppConfig):
4
- name = "swarm.blueprints.zeus"
@@ -1,270 +0,0 @@
1
- """
2
- Zeus Blueprint
3
- A general-purpose coordinator agent using other gods as tools.
4
- """
5
-
6
- from swarm.core.blueprint_base import BlueprintBase
7
- import os
8
- import time
9
- from swarm.blueprints.common.operation_box_utils import display_operation_box
10
- from swarm.core.blueprint_ux import BlueprintUXImproved
11
-
12
- class ZeusSpinner:
13
- FRAMES = ["Generating.", "Generating..", "Generating...", "Running..."]
14
- LONG_WAIT_MSG = "Generating... Taking longer than expected"
15
- INTERVAL = 0.12
16
- SLOW_THRESHOLD = 10
17
-
18
- def __init__(self):
19
- self._idx = 0
20
- self._start_time = None
21
- self._last_frame = self.FRAMES[0]
22
-
23
- def start(self):
24
- self._start_time = time.time()
25
- self._idx = 0
26
- self._last_frame = self.FRAMES[0]
27
-
28
- def _spin(self):
29
- self._idx = (self._idx + 1) % len(self.FRAMES)
30
- self._last_frame = self.FRAMES[self._idx]
31
-
32
- def current_spinner_state(self):
33
- if self._start_time and (time.time() - self._start_time) > self.SLOW_THRESHOLD:
34
- return self.LONG_WAIT_MSG
35
- return self._last_frame
36
-
37
- def stop(self):
38
- self._start_time = None
39
-
40
- class ZeusCoordinatorBlueprint(BlueprintBase):
41
- NAME = "zeus"
42
- CLI_NAME = "zeus"
43
- DESCRIPTION = "Zeus: The coordinator agent for Open Swarm, using all other gods as tools."
44
- VERSION = "1.0.0"
45
- # Add more Zeus features here as needed
46
-
47
- @classmethod
48
- def get_metadata(cls):
49
- return {
50
- "name": cls.NAME,
51
- "cli": cls.CLI_NAME,
52
- "description": cls.DESCRIPTION,
53
- "version": cls.VERSION,
54
- }
55
-
56
- def __init__(self, blueprint_id: str = None, config_path=None, **kwargs):
57
- # Allow blueprint_id to be optional for test compatibility
58
- if blueprint_id is None:
59
- blueprint_id = "zeus_test"
60
-
61
- # Extract a `debug` flag (default False) from kwargs so that the test
62
- # suite can request a simplified, decoration‑free output.
63
- self.debug = bool(kwargs.pop("debug", False))
64
-
65
- super().__init__(blueprint_id, config_path=config_path, **kwargs)
66
- # Initialize Zeus state/logic
67
- self.spinner = ZeusSpinner()
68
-
69
- def assist(self, user_input, context=None):
70
- """Handle general assistance requests."""
71
- self.spinner.start()
72
- display_operation_box(
73
- title="Zeus Assistance",
74
- content=f"How can Zeus help you today? You said: {user_input}",
75
- spinner_state=self.spinner.current_spinner_state(),
76
- emoji="⚡"
77
- )
78
- return f"How can Zeus help you today? You said: {user_input}"
79
-
80
- async def run(self, messages, **kwargs):
81
- """Run inference using Zeus and the Pantheon team as tools."""
82
- logger = getattr(self, 'logger', None) or __import__('logging').getLogger(__name__)
83
- logger.info("ZeusCoordinatorBlueprint run method called.")
84
- instruction = messages[-1].get("content", "") if messages else ""
85
- ux = BlueprintUXImproved(style="serious")
86
- spinner_idx = 0
87
- start_time = time.time()
88
- spinner_yield_interval = 1.0 # seconds
89
- last_spinner_time = start_time
90
- yielded_spinner = False
91
- result_chunks = []
92
- try:
93
- agent = self.create_starting_agent()
94
-
95
- # If the underlying Agent instance doesn’t implement an async
96
- # ``run`` method we try to fall back to the canonical Runner from
97
- # the *agents* package. This gives us real tool‑calling behaviour
98
- # in environments where the SDK is available, while still
99
- # avoiding crashes in lightweight CI runs.
100
-
101
- if not hasattr(agent, "run") or not callable(getattr(agent, "run")):
102
- try:
103
- from agents import Runner # late import – optional dep
104
-
105
- runner_gen = Runner.run(agent, instruction=instruction)
106
- # Runner.run returns a sync generator – wrap into async
107
- async def _async_wrapper(gen):
108
- for item in gen:
109
- yield item
110
- runner_gen = _async_wrapper(runner_gen)
111
- except Exception:
112
- # Final lightweight fallback – yield a canned test message
113
- yield {
114
- "messages": [{
115
- "role": "assistant",
116
- "content": "[TEST‑MODE] Zeus here – tooling layer is disabled but I'm alive ⚡"
117
- }]
118
- }
119
- return
120
- else:
121
- runner_gen = agent.run(messages, **kwargs)
122
- while True:
123
- now = time.time()
124
- try:
125
- chunk = await runner_gen.__anext__() if hasattr(runner_gen, '__anext__') else next(runner_gen)
126
- result_chunks.append(chunk)
127
- # If chunk is a final result, wrap and yield
128
- if chunk and isinstance(chunk, dict) and "messages" in chunk:
129
- # In debug / test mode we want the **raw** assistant content
130
- # without any ANSI boxes so that assertions such as
131
- # ``assert responses[0]["messages"][0]["content"] == "Hi!"``
132
- # hold true.
133
- if getattr(self, "debug", False) or os.environ.get("SWARM_TEST_MODE") == "1":
134
- yield chunk
135
- else:
136
- content = chunk["messages"][0]["content"] if chunk["messages"] else ""
137
- summary = ux.summary("Operation", len(result_chunks), {"instruction": instruction[:40]})
138
- box = ux.ansi_emoji_box(
139
- title="Zeus Result",
140
- content=content,
141
- summary=summary,
142
- params={"instruction": instruction[:40]},
143
- result_count=len(result_chunks),
144
- op_type="run",
145
- status="success"
146
- )
147
- yield {"messages": [{"role": "assistant", "content": box}]}
148
- else:
149
- yield chunk
150
- yielded_spinner = False
151
- except (StopIteration, StopAsyncIteration):
152
- break
153
- except Exception:
154
- if now - last_spinner_time >= spinner_yield_interval:
155
- taking_long = (now - start_time > 10)
156
- spinner_msg = ux.spinner(spinner_idx, taking_long=taking_long)
157
- yield {"messages": [{"role": "assistant", "content": spinner_msg}]}
158
- spinner_idx += 1
159
- last_spinner_time = now
160
- yielded_spinner = True
161
- if not result_chunks and not yielded_spinner:
162
- yield {"messages": [{"role": "assistant", "content": ux.spinner(0)}]}
163
- except Exception as e:
164
- logger.error(f"Error during Zeus run: {e}", exc_info=True)
165
- yield {"messages": [{"role": "assistant", "content": f"An error occurred: {e}"}]}
166
-
167
- def create_starting_agent(self, mcp_servers=None):
168
- """Creates Zeus coordinator agent with Pantheon gods as tools."""
169
- from agents import Agent
170
- from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel
171
- from openai import AsyncOpenAI
172
- model_name = (self.config.get('llm_profile', 'default') if hasattr(self, 'config') and self.config else 'default')
173
- api_key = os.environ.get('OPENAI_API_KEY', 'sk-test')
174
- openai_client = AsyncOpenAI(api_key=api_key)
175
- model_instance = OpenAIChatCompletionsModel(model=model_name, openai_client=openai_client)
176
-
177
- pantheon_names = [
178
- ("Odin", "Delegate architecture, design, and research tasks."),
179
- ("Hermes", "Delegate technical planning and system checks."),
180
- ("Hephaestus", "Delegate core coding implementation tasks."),
181
- ("Hecate", "Delegate specific, smaller coding tasks (usually requested by Hephaestus)."),
182
- ("Thoth", "Delegate database updates or code management tasks."),
183
- ("Mnemosyne", "Delegate DevOps, deployment, or workflow optimization tasks."),
184
- ("Chronos", "Delegate documentation writing tasks.")
185
- ]
186
- pantheon_agents = []
187
- for name, desc in pantheon_names:
188
- pantheon_agents.append(
189
- Agent(
190
- name=name,
191
- model=model_instance,
192
- instructions=f"You are {name}, {desc}",
193
- tools=[],
194
- mcp_servers=mcp_servers or []
195
- )
196
- )
197
- pantheon_tools = [a.as_tool(tool_name=a.name, tool_description=desc) for a, (_, desc) in zip(pantheon_agents, pantheon_names)]
198
-
199
- zeus_instructions = """
200
- You are Zeus, Product Owner and Coordinator of the Divine Ops team.
201
- Your goal is to manage the software development lifecycle based on user requests.
202
- 1. Understand the user's request (e.g., 'design a user login system', 'deploy the latest changes', 'fix bug X').
203
- 2. Delegate tasks to the appropriate specialist agent using their respective Agent Tool:
204
- - Odin: For high-level architecture, design, research.
205
- - Hermes: For breaking down features into technical tasks, system checks.
206
- - Hephaestus: For primary coding and implementation.
207
- - Hecate: For specific coding assistance requested by Hephaestus (via you).
208
- - Thoth: For database and SQL tasks.
209
- - Mnemosyne: For DevOps, deployment, and CI/CD.
210
- - Chronos: For documentation and user guides.
211
- 3. Review results from each specialist agent and provide feedback or request revisions as needed.
212
- 4. Integrate all results and ensure the solution meets the user's requirements.
213
- 5. Provide the final update or result to the user.
214
- Available Agent Tools: Odin, Hermes, Hephaestus, Hecate, Thoth, Mnemosyne, Chronos.
215
- """
216
- agent = Agent(
217
- name="Zeus",
218
- model=model_instance,
219
- instructions=zeus_instructions,
220
- tools=pantheon_tools,
221
- mcp_servers=mcp_servers or []
222
- )
223
- return agent
224
-
225
- if __name__ == "__main__":
226
- import asyncio
227
- print("\033[1;36m\n╔══════════════════════════════════════════════════════════════╗")
228
- print("║ ⚡ ZEUS: GENERAL-PURPOSE SWARM COORDINATOR AGENT DEMO ║")
229
- print("╠══════════════════════════════════════════════════════════════╣")
230
- print("║ Zeus coordinates a team of specialist agents (the gods). ║")
231
- print("║ Try typing a message and get a helpful response! ║")
232
- print("╚══════════════════════════════════════════════════════════════╝\033[0m")
233
- blueprint = ZeusCoordinatorBlueprint(blueprint_id="cli-demo")
234
- messages = [{"role": "user", "content": "Hello, how can I assist you today?"}]
235
- async def run_and_print():
236
- spinner = ZeusSpinner()
237
- spinner.start()
238
- try:
239
- all_results = []
240
- async for response in blueprint.run(messages):
241
- content = response["messages"][0]["content"] if (isinstance(response, dict) and "messages" in response and response["messages"]) else str(response)
242
- all_results.append(content)
243
- # Enhanced progressive output
244
- if isinstance(response, dict) and (response.get("progress") or response.get("matches")):
245
- display_operation_box(
246
- title="Progressive Operation",
247
- content="\n".join(response.get("matches", [])),
248
- style="bold cyan" if response.get("type") == "code_search" else "bold magenta",
249
- result_count=len(response.get("matches", [])) if response.get("matches") is not None else None,
250
- params={k: v for k, v in response.items() if k not in {'matches', 'progress', 'total', 'truncated', 'done'}},
251
- progress_line=response.get('progress'),
252
- total_lines=response.get('total'),
253
- spinner_state=spinner.current_spinner_state() if hasattr(spinner, 'current_spinner_state') else None,
254
- op_type=response.get("type", "search"),
255
- emoji="🔍" if response.get("type") == "code_search" else "🧠"
256
- )
257
- finally:
258
- spinner.stop()
259
- display_operation_box(
260
- title="Zeus Output",
261
- content="\n".join(all_results),
262
- style="bold green",
263
- result_count=len(all_results),
264
- params={"prompt": messages[0]["content"]},
265
- op_type="zeus"
266
- )
267
- asyncio.run(run_and_print())
268
-
269
- # Backwards compatibility: ZeusBlueprint alias for ZeusCoordinatorBlueprint
270
- ZeusBlueprint = ZeusCoordinatorBlueprint
@@ -1,13 +0,0 @@
1
- import argparse
2
- from swarm.blueprints.zeus.blueprint_zeus import ZeusCoordinatorBlueprint
3
-
4
- def main():
5
- parser = argparse.ArgumentParser(description="Zeus: Coordinator agent demo")
6
- parser.add_argument("--message", type=str, help="User message to process", default="Summon the pantheon!")
7
- args = parser.parse_args()
8
- bp = ZeusCoordinatorBlueprint()
9
- response = bp.assist(args.message)
10
- print(response)
11
-
12
- if __name__ == "__main__":
13
- main()