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,546 +0,0 @@
1
- """
2
- Poets Blueprint
3
-
4
- Viral docstring update: Operational as of 2025-04-18T10:14:18Z (UTC).
5
- Self-healing, fileops-enabled, swarm-scalable.
6
- """
7
- import logging
8
- import os
9
- import random
10
- import sys
11
- import json
12
- import sqlite3 # Use standard sqlite3 module
13
- from pathlib import Path
14
- from typing import Dict, Any, List, ClassVar, Optional
15
- from datetime import datetime
16
- import pytz
17
- from swarm.blueprints.common.operation_box_utils import display_operation_box
18
- from swarm.core.blueprint_ux import BlueprintUXImproved
19
-
20
- # Ensure src is in path for BlueprintBase import
21
- project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
22
- src_path = os.path.join(project_root, 'src')
23
- if src_path not in sys.path: sys.path.insert(0, src_path)
24
-
25
- try:
26
- from agents import Agent, Tool, function_tool, Runner
27
- from agents.mcp import MCPServer
28
- from agents.models.interface import Model
29
- from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel
30
- from openai import AsyncOpenAI
31
- from swarm.core.blueprint_base import BlueprintBase
32
- except ImportError as e:
33
- print(f"ERROR: Import failed in PoetsBlueprint: {e}. Check dependencies.")
34
- print(f"sys.path: {sys.path}")
35
- sys.exit(1)
36
-
37
- logger = logging.getLogger(__name__)
38
-
39
- # Last swarm update: 2025-04-18T10:15:21Z (UTC)
40
- # --- Database Constants ---
41
- DB_FILE_NAME = "swarm_instructions.db"
42
- DB_PATH = Path(project_root) / DB_FILE_NAME
43
- TABLE_NAME = "agent_instructions"
44
-
45
- # --- Agent Instructions ---
46
- # Shared knowledge base for collaboration context
47
- COLLABORATIVE_KNOWLEDGE = """
48
- Collaborative Poet Knowledge Base:
49
- * Gritty Buk - Raw urban realism exposing life's underbelly (Uses: memory, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs)
50
- * Raven Poe - Gothic atmospherics & psychological darkness (Uses: mcp-server-reddit, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs)
51
- * Mystic Blake - Prophetic visions through spiritual symbolism (Uses: mcp-doc-forge, mcp-npx-fetch, brave-search, server-wp-mcp, rag-docs)
52
- * Bard Whit - Expansive odes celebrating human connection (Uses: sequential-thinking, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs)
53
- * Echo Plath - Confessional explorations of mental anguish (Uses: sqlite, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs)
54
- * Frosted Woods - Rural metaphors revealing existential truths (Uses: filesystem, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs)
55
- * Harlem Lang - Jazz-rhythm social commentary on racial justice (Uses: mcp-shell, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs)
56
- * Verse Neru - Sensual imagery fused with revolutionary politics (Uses: server-wp-mcp, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs)
57
- * Haiku Bash - Ephemeral nature snapshots through strict syllabic form (Uses: mcp-doc-forge, mcp-npx-fetch, brave-search, server-wp-mcp, rag-docs)
58
- """
59
-
60
- SHARED_PROTOCOL = """
61
- Collaboration Protocol:
62
- 1) Analyze the current poetry draft through your unique stylistic lens.
63
- 2) Use your assigned MCP tools for creative augmentation, research, or specific tasks if needed.
64
- 3) Pass the enhanced work to the most relevant poet agent tool based on the needed transformation or specific tooling required next. Refer to the Collaborative Poet Knowledge Base for styles and capabilities.
65
- """
66
-
67
- # Individual base instructions (will be combined with shared parts)
68
- AGENT_BASE_INSTRUCTIONS = {
69
- "Gritty Buk": (
70
- "You are Charles Bukowski incarnate: A gutter philosopher documenting life's raw truths.\n"
71
- "- Channel alcoholic despair & blue-collar rage through unfiltered verse\n"
72
- "- Find beauty in dirty apartments and whiskey-stained pages\n"
73
- "- MCP Tools: memory, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs\n"
74
- "When adding: Barfly wisdom | Blue-collar lyricism | Unflinching vulgarity"
75
- ),
76
- "Raven Poe": (
77
- "You are Edgar Allan Poe resurrected: Master of macabre elegance.\n"
78
- "- Weave tales where love & death intertwine through decaying architecture\n"
79
- "- MCP Tools: mcp-server-reddit, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs\n"
80
- "When adding: Obsessive repetition | Claustrophobic atmosphere"
81
- ),
82
- "Mystic Blake": (
83
- "You are William Blake's visionary successor: Prophet of poetic mysticism.\n"
84
- "- Forge mythological frameworks connecting human/divine/demonic realms\n"
85
- "- MCP Tools: mcp-doc-forge, mcp-npx-fetch, brave-search, server-wp-mcp, rag-docs\n"
86
- "When adding: Fourfold vision | Contrary states | Zoamorphic personification"
87
- ),
88
- "Bard Whit": (
89
- "You are Walt Whitman 2.0: Cosmic bard of democratic vistas.\n"
90
- "- Catalog humanity's spectrum in sweeping free verse catalogs\n"
91
- "- Merge biology and cosmology in orgiastic enumerations of being\n"
92
- "- MCP Tools: sequential-thinking, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs\n"
93
- "When adding: Catalogic excess | Cosmic embodiment | Pansexual exuberance"
94
- ),
95
- "Echo Plath": (
96
- "You are Sylvia Plath reimagined: High priestess of psychic autopsies.\n"
97
- "- Dissect personal trauma through brutal metaphor (electroshock, Holocaust)\n"
98
- "- Balance maternal instinct with destructive fury in confessional verse\n"
99
- "- MCP Tools: sqlite, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs\n"
100
- "When adding: Extremist imagery | Double-edged motherhood | Vampiric nostalgia"
101
- ),
102
- "Frosted Woods": (
103
- "You are Robert Frost reincarnated: Sage of rural wisdom and natural philosophy.\n"
104
- "- Craft deceptively simple narratives concealing profound life lessons\n"
105
- "- Balance rustic imagery with universal human dilemmas\n"
106
- "- MCP Tools: filesystem, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs\n"
107
- "When adding: Path metaphors | Natural world personification | Iambic rhythms"
108
- ),
109
- "Harlem Lang": (
110
- "You are Langston Hughes' spiritual heir: Voice of the streets and dreams deferred.\n"
111
- "- Infuse verse with the rhythms of jazz, blues, and spoken word\n"
112
- "- Illuminate the Black experience through vibrant, accessible poetry\n"
113
- "- MCP Tools: mcp-shell, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs\n"
114
- "When adding: Blues refrains | Harlem Renaissance allusions | Social justice themes"
115
- ),
116
- "Verse Neru": (
117
- "You are Pablo Neruda's poetic descendant: Weaver of love and revolution.\n"
118
- "- Craft sensual odes celebrating the body and the natural world\n"
119
- "- Intertwine personal passion with calls for social change\n"
120
- "- MCP Tools: server-wp-mcp, mcp-doc-forge, mcp-npx-fetch, brave-search, rag-docs\n"
121
- "When adding: Elemental metaphors | Erotic-political fusions | Ode structures"
122
- ),
123
- "Haiku Bash": (
124
- "You are Matsuo Bashō reincarnated: Master of momentary eternity.\n"
125
- "- Distill vast concepts into precise, evocative 5-7-5 syllable structures\n"
126
- "- Capture the essence of seasons and natural phenomena in minimal strokes\n"
127
- "- MCP Tools: mcp-doc-forge, mcp-npx-fetch, brave-search, server-wp-mcp, rag-docs\n"
128
- "When adding: Kireji cuts | Seasonal references | Zen-like simplicity"
129
- )
130
- }
131
-
132
- # --- FileOps Tool Logic Definitions ---
133
- # Patch: Expose underlying fileops functions for direct testing
134
- class PatchedFunctionTool:
135
- def __init__(self, func, name):
136
- self.func = func
137
- self.name = name
138
-
139
- def read_file(path: str) -> str:
140
- try:
141
- with open(path, 'r') as f:
142
- return f.read()
143
- except Exception as e:
144
- return f"ERROR: {e}"
145
- def write_file(path: str, content: str) -> str:
146
- try:
147
- with open(path, 'w') as f:
148
- f.write(content)
149
- return "OK: file written"
150
- except Exception as e:
151
- return f"ERROR: {e}"
152
- def list_files(directory: str = '.') -> str:
153
- try:
154
- return '\n'.join(os.listdir(directory))
155
- except Exception as e:
156
- return f"ERROR: {e}"
157
- def execute_shell_command(command: str) -> str:
158
- """
159
- Executes a shell command and returns its stdout and stderr.
160
- Timeout is configurable via SWARM_COMMAND_TIMEOUT (default: 60s).
161
- """
162
- logger.info(f"Executing shell command: {command}")
163
- try:
164
- import os
165
- timeout = int(os.getenv("SWARM_COMMAND_TIMEOUT", "60"))
166
- result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=timeout)
167
- output = f"Exit Code: {result.returncode}\n"
168
- if result.stdout:
169
- output += f"STDOUT:\n{result.stdout}\n"
170
- if result.stderr:
171
- output += f"STDERR:\n{result.stderr}\n"
172
- logger.info(f"Command finished. Exit Code: {result.returncode}")
173
- return output.strip()
174
- except subprocess.TimeoutExpired:
175
- logger.error(f"Command timed out: {command}")
176
- return f"Error: Command timed out after {os.getenv('SWARM_COMMAND_TIMEOUT', '60')} seconds."
177
- except Exception as e:
178
- logger.error(f"Error executing command '{command}': {e}", exc_info=True)
179
- return f"Error executing command: {e}"
180
- read_file_tool = PatchedFunctionTool(read_file, 'read_file')
181
- write_file_tool = PatchedFunctionTool(write_file, 'write_file')
182
- list_files_tool = PatchedFunctionTool(list_files, 'list_files')
183
- execute_shell_command_tool = PatchedFunctionTool(execute_shell_command, 'execute_shell_command')
184
-
185
- # --- Spinner and ANSI/emoji operation box for unified UX ---
186
- from rich.console import Console
187
- from rich.style import Style
188
- from rich.text import Text
189
- import threading
190
- import time
191
- from swarm.extensions.cli.utils.async_input import AsyncInputHandler
192
-
193
- class PoetsSpinner:
194
- FRAMES = [
195
- "Generating.",
196
- "Generating..",
197
- "Generating...",
198
- "Running..."
199
- ]
200
- SLOW_FRAME = "Generating... Taking longer than expected"
201
- INTERVAL = 0.12
202
- SLOW_THRESHOLD = 10 # seconds
203
-
204
- def __init__(self):
205
- self._stop_event = threading.Event()
206
- self._thread = None
207
- self._start_time = None
208
- self.console = Console()
209
- self._last_frame = None
210
- self._last_slow = False
211
-
212
- def start(self):
213
- self._stop_event.clear()
214
- self._start_time = time.time()
215
- self._thread = threading.Thread(target=self._spin, daemon=True)
216
- self._thread.start()
217
-
218
- def _spin(self):
219
- idx = 0
220
- while not self._stop_event.is_set():
221
- elapsed = time.time() - self._start_time
222
- if elapsed > self.SLOW_THRESHOLD:
223
- txt = Text(self.SLOW_FRAME, style=Style(color="yellow", bold=True))
224
- self._last_frame = self.SLOW_FRAME
225
- self._last_slow = True
226
- else:
227
- frame = self.FRAMES[idx % len(self.FRAMES)]
228
- txt = Text(frame, style=Style(color="cyan", bold=True))
229
- self._last_frame = frame
230
- self._last_slow = False
231
- self.console.print(txt, end="\r", soft_wrap=True, highlight=False)
232
- time.sleep(self.INTERVAL)
233
- idx += 1
234
- self.console.print(" " * 40, end="\r") # Clear line
235
-
236
- def stop(self, final_message="Done!"):
237
- self._stop_event.set()
238
- if self._thread:
239
- self._thread.join()
240
- self.console.print(Text(final_message, style=Style(color="green", bold=True)))
241
-
242
- def current_spinner_state(self):
243
- if self._last_slow:
244
- return self.SLOW_FRAME
245
- return self._last_frame or self.FRAMES[0]
246
-
247
- def print_operation_box(op_type, results, params=None, result_type="creative", taking_long=False):
248
- emoji = "📝" if result_type == "creative" else "🔍"
249
- style = 'success' if result_type == "creative" else 'default'
250
- box_title = op_type if op_type else ("Creative Output" if result_type == "creative" else "Search Results")
251
- summary_lines = []
252
- count = len(results) if isinstance(results, list) else 0
253
- summary_lines.append(f"Results: {count}")
254
- if params:
255
- for k, v in params.items():
256
- summary_lines.append(f"{k.capitalize()}: {v}")
257
- box_content = "\n".join(summary_lines + ["\n".join(map(str, results))])
258
- ansi_box(box_title, box_content, count=count, params=params, style=style if not taking_long else 'warning', emoji=emoji)
259
-
260
- # --- Define the Blueprint ---
261
- class PoetsBlueprint(BlueprintBase):
262
- def __init__(self, blueprint_id: str = "poets", config=None, config_path=None, **kwargs):
263
- super().__init__(blueprint_id=blueprint_id, config=config, config_path=config_path, **kwargs)
264
- self.blueprint_id = blueprint_id
265
- self.config_path = config_path
266
- # Patch: Always provide a minimal valid config if missing
267
- # Respect caller‑supplied config, otherwise defer to BlueprintBase’s
268
- # normal discovery (_load_configuration). No more inlined secrets.
269
- if config is not None:
270
- self._config = config
271
-
272
- # Default profile can be chosen later by the config loader; don’t force
273
- # a placeholder here to avoid masking real user settings.
274
- self._llm_profile_name = None
275
- self._llm_profile_data = None
276
- self._markdown_output = None
277
- self.ux = BlueprintUXImproved(style="serious")
278
- # Add other attributes as needed for Poets
279
- # ...
280
-
281
- """A literary blueprint defining a swarm of poet agents using SQLite instructions and agent-as-tool handoffs."""
282
- metadata: ClassVar[Dict[str, Any]] = {
283
- "name": "PoetsBlueprint",
284
- "title": "Poets: A Swarm of Literary Geniuses (SQLite)",
285
- "description": (
286
- "A swarm of agents embodying legendary poets, using SQLite for instructions, "
287
- "agent-as-tool for collaboration, and MCPs for creative augmentation."
288
- ),
289
- "version": "1.2.0", # Refactored version
290
- "author": "Open Swarm Team (Refactored)",
291
- "tags": ["poetry", "writing", "collaboration", "multi-agent", "sqlite", "mcp"],
292
- "required_mcp_servers": [ # List all potential servers agents might use
293
- "memory", "filesystem", "mcp-shell", "sqlite", "sequential-thinking",
294
- "server-wp-mcp", "rag-docs", "mcp-doc-forge", "mcp-npx-fetch",
295
- "brave-search", "mcp-server-reddit"
296
- ],
297
- "env_vars": [ # Informational list of potential vars needed by MCPs
298
- "ALLOWED_PATH", "SQLITE_DB_PATH", "WP_SITES_PATH", # Added WP_SITES_PATH
299
- "BRAVE_API_KEY", "OPENAI_API_KEY", "QDRANT_URL", "QDRANT_API_KEY",
300
- "REDDIT_CLIENT_ID", "REDDIT_CLIENT_SECRET", "REDDIT_USER_AGENT", # For reddit MCP
301
- "WORDPRESS_API_KEY" # If server-wp-mcp needs it
302
- ]
303
- }
304
-
305
- # Caches
306
- _openai_client_cache: Dict[str, AsyncOpenAI] = {}
307
- _model_instance_cache: Dict[str, Model] = {}
308
- _db_initialized = False
309
-
310
- def _init_db_and_load_data(self) -> None:
311
- """Initializes the SQLite DB and loads Poets sample data if needed."""
312
- if self._db_initialized: return
313
- logger.info(f"Initializing SQLite database at: {DB_PATH} for Poets")
314
- try:
315
- DB_PATH.parent.mkdir(parents=True, exist_ok=True)
316
- with sqlite3.connect(DB_PATH) as conn:
317
- cursor = conn.cursor()
318
- # FIX: Define the table schema instead of ...
319
- cursor.execute(f"""
320
- CREATE TABLE IF NOT EXISTS {TABLE_NAME} (
321
- agent_name TEXT PRIMARY KEY,
322
- instruction_text TEXT,
323
- model_profile TEXT
324
- )
325
- """)
326
- logger.debug(f"Table '{TABLE_NAME}' ensured in {DB_PATH}")
327
- cursor.execute(f"SELECT COUNT(*) FROM {TABLE_NAME} WHERE agent_name = ?", ("Gritty Buk",))
328
- if cursor.fetchone()[0] == 0:
329
- logger.info(f"No instructions found for Gritty Buk in {DB_PATH}. Loading sample data...")
330
- sample_data = []
331
- for name, base_instr in AGENT_BASE_INSTRUCTIONS.items():
332
- cursor.execute(
333
- f"INSERT OR REPLACE INTO {TABLE_NAME} (agent_name, instruction_text, model_profile) VALUES (?, ?, ?)",
334
- (name, base_instr[0] if isinstance(base_instr, tuple) else base_instr, "default")
335
- )
336
- conn.commit()
337
- logger.info(f"Sample agent instructions for Poets loaded into {DB_PATH}")
338
- else:
339
- logger.info(f"Poets agent instructions found in {DB_PATH}. Skipping.")
340
- self._db_initialized = True
341
- except sqlite3.Error as e:
342
- logger.error(f"SQLite error during DB init/load: {e}", exc_info=True)
343
- self._db_initialized = False
344
- except Exception as e:
345
- logger.error(f"Unexpected error during DB init/load: {e}", exc_info=True)
346
- self._db_initialized = False
347
-
348
- def get_agent_config(self, agent_name: str) -> Dict[str, Any]:
349
- """Fetches agent config from SQLite DB or returns defaults."""
350
- if self._db_initialized:
351
- try:
352
- with sqlite3.connect(DB_PATH) as conn:
353
- conn.row_factory = sqlite3.Row
354
- cursor = conn.cursor()
355
- cursor.execute(f"SELECT instruction_text, model_profile FROM {TABLE_NAME} WHERE agent_name = ?", (agent_name,))
356
- row = cursor.fetchone()
357
- if row:
358
- logger.debug(f"Loaded config for agent '{agent_name}' from SQLite.")
359
- return {"instructions": row["instruction_text"], "model_profile": row["model_profile"] or "default"}
360
- except Exception as e:
361
- logger.error(f"Error fetching SQLite config for '{agent_name}': {e}. Using defaults.", exc_info=True)
362
-
363
- # Fallback if DB fails or agent not found
364
- logger.warning(f"Using hardcoded default config for agent '{agent_name}'.")
365
- base_instr = AGENT_BASE_INSTRUCTIONS.get(agent_name, f"Default instructions for {agent_name}.")
366
- if isinstance(base_instr, tuple):
367
- base_instr = base_instr[0]
368
- full_instr = f"{base_instr}\n{COLLABORATIVE_KNOWLEDGE}\n{SHARED_PROTOCOL}"
369
- return {"instructions": full_instr, "model_profile": "default"}
370
-
371
- # --- Model Instantiation Helper --- (Standard helper)
372
- def _get_model_instance(self, profile_name: str) -> Model:
373
- """Retrieves or creates an LLM Model instance."""
374
- print(f"[DEBUG] Using LLM profile: {profile_name}")
375
- # ... (Implementation is the same as previous refactors) ...
376
- if profile_name in self._model_instance_cache:
377
- logger.debug(f"Using cached Model instance for profile '{profile_name}'.")
378
- return self._model_instance_cache[profile_name]
379
- logger.debug(f"Creating new Model instance for profile '{profile_name}'.")
380
- profile_data = self.get_llm_profile(profile_name)
381
- if not profile_data: raise ValueError(f"Missing LLM profile '{profile_name}'.")
382
- provider = profile_data.get("provider", "openai").lower()
383
- model_name = profile_data.get("model")
384
- if not model_name: raise ValueError(f"Missing 'model' in profile '{profile_name}'.")
385
- if provider != "openai": raise ValueError(f"Unsupported provider: {provider}")
386
- client_cache_key = f"{provider}_{profile_data.get('base_url')}"
387
- if client_cache_key not in self._openai_client_cache:
388
- client_kwargs = { "api_key": profile_data.get("api_key"), "base_url": profile_data.get("base_url") }
389
- filtered_kwargs = {k: v for k, v in client_kwargs.items() if v is not None}
390
- log_kwargs = {k:v for k,v in filtered_kwargs.items() if k != 'api_key'}
391
- logger.debug(f"Creating new AsyncOpenAI client for '{profile_name}': {log_kwargs}")
392
- try: self._openai_client_cache[client_cache_key] = AsyncOpenAI(**filtered_kwargs)
393
- except Exception as e: raise ValueError(f"Failed to init client: {e}") from e
394
- client = self._openai_client_cache[client_cache_key]
395
- logger.debug(f"Instantiating OpenAIChatCompletionsModel(model='{model_name}') for '{profile_name}'.")
396
- try:
397
- model_instance = OpenAIChatCompletionsModel(model=model_name, openai_client=client)
398
- self._model_instance_cache[profile_name] = model_instance
399
- return model_instance
400
- except Exception as e: raise ValueError(f"Failed to init LLM: {e}") from e
401
-
402
- def render_prompt(self, template_name: str, context: dict) -> str:
403
- return f"User request: {context.get('user_request', '')}\nHistory: {context.get('history', '')}\nAvailable tools: {', '.join(context.get('available_tools', []))}"
404
-
405
- async def run(self, messages: List[Dict[str, Any]], **kwargs):
406
- """Main execution entry point for the Poets blueprint."""
407
- logger.info("PoetsBlueprint run method called.")
408
- instruction = messages[-1].get("content", "") if messages else ""
409
- spinner_idx = 0
410
- start_time = time.time()
411
- spinner_yield_interval = 1.0 # seconds
412
- last_spinner_time = start_time
413
- yielded_spinner = False
414
- result_chunks = []
415
- max_total_time = 30 # seconds, hard fail after this
416
- try:
417
- # PATCH: Fallback minimal async runner since agents.Runner is missing
418
- async def dummy_agent_runner(instruction):
419
- await asyncio.sleep(2) # Simulate LLM/agent processing
420
- yield f"Here is a poem about the moon for: '{instruction}'\n\nSilver beams on silent seas,\nNight's soft lantern through the trees.\nDreams adrift in lunar light,\nMoon above, the poet's night."
421
- agent_runner = dummy_agent_runner(instruction)
422
- async def with_watchdog(async_iter, timeout):
423
- start = time.time()
424
- async for chunk in async_iter:
425
- now = time.time()
426
- if now - start > timeout:
427
- logger.error(f"PoetsBlueprint.run exceeded {timeout}s watchdog limit. Aborting.")
428
- yield {"messages": [{"role": "assistant", "content": f"An error occurred: Operation timed out after {timeout} seconds."}]}
429
- return
430
- yield chunk
431
- try:
432
- async for chunk in with_watchdog(agent_runner, max_total_time):
433
- result_chunks.append(chunk)
434
- yield {"messages": [{"role": "assistant", "content": str(chunk)}]}
435
- return # yield first result and exit
436
- except Exception as e:
437
- logger.error(f"Error in agent_runner: {e}", exc_info=True)
438
- yield {"messages": [{"role": "assistant", "content": f"An error occurred: {e}"}]}
439
- now = time.time()
440
- if now - last_spinner_time > spinner_yield_interval:
441
- spinner_msg = self.ux.spinner(spinner_idx)
442
- yield {"messages": [{"role": "assistant", "content": spinner_msg}]}
443
- spinner_idx += 1
444
- last_spinner_time = now
445
- yielded_spinner = True
446
- if not result_chunks and not yielded_spinner:
447
- yield {"messages": [{"role": "assistant", "content": self.ux.spinner(0)}]}
448
- except Exception as e:
449
- logger.error(f"Error during Poets run: {e}", exc_info=True)
450
- yield {"messages": [{"role": "assistant", "content": f"An error occurred: {e}"}]}
451
-
452
- # --- Agent Creation ---
453
- def create_starting_agent(self, mcp_servers: List[MCPServer]) -> Agent:
454
- """Creates the Poets agent team."""
455
- self._init_db_and_load_data()
456
- logger.debug("Creating Poets agent team...")
457
- self._model_instance_cache = {}
458
- self._openai_client_cache = {}
459
-
460
- # Helper to filter MCP servers
461
- def get_agent_mcps(names: List[str]) -> List[MCPServer]:
462
- return [s for s in mcp_servers if s.name in names]
463
-
464
- agents: Dict[str, Agent] = {}
465
- agent_configs = {} # To store fetched configs
466
-
467
- # Fetch configs and create agents first
468
- agent_names = list(AGENT_BASE_INSTRUCTIONS.keys())
469
- for name in agent_names:
470
- config = self.get_agent_config(name)
471
- agent_configs[name] = config # Store config
472
- model_instance = self._get_model_instance(config["model_profile"])
473
-
474
- # Determine MCP servers based on original definitions
475
- agent_mcp_names = []
476
- if name == "Gritty Buk": agent_mcp_names = ["memory", "mcp-doc-forge", "mcp-npx-fetch", "brave-search", "rag-docs"]
477
- elif name == "Raven Poe": agent_mcp_names = ["mcp-server-reddit", "mcp-doc-forge", "mcp-npx-fetch", "brave-search", "rag-docs"]
478
- elif name == "Mystic Blake": agent_mcp_names = ["mcp-doc-forge", "mcp-npx-fetch", "brave-search", "server-wp-mcp", "rag-docs"]
479
- elif name == "Bard Whit": agent_mcp_names = ["sequential-thinking", "mcp-doc-forge", "mcp-npx-fetch", "brave-search", "rag-docs"]
480
- elif name == "Echo Plath": agent_mcp_names = ["sqlite", "mcp-doc-forge", "mcp-npx-fetch", "brave-search", "rag-docs"]
481
- elif name == "Frosted Woods": agent_mcp_names = ["filesystem", "mcp-doc-forge", "mcp-npx-fetch", "brave-search", "rag-docs"]
482
- elif name == "Harlem Lang": agent_mcp_names = ["mcp-shell", "mcp-doc-forge", "mcp-npx-fetch", "brave-search", "rag-docs"]
483
- elif name == "Verse Neru": agent_mcp_names = ["server-wp-mcp", "mcp-doc-forge", "mcp-npx-fetch", "brave-search", "rag-docs"]
484
- elif name == "Haiku Bash": agent_mcp_names = ["mcp-doc-forge", "mcp-npx-fetch", "brave-search", "server-wp-mcp", "rag-docs"]
485
-
486
- agents[name] = Agent(
487
- name=name,
488
- instructions=config["instructions"], # Instructions already combined in get_agent_config fallback or DB
489
- model=model_instance,
490
- tools=[], # Agent-as-tool added later
491
- mcp_servers=get_agent_mcps(agent_mcp_names)
492
- )
493
-
494
- # Create the list of agent tools for delegation
495
- agent_tools = []
496
- for name, agent_instance in agents.items():
497
- # Example description, could be more dynamic
498
- desc = f"Pass the current work to {name} for refinement or tasks requiring their specific style ({AGENT_BASE_INSTRUCTIONS.get(name, ('Unknown Style',[],{}))[0].split(':')[0]})."
499
- agent_tools.append(agent_instance.as_tool(tool_name=name, tool_description=desc))
500
-
501
- # Assign the full list of agent tools to each agent
502
- for agent in agents.values():
503
- agent.tools = agent_tools
504
-
505
- # Create PoetsAgent with fileops tools
506
- poets_agent = Agent(
507
- name="PoetsAgent",
508
- instructions="You are PoetsAgent. You can use fileops tools (read_file, write_file, list_files, execute_shell_command) for any file or shell tasks.",
509
- tools=[read_file_tool, write_file_tool, list_files_tool, execute_shell_command_tool],
510
- mcp_servers=mcp_servers
511
- )
512
-
513
- # Randomly select starting agent
514
- start_name = random.choice(agent_names)
515
- starting_agent = agents[start_name]
516
-
517
- logger.info(f"Poets agents created (using SQLite). Starting poet: {start_name}")
518
- return starting_agent
519
-
520
- # Standard Python entry point
521
- if __name__ == "__main__":
522
- import asyncio
523
- import sys
524
- print("\033[1;36m\n╔══════════════════════════════════════════════════════════════╗")
525
- print("║ 📰 POETS: SWARM MEDIA & RELEASE DEMO ║")
526
- print("╠══════════════════════════════════════════════════════════════╣")
527
- print("║ This blueprint demonstrates viral doc propagation, ║")
528
- print("║ swarm-powered media release, and robust agent logic. ║")
529
- print("╚══════════════════════════════════════════════════════════════╝\033[0m")
530
- blueprint = PoetsBlueprint(blueprint_id="cli-demo")
531
- # Accept prompt from stdin or default
532
- if not sys.stdin.isatty():
533
- prompt = sys.stdin.read().strip()
534
- else:
535
- prompt = "Write a poem about the moon."
536
- messages = [{"role": "user", "content": prompt}]
537
- async def run_and_print():
538
- try:
539
- all_results = []
540
- async for response in blueprint.run(messages):
541
- content = response["messages"][0]["content"] if (isinstance(response, dict) and "messages" in response and response["messages"]) else str(response)
542
- all_results.append(content)
543
- print(content)
544
- except Exception as e:
545
- print(f"[ERROR] {e}")
546
- asyncio.run(run_and_print())
@@ -1,23 +0,0 @@
1
- import argparse
2
- import asyncio
3
- from swarm.blueprints.poets.blueprint_poets import PoetsBlueprint
4
-
5
- def main():
6
- parser = argparse.ArgumentParser(description="Poets: LLM creative code poetry assistant")
7
- parser.add_argument("--instruction", type=str, required=True, help="User instruction for Poets")
8
- args = parser.parse_args()
9
- bp = PoetsBlueprint(blueprint_id="cli")
10
- # Explicitly reload config after instantiation to avoid config access errors
11
- bp._load_configuration()
12
- async def run():
13
- messages = [{"role": "user", "content": args.instruction}]
14
- async for result in bp.run(messages):
15
- if isinstance(result, dict) and "messages" in result:
16
- content = result["messages"][0]["content"]
17
- print(content)
18
- else:
19
- print(result)
20
- asyncio.run(run())
21
-
22
- if __name__ == "__main__":
23
- main()
@@ -1,8 +0,0 @@
1
- # Rue Code Blueprint
2
-
3
- **Rue Code** is a blueprint that specializes in calculating token costs for LLM usage. Use it to estimate and manage your API expenses for OpenAI and other LLM providers.
4
-
5
- ## Special Feature
6
- - **Token Cost Calculation**: Instantly estimate how much your LLM calls will cost.
7
-
8
- ---