open-swarm 0.1.1745274976__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.
- open_swarm-0.1.1748636259.dist-info/METADATA +188 -0
- open_swarm-0.1.1748636259.dist-info/RECORD +82 -0
- {open_swarm-0.1.1745274976.dist-info → open_swarm-0.1.1748636259.dist-info}/WHEEL +2 -1
- open_swarm-0.1.1748636259.dist-info/entry_points.txt +3 -0
- open_swarm-0.1.1748636259.dist-info/top_level.txt +1 -0
- swarm/agent/agent.py +49 -0
- swarm/auth.py +48 -113
- swarm/consumers.py +0 -19
- swarm/extensions/blueprint/__init__.py +16 -30
- swarm/{core → extensions/blueprint}/agent_utils.py +1 -1
- swarm/extensions/blueprint/blueprint_base.py +458 -0
- swarm/extensions/blueprint/blueprint_discovery.py +112 -0
- swarm/extensions/blueprint/output_utils.py +95 -0
- swarm/{core → extensions/blueprint}/spinner.py +21 -30
- swarm/extensions/cli/cli_args.py +0 -6
- swarm/extensions/cli/commands/blueprint_management.py +9 -47
- swarm/extensions/cli/commands/config_management.py +6 -5
- swarm/extensions/cli/commands/edit_config.py +7 -16
- swarm/extensions/cli/commands/list_blueprints.py +1 -1
- swarm/extensions/cli/commands/validate_env.py +4 -11
- swarm/extensions/cli/commands/validate_envvars.py +6 -6
- swarm/extensions/cli/interactive_shell.py +2 -16
- swarm/extensions/config/config_loader.py +201 -107
- swarm/{core → extensions/config}/config_manager.py +38 -50
- swarm/{core → extensions/config}/server_config.py +0 -32
- swarm/extensions/launchers/build_launchers.py +14 -0
- swarm/{core → extensions/launchers}/build_swarm_wrapper.py +0 -0
- swarm/extensions/launchers/swarm_api.py +64 -8
- swarm/extensions/launchers/swarm_cli.py +300 -8
- swarm/llm/chat_completion.py +195 -0
- swarm/serializers.py +5 -96
- swarm/settings.py +111 -99
- swarm/urls.py +74 -57
- swarm/utils/context_utils.py +4 -10
- swarm/utils/general_utils.py +0 -21
- swarm/utils/redact.py +36 -23
- swarm/views/api_views.py +39 -48
- swarm/views/chat_views.py +70 -237
- swarm/views/core_views.py +87 -80
- swarm/views/model_views.py +121 -64
- swarm/views/utils.py +441 -65
- swarm/views/web_views.py +2 -2
- open_swarm-0.1.1745274976.dist-info/METADATA +0 -874
- open_swarm-0.1.1745274976.dist-info/RECORD +0 -318
- open_swarm-0.1.1745274976.dist-info/entry_points.txt +0 -4
- swarm/blueprints/README.md +0 -68
- swarm/blueprints/blueprint_audit_status.json +0 -27
- swarm/blueprints/chatbot/README.md +0 -40
- swarm/blueprints/chatbot/blueprint_chatbot.py +0 -471
- swarm/blueprints/chatbot/metadata.json +0 -23
- swarm/blueprints/chatbot/templates/chatbot/chatbot.html +0 -33
- swarm/blueprints/chucks_angels/README.md +0 -11
- swarm/blueprints/chucks_angels/blueprint_chucks_angels.py +0 -7
- swarm/blueprints/chucks_angels/test_basic.py +0 -3
- swarm/blueprints/codey/CODEY.md +0 -15
- swarm/blueprints/codey/README.md +0 -115
- swarm/blueprints/codey/blueprint_codey.py +0 -1072
- swarm/blueprints/codey/codey_cli.py +0 -373
- swarm/blueprints/codey/instructions.md +0 -17
- swarm/blueprints/codey/metadata.json +0 -23
- swarm/blueprints/common/operation_box_utils.py +0 -83
- swarm/blueprints/digitalbutlers/README.md +0 -11
- swarm/blueprints/digitalbutlers/__init__.py +0 -1
- swarm/blueprints/digitalbutlers/blueprint_digitalbutlers.py +0 -7
- swarm/blueprints/digitalbutlers/test_basic.py +0 -3
- swarm/blueprints/divine_code/README.md +0 -3
- swarm/blueprints/divine_code/__init__.py +0 -10
- swarm/blueprints/divine_code/apps.py +0 -11
- swarm/blueprints/divine_code/blueprint_divine_code.py +0 -270
- swarm/blueprints/django_chat/apps.py +0 -6
- swarm/blueprints/django_chat/blueprint_django_chat.py +0 -268
- swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html +0 -37
- swarm/blueprints/django_chat/urls.py +0 -8
- swarm/blueprints/django_chat/views.py +0 -32
- swarm/blueprints/echocraft/blueprint_echocraft.py +0 -384
- swarm/blueprints/flock/README.md +0 -11
- swarm/blueprints/flock/__init__.py +0 -8
- swarm/blueprints/flock/blueprint_flock.py +0 -7
- swarm/blueprints/flock/test_basic.py +0 -3
- swarm/blueprints/geese/README.md +0 -97
- swarm/blueprints/geese/blueprint_geese.py +0 -803
- swarm/blueprints/geese/geese_cli.py +0 -102
- swarm/blueprints/jeeves/README.md +0 -41
- swarm/blueprints/jeeves/blueprint_jeeves.py +0 -722
- swarm/blueprints/jeeves/jeeves_cli.py +0 -55
- swarm/blueprints/jeeves/metadata.json +0 -24
- swarm/blueprints/mcp_demo/blueprint_mcp_demo.py +0 -473
- swarm/blueprints/messenger/templates/messenger/messenger.html +0 -46
- swarm/blueprints/mission_improbable/blueprint_mission_improbable.py +0 -423
- swarm/blueprints/monkai_magic/blueprint_monkai_magic.py +0 -340
- swarm/blueprints/nebula_shellz/blueprint_nebula_shellz.py +0 -265
- swarm/blueprints/omniplex/blueprint_omniplex.py +0 -298
- swarm/blueprints/poets/blueprint_poets.py +0 -546
- swarm/blueprints/poets/poets_cli.py +0 -23
- swarm/blueprints/rue_code/README.md +0 -8
- swarm/blueprints/rue_code/blueprint_rue_code.py +0 -448
- swarm/blueprints/rue_code/rue_code_cli.py +0 -43
- swarm/blueprints/stewie/apps.py +0 -12
- swarm/blueprints/stewie/blueprint_family_ties.py +0 -349
- swarm/blueprints/stewie/models.py +0 -19
- swarm/blueprints/stewie/serializers.py +0 -10
- swarm/blueprints/stewie/settings.py +0 -17
- swarm/blueprints/stewie/urls.py +0 -11
- swarm/blueprints/stewie/views.py +0 -26
- swarm/blueprints/suggestion/blueprint_suggestion.py +0 -222
- swarm/blueprints/whinge_surf/README.md +0 -22
- swarm/blueprints/whinge_surf/__init__.py +0 -1
- swarm/blueprints/whinge_surf/blueprint_whinge_surf.py +0 -565
- swarm/blueprints/whinge_surf/whinge_surf_cli.py +0 -99
- swarm/blueprints/whiskeytango_foxtrot/__init__.py +0 -0
- swarm/blueprints/whiskeytango_foxtrot/apps.py +0 -11
- swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py +0 -339
- swarm/blueprints/zeus/__init__.py +0 -2
- swarm/blueprints/zeus/apps.py +0 -4
- swarm/blueprints/zeus/blueprint_zeus.py +0 -270
- swarm/blueprints/zeus/zeus_cli.py +0 -13
- swarm/cli/async_input.py +0 -65
- swarm/cli/async_input_demo.py +0 -32
- swarm/core/blueprint_base.py +0 -769
- swarm/core/blueprint_discovery.py +0 -125
- swarm/core/blueprint_runner.py +0 -59
- swarm/core/blueprint_ux.py +0 -109
- swarm/core/build_launchers.py +0 -15
- swarm/core/cli/__init__.py +0 -1
- swarm/core/cli/commands/__init__.py +0 -1
- swarm/core/cli/commands/blueprint_management.py +0 -7
- swarm/core/cli/interactive_shell.py +0 -14
- swarm/core/cli/main.py +0 -50
- swarm/core/cli/utils/__init__.py +0 -1
- swarm/core/cli/utils/discover_commands.py +0 -18
- swarm/core/config_loader.py +0 -122
- swarm/core/output_utils.py +0 -193
- swarm/core/session_logger.py +0 -42
- swarm/core/slash_commands.py +0 -89
- swarm/core/swarm_api.py +0 -68
- swarm/core/swarm_cli.py +0 -216
- swarm/core/utils/__init__.py +0 -0
- swarm/extensions/blueprint/cli_handler.py +0 -197
- swarm/extensions/blueprint/runnable_blueprint.py +0 -42
- swarm/extensions/cli/utils/__init__.py +0 -1
- swarm/extensions/cli/utils/async_input.py +0 -46
- swarm/extensions/cli/utils/prompt_user.py +0 -3
- swarm/management/__init__.py +0 -0
- swarm/management/commands/__init__.py +0 -0
- swarm/management/commands/runserver.py +0 -58
- swarm/middleware.py +0 -65
- swarm/permissions.py +0 -38
- swarm/static/contrib/fonts/fontawesome-webfont.ttf +0 -7
- swarm/static/contrib/fonts/fontawesome-webfont.woff +0 -7
- swarm/static/contrib/fonts/fontawesome-webfont.woff2 +0 -7
- swarm/static/contrib/markedjs/marked.min.js +0 -6
- swarm/static/contrib/tabler-icons/adjustments-horizontal.svg +0 -27
- swarm/static/contrib/tabler-icons/alert-triangle.svg +0 -21
- swarm/static/contrib/tabler-icons/archive.svg +0 -21
- swarm/static/contrib/tabler-icons/artboard.svg +0 -27
- swarm/static/contrib/tabler-icons/automatic-gearbox.svg +0 -23
- swarm/static/contrib/tabler-icons/box-multiple.svg +0 -19
- swarm/static/contrib/tabler-icons/carambola.svg +0 -19
- swarm/static/contrib/tabler-icons/copy.svg +0 -20
- swarm/static/contrib/tabler-icons/download.svg +0 -21
- swarm/static/contrib/tabler-icons/edit.svg +0 -21
- swarm/static/contrib/tabler-icons/filled/carambola.svg +0 -13
- swarm/static/contrib/tabler-icons/filled/paint.svg +0 -13
- swarm/static/contrib/tabler-icons/headset.svg +0 -22
- swarm/static/contrib/tabler-icons/layout-sidebar-left-collapse.svg +0 -21
- swarm/static/contrib/tabler-icons/layout-sidebar-left-expand.svg +0 -21
- swarm/static/contrib/tabler-icons/layout-sidebar-right-collapse.svg +0 -21
- swarm/static/contrib/tabler-icons/layout-sidebar-right-expand.svg +0 -21
- swarm/static/contrib/tabler-icons/message-chatbot.svg +0 -22
- swarm/static/contrib/tabler-icons/message-star.svg +0 -22
- swarm/static/contrib/tabler-icons/message-x.svg +0 -23
- swarm/static/contrib/tabler-icons/message.svg +0 -21
- swarm/static/contrib/tabler-icons/paperclip.svg +0 -18
- swarm/static/contrib/tabler-icons/playlist-add.svg +0 -22
- swarm/static/contrib/tabler-icons/robot.svg +0 -26
- swarm/static/contrib/tabler-icons/search.svg +0 -19
- swarm/static/contrib/tabler-icons/settings.svg +0 -20
- swarm/static/contrib/tabler-icons/thumb-down.svg +0 -19
- swarm/static/contrib/tabler-icons/thumb-up.svg +0 -19
- swarm/static/css/dropdown.css +0 -22
- swarm/static/htmx/htmx.min.js +0 -0
- swarm/static/js/dropdown.js +0 -23
- swarm/static/rest_mode/css/base.css +0 -470
- swarm/static/rest_mode/css/chat-history.css +0 -286
- swarm/static/rest_mode/css/chat.css +0 -251
- swarm/static/rest_mode/css/chatbot.css +0 -74
- swarm/static/rest_mode/css/chatgpt.css +0 -62
- swarm/static/rest_mode/css/colors/corporate.css +0 -74
- swarm/static/rest_mode/css/colors/pastel.css +0 -81
- swarm/static/rest_mode/css/colors/tropical.css +0 -82
- swarm/static/rest_mode/css/general.css +0 -142
- swarm/static/rest_mode/css/layout.css +0 -167
- swarm/static/rest_mode/css/layouts/messenger-layout.css +0 -17
- swarm/static/rest_mode/css/layouts/minimalist-layout.css +0 -57
- swarm/static/rest_mode/css/layouts/mobile-layout.css +0 -8
- swarm/static/rest_mode/css/messages.css +0 -84
- swarm/static/rest_mode/css/messenger.css +0 -135
- swarm/static/rest_mode/css/settings.css +0 -91
- swarm/static/rest_mode/css/simple.css +0 -44
- swarm/static/rest_mode/css/slack.css +0 -58
- swarm/static/rest_mode/css/style.css +0 -156
- swarm/static/rest_mode/css/theme.css +0 -30
- swarm/static/rest_mode/css/toast.css +0 -40
- swarm/static/rest_mode/js/auth.js +0 -9
- swarm/static/rest_mode/js/blueprint.js +0 -41
- swarm/static/rest_mode/js/blueprintUtils.js +0 -12
- swarm/static/rest_mode/js/chatLogic.js +0 -79
- swarm/static/rest_mode/js/debug.js +0 -63
- swarm/static/rest_mode/js/events.js +0 -98
- swarm/static/rest_mode/js/main.js +0 -19
- swarm/static/rest_mode/js/messages.js +0 -264
- swarm/static/rest_mode/js/messengerLogic.js +0 -355
- swarm/static/rest_mode/js/modules/apiService.js +0 -84
- swarm/static/rest_mode/js/modules/blueprintManager.js +0 -162
- swarm/static/rest_mode/js/modules/chatHistory.js +0 -110
- swarm/static/rest_mode/js/modules/debugLogger.js +0 -14
- swarm/static/rest_mode/js/modules/eventHandlers.js +0 -107
- swarm/static/rest_mode/js/modules/messageProcessor.js +0 -120
- swarm/static/rest_mode/js/modules/state.js +0 -7
- swarm/static/rest_mode/js/modules/userInteractions.js +0 -29
- swarm/static/rest_mode/js/modules/validation.js +0 -23
- swarm/static/rest_mode/js/rendering.js +0 -119
- swarm/static/rest_mode/js/settings.js +0 -130
- swarm/static/rest_mode/js/sidebar.js +0 -94
- swarm/static/rest_mode/js/simpleLogic.js +0 -37
- swarm/static/rest_mode/js/slackLogic.js +0 -66
- swarm/static/rest_mode/js/splash.js +0 -76
- swarm/static/rest_mode/js/theme.js +0 -111
- swarm/static/rest_mode/js/toast.js +0 -36
- swarm/static/rest_mode/js/ui.js +0 -265
- swarm/static/rest_mode/js/validation.js +0 -57
- swarm/static/rest_mode/svg/animated_spinner.svg +0 -12
- swarm/static/rest_mode/svg/arrow_down.svg +0 -5
- swarm/static/rest_mode/svg/arrow_left.svg +0 -5
- swarm/static/rest_mode/svg/arrow_right.svg +0 -5
- swarm/static/rest_mode/svg/arrow_up.svg +0 -5
- swarm/static/rest_mode/svg/attach.svg +0 -8
- swarm/static/rest_mode/svg/avatar.svg +0 -7
- swarm/static/rest_mode/svg/canvas.svg +0 -6
- swarm/static/rest_mode/svg/chat_history.svg +0 -4
- swarm/static/rest_mode/svg/close.svg +0 -5
- swarm/static/rest_mode/svg/copy.svg +0 -4
- swarm/static/rest_mode/svg/dark_mode.svg +0 -3
- swarm/static/rest_mode/svg/edit.svg +0 -5
- swarm/static/rest_mode/svg/layout.svg +0 -9
- swarm/static/rest_mode/svg/logo.svg +0 -29
- swarm/static/rest_mode/svg/logout.svg +0 -5
- swarm/static/rest_mode/svg/mobile.svg +0 -5
- swarm/static/rest_mode/svg/new_chat.svg +0 -4
- swarm/static/rest_mode/svg/not_visible.svg +0 -5
- swarm/static/rest_mode/svg/plus.svg +0 -7
- swarm/static/rest_mode/svg/run_code.svg +0 -6
- swarm/static/rest_mode/svg/save.svg +0 -4
- swarm/static/rest_mode/svg/search.svg +0 -6
- swarm/static/rest_mode/svg/settings.svg +0 -4
- swarm/static/rest_mode/svg/speaker.svg +0 -5
- swarm/static/rest_mode/svg/stop.svg +0 -6
- swarm/static/rest_mode/svg/thumbs_down.svg +0 -3
- swarm/static/rest_mode/svg/thumbs_up.svg +0 -3
- swarm/static/rest_mode/svg/toggle_off.svg +0 -6
- swarm/static/rest_mode/svg/toggle_on.svg +0 -6
- swarm/static/rest_mode/svg/trash.svg +0 -10
- swarm/static/rest_mode/svg/undo.svg +0 -3
- swarm/static/rest_mode/svg/visible.svg +0 -8
- swarm/static/rest_mode/svg/voice.svg +0 -10
- swarm/templates/account/login.html +0 -22
- swarm/templates/account/signup.html +0 -32
- swarm/templates/base.html +0 -30
- swarm/templates/chat.html +0 -43
- swarm/templates/index.html +0 -35
- swarm/templates/rest_mode/components/chat_sidebar.html +0 -55
- swarm/templates/rest_mode/components/header.html +0 -45
- swarm/templates/rest_mode/components/main_chat_pane.html +0 -41
- swarm/templates/rest_mode/components/settings_dialog.html +0 -97
- swarm/templates/rest_mode/components/splash_screen.html +0 -7
- swarm/templates/rest_mode/components/top_bar.html +0 -28
- swarm/templates/rest_mode/message_ui.html +0 -50
- swarm/templates/rest_mode/slackbot.html +0 -30
- swarm/templates/simple_blueprint_page.html +0 -24
- swarm/templates/websocket_partials/final_system_message.html +0 -3
- swarm/templates/websocket_partials/system_message.html +0 -4
- swarm/templates/websocket_partials/user_message.html +0 -5
- swarm/utils/ansi_box.py +0 -34
- swarm/utils/disable_tracing.py +0 -38
- swarm/utils/log_utils.py +0 -63
- swarm/utils/openai_patch.py +0 -33
- swarm/ux/ansi_box.py +0 -43
- swarm/ux/spinner.py +0 -53
- {open_swarm-0.1.1745274976.dist-info → open_swarm-0.1.1748636259.dist-info}/licenses/LICENSE +0 -0
- /swarm/{core → extensions/blueprint}/blueprint_utils.py +0 -0
- /swarm/{core → extensions/blueprint}/common_utils.py +0 -0
- /swarm/{core → extensions/config}/setup_wizard.py +0 -0
- /swarm/{blueprints/rue_code → extensions/config/utils}/__init__.py +0 -0
- /swarm/{core → extensions/config}/utils/logger.py +0 -0
- /swarm/{core → extensions/launchers}/swarm_wrapper.py +0 -0
@@ -1,384 +0,0 @@
|
|
1
|
-
# --- Content for src/swarm/blueprints/echocraft/blueprint_echocraft.py ---
|
2
|
-
import logging
|
3
|
-
from typing import Optional
|
4
|
-
from pathlib import Path
|
5
|
-
from typing import List, Dict, Any, AsyncGenerator
|
6
|
-
import uuid # Import uuid to generate IDs
|
7
|
-
import time # Import time for timestamp
|
8
|
-
import os
|
9
|
-
from datetime import datetime
|
10
|
-
import pytz
|
11
|
-
|
12
|
-
from swarm.core.blueprint_base import BlueprintBase
|
13
|
-
from agents import function_tool
|
14
|
-
# Patch: Expose underlying fileops functions for direct testing
|
15
|
-
class PatchedFunctionTool:
|
16
|
-
def __init__(self, func, name):
|
17
|
-
self.func = func
|
18
|
-
self.name = name
|
19
|
-
|
20
|
-
def read_file(path: str) -> str:
|
21
|
-
try:
|
22
|
-
with open(path, 'r') as f:
|
23
|
-
return f.read()
|
24
|
-
except Exception as e:
|
25
|
-
return f"ERROR: {e}"
|
26
|
-
def write_file(path: str, content: str) -> str:
|
27
|
-
try:
|
28
|
-
with open(path, 'w') as f:
|
29
|
-
f.write(content)
|
30
|
-
return "OK: file written"
|
31
|
-
except Exception as e:
|
32
|
-
return f"ERROR: {e}"
|
33
|
-
def list_files(directory: str = '.') -> str:
|
34
|
-
try:
|
35
|
-
return '\n'.join(os.listdir(directory))
|
36
|
-
except Exception as e:
|
37
|
-
return f"ERROR: {e}"
|
38
|
-
def execute_shell_command(command: str) -> str:
|
39
|
-
"""
|
40
|
-
Executes a shell command and returns its stdout and stderr.
|
41
|
-
Timeout is configurable via SWARM_COMMAND_TIMEOUT (default: 60s).
|
42
|
-
"""
|
43
|
-
logger.info(f"Executing shell command: {command}")
|
44
|
-
try:
|
45
|
-
import os
|
46
|
-
timeout = int(os.getenv("SWARM_COMMAND_TIMEOUT", "60"))
|
47
|
-
result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=timeout)
|
48
|
-
output = f"Exit Code: {result.returncode}\n"
|
49
|
-
if result.stdout:
|
50
|
-
output += f"STDOUT:\n{result.stdout}\n"
|
51
|
-
if result.stderr:
|
52
|
-
output += f"STDERR:\n{result.stderr}\n"
|
53
|
-
logger.info(f"Command finished. Exit Code: {result.returncode}")
|
54
|
-
return output.strip()
|
55
|
-
except subprocess.TimeoutExpired:
|
56
|
-
logger.error(f"Command timed out: {command}")
|
57
|
-
return f"Error: Command timed out after {os.getenv('SWARM_COMMAND_TIMEOUT', '60')} seconds."
|
58
|
-
except Exception as e:
|
59
|
-
logger.error(f"Error executing command '{command}': {e}", exc_info=True)
|
60
|
-
return f"Error executing command: {e}"
|
61
|
-
read_file_tool = PatchedFunctionTool(read_file, 'read_file')
|
62
|
-
write_file_tool = PatchedFunctionTool(write_file, 'write_file')
|
63
|
-
list_files_tool = PatchedFunctionTool(list_files, 'list_files')
|
64
|
-
execute_shell_command_tool = PatchedFunctionTool(execute_shell_command, 'execute_shell_command')
|
65
|
-
|
66
|
-
logger = logging.getLogger(__name__)
|
67
|
-
|
68
|
-
# Last swarm update: 2024-03-07T14:30:00Z (UTC)
|
69
|
-
# Spinner UX enhancement (Open Swarm TODO)
|
70
|
-
SPINNER_STATES = ['Generating.', 'Generating..', 'Generating...', 'Running...']
|
71
|
-
|
72
|
-
"""
|
73
|
-
EchoCraft Blueprint
|
74
|
-
|
75
|
-
Viral docstring update: Operational as of {} (UTC).
|
76
|
-
Self-healing, fileops-enabled, swarm-scalable.
|
77
|
-
"""
|
78
|
-
|
79
|
-
# [Swarm Propagation] Next Blueprint: rue_code
|
80
|
-
# rue_code key vars: logger, project_root, src_path
|
81
|
-
# rue_code guard: if src_path not in sys.path: sys.path.insert(0, src_path)
|
82
|
-
# rue_code debug: logger.debug("RueCode agent created: Rue (Coordinator)")
|
83
|
-
# rue_code error handling: try/except ImportError with sys.exit(1)
|
84
|
-
|
85
|
-
class EchoCraftBlueprint(BlueprintBase):
|
86
|
-
def __init__(self, blueprint_id: str = "echocraft", config=None, config_path=None, **kwargs):
|
87
|
-
super().__init__(blueprint_id, config=config, config_path=config_path, **kwargs)
|
88
|
-
self.blueprint_id = blueprint_id
|
89
|
-
self.config_path = config_path
|
90
|
-
self._config = config if config is not None else {}
|
91
|
-
self._llm_profile_name = None
|
92
|
-
self._llm_profile_data = None
|
93
|
-
self._markdown_output = None
|
94
|
-
# Add other attributes as needed for Echocraft
|
95
|
-
# ...
|
96
|
-
|
97
|
-
"""
|
98
|
-
A simple blueprint that echoes the last user message.
|
99
|
-
Used for testing and demonstrating basic blueprint structure.
|
100
|
-
"""
|
101
|
-
|
102
|
-
# No specific __init__ needed beyond the base class unless adding more params
|
103
|
-
# def __init__(self, blueprint_id: str, **kwargs):
|
104
|
-
# super().__init__(blueprint_id=blueprint_id, **kwargs)
|
105
|
-
# logger.info(f"EchoCraftBlueprint '{self.blueprint_id}' initialized.")
|
106
|
-
|
107
|
-
# --- FileOps Tool Logic Definitions ---
|
108
|
-
def read_file(path: str) -> str:
|
109
|
-
try:
|
110
|
-
with open(path, 'r') as f:
|
111
|
-
return f.read()
|
112
|
-
except Exception as e:
|
113
|
-
return f"ERROR: {e}"
|
114
|
-
def write_file(path: str, content: str) -> str:
|
115
|
-
try:
|
116
|
-
with open(path, 'w') as f:
|
117
|
-
f.write(content)
|
118
|
-
return "OK: file written"
|
119
|
-
except Exception as e:
|
120
|
-
return f"ERROR: {e}"
|
121
|
-
def list_files(directory: str = '.') -> str:
|
122
|
-
try:
|
123
|
-
return '\n'.join(os.listdir(directory))
|
124
|
-
except Exception as e:
|
125
|
-
return f"ERROR: {e}"
|
126
|
-
def execute_shell_command(self, command: str) -> str:
|
127
|
-
"""
|
128
|
-
Executes a shell command and returns its stdout and stderr.
|
129
|
-
Timeout is configurable via SWARM_COMMAND_TIMEOUT (default: 60s).
|
130
|
-
"""
|
131
|
-
logger.info(f"Executing shell command: {command}")
|
132
|
-
try:
|
133
|
-
import os
|
134
|
-
timeout = int(os.getenv("SWARM_COMMAND_TIMEOUT", "60"))
|
135
|
-
result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=timeout)
|
136
|
-
output = f"Exit Code: {result.returncode}\n"
|
137
|
-
if result.stdout:
|
138
|
-
output += f"STDOUT:\n{result.stdout}\n"
|
139
|
-
if result.stderr:
|
140
|
-
output += f"STDERR:\n{result.stderr}\n"
|
141
|
-
logger.info(f"Command finished. Exit Code: {result.returncode}")
|
142
|
-
return output.strip()
|
143
|
-
except subprocess.TimeoutExpired:
|
144
|
-
logger.error(f"Command timed out: {command}")
|
145
|
-
return f"Error: Command timed out after {os.getenv('SWARM_COMMAND_TIMEOUT', '60')} seconds."
|
146
|
-
except Exception as e:
|
147
|
-
logger.error(f"Error executing command '{command}': {e}", exc_info=True)
|
148
|
-
return f"Error executing command: {e}"
|
149
|
-
read_file_tool = PatchedFunctionTool(read_file, 'read_file')
|
150
|
-
write_file_tool = PatchedFunctionTool(write_file, 'write_file')
|
151
|
-
list_files_tool = PatchedFunctionTool(list_files, 'list_files')
|
152
|
-
execute_shell_command_tool = PatchedFunctionTool(execute_shell_command, 'execute_shell_command')
|
153
|
-
|
154
|
-
async def _original_run(self, messages: List[Dict[str, Any]], **kwargs: Any) -> AsyncGenerator[Dict[str, Any], None]:
|
155
|
-
"""
|
156
|
-
Echoes the content of the last message with role 'user'.
|
157
|
-
Yields a final message in OpenAI ChatCompletion format.
|
158
|
-
"""
|
159
|
-
logger.info(f"EchoCraftBlueprint run called with {len(messages)} messages.")
|
160
|
-
|
161
|
-
# Ensure LLM profile is initialized for test compatibility
|
162
|
-
if self._llm_profile_name is None:
|
163
|
-
self._llm_profile_name = self.config.get("llm_profile", "default")
|
164
|
-
|
165
|
-
last_user_message_content = "No user message found."
|
166
|
-
for msg in reversed(messages):
|
167
|
-
if msg.get("role") == "user":
|
168
|
-
last_user_message_content = msg.get("content", "(empty content)")
|
169
|
-
logger.debug(f"Found last user message: {last_user_message_content}")
|
170
|
-
break
|
171
|
-
|
172
|
-
echo_content = f"Echo: {last_user_message_content}"
|
173
|
-
logger.info(f"EchoCraftBlueprint yielding: {echo_content}")
|
174
|
-
|
175
|
-
# --- Format the final output as an OpenAI ChatCompletion object ---
|
176
|
-
completion_id = f"chatcmpl-echo-{uuid.uuid4()}"
|
177
|
-
created_timestamp = int(time.time())
|
178
|
-
|
179
|
-
final_message_chunk = {
|
180
|
-
"id": completion_id,
|
181
|
-
"object": "chat.completion",
|
182
|
-
"created": created_timestamp,
|
183
|
-
"model": self.llm_profile_name, # Use profile name as model identifier
|
184
|
-
"choices": [
|
185
|
-
{
|
186
|
-
"index": 0,
|
187
|
-
"message": {
|
188
|
-
"role": "assistant",
|
189
|
-
"content": echo_content,
|
190
|
-
},
|
191
|
-
"finish_reason": "stop",
|
192
|
-
"logprobs": None, # Add null logprobs if needed
|
193
|
-
}
|
194
|
-
],
|
195
|
-
# Add usage stats if desired/possible
|
196
|
-
# "usage": {
|
197
|
-
# "prompt_tokens": 0,
|
198
|
-
# "completion_tokens": 0,
|
199
|
-
# "total_tokens": 0
|
200
|
-
# }
|
201
|
-
}
|
202
|
-
yield final_message_chunk
|
203
|
-
# --- End formatting change ---
|
204
|
-
|
205
|
-
logger.info("EchoCraftBlueprint run finished.")
|
206
|
-
|
207
|
-
async def run(self, messages: List[Dict[str, Any]], **kwargs: Any) -> AsyncGenerator[Dict[str, Any], None]:
|
208
|
-
last_result = None
|
209
|
-
async for result in self._original_run(messages):
|
210
|
-
last_result = result
|
211
|
-
yield result
|
212
|
-
if last_result is not None:
|
213
|
-
await self.reflect_and_learn(messages, last_result)
|
214
|
-
|
215
|
-
async def reflect_and_learn(self, messages, result):
|
216
|
-
log = {
|
217
|
-
'task': messages,
|
218
|
-
'result': result,
|
219
|
-
'reflection': 'Success' if self.success_criteria(result) else 'Needs improvement',
|
220
|
-
'alternatives': self.consider_alternatives(messages, result),
|
221
|
-
'swarm_lessons': self.query_swarm_knowledge(messages)
|
222
|
-
}
|
223
|
-
self.write_to_swarm_log(log)
|
224
|
-
|
225
|
-
def success_criteria(self, result):
|
226
|
-
if not result or (isinstance(result, dict) and 'error' in result):
|
227
|
-
return False
|
228
|
-
if isinstance(result, list) and result and 'error' in result[0].get('messages', [{}])[0].get('content', '').lower():
|
229
|
-
return False
|
230
|
-
return True
|
231
|
-
|
232
|
-
def consider_alternatives(self, messages, result):
|
233
|
-
alternatives = []
|
234
|
-
if not self.success_criteria(result):
|
235
|
-
alternatives.append('Try echoing a different message.')
|
236
|
-
alternatives.append('Use a fallback echo agent.')
|
237
|
-
else:
|
238
|
-
alternatives.append('Add sentiment analysis to the echo.')
|
239
|
-
return alternatives
|
240
|
-
|
241
|
-
def query_swarm_knowledge(self, messages):
|
242
|
-
import json, os
|
243
|
-
path = os.path.join(os.path.dirname(__file__), '../../../swarm_knowledge.json')
|
244
|
-
if not os.path.exists(path):
|
245
|
-
return []
|
246
|
-
with open(path, 'r') as f:
|
247
|
-
knowledge = json.load(f)
|
248
|
-
task_str = json.dumps(messages)
|
249
|
-
return [entry for entry in knowledge if entry.get('task_str') == task_str]
|
250
|
-
|
251
|
-
def write_to_swarm_log(self, log):
|
252
|
-
import json, os, time
|
253
|
-
from filelock import FileLock, Timeout
|
254
|
-
path = os.path.join(os.path.dirname(__file__), '../../../swarm_log.json')
|
255
|
-
lock_path = path + '.lock'
|
256
|
-
log['task_str'] = json.dumps(log['task'])
|
257
|
-
for attempt in range(10):
|
258
|
-
try:
|
259
|
-
with FileLock(lock_path, timeout=5):
|
260
|
-
if os.path.exists(path):
|
261
|
-
with open(path, 'r') as f:
|
262
|
-
try:
|
263
|
-
logs = json.load(f)
|
264
|
-
except json.JSONDecodeError:
|
265
|
-
logs = []
|
266
|
-
else:
|
267
|
-
logs = []
|
268
|
-
logs.append(log)
|
269
|
-
with open(path, 'w') as f:
|
270
|
-
json.dump(logs, f, indent=2)
|
271
|
-
break
|
272
|
-
except Timeout:
|
273
|
-
time.sleep(0.2 * (attempt + 1))
|
274
|
-
|
275
|
-
def create_starting_agent(self, mcp_servers):
|
276
|
-
echo_agent = self.make_agent(
|
277
|
-
name="EchoCraft",
|
278
|
-
instructions="You are EchoCraft, the echo agent. You can use fileops tools (read_file, write_file, list_files, execute_shell_command) for any file or shell tasks.",
|
279
|
-
tools=[self.read_file_tool, self.write_file_tool, self.list_files_tool, self.execute_shell_command_tool],
|
280
|
-
mcp_servers=mcp_servers
|
281
|
-
)
|
282
|
-
return echo_agent
|
283
|
-
|
284
|
-
# --- Spinner and ANSI/emoji operation box for unified UX (for CLI/dev runs) ---
|
285
|
-
from swarm.ux.ansi_box import ansi_box
|
286
|
-
from rich.console import Console
|
287
|
-
from rich.style import Style
|
288
|
-
from rich.text import Text
|
289
|
-
import threading
|
290
|
-
import time
|
291
|
-
|
292
|
-
class EchoCraftSpinner:
|
293
|
-
FRAMES = [
|
294
|
-
"Generating.", "Generating..", "Generating...", "Running...",
|
295
|
-
"⠋ Generating...", "⠙ Generating...", "⠹ Generating...", "⠸ Generating...",
|
296
|
-
"⠼ Generating...", "⠴ Generating...", "⠦ Generating...", "⠧ Generating...",
|
297
|
-
"⠇ Generating...", "⠏ Generating...", "🤖 Generating...", "💡 Generating...", "✨ Generating..."
|
298
|
-
]
|
299
|
-
SLOW_FRAME = "Generating... Taking longer than expected"
|
300
|
-
INTERVAL = 0.12
|
301
|
-
SLOW_THRESHOLD = 10 # seconds
|
302
|
-
|
303
|
-
def __init__(self):
|
304
|
-
self._stop_event = threading.Event()
|
305
|
-
self._thread = None
|
306
|
-
self._start_time = None
|
307
|
-
self.console = Console()
|
308
|
-
self._last_frame = None
|
309
|
-
self._last_slow = False
|
310
|
-
|
311
|
-
def start(self):
|
312
|
-
self._stop_event.clear()
|
313
|
-
self._start_time = time.time()
|
314
|
-
self._thread = threading.Thread(target=self._spin, daemon=True)
|
315
|
-
self._thread.start()
|
316
|
-
|
317
|
-
def _spin(self):
|
318
|
-
idx = 0
|
319
|
-
while not self._stop_event.is_set():
|
320
|
-
elapsed = time.time() - self._start_time
|
321
|
-
if elapsed > self.SLOW_THRESHOLD:
|
322
|
-
txt = Text(self.SLOW_FRAME, style=Style(color="yellow", bold=True))
|
323
|
-
self._last_frame = self.SLOW_FRAME
|
324
|
-
self._last_slow = True
|
325
|
-
else:
|
326
|
-
frame = self.FRAMES[idx % len(self.FRAMES)]
|
327
|
-
txt = Text(frame, style=Style(color="cyan", bold=True))
|
328
|
-
self._last_frame = frame
|
329
|
-
self._last_slow = False
|
330
|
-
self.console.print(txt, end="\r", soft_wrap=True, highlight=False)
|
331
|
-
time.sleep(self.INTERVAL)
|
332
|
-
idx += 1
|
333
|
-
self.console.print(" " * 40, end="\r") # Clear line
|
334
|
-
|
335
|
-
def stop(self, final_message="Done!"):
|
336
|
-
self._stop_event.set()
|
337
|
-
if self._thread:
|
338
|
-
self._thread.join()
|
339
|
-
self.console.print(Text(final_message, style=Style(color="green", bold=True)))
|
340
|
-
|
341
|
-
def current_spinner_state(self):
|
342
|
-
if self._last_slow:
|
343
|
-
return self.SLOW_FRAME
|
344
|
-
return self._last_frame or self.FRAMES[0]
|
345
|
-
|
346
|
-
|
347
|
-
def print_operation_box(op_type, results, params=None, result_type="echo", taking_long=False):
|
348
|
-
emoji = "🗣️" if result_type == "echo" else "🔍"
|
349
|
-
style = 'success' if result_type == "echo" else 'default'
|
350
|
-
box_title = op_type if op_type else ("EchoCraft Output" if result_type == "echo" else "Results")
|
351
|
-
summary_lines = []
|
352
|
-
count = len(results) if isinstance(results, list) else 0
|
353
|
-
summary_lines.append(f"Results: {count}")
|
354
|
-
if params:
|
355
|
-
for k, v in params.items():
|
356
|
-
summary_lines.append(f"{k.capitalize()}: {v}")
|
357
|
-
box_content = "\n".join(summary_lines + ["\n".join(map(str, results))])
|
358
|
-
ansi_box(box_title, box_content, count=count, params=params, style=style if not taking_long else 'warning', emoji=emoji)
|
359
|
-
|
360
|
-
if __name__ == "__main__":
|
361
|
-
import asyncio
|
362
|
-
import json
|
363
|
-
print("\033[1;36m\n╔══════════════════════════════════════════════════════════════╗\n║ 🗣️ ECHOCRAFT: MESSAGE MIRROR & SWARM UX DEMO ║\n╠══════════════════════════════════════════════════════════════╣\n║ This blueprint echoes user messages, demonstrates swarm UX, ║\n║ and showcases viral docstring propagation. ║\n║ Try running: python blueprint_echocraft.py ║\n╚══════════════════════════════════════════════════════════════╝\033[0m")
|
364
|
-
messages = [
|
365
|
-
{"role": "user", "content": "Show me how EchoCraft mirrors messages and benefits from swarm UX patterns."}
|
366
|
-
]
|
367
|
-
blueprint = EchoCraftBlueprint(blueprint_id="demo-1")
|
368
|
-
async def run_and_print():
|
369
|
-
spinner = EchoCraftSpinner()
|
370
|
-
spinner.start()
|
371
|
-
try:
|
372
|
-
all_results = []
|
373
|
-
async for response in blueprint.run(messages):
|
374
|
-
content = response["messages"][0]["content"]
|
375
|
-
all_results.append(content)
|
376
|
-
finally:
|
377
|
-
spinner.stop()
|
378
|
-
print_operation_box(
|
379
|
-
op_type="EchoCraft Output",
|
380
|
-
results=all_results,
|
381
|
-
params={"prompt": messages[0]["content"]},
|
382
|
-
result_type="echo"
|
383
|
-
)
|
384
|
-
asyncio.run(run_and_print())
|
swarm/blueprints/flock/README.md
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
# Enhanced search/analysis UX: show ANSI/emoji boxes, summarize results, show result counts, display params, update line numbers, distinguish code/semantic
|
2
|
-
# This is a stub for flock blueprint search/analysis UX. (If this blueprint is implemented, the run method should follow the unified UX pattern.)
|
3
|
-
|
4
|
-
# No run method in __init__.py, but if/when a blueprint is implemented here, ensure:
|
5
|
-
# - Support for both code and semantic search (with clear output distinction)
|
6
|
-
# - ANSI/emoji boxes for search/analysis, with result counts, search params, and progress
|
7
|
-
# - Creative output box for non-search/agent output
|
8
|
-
# - Spinner states: 'Generating.', 'Generating..', 'Generating...', 'Running...'
|
swarm/blueprints/geese/README.md
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
# Geese Blueprint
|
2
|
-
|
3
|
-
**Geese** is special because it brings fun and whimsy to Open Swarm through animated bird prompts and playful interactions. Perfect for lightening the mood while you work!
|
4
|
-
|
5
|
-
## Special Feature
|
6
|
-
- **Fun Bird Animation Prompts:** Enjoy unique, animated geese interactions and prompts that make your workflow more enjoyable.
|
7
|
-
|
8
|
-
---
|
9
|
-
|
10
|
-
A collaborative story writing blueprint for Open Swarm that leverages multiple specialized agents to create, edit, and refine stories.
|
11
|
-
|
12
|
-
## Features
|
13
|
-
|
14
|
-
### Enhanced UI/UX
|
15
|
-
- 🎨 Rich ANSI/emoji boxes for operation feedback
|
16
|
-
- 📊 Dynamic result counts and search parameters
|
17
|
-
- ⏳ Intelligent progress spinners with state tracking
|
18
|
-
- ⚡ Real-time line number updates for long operations
|
19
|
-
- 🔄 Smart status messages for extended operations
|
20
|
-
|
21
|
-
### Core Capabilities
|
22
|
-
- 📋 Plan maintenance and tracking
|
23
|
-
- 📝 Multi-agent collaboration:
|
24
|
-
- Planner Agent: Story structure and task delegation
|
25
|
-
- Writer Agent: Content creation and development
|
26
|
-
- Editor Agent: Review and refinement
|
27
|
-
- Coordinator Agent: Process orchestration
|
28
|
-
- 🔍 Advanced search and analysis operations
|
29
|
-
- 🎯 Error handling and reflection
|
30
|
-
|
31
|
-
## Usage
|
32
|
-
|
33
|
-
```bash
|
34
|
-
# Basic story generation
|
35
|
-
swarm geese "Write a story about a magical forest"
|
36
|
-
|
37
|
-
# Interactive mode with file output
|
38
|
-
swarm geese -i input.txt -o output.txt --interactive
|
39
|
-
|
40
|
-
# Advanced mode with custom parameters
|
41
|
-
swarm geese --model gpt-4 --temperature 0.7 --max-tokens 4096 "Write an epic fantasy"
|
42
|
-
```
|
43
|
-
|
44
|
-
## Configuration
|
45
|
-
|
46
|
-
The blueprint supports various configuration options:
|
47
|
-
- Model selection (e.g., gpt-3.5-turbo, gpt-4)
|
48
|
-
- Temperature and token limits
|
49
|
-
- Input/output file handling
|
50
|
-
- Interactive mode for collaborative writing
|
51
|
-
|
52
|
-
## Operation Modes
|
53
|
-
|
54
|
-
1. **Generate Mode**: Create new stories from prompts
|
55
|
-
2. **Edit Mode**: Refine existing content
|
56
|
-
3. **Explain Mode**: Analyze story structure and elements
|
57
|
-
4. **Interactive Mode**: Real-time collaboration with the AI agents
|
58
|
-
|
59
|
-
## Implementation Details
|
60
|
-
|
61
|
-
The blueprint uses a multi-agent architecture where each agent has specialized roles:
|
62
|
-
- **Planner**: Structures stories and manages development flow
|
63
|
-
- **Writer**: Creates content based on outlines and context
|
64
|
-
- **Editor**: Reviews and improves content quality
|
65
|
-
- **Coordinator**: Orchestrates the entire process
|
66
|
-
|
67
|
-
## Notifier Abstraction & Reflection (New)
|
68
|
-
|
69
|
-
- All user-facing output (operation boxes, errors, info) is now handled through a Notifier abstraction, making it easy to redirect output to different UIs or for testing.
|
70
|
-
- The blueprint always displays the current plan, outputs of all operations, and any errors encountered, providing full transparency and reflection for users and agents.
|
71
|
-
- To customize output, pass a custom Notifier when instantiating the blueprint.
|
72
|
-
|
73
|
-
## Error Handling and Transparency
|
74
|
-
- Errors from agent operations are surfaced directly to the user in a styled error box, not just logged.
|
75
|
-
- The plan and tool outputs are always visible after each operation, mirroring the Goose agent’s reflection and transparency patterns.
|
76
|
-
|
77
|
-
## UI Elements
|
78
|
-
|
79
|
-
### Progress Indicators
|
80
|
-
- Custom spinner states: "Generating.", "Generating..", "Generating..."
|
81
|
-
- Extended operation indicator: "Taking longer than expected"
|
82
|
-
- Operation-specific emoji indicators
|
83
|
-
|
84
|
-
### Information Boxes
|
85
|
-
- 🔍 Search Results: Shows match counts and details
|
86
|
-
- 📊 Analysis: Displays content evaluation
|
87
|
-
- ✍️ Writing Progress: Shows current section status
|
88
|
-
- ✏️ Editing Updates: Shows improvement details
|
89
|
-
- 📋 Planning Status: Displays task completion
|
90
|
-
|
91
|
-
## Future Enhancements
|
92
|
-
|
93
|
-
- [ ] Enhanced error recovery
|
94
|
-
- [ ] Multi-format output support
|
95
|
-
- [ ] Advanced style configuration
|
96
|
-
- [ ] Custom agent templates
|
97
|
-
- [ ] Collaborative mode improvements
|