open-swarm 0.1.1745275181__py3-none-any.whl → 0.1.1748636259__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 (296) hide show
  1. open_swarm-0.1.1748636259.dist-info/METADATA +188 -0
  2. open_swarm-0.1.1748636259.dist-info/RECORD +82 -0
  3. {open_swarm-0.1.1745275181.dist-info → open_swarm-0.1.1748636259.dist-info}/WHEEL +2 -1
  4. open_swarm-0.1.1748636259.dist-info/entry_points.txt +3 -0
  5. open_swarm-0.1.1748636259.dist-info/top_level.txt +1 -0
  6. swarm/agent/agent.py +49 -0
  7. swarm/auth.py +48 -113
  8. swarm/consumers.py +0 -19
  9. swarm/extensions/blueprint/__init__.py +16 -30
  10. swarm/{core → extensions/blueprint}/agent_utils.py +1 -1
  11. swarm/extensions/blueprint/blueprint_base.py +458 -0
  12. swarm/extensions/blueprint/blueprint_discovery.py +112 -0
  13. swarm/extensions/blueprint/output_utils.py +95 -0
  14. swarm/{core → extensions/blueprint}/spinner.py +21 -30
  15. swarm/extensions/cli/cli_args.py +0 -6
  16. swarm/extensions/cli/commands/blueprint_management.py +9 -47
  17. swarm/extensions/cli/commands/config_management.py +6 -5
  18. swarm/extensions/cli/commands/edit_config.py +7 -16
  19. swarm/extensions/cli/commands/list_blueprints.py +1 -1
  20. swarm/extensions/cli/commands/validate_env.py +4 -11
  21. swarm/extensions/cli/commands/validate_envvars.py +6 -6
  22. swarm/extensions/cli/interactive_shell.py +2 -16
  23. swarm/extensions/config/config_loader.py +201 -107
  24. swarm/{core → extensions/config}/config_manager.py +38 -50
  25. swarm/{core → extensions/config}/server_config.py +0 -32
  26. swarm/extensions/launchers/build_launchers.py +14 -0
  27. swarm/{core → extensions/launchers}/build_swarm_wrapper.py +0 -0
  28. swarm/extensions/launchers/swarm_api.py +64 -8
  29. swarm/extensions/launchers/swarm_cli.py +300 -8
  30. swarm/llm/chat_completion.py +195 -0
  31. swarm/serializers.py +5 -96
  32. swarm/settings.py +111 -99
  33. swarm/urls.py +74 -57
  34. swarm/utils/context_utils.py +4 -10
  35. swarm/utils/general_utils.py +0 -21
  36. swarm/utils/redact.py +36 -23
  37. swarm/views/api_views.py +39 -48
  38. swarm/views/chat_views.py +70 -237
  39. swarm/views/core_views.py +87 -80
  40. swarm/views/model_views.py +121 -64
  41. swarm/views/utils.py +441 -65
  42. swarm/views/web_views.py +2 -2
  43. open_swarm-0.1.1745275181.dist-info/METADATA +0 -874
  44. open_swarm-0.1.1745275181.dist-info/RECORD +0 -319
  45. open_swarm-0.1.1745275181.dist-info/entry_points.txt +0 -4
  46. swarm/blueprints/README.md +0 -68
  47. swarm/blueprints/blueprint_audit_status.json +0 -27
  48. swarm/blueprints/chatbot/README.md +0 -40
  49. swarm/blueprints/chatbot/blueprint_chatbot.py +0 -471
  50. swarm/blueprints/chatbot/metadata.json +0 -23
  51. swarm/blueprints/chatbot/templates/chatbot/chatbot.html +0 -33
  52. swarm/blueprints/chucks_angels/README.md +0 -11
  53. swarm/blueprints/chucks_angels/blueprint_chucks_angels.py +0 -7
  54. swarm/blueprints/chucks_angels/test_basic.py +0 -3
  55. swarm/blueprints/codey/CODEY.md +0 -15
  56. swarm/blueprints/codey/README.md +0 -115
  57. swarm/blueprints/codey/blueprint_codey.py +0 -1072
  58. swarm/blueprints/codey/codey_cli.py +0 -373
  59. swarm/blueprints/codey/instructions.md +0 -17
  60. swarm/blueprints/codey/metadata.json +0 -23
  61. swarm/blueprints/common/operation_box_utils.py +0 -83
  62. swarm/blueprints/digitalbutlers/README.md +0 -11
  63. swarm/blueprints/digitalbutlers/__init__.py +0 -1
  64. swarm/blueprints/digitalbutlers/blueprint_digitalbutlers.py +0 -7
  65. swarm/blueprints/digitalbutlers/test_basic.py +0 -3
  66. swarm/blueprints/divine_code/README.md +0 -3
  67. swarm/blueprints/divine_code/__init__.py +0 -10
  68. swarm/blueprints/divine_code/apps.py +0 -11
  69. swarm/blueprints/divine_code/blueprint_divine_code.py +0 -270
  70. swarm/blueprints/django_chat/apps.py +0 -6
  71. swarm/blueprints/django_chat/blueprint_django_chat.py +0 -268
  72. swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html +0 -37
  73. swarm/blueprints/django_chat/urls.py +0 -8
  74. swarm/blueprints/django_chat/views.py +0 -32
  75. swarm/blueprints/echocraft/blueprint_echocraft.py +0 -384
  76. swarm/blueprints/flock/README.md +0 -11
  77. swarm/blueprints/flock/__init__.py +0 -8
  78. swarm/blueprints/flock/blueprint_flock.py +0 -7
  79. swarm/blueprints/flock/test_basic.py +0 -3
  80. swarm/blueprints/geese/README.md +0 -10
  81. swarm/blueprints/geese/__init__.py +0 -8
  82. swarm/blueprints/geese/blueprint_geese.py +0 -384
  83. swarm/blueprints/geese/geese_cli.py +0 -102
  84. swarm/blueprints/jeeves/README.md +0 -41
  85. swarm/blueprints/jeeves/blueprint_jeeves.py +0 -722
  86. swarm/blueprints/jeeves/jeeves_cli.py +0 -55
  87. swarm/blueprints/jeeves/metadata.json +0 -24
  88. swarm/blueprints/mcp_demo/blueprint_mcp_demo.py +0 -473
  89. swarm/blueprints/messenger/templates/messenger/messenger.html +0 -46
  90. swarm/blueprints/mission_improbable/blueprint_mission_improbable.py +0 -423
  91. swarm/blueprints/monkai_magic/blueprint_monkai_magic.py +0 -340
  92. swarm/blueprints/nebula_shellz/blueprint_nebula_shellz.py +0 -265
  93. swarm/blueprints/omniplex/blueprint_omniplex.py +0 -298
  94. swarm/blueprints/poets/blueprint_poets.py +0 -546
  95. swarm/blueprints/poets/poets_cli.py +0 -23
  96. swarm/blueprints/rue_code/README.md +0 -8
  97. swarm/blueprints/rue_code/blueprint_rue_code.py +0 -448
  98. swarm/blueprints/rue_code/rue_code_cli.py +0 -43
  99. swarm/blueprints/stewie/apps.py +0 -12
  100. swarm/blueprints/stewie/blueprint_family_ties.py +0 -349
  101. swarm/blueprints/stewie/models.py +0 -19
  102. swarm/blueprints/stewie/serializers.py +0 -10
  103. swarm/blueprints/stewie/settings.py +0 -17
  104. swarm/blueprints/stewie/urls.py +0 -11
  105. swarm/blueprints/stewie/views.py +0 -26
  106. swarm/blueprints/suggestion/blueprint_suggestion.py +0 -222
  107. swarm/blueprints/whinge_surf/README.md +0 -22
  108. swarm/blueprints/whinge_surf/__init__.py +0 -1
  109. swarm/blueprints/whinge_surf/blueprint_whinge_surf.py +0 -565
  110. swarm/blueprints/whinge_surf/whinge_surf_cli.py +0 -99
  111. swarm/blueprints/whiskeytango_foxtrot/__init__.py +0 -0
  112. swarm/blueprints/whiskeytango_foxtrot/apps.py +0 -11
  113. swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py +0 -339
  114. swarm/blueprints/zeus/__init__.py +0 -2
  115. swarm/blueprints/zeus/apps.py +0 -4
  116. swarm/blueprints/zeus/blueprint_zeus.py +0 -270
  117. swarm/blueprints/zeus/zeus_cli.py +0 -13
  118. swarm/cli/async_input.py +0 -65
  119. swarm/cli/async_input_demo.py +0 -32
  120. swarm/core/blueprint_base.py +0 -769
  121. swarm/core/blueprint_discovery.py +0 -125
  122. swarm/core/blueprint_runner.py +0 -59
  123. swarm/core/blueprint_ux.py +0 -109
  124. swarm/core/build_launchers.py +0 -15
  125. swarm/core/cli/__init__.py +0 -1
  126. swarm/core/cli/commands/__init__.py +0 -1
  127. swarm/core/cli/commands/blueprint_management.py +0 -7
  128. swarm/core/cli/interactive_shell.py +0 -14
  129. swarm/core/cli/main.py +0 -50
  130. swarm/core/cli/utils/__init__.py +0 -1
  131. swarm/core/cli/utils/discover_commands.py +0 -18
  132. swarm/core/config_loader.py +0 -122
  133. swarm/core/output_utils.py +0 -193
  134. swarm/core/session_logger.py +0 -42
  135. swarm/core/slash_commands.py +0 -89
  136. swarm/core/swarm_api.py +0 -68
  137. swarm/core/swarm_cli.py +0 -216
  138. swarm/core/utils/__init__.py +0 -0
  139. swarm/extensions/blueprint/cli_handler.py +0 -197
  140. swarm/extensions/blueprint/runnable_blueprint.py +0 -42
  141. swarm/extensions/cli/utils/__init__.py +0 -1
  142. swarm/extensions/cli/utils/async_input.py +0 -46
  143. swarm/extensions/cli/utils/prompt_user.py +0 -3
  144. swarm/management/__init__.py +0 -0
  145. swarm/management/commands/__init__.py +0 -0
  146. swarm/management/commands/runserver.py +0 -58
  147. swarm/middleware.py +0 -65
  148. swarm/permissions.py +0 -38
  149. swarm/static/contrib/fonts/fontawesome-webfont.ttf +0 -7
  150. swarm/static/contrib/fonts/fontawesome-webfont.woff +0 -7
  151. swarm/static/contrib/fonts/fontawesome-webfont.woff2 +0 -7
  152. swarm/static/contrib/markedjs/marked.min.js +0 -6
  153. swarm/static/contrib/tabler-icons/adjustments-horizontal.svg +0 -27
  154. swarm/static/contrib/tabler-icons/alert-triangle.svg +0 -21
  155. swarm/static/contrib/tabler-icons/archive.svg +0 -21
  156. swarm/static/contrib/tabler-icons/artboard.svg +0 -27
  157. swarm/static/contrib/tabler-icons/automatic-gearbox.svg +0 -23
  158. swarm/static/contrib/tabler-icons/box-multiple.svg +0 -19
  159. swarm/static/contrib/tabler-icons/carambola.svg +0 -19
  160. swarm/static/contrib/tabler-icons/copy.svg +0 -20
  161. swarm/static/contrib/tabler-icons/download.svg +0 -21
  162. swarm/static/contrib/tabler-icons/edit.svg +0 -21
  163. swarm/static/contrib/tabler-icons/filled/carambola.svg +0 -13
  164. swarm/static/contrib/tabler-icons/filled/paint.svg +0 -13
  165. swarm/static/contrib/tabler-icons/headset.svg +0 -22
  166. swarm/static/contrib/tabler-icons/layout-sidebar-left-collapse.svg +0 -21
  167. swarm/static/contrib/tabler-icons/layout-sidebar-left-expand.svg +0 -21
  168. swarm/static/contrib/tabler-icons/layout-sidebar-right-collapse.svg +0 -21
  169. swarm/static/contrib/tabler-icons/layout-sidebar-right-expand.svg +0 -21
  170. swarm/static/contrib/tabler-icons/message-chatbot.svg +0 -22
  171. swarm/static/contrib/tabler-icons/message-star.svg +0 -22
  172. swarm/static/contrib/tabler-icons/message-x.svg +0 -23
  173. swarm/static/contrib/tabler-icons/message.svg +0 -21
  174. swarm/static/contrib/tabler-icons/paperclip.svg +0 -18
  175. swarm/static/contrib/tabler-icons/playlist-add.svg +0 -22
  176. swarm/static/contrib/tabler-icons/robot.svg +0 -26
  177. swarm/static/contrib/tabler-icons/search.svg +0 -19
  178. swarm/static/contrib/tabler-icons/settings.svg +0 -20
  179. swarm/static/contrib/tabler-icons/thumb-down.svg +0 -19
  180. swarm/static/contrib/tabler-icons/thumb-up.svg +0 -19
  181. swarm/static/css/dropdown.css +0 -22
  182. swarm/static/htmx/htmx.min.js +0 -0
  183. swarm/static/js/dropdown.js +0 -23
  184. swarm/static/rest_mode/css/base.css +0 -470
  185. swarm/static/rest_mode/css/chat-history.css +0 -286
  186. swarm/static/rest_mode/css/chat.css +0 -251
  187. swarm/static/rest_mode/css/chatbot.css +0 -74
  188. swarm/static/rest_mode/css/chatgpt.css +0 -62
  189. swarm/static/rest_mode/css/colors/corporate.css +0 -74
  190. swarm/static/rest_mode/css/colors/pastel.css +0 -81
  191. swarm/static/rest_mode/css/colors/tropical.css +0 -82
  192. swarm/static/rest_mode/css/general.css +0 -142
  193. swarm/static/rest_mode/css/layout.css +0 -167
  194. swarm/static/rest_mode/css/layouts/messenger-layout.css +0 -17
  195. swarm/static/rest_mode/css/layouts/minimalist-layout.css +0 -57
  196. swarm/static/rest_mode/css/layouts/mobile-layout.css +0 -8
  197. swarm/static/rest_mode/css/messages.css +0 -84
  198. swarm/static/rest_mode/css/messenger.css +0 -135
  199. swarm/static/rest_mode/css/settings.css +0 -91
  200. swarm/static/rest_mode/css/simple.css +0 -44
  201. swarm/static/rest_mode/css/slack.css +0 -58
  202. swarm/static/rest_mode/css/style.css +0 -156
  203. swarm/static/rest_mode/css/theme.css +0 -30
  204. swarm/static/rest_mode/css/toast.css +0 -40
  205. swarm/static/rest_mode/js/auth.js +0 -9
  206. swarm/static/rest_mode/js/blueprint.js +0 -41
  207. swarm/static/rest_mode/js/blueprintUtils.js +0 -12
  208. swarm/static/rest_mode/js/chatLogic.js +0 -79
  209. swarm/static/rest_mode/js/debug.js +0 -63
  210. swarm/static/rest_mode/js/events.js +0 -98
  211. swarm/static/rest_mode/js/main.js +0 -19
  212. swarm/static/rest_mode/js/messages.js +0 -264
  213. swarm/static/rest_mode/js/messengerLogic.js +0 -355
  214. swarm/static/rest_mode/js/modules/apiService.js +0 -84
  215. swarm/static/rest_mode/js/modules/blueprintManager.js +0 -162
  216. swarm/static/rest_mode/js/modules/chatHistory.js +0 -110
  217. swarm/static/rest_mode/js/modules/debugLogger.js +0 -14
  218. swarm/static/rest_mode/js/modules/eventHandlers.js +0 -107
  219. swarm/static/rest_mode/js/modules/messageProcessor.js +0 -120
  220. swarm/static/rest_mode/js/modules/state.js +0 -7
  221. swarm/static/rest_mode/js/modules/userInteractions.js +0 -29
  222. swarm/static/rest_mode/js/modules/validation.js +0 -23
  223. swarm/static/rest_mode/js/rendering.js +0 -119
  224. swarm/static/rest_mode/js/settings.js +0 -130
  225. swarm/static/rest_mode/js/sidebar.js +0 -94
  226. swarm/static/rest_mode/js/simpleLogic.js +0 -37
  227. swarm/static/rest_mode/js/slackLogic.js +0 -66
  228. swarm/static/rest_mode/js/splash.js +0 -76
  229. swarm/static/rest_mode/js/theme.js +0 -111
  230. swarm/static/rest_mode/js/toast.js +0 -36
  231. swarm/static/rest_mode/js/ui.js +0 -265
  232. swarm/static/rest_mode/js/validation.js +0 -57
  233. swarm/static/rest_mode/svg/animated_spinner.svg +0 -12
  234. swarm/static/rest_mode/svg/arrow_down.svg +0 -5
  235. swarm/static/rest_mode/svg/arrow_left.svg +0 -5
  236. swarm/static/rest_mode/svg/arrow_right.svg +0 -5
  237. swarm/static/rest_mode/svg/arrow_up.svg +0 -5
  238. swarm/static/rest_mode/svg/attach.svg +0 -8
  239. swarm/static/rest_mode/svg/avatar.svg +0 -7
  240. swarm/static/rest_mode/svg/canvas.svg +0 -6
  241. swarm/static/rest_mode/svg/chat_history.svg +0 -4
  242. swarm/static/rest_mode/svg/close.svg +0 -5
  243. swarm/static/rest_mode/svg/copy.svg +0 -4
  244. swarm/static/rest_mode/svg/dark_mode.svg +0 -3
  245. swarm/static/rest_mode/svg/edit.svg +0 -5
  246. swarm/static/rest_mode/svg/layout.svg +0 -9
  247. swarm/static/rest_mode/svg/logo.svg +0 -29
  248. swarm/static/rest_mode/svg/logout.svg +0 -5
  249. swarm/static/rest_mode/svg/mobile.svg +0 -5
  250. swarm/static/rest_mode/svg/new_chat.svg +0 -4
  251. swarm/static/rest_mode/svg/not_visible.svg +0 -5
  252. swarm/static/rest_mode/svg/plus.svg +0 -7
  253. swarm/static/rest_mode/svg/run_code.svg +0 -6
  254. swarm/static/rest_mode/svg/save.svg +0 -4
  255. swarm/static/rest_mode/svg/search.svg +0 -6
  256. swarm/static/rest_mode/svg/settings.svg +0 -4
  257. swarm/static/rest_mode/svg/speaker.svg +0 -5
  258. swarm/static/rest_mode/svg/stop.svg +0 -6
  259. swarm/static/rest_mode/svg/thumbs_down.svg +0 -3
  260. swarm/static/rest_mode/svg/thumbs_up.svg +0 -3
  261. swarm/static/rest_mode/svg/toggle_off.svg +0 -6
  262. swarm/static/rest_mode/svg/toggle_on.svg +0 -6
  263. swarm/static/rest_mode/svg/trash.svg +0 -10
  264. swarm/static/rest_mode/svg/undo.svg +0 -3
  265. swarm/static/rest_mode/svg/visible.svg +0 -8
  266. swarm/static/rest_mode/svg/voice.svg +0 -10
  267. swarm/templates/account/login.html +0 -22
  268. swarm/templates/account/signup.html +0 -32
  269. swarm/templates/base.html +0 -30
  270. swarm/templates/chat.html +0 -43
  271. swarm/templates/index.html +0 -35
  272. swarm/templates/rest_mode/components/chat_sidebar.html +0 -55
  273. swarm/templates/rest_mode/components/header.html +0 -45
  274. swarm/templates/rest_mode/components/main_chat_pane.html +0 -41
  275. swarm/templates/rest_mode/components/settings_dialog.html +0 -97
  276. swarm/templates/rest_mode/components/splash_screen.html +0 -7
  277. swarm/templates/rest_mode/components/top_bar.html +0 -28
  278. swarm/templates/rest_mode/message_ui.html +0 -50
  279. swarm/templates/rest_mode/slackbot.html +0 -30
  280. swarm/templates/simple_blueprint_page.html +0 -24
  281. swarm/templates/websocket_partials/final_system_message.html +0 -3
  282. swarm/templates/websocket_partials/system_message.html +0 -4
  283. swarm/templates/websocket_partials/user_message.html +0 -5
  284. swarm/utils/ansi_box.py +0 -34
  285. swarm/utils/disable_tracing.py +0 -38
  286. swarm/utils/log_utils.py +0 -63
  287. swarm/utils/openai_patch.py +0 -33
  288. swarm/ux/ansi_box.py +0 -43
  289. swarm/ux/spinner.py +0 -53
  290. {open_swarm-0.1.1745275181.dist-info → open_swarm-0.1.1748636259.dist-info}/licenses/LICENSE +0 -0
  291. /swarm/{core → extensions/blueprint}/blueprint_utils.py +0 -0
  292. /swarm/{core → extensions/blueprint}/common_utils.py +0 -0
  293. /swarm/{core → extensions/config}/setup_wizard.py +0 -0
  294. /swarm/{blueprints/rue_code → extensions/config/utils}/__init__.py +0 -0
  295. /swarm/{core → extensions/config}/utils/logger.py +0 -0
  296. /swarm/{core → extensions/launchers}/swarm_wrapper.py +0 -0
@@ -1,125 +0,0 @@
1
- import os
2
- import importlib
3
- import importlib.util
4
- import inspect
5
- import logging # Ensure logging is imported
6
- import sys
7
- from typing import Dict, Type, Any
8
- from pathlib import Path
9
-
10
- # *** Define logger EARLIER ***
11
- logger = logging.getLogger(__name__)
12
-
13
- # *** Import the ACTUAL BlueprintBase from the likely correct path ***
14
- try:
15
- # Adjust this path if BlueprintBase lives elsewhere
16
- from swarm.core.blueprint_base import BlueprintBase
17
- except ImportError:
18
- # This logger call is now safe
19
- logger.error("Failed to import BlueprintBase from swarm.core.blueprint_base. Using placeholder.", exc_info=True)
20
- # REMOVED DUMMY BlueprintBase to prevent MRO/import bugs. Always import BlueprintBase from swarm.core.blueprint_base
21
-
22
-
23
- class BlueprintLoadError(Exception):
24
- """Custom exception for errors during blueprint loading."""
25
- pass
26
-
27
- def _get_blueprint_name_from_dir(dir_name: str) -> str:
28
- """Converts directory name (e.g., 'blueprint_my_agent') to blueprint name (e.g., 'my_agent')."""
29
- prefix = "blueprint_"
30
- if dir_name.startswith(prefix):
31
- return dir_name[len(prefix):]
32
- return dir_name
33
-
34
- def discover_blueprints(blueprint_dir: str) -> Dict[str, Type[BlueprintBase]]:
35
- """
36
- Discovers blueprints (subclasses of BlueprintBase) by looking for
37
- 'blueprint_{name}.py' files within subdirectories of the given blueprint directory.
38
-
39
- Args:
40
- blueprint_dir: The path to the directory containing blueprint subdirectories.
41
-
42
- Returns:
43
- A dictionary mapping blueprint names to their corresponding class objects.
44
- """
45
- logger.info(f"Starting blueprint discovery in directory: {blueprint_dir}")
46
- blueprints: Dict[str, Type[BlueprintBase]] = {}
47
- base_dir = Path(blueprint_dir).resolve()
48
-
49
- if not base_dir.is_dir():
50
- logger.error(f"Blueprint directory not found or is not a directory: {base_dir}")
51
- return blueprints
52
-
53
- # Iterate over items inside the base blueprint directory
54
- for subdir in base_dir.iterdir():
55
- if not subdir.is_dir():
56
- continue # Skip files directly under blueprints/
57
-
58
- # Use directory name as blueprint name (e.g., 'echocraft')
59
- blueprint_name = subdir.name
60
- logger.debug(f"Processing potential blueprint '{blueprint_name}' in directory: {subdir.name}")
61
-
62
- # Look for the specific .py file, e.g., blueprint_echocraft.py
63
- py_file_name = f"blueprint_{blueprint_name}.py"
64
- py_file_path = subdir / py_file_name
65
-
66
- if not py_file_path.is_file():
67
- # Also check for just {blueprint_name}.py if that's a convention
68
- alt_py_file_name = f"{blueprint_name}.py"
69
- alt_py_file_path = subdir / alt_py_file_name
70
- if alt_py_file_path.is_file():
71
- py_file_path = alt_py_file_path # Use the alternative path
72
- py_file_name = alt_py_file_name
73
- logger.debug(f"Found alternative blueprint file: {py_file_name}")
74
- else:
75
- logger.warning(f"Skipping directory '{subdir.name}': Neither '{py_file_name}' nor '{alt_py_file_name}' found.")
76
- continue
77
-
78
-
79
- # Construct module import path, e.g., blueprints.echocraft.blueprint_echocraft
80
- if py_file_path.name.startswith('blueprint_gatcha'):
81
- module_import_path = f"swarm.blueprints.gatcha.{py_file_path.stem}"
82
- elif py_file_path.name.startswith('blueprint_'):
83
- module_import_path = f"swarm.blueprints.{subdir.name}.{py_file_path.stem}"
84
- else:
85
- continue
86
-
87
- try:
88
- # Ensure parent directory is in path
89
- parent_dir = str(base_dir.parent)
90
- if parent_dir not in sys.path:
91
- logger.debug(f"Adding '{parent_dir}' to sys.path for blueprint discovery.")
92
- sys.path.insert(0, parent_dir)
93
-
94
- # Create module spec from file path
95
- module_spec = importlib.util.spec_from_file_location(module_import_path, py_file_path)
96
-
97
- if module_spec and module_spec.loader:
98
- module = importlib.util.module_from_spec(module_spec)
99
- sys.modules[module_import_path] = module
100
- module_spec.loader.exec_module(module)
101
- logger.debug(f"Successfully loaded module: {module_import_path}")
102
-
103
- found_bp_class = None
104
- for name, obj in inspect.getmembers(module):
105
- if inspect.isclass(obj) and obj.__module__ == module_import_path and issubclass(obj, BlueprintBase) and obj is not BlueprintBase:
106
- if found_bp_class:
107
- logger.warning(f"Multiple BlueprintBase subclasses found in {py_file_name}. Using the first: {found_bp_class.__name__}.")
108
- else:
109
- logger.debug(f"Found Blueprint class '{name}' in module '{module_import_path}'")
110
- found_bp_class = obj
111
- blueprints[blueprint_name] = found_bp_class
112
- # break
113
-
114
- if not found_bp_class:
115
- logger.warning(f"No BlueprintBase subclass found directly defined in module: {module_import_path}")
116
- else:
117
- logger.warning(f"Could not create module spec for {py_file_path}")
118
-
119
- except Exception as e:
120
- logger.error(f"Error processing blueprint file '{py_file_path}': {e}", exc_info=True)
121
- if module_import_path in sys.modules:
122
- del sys.modules[module_import_path]
123
-
124
- logger.info(f"Blueprint discovery complete. Found: {list(blueprints.keys())}")
125
- return blueprints
@@ -1,59 +0,0 @@
1
- import sys
2
- import traceback
3
- import types
4
- from typing import AsyncGenerator
5
- import inspect
6
-
7
- from .blueprint_base import Spinner
8
-
9
- class BlueprintRunner:
10
- @staticmethod
11
- async def run_agent(agent, instruction, filter_llm_function_calls=True, spinner_enabled=True) -> AsyncGenerator[dict, None]:
12
- """
13
- Runs the agent using Runner.run as an async generator or coroutine, with spinner and error handling.
14
- Filters out LLM function call outputs if requested.
15
- Handles both coroutine and async generator return types.
16
- """
17
- from agents import Runner
18
- # Only enable spinner if spinner_enabled is True and not in non-interactive mode
19
- # (i.e., only if show_intermediate is True)
20
- spinner = None
21
- if spinner_enabled:
22
- # Check for a marker in instruction or a kwarg to disable spinner in non-interactive
23
- frame = inspect.currentframe()
24
- show_intermediate = False
25
- while frame:
26
- if 'kwargs' in frame.f_locals and isinstance(frame.f_locals['kwargs'], dict):
27
- show_intermediate = frame.f_locals['kwargs'].get('show_intermediate', False)
28
- break
29
- frame = frame.f_back
30
- if show_intermediate:
31
- spinner = Spinner()
32
- try:
33
- if spinner:
34
- spinner.start()
35
- result = await Runner.run(agent, instruction)
36
- # If result is an async generator, iterate over it
37
- if isinstance(result, types.AsyncGeneratorType):
38
- async for chunk in result:
39
- if filter_llm_function_calls:
40
- content = chunk.get("content")
41
- if content and ("function call" in content or "args" in content):
42
- continue
43
- yield chunk
44
- elif isinstance(result, (list, dict)):
45
- # If it's a list of chunks or a single chunk, yield directly
46
- if isinstance(result, list):
47
- for chunk in result:
48
- yield chunk
49
- else:
50
- yield result
51
- elif result is not None:
52
- # Fallback: yield as a single chunk
53
- yield {"messages": [{"role": "assistant", "content": str(result)}]}
54
- except Exception as e:
55
- tb = traceback.format_exc()
56
- yield {"messages": [{"role": "assistant", "content": f"Error: {e}\n{tb}"}]}
57
- finally:
58
- if spinner:
59
- spinner.stop()
@@ -1,109 +0,0 @@
1
- # UX utilities for Swarm blueprints (stub for legacy/test compatibility)
2
-
3
- class BlueprintUX:
4
- def __init__(self, style=None):
5
- self.style = style or "default"
6
- def box(self, title, content, summary=None, params=None):
7
- # Minimal ANSI/emoji box for test compatibility
8
- box = f"\033[1;36m┏━ {title} ━\033[0m\n"
9
- if params:
10
- box += f"\033[1;34m┃ Params: {params}\033[0m\n"
11
- if summary:
12
- box += f"\033[1;33m┃ {summary}\033[0m\n"
13
- for line in content.split('\n'):
14
- box += f"┃ {line}\n"
15
- box += "┗"+"━"*20
16
- return box
17
-
18
- import time
19
- import itertools
20
-
21
- # Style presets
22
-
23
- def get_style(style):
24
- if style == "serious":
25
- return {
26
- "border_top": "\033[1;34m╔" + "═"*50 + "╗\033[0m",
27
- "border_bottom": "\033[1;34m╚" + "═"*50 + "╝\033[0m",
28
- "border_side": "\033[1;34m║\033[0m",
29
- "emoji": "🛠️",
30
- "spinner": ['Generating.', 'Generating..', 'Generating...', 'Running...'],
31
- "fallback": 'Generating... Taking longer than expected',
32
- }
33
- elif style == "silly":
34
- return {
35
- "border_top": "\033[1;35m(ノ◕ヮ◕)ノ*:・゚✧" + "~"*40 + "✧゚・: *ヽ(◕ヮ◕ヽ)\033[0m",
36
- "border_bottom": "\033[1;35m(づ。◕‿‿◕。)づ" + "~"*40 + "づ(。◕‿‿◕。)づ\033[0m",
37
- "border_side": "\033[1;35m~\033[0m",
38
- "emoji": "🦆",
39
- "spinner": ['Quacking.', 'Quacking..', 'Quacking...', 'Flapping...'],
40
- "fallback": 'Quacking... Taking longer than expected',
41
- }
42
- else:
43
- return get_style("serious")
44
-
45
- class BlueprintUXImproved:
46
- def __init__(self, style="serious"):
47
- self.style = style
48
- self._style_conf = get_style(style)
49
- self._spinner_cycle = itertools.cycle(self._style_conf["spinner"])
50
- self._spinner_start = None
51
-
52
- def spinner(self, state_idx, taking_long=False):
53
- if taking_long:
54
- return self._style_conf["fallback"]
55
- spinner_states = self._style_conf["spinner"]
56
- return spinner_states[state_idx % len(spinner_states)]
57
-
58
- def summary(self, op_type, result_count, params):
59
- # Enhanced: pretty param formatting
60
- param_str = ', '.join(f'{k}={v!r}' for k, v in (params or {}).items()) if params else 'None'
61
- return f"{op_type} | Results: {result_count} | Params: {param_str}"
62
-
63
- def progress(self, current, total=None):
64
- if total:
65
- return f"Processed {current}/{total} lines..."
66
- return f"Processed {current} lines..."
67
-
68
- def code_vs_semantic(self, result_type, results):
69
- if result_type == "code":
70
- header = "[Code Search Results]"
71
- elif result_type == "semantic":
72
- header = "[Semantic Search Results]"
73
- else:
74
- header = "[Results]"
75
- # Enhanced: visually distinct divider
76
- divider = "\n" + ("=" * 40) + "\n"
77
- return f"{header}{divider}" + "\n".join(results)
78
-
79
- def ansi_emoji_box(self, title, content, summary=None, params=None, result_count=None, op_type=None, style=None, color=None, status=None):
80
- """
81
- Unified ANSI/emoji box for search/analysis/fileops results.
82
- Summarizes: operation, result count, params, and allows for periodic updates.
83
- Supports color and status for advanced UX.
84
- """
85
- style_conf = get_style(style or self.style)
86
- # Color/status logic
87
- color_map = {
88
- "success": "92", # green
89
- "info": "94", # blue
90
- "warning": "93", # yellow
91
- "error": "91", # red
92
- None: "94", # default blue
93
- }
94
- ansi_color = color_map.get(status, color_map[None])
95
- box = f"\033[{ansi_color}m" + style_conf["border_top"] + "\033[0m\n"
96
- box += f"\033[{ansi_color}m{style_conf['border_side']} {style_conf['emoji']} {title}"
97
- if op_type:
98
- box += f" | {op_type}"
99
- if result_count is not None:
100
- box += f" | Results: {result_count}"
101
- box += "\033[0m\n"
102
- if params:
103
- box += f"\033[{ansi_color}m{style_conf['border_side']} Params: {params}\033[0m\n"
104
- if summary:
105
- box += f"\033[{ansi_color}m{style_conf['border_side']} {summary}\033[0m\n"
106
- for line in content.split('\n'):
107
- box += f"\033[{ansi_color}m{style_conf['border_side']} {line}\033[0m\n"
108
- box += f"\033[{ansi_color}m" + style_conf["border_bottom"] + "\033[0m"
109
- return box
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env python3
2
- import PyInstaller.__main__
3
-
4
- def build_executable(script, output_name):
5
- PyInstaller.__main__.run([
6
- script,
7
- "--onefile",
8
- "--name", output_name,
9
- ])
10
-
11
- if __name__ == "__main__":
12
- # build echocraft first (already done), now build rue_code
13
- build_executable("src/swarm/blueprints/rue_code/blueprint_rue_code.py", "ruecode-blueprint")
14
- # Uncomment below to build suggestion after verifying disk space
15
- # build_executable("src/swarm/blueprints/suggestion/blueprint_suggestion.py", "suggestion-blueprint")
@@ -1 +0,0 @@
1
-
@@ -1 +0,0 @@
1
-
@@ -1,7 +0,0 @@
1
- from swarm.core.blueprint_utils import list_blueprints
2
-
3
- def execute():
4
- """Manage blueprints (list, add, remove, etc)."""
5
- print("Blueprints:")
6
- for bp in list_blueprints():
7
- print(f"- {bp}")
@@ -1,14 +0,0 @@
1
- def interactive_shell():
2
- print("Welcome to Swarm Core CLI Interactive Shell!")
3
- print("Type 'help' for available commands.")
4
- while True:
5
- try:
6
- cmd = input("swarm> ").strip()
7
- if cmd in ("exit", "quit"): break
8
- elif cmd == "help":
9
- print("Available commands: list, edit-config, validate-env, validate-envvars, blueprint-manage, config-manage")
10
- elif cmd:
11
- print(f"Command '{cmd}' not recognized (type 'help').")
12
- except KeyboardInterrupt:
13
- print("\nExiting shell.")
14
- break
swarm/core/cli/main.py DELETED
@@ -1,50 +0,0 @@
1
- """
2
- Main entry point for Swarm CLI (core).
3
- """
4
-
5
- import argparse
6
- import os
7
- from swarm.core.cli.utils.discover_commands import discover_commands
8
- from swarm.core.cli.interactive_shell import interactive_shell
9
-
10
- COMMANDS_DIR = os.path.join(os.path.dirname(__file__), "commands")
11
-
12
- USER_FRIENDLY_COMMANDS = {
13
- "list": "list_blueprints",
14
- "edit-config": "edit_config",
15
- "validate-env": "validate_env",
16
- "validate-envvars": "validate_envvars",
17
- "blueprint-manage": "blueprint_management",
18
- "config-manage": "config_management",
19
- }
20
-
21
- def parse_args(commands):
22
- """Parse CLI arguments dynamically with user-friendly names."""
23
- parser = argparse.ArgumentParser(description="Swarm CLI Utility (core)")
24
- subparsers = parser.add_subparsers(dest="command")
25
-
26
- for cmd_name, metadata in commands.items():
27
- subparsers.add_parser(cmd_name, help=metadata["description"])
28
-
29
- return parser.parse_args()
30
-
31
- def main():
32
- # Discover commands using user-friendly mapping
33
- raw_commands = discover_commands(COMMANDS_DIR)
34
- commands = {}
35
- for user_cmd, internal_cmd in USER_FRIENDLY_COMMANDS.items():
36
- if internal_cmd in raw_commands:
37
- commands[user_cmd] = raw_commands[internal_cmd]
38
- args = parse_args(commands)
39
-
40
- if args.command:
41
- command = commands.get(args.command, {}).get("execute")
42
- if command:
43
- command()
44
- else:
45
- print(f"Command '{args.command}' is not executable.")
46
- else:
47
- interactive_shell()
48
-
49
- if __name__ == "__main__":
50
- main()
@@ -1 +0,0 @@
1
-
@@ -1,18 +0,0 @@
1
- import os
2
- import importlib.util
3
- import inspect
4
-
5
- def discover_commands(commands_dir):
6
- commands = {}
7
- for filename in os.listdir(commands_dir):
8
- if filename.endswith('.py') and not filename.startswith('__'):
9
- module_name = filename[:-3]
10
- module_path = os.path.join(commands_dir, filename)
11
- spec = importlib.util.spec_from_file_location(f'swarm.core.cli.commands.{module_name}', module_path)
12
- module = importlib.util.module_from_spec(spec)
13
- spec.loader.exec_module(module)
14
- # Look for an 'execute' function
15
- if hasattr(module, 'execute'):
16
- desc = inspect.getdoc(module.execute) or f"Run {module_name} command."
17
- commands[module_name] = {"execute": module.execute, "description": desc}
18
- return commands
@@ -1,122 +0,0 @@
1
- import json
2
- import logging
3
- import os
4
- from pathlib import Path
5
- from typing import Any, Dict, Optional, Union
6
-
7
- from dotenv import load_dotenv
8
-
9
- logger = logging.getLogger("swarm.config")
10
-
11
- def _substitute_env_vars(value: Any) -> Any:
12
- import os
13
- if isinstance(value, str):
14
- # Always expand env vars in any string
15
- return os.path.expandvars(value)
16
- elif isinstance(value, list):
17
- return [_substitute_env_vars(item) for item in value]
18
- elif isinstance(value, dict):
19
- return {k: _substitute_env_vars(v) for k, v in value.items()}
20
- return value
21
-
22
- def load_environment(project_root: Path):
23
- """Loads environment variables from a `.env` file located at the project root."""
24
- dotenv_path = project_root / ".env"
25
- logger.debug(f"Checking for .env file at: {dotenv_path}")
26
- try:
27
- if dotenv_path.is_file():
28
- loaded = load_dotenv(dotenv_path=dotenv_path, override=True)
29
- if loaded:
30
- logger.debug(f".env file Loaded/Overridden at: {dotenv_path}")
31
- else:
32
- logger.debug(f"No .env file found at {dotenv_path}.")
33
- except Exception as e:
34
- logger.error(f"Error loading .env file '{dotenv_path}': {e}", exc_info=logger.level <= logging.DEBUG)
35
-
36
- def load_full_configuration(
37
- blueprint_class_name: str,
38
- default_config_path: Path,
39
- config_path_override: Optional[Union[str, Path]] = None,
40
- profile_override: Optional[str] = None,
41
- cli_config_overrides: Optional[Dict[str, Any]] = None,
42
- ) -> Dict[str, Any]:
43
- """
44
- Loads and merges configuration settings from base file, blueprint specifics, profiles, and CLI overrides.
45
-
46
- Args:
47
- blueprint_class_name (str): The name of the blueprint class (e.g., "MyBlueprint").
48
- default_config_path (Path): The default path to the swarm_config.json file.
49
- config_path_override (Optional[Union[str, Path]]): Path specified via CLI argument.
50
- profile_override (Optional[str]): Profile specified via CLI argument.
51
- cli_config_overrides (Optional[Dict[str, Any]]): Overrides provided via CLI argument.
52
-
53
- Returns:
54
- Dict[str, Any]: The final, merged configuration dictionary.
55
-
56
- Raises:
57
- ValueError: If the configuration file has JSON errors or cannot be read.
58
- FileNotFoundError: If a specific config_path_override is given but the file doesn't exist.
59
- """
60
- config_path = Path(config_path_override) if config_path_override else default_config_path
61
- logger.debug(f"Attempting to load base configuration from: {config_path}")
62
- base_config = {}
63
- if config_path.is_file():
64
- try:
65
- with open(config_path, "r", encoding="utf-8") as f:
66
- base_config = json.load(f)
67
- logger.debug(f"Successfully loaded base configuration from: {config_path}")
68
- except json.JSONDecodeError as e:
69
- raise ValueError(f"Config Error: Failed to parse JSON in {config_path}: {e}") from e
70
- except Exception as e:
71
- raise ValueError(f"Config Error: Failed to read {config_path}: {e}") from e
72
- else:
73
- if config_path_override:
74
- raise FileNotFoundError(f"Configuration Error: Specified config file not found: {config_path}")
75
- else:
76
- logger.warning(f"Default configuration file not found at {config_path}. Proceeding without base configuration.")
77
-
78
- # 1. Start with base defaults
79
- final_config = base_config.get("defaults", {}).copy()
80
- logger.debug(f"Applied base defaults. Keys: {list(final_config.keys())}")
81
-
82
- # 2. Merge base llm and mcpServers sections
83
- if "llm" in base_config:
84
- final_config.setdefault("llm", {}).update(base_config["llm"])
85
- logger.debug("Merged base 'llm'.")
86
- if "mcpServers" in base_config:
87
- final_config.setdefault("mcpServers", {}).update(base_config["mcpServers"])
88
- logger.debug("Merged base 'mcpServers'.")
89
-
90
- # 3. Merge blueprint-specific settings
91
- blueprint_settings = base_config.get("blueprints", {}).get(blueprint_class_name, {})
92
- if blueprint_settings:
93
- final_config.update(blueprint_settings)
94
- logger.debug(f"Merged BP '{blueprint_class_name}' settings. Keys: {list(blueprint_settings.keys())}")
95
-
96
- # 4. Determine and merge profile settings
97
- # Priority: CLI > Blueprint Specific > Base Defaults > "default"
98
- profile_in_bp_settings = blueprint_settings.get("default_profile")
99
- profile_in_base_defaults = base_config.get("defaults", {}).get("default_profile")
100
- profile_to_use = profile_override or profile_in_bp_settings or profile_in_base_defaults or "default"
101
- logger.debug(f"Using profile: '{profile_to_use}'")
102
- profile_settings = base_config.get("profiles", {}).get(profile_to_use, {})
103
- if profile_settings:
104
- final_config.update(profile_settings)
105
- logger.debug(f"Merged profile '{profile_to_use}'. Keys: {list(profile_settings.keys())}")
106
- elif profile_to_use != "default" and (profile_override or profile_in_bp_settings or profile_in_base_defaults):
107
- logger.warning(f"Profile '{profile_to_use}' requested but not found.")
108
-
109
- # 5. Merge CLI overrides (highest priority)
110
- if cli_config_overrides:
111
- final_config.update(cli_config_overrides)
112
- logger.debug(f"Merged CLI overrides. Keys: {list(cli_config_overrides.keys())}")
113
-
114
- # Ensure top-level keys exist
115
- final_config.setdefault("llm", {})
116
- final_config.setdefault("mcpServers", {})
117
-
118
- # 6. Substitute environment variables in the final config
119
- final_config = _substitute_env_vars(final_config)
120
- logger.debug("Applied final env var substitution.")
121
-
122
- return final_config