open-swarm 0.1.1743362777__tar.gz → 0.1.1743368545__tar.gz
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.1743362777 → open_swarm-0.1.1743368545}/PKG-INFO +128 -59
- open_swarm-0.1.1743368545/README.md +199 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/pyproject.toml +2 -1
- open_swarm-0.1.1743368545/src/swarm/auth.py +121 -0
- open_swarm-0.1.1743368545/src/swarm/views/chat_views.py +243 -0
- open_swarm-0.1.1743368545/tests/api/conftest.py +32 -0
- open_swarm-0.1.1743368545/tests/api/test_chat_completions_validation_async.py +168 -0
- open_swarm-0.1.1743362777/README.md +0 -131
- open_swarm-0.1.1743362777/src/swarm/auth.py +0 -60
- open_swarm-0.1.1743362777/src/swarm/views/chat_views.py +0 -162
- open_swarm-0.1.1743362777/tests/api/test_chat_completions_validation_async.py +0 -179
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/.gitignore +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/LICENSE +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/agent/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/apps.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/README.md +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/burnt_noodles/blueprint_burnt_noodles.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/chatbot/blueprint_chatbot.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/chatbot/templates/chatbot/chatbot.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/digitalbutlers/blueprint_digitalbutlers.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/dilbot_universe/blueprint_dilbot_universe.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/divine_code/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/divine_code/apps.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/divine_code/blueprint_divine_code.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/django_chat/apps.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/django_chat/blueprint_django_chat.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/django_chat/urls.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/django_chat/views.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/echocraft/blueprint_echocraft.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/family_ties/apps.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/family_ties/blueprint_family_ties.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/family_ties/models.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/family_ties/serializers.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/family_ties/settings.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/family_ties/urls.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/family_ties/views.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/flock/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/gaggle/blueprint_gaggle.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/gotchaman/blueprint_gotchaman.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/mcp_demo/blueprint_mcp_demo.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/messenger/templates/messenger/messenger.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/mission_improbable/blueprint_mission_improbable.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/monkai_magic/blueprint_monkai_magic.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/nebula_shellz/blueprint_nebula_shellz.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/omniplex/blueprint_omniplex.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/rue_code/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/rue_code/blueprint_rue_code.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/suggestion/blueprint_suggestion.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/unapologetic_press/blueprint_unapologetic_press.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/whiskeytango_foxtrot/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/whiskeytango_foxtrot/apps.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/consumers.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/agent_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/blueprint_base.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/blueprint_discovery.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/blueprint_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/cli_handler.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/common_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/config_loader.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/django_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/interactive_mode.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/modes/rest_mode.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/output_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/blueprint/spinner.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/blueprint_runner.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/cli_args.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/commands/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/commands/blueprint_management.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/commands/config_management.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/commands/edit_config.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/commands/list_blueprints.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/commands/validate_env.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/commands/validate_envvars.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/interactive_shell.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/main.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/selection.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/utils/discover_commands.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/utils/env_setup.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/cli/utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/config/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/config/config_loader.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/config/config_manager.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/config/server_config.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/config/setup_wizard.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/config/utils/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/config/utils/logger.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/launchers/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/launchers/build_launchers.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/launchers/build_swarm_wrapper.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/launchers/swarm_api.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/launchers/swarm_cli.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/extensions/launchers/swarm_wrapper.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/llm/chat_completion.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/management/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/management/commands/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/management/commands/runserver.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/messages.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/migrations/0010_initial_chat_models.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/migrations/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/models.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/permissions.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/repl/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/repl/repl.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/serializers.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/settings.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/fonts/fontawesome-webfont.ttf +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/fonts/fontawesome-webfont.woff +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/fonts/fontawesome-webfont.woff2 +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/markedjs/marked.min.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/adjustments-horizontal.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/alert-triangle.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/archive.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/artboard.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/automatic-gearbox.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/box-multiple.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/carambola.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/copy.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/download.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/edit.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/filled/carambola.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/filled/paint.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/headset.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/layout-sidebar-left-collapse.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/layout-sidebar-left-expand.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/layout-sidebar-right-collapse.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/layout-sidebar-right-expand.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/message-chatbot.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/message-star.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/message-x.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/message.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/paperclip.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/playlist-add.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/robot.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/search.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/settings.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/thumb-down.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/contrib/tabler-icons/thumb-up.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/css/dropdown.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/htmx/htmx.min.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/js/dropdown.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/base.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/chat-history.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/chat.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/chatbot.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/chatgpt.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/colors/corporate.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/colors/pastel.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/colors/tropical.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/general.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/layout.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/layouts/messenger-layout.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/layouts/minimalist-layout.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/layouts/mobile-layout.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/messages.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/messenger.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/settings.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/simple.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/slack.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/style.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/theme.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/css/toast.css +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/auth.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/blueprint.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/blueprintUtils.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/chatLogic.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/debug.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/events.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/main.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/messages.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/messengerLogic.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/apiService.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/blueprintManager.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/chatHistory.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/debugLogger.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/eventHandlers.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/messageProcessor.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/state.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/userInteractions.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/modules/validation.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/rendering.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/settings.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/sidebar.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/simpleLogic.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/slackLogic.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/splash.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/theme.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/toast.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/ui.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/js/validation.js +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/animated_spinner.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/arrow_down.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/arrow_left.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/arrow_right.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/arrow_up.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/attach.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/avatar.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/canvas.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/chat_history.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/close.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/copy.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/dark_mode.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/edit.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/layout.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/logo.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/logout.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/mobile.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/new_chat.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/not_visible.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/plus.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/run_code.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/save.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/search.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/settings.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/speaker.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/stop.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/thumbs_down.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/thumbs_up.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/toggle_off.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/toggle_on.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/trash.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/undo.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/visible.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/static/rest_mode/svg/voice.svg +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/account/login.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/account/signup.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/base.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/chat.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/index.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/components/chat_sidebar.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/components/header.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/components/main_chat_pane.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/components/settings_dialog.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/components/splash_screen.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/components/top_bar.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/message_ui.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/rest_mode/slackbot.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/simple_blueprint_page.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/websocket_partials/final_system_message.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/websocket_partials/system_message.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/templates/websocket_partials/user_message.html +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/tool_executor.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/urls.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/util.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/color_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/context_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/general_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/log_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/logger.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/logger_setup.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/message_sequence.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/message_utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/utils/redact.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/views/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/views/api_views.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/views/core_views.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/views/message_views.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/views/model_views.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/views/utils.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/views/web_views.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/src/swarm/wsgi.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/__init__.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/api/test_chat_completions_auth_async.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/api/test_chat_completions_failing_async.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_burnt_noodles.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_chatbot.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_digitalbutlers.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_dilbot_universe.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_divine_code.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_echocraft.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_family_ties.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_gaggle.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_gotchaman.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_mcp_demo.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_mission_improbable.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_monkai_magic.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_nebula_shellz.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_omniplex.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_suggestion.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_unapologetic_press.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/blueprints/test_whiskeytangofoxtrot.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/cli/test_launchers.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/cli/test_list_blueprints.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/conftest.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/swarm_config.json +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_burnt_noodles.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_chucks_angels.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_digitalbutlers.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_dilbot_universe.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_divine_code.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_django_chat.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_echocraft.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_family_ties.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_flock.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_gaggle.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_gotchaman.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_monkai-magic.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_nebula_shellz.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_omniplex.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_rue-code.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_suggestion.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_unapologetic_press.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_university.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/system/test_whiskeytango_foxtrot.sh +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_blueprint_loading.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_cli_mode_selection.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_core_filter_duplicate_system_messages.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_core_filter_messages.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_core_truncate_message_history.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_core_update_null_content.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_dummy.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/test_truncate_message_history.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/unit/blueprints/rue_code/test_rue_code_tools.py +0 -0
- {open_swarm-0.1.1743362777 → open_swarm-0.1.1743368545}/tests/unit/test_blueprint_base_config.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: open-swarm
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.1743368545
|
4
4
|
Summary: Open Swarm: Orchestrating AI Agent Swarms with Django
|
5
5
|
Project-URL: Homepage, https://github.com/yourusername/open-swarm
|
6
6
|
Project-URL: Documentation, https://github.com/yourusername/open-swarm/blob/main/README.md
|
@@ -40,6 +40,7 @@ Requires-Dist: google-auth-oauthlib>=1.2.1
|
|
40
40
|
Requires-Dist: gunicorn>=21.0.0
|
41
41
|
Requires-Dist: httpx<0.26.0,>=0.25.2
|
42
42
|
Requires-Dist: jinja2>=3.1.6
|
43
|
+
Requires-Dist: jmespath>=1.0.1
|
43
44
|
Requires-Dist: openai-agents>=0.0.1
|
44
45
|
Requires-Dist: openai<2.0.0,>=1.3.0
|
45
46
|
Requires-Dist: platformdirs>=4.0.0
|
@@ -92,6 +93,11 @@ Description-Content-Type: text/markdown
|
|
92
93
|
|
93
94
|
**Open Swarm** is a Python framework for creating, managing, and deploying autonomous agent swarms. It leverages the `openai-agents` library for core agent functionality and provides a structured way to build complex, multi-agent workflows using **Blueprints**.
|
94
95
|
|
96
|
+
Open Swarm can be used in two primary ways:
|
97
|
+
|
98
|
+
1. **As a CLI Utility (`swarm-cli`):** Manage, run, and install blueprints directly on your local machine. Ideal for personal use, testing, and creating standalone agent tools. (Recommended installation: PyPI)
|
99
|
+
2. **As an API Service (`swarm-api`):** Deploy a web server that exposes your blueprints via an OpenAI-compatible REST API. Ideal for integrations, web UIs, and shared access. (Recommended deployment: Docker)
|
100
|
+
|
95
101
|
---
|
96
102
|
|
97
103
|
## Core Concepts
|
@@ -105,97 +111,160 @@ Description-Content-Type: text/markdown
|
|
105
111
|
|
106
112
|
---
|
107
113
|
|
108
|
-
## Quickstart
|
114
|
+
## Quickstart 1: Using `swarm-cli` Locally (via PyPI)
|
109
115
|
|
110
|
-
This is the
|
116
|
+
This is the recommended way to use `swarm-cli` for managing and running blueprints on your local machine.
|
111
117
|
|
112
118
|
**Prerequisites:**
|
113
|
-
*
|
114
|
-
*
|
119
|
+
* Python 3.10+
|
120
|
+
* `pip` (Python package installer)
|
115
121
|
|
116
122
|
**Steps:**
|
117
123
|
|
118
|
-
1. **
|
124
|
+
1. **Install `open-swarm` from PyPI:**
|
119
125
|
```bash
|
120
|
-
|
121
|
-
cd open-swarm
|
126
|
+
pip install open-swarm
|
122
127
|
```
|
128
|
+
*(Using a virtual environment is recommended: `python -m venv .venv && source .venv/bin/activate`)*
|
123
129
|
|
124
|
-
2. **
|
125
|
-
*
|
130
|
+
2. **Initial Configuration (First Run):**
|
131
|
+
* The first time you run a `swarm-cli` command that requires configuration (like `run` or `config`), it will automatically create a default `swarm_config.json` at `~/.config/swarm/swarm_config.json` if one doesn't exist.
|
132
|
+
* You **must** set the required environment variables (like `OPENAI_API_KEY`) in your shell for the configuration to work. Create a `.env` file in your working directory or export them:
|
126
133
|
```bash
|
127
|
-
|
134
|
+
export OPENAI_API_KEY="sk-..."
|
135
|
+
# Add other keys as needed (GROQ_API_KEY, etc.)
|
128
136
|
```
|
129
|
-
*
|
137
|
+
* You can customize the configuration further using `swarm-cli config` commands (see `USERGUIDE.md`).
|
130
138
|
|
131
|
-
3. **
|
132
|
-
*
|
139
|
+
3. **Add a Blueprint:**
|
140
|
+
* Download or create a blueprint file (e.g., `my_blueprint.py`). Example blueprints are available in the [project repository](https://github.com/matthewhand/open-swarm/tree/main/src/swarm/blueprints).
|
141
|
+
* Add it using `swarm-cli`:
|
133
142
|
```bash
|
134
|
-
|
135
|
-
|
136
|
-
* Edit `docker-compose.override.yaml` to:
|
137
|
-
* Mount any local directories containing custom blueprints you want the API server to access (e.g., uncomment and adjust the `./my_custom_blueprints:/app/custom_blueprints:ro` line).
|
138
|
-
* Make any other necessary adjustments (ports, environment variables, etc.).
|
143
|
+
# Example: Adding a downloaded blueprint file
|
144
|
+
swarm-cli add ./path/to/downloaded/blueprint_echocraft.py
|
139
145
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
```
|
144
|
-
This will build the image (if not already pulled/built) and start the `open-swarm` service, exposing the API on port 8000 (or the port specified in your `.env`/override).
|
146
|
+
# Example: Adding a directory containing a blueprint
|
147
|
+
swarm-cli add ./my_custom_blueprints/agent_smith --name agent_smith
|
148
|
+
```
|
145
149
|
|
146
|
-
|
147
|
-
*
|
150
|
+
4. **Run the Blueprint:**
|
151
|
+
* **Single Instruction:**
|
148
152
|
```bash
|
149
|
-
|
153
|
+
swarm-cli run echocraft --instruction "Hello from CLI!"
|
150
154
|
```
|
151
|
-
*
|
155
|
+
* **Interactive Mode:**
|
152
156
|
```bash
|
153
|
-
|
154
|
-
|
155
|
-
-d '{
|
156
|
-
"model": "echocraft",
|
157
|
-
"messages": [{"role": "user", "content": "Hello Docker!"}]
|
158
|
-
}'
|
157
|
+
swarm-cli run echocraft
|
158
|
+
# Now you can chat with the blueprint interactively
|
159
159
|
```
|
160
|
-
|
160
|
+
|
161
|
+
5. **(Optional) Install as Command:**
|
162
|
+
```bash
|
163
|
+
swarm-cli install echocraft
|
164
|
+
# Now run (ensure ~/.local/share/swarm/bin is in your PATH):
|
165
|
+
echocraft --instruction "I am a command now!"
|
166
|
+
```
|
161
167
|
|
162
168
|
---
|
163
169
|
|
164
|
-
##
|
170
|
+
## Quickstart 2: Deploying `swarm-api` Service (via Docker)
|
171
|
+
|
172
|
+
This section covers deploying the API service using Docker.
|
173
|
+
|
174
|
+
### Option A: Docker Compose (Recommended for Flexibility)
|
175
|
+
|
176
|
+
This method uses `docker-compose.yaml` and is best if you need to customize volumes, environment variables easily, or manage related services (like Redis).
|
177
|
+
|
178
|
+
**Prerequisites:**
|
179
|
+
* Docker ([Install Docker](https://docs.docker.com/engine/install/))
|
180
|
+
* Docker Compose ([Install Docker Compose](https://docs.docker.com/compose/install/))
|
181
|
+
* Git
|
182
|
+
|
183
|
+
**Steps:**
|
184
|
+
|
185
|
+
1. **Clone the Repository:** (Needed for `docker-compose.yaml` and config files)
|
186
|
+
```bash
|
187
|
+
git clone https://github.com/matthewhand/open-swarm.git
|
188
|
+
cd open-swarm
|
189
|
+
```
|
190
|
+
|
191
|
+
2. **Configure Environment:**
|
192
|
+
* Copy `cp .env.example .env` and edit `.env` with your API keys (e.g., `OPENAI_API_KEY`, `SWARM_API_KEY`).
|
193
|
+
|
194
|
+
3. **Prepare Blueprints & Config:**
|
195
|
+
* Place blueprints in `./blueprints`.
|
196
|
+
* Ensure `./swarm_config.json` exists and is configured.
|
197
|
+
|
198
|
+
4. **Configure Overrides (Optional):**
|
199
|
+
* Copy `cp docker-compose.override.yaml.example docker-compose.override.yaml`.
|
200
|
+
* Edit the override file to mount additional volumes, change ports, etc.
|
201
|
+
|
202
|
+
5. **Start the Service:**
|
203
|
+
```bash
|
204
|
+
docker compose up -d
|
205
|
+
```
|
206
|
+
|
207
|
+
6. **Verify API:** (Default port 8000)
|
208
|
+
* Models: `curl http://localhost:8000/v1/models`
|
209
|
+
* Chat: `curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "echocraft", ...}'` (Add `-H "Authorization: Bearer <key>"` if needed).
|
210
|
+
|
211
|
+
### Option B: Direct `docker run` (Simpler for Single Container)
|
212
|
+
|
213
|
+
This method runs the pre-built image directly from Docker Hub. Good for quick tests or simple deployments without cloning the repo. Customization requires careful use of `-v` (volume) and `-e` (environment) flags.
|
214
|
+
|
215
|
+
**Prerequisites:**
|
216
|
+
* Docker ([Install Docker](https://docs.docker.com/engine/install/))
|
217
|
+
|
218
|
+
**Steps:**
|
165
219
|
|
166
|
-
|
220
|
+
1. **Prepare Local Files (If Customizing):**
|
221
|
+
* Create a directory for your blueprints (e.g., `~/my_swarm_blueprints`).
|
222
|
+
* Create your `swarm_config.json` file locally (e.g., `~/my_swarm_config.json`).
|
223
|
+
* Create a `.env` file locally (e.g., `~/swarm.env`) with your API keys (`OPENAI_API_KEY`, `SWARM_API_KEY`, etc.).
|
167
224
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
225
|
+
2. **Run the Container:**
|
226
|
+
```bash
|
227
|
+
docker run -d \
|
228
|
+
--name open-swarm-api \
|
229
|
+
-p 8000:8000 \
|
230
|
+
--env-file ~/swarm.env \
|
231
|
+
-v ~/my_swarm_blueprints:/app/blueprints:ro \
|
232
|
+
-v ~/my_swarm_config.json:/app/swarm_config.json:ro \
|
233
|
+
-v open_swarm_db:/app/db.sqlite3 \
|
234
|
+
--restart unless-stopped \
|
235
|
+
mhand79/open-swarm:latest
|
236
|
+
```
|
237
|
+
* `-d`: Run detached (in background).
|
238
|
+
* `--name`: Assign a name to the container.
|
239
|
+
* `-p 8000:8000`: Map host port 8000 to container port 8000 (adjust if needed).
|
240
|
+
* `--env-file`: Load environment variables from your local file.
|
241
|
+
* `-v ...:/app/blueprints:ro`: Mount your local blueprints directory (read-only). **Required** if you want to use custom blueprints.
|
242
|
+
* `-v ...:/app/swarm_config.json:ro`: Mount your local config file (read-only). **Required** for custom LLM/MCP settings.
|
243
|
+
* `-v open_swarm_db:/app/db.sqlite3`: Use a named Docker volume for the database to persist data.
|
244
|
+
* `--restart unless-stopped`: Automatically restart the container unless manually stopped.
|
245
|
+
* `mhand79/open-swarm:latest`: The image name on Docker Hub.
|
246
|
+
|
247
|
+
3. **Verify API:** (Same as Docker Compose)
|
248
|
+
* Models: `curl http://localhost:8000/v1/models`
|
249
|
+
* Chat: `curl http://localhost:8000/v1/chat/completions ...` (Add `-H "Authorization: Bearer <key>"` if needed).
|
174
250
|
|
175
|
-
|
176
|
-
* **How:** `swarm-cli run <blueprint_name> --instruction "Your single instruction"`
|
177
|
-
* **What:** Executes a blueprint managed by `swarm-cli` (located in `~/.local/share/swarm/blueprints/`) directly in the terminal. Uses configuration from `~/.config/swarm/swarm_config.json`.
|
178
|
-
* **Interactive Mode:** If you omit the `--instruction` argument (`swarm-cli run <blueprint_name>`), it will enter an interactive chat mode in the terminal.
|
179
|
-
* **Use Case:** Good for testing, debugging, interactive sessions, or running specific tasks locally without the API overhead.
|
251
|
+
---
|
180
252
|
|
181
|
-
|
182
|
-
* **How:** `swarm-cli install <blueprint_name>`, then run `<blueprint_name> --instruction "..."`
|
183
|
-
* **What:** Creates a standalone executable for a managed blueprint using PyInstaller and places it in the user's binary directory (e.g., `~/.local/bin/` or similar, ensure it's in your `PATH`).
|
184
|
-
* **Use Case:** Convenient for frequently used blueprints that act like regular command-line tools.
|
253
|
+
## Usage Modes Summary
|
185
254
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
255
|
+
* **`swarm-api` (via Docker or `manage.py runserver`):** Exposes blueprints as an OpenAI-compatible REST API. Ideal for integrations. Requires `SWARM_API_KEY` for security in non-local deployments.
|
256
|
+
* **`swarm-cli run` (via PyPI install):** Executes managed blueprints locally, either with a single instruction or in interactive chat mode. Good for testing and local tasks.
|
257
|
+
* **`swarm-cli install` (via PyPI install):** Creates standalone command-line executables from managed blueprints.
|
258
|
+
* **Direct Python Execution (via Git clone):** Running `uv run python <blueprint_file.py>` is mainly for development and testing individual files.
|
190
259
|
|
191
260
|
---
|
192
261
|
|
193
262
|
## Further Documentation
|
194
263
|
|
195
|
-
This README provides a high-level overview and quickstart. For more detailed information, please refer to:
|
264
|
+
This README provides a high-level overview and quickstart guides. For more detailed information, please refer to:
|
196
265
|
|
197
|
-
* **User Guide (`USERGUIDE.md`):** Detailed instructions on using `swarm-cli` commands for managing blueprints and configuration.
|
198
|
-
* **Development Guide (`DEVELOPMENT.md`):** Information for contributors and developers, including architecture details, testing strategies, project layout, and advanced topics
|
266
|
+
* **User Guide (`USERGUIDE.md`):** Detailed instructions on using `swarm-cli` commands for managing blueprints and configuration locally.
|
267
|
+
* **Development Guide (`DEVELOPMENT.md`):** Information for contributors and developers, including architecture details, testing strategies, project layout, API details, and advanced topics.
|
199
268
|
* **Example Blueprints (`src/swarm/blueprints/README.md`):** A list and description of the example blueprints included with the framework, showcasing various features and integration patterns.
|
200
269
|
|
201
270
|
---
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# Open Swarm
|
2
|
+
|
3
|
+
<div align="center">
|
4
|
+
<img src="assets/images/openswarm-project-image.jpg" alt="Project Logo" width="70%"/>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
**Open Swarm** is a Python framework for creating, managing, and deploying autonomous agent swarms. It leverages the `openai-agents` library for core agent functionality and provides a structured way to build complex, multi-agent workflows using **Blueprints**.
|
8
|
+
|
9
|
+
Open Swarm can be used in two primary ways:
|
10
|
+
|
11
|
+
1. **As a CLI Utility (`swarm-cli`):** Manage, run, and install blueprints directly on your local machine. Ideal for personal use, testing, and creating standalone agent tools. (Recommended installation: PyPI)
|
12
|
+
2. **As an API Service (`swarm-api`):** Deploy a web server that exposes your blueprints via an OpenAI-compatible REST API. Ideal for integrations, web UIs, and shared access. (Recommended deployment: Docker)
|
13
|
+
|
14
|
+
---
|
15
|
+
|
16
|
+
## Core Concepts
|
17
|
+
|
18
|
+
* **Agents:** Individual AI units performing specific tasks, powered by LLMs (like GPT-4, Claude, etc.). Built using the `openai-agents` SDK.
|
19
|
+
* **Blueprints:** Python classes (`BlueprintBase` subclasses) defining a swarm's structure, agents, coordination logic, and external dependencies (like required environment variables or MCP servers). They act as reusable templates for specific tasks (e.g., code generation, research, data analysis).
|
20
|
+
* **MCP (Mission Control Platform) Servers:** Optional external processes providing specialized capabilities (tools) to agents, such as filesystem access, web browsing, database interaction, or interacting with specific APIs (Slack, Monday.com, etc.). Agents interact with MCP servers via a standardized communication protocol.
|
21
|
+
* **Configuration (`swarm_config.json`):** A central JSON file defining available LLM profiles (API keys, models) and configurations for MCP servers. Typically managed via `swarm-cli` in `~/.config/swarm/`.
|
22
|
+
* **`swarm-cli`:** A command-line tool for managing blueprints (adding, listing, running, installing) and the `swarm_config.json` file. Uses XDG directories for storing blueprints (`~/.local/share/swarm/blueprints/`) and configuration (`~/.config/swarm/`).
|
23
|
+
* **`swarm-api`:** A launcher for the Django/DRF backend that exposes installed blueprints via an OpenAI-compatible REST API (`/v1/models`, `/v1/chat/completions`).
|
24
|
+
|
25
|
+
---
|
26
|
+
|
27
|
+
## Quickstart 1: Using `swarm-cli` Locally (via PyPI)
|
28
|
+
|
29
|
+
This is the recommended way to use `swarm-cli` for managing and running blueprints on your local machine.
|
30
|
+
|
31
|
+
**Prerequisites:**
|
32
|
+
* Python 3.10+
|
33
|
+
* `pip` (Python package installer)
|
34
|
+
|
35
|
+
**Steps:**
|
36
|
+
|
37
|
+
1. **Install `open-swarm` from PyPI:**
|
38
|
+
```bash
|
39
|
+
pip install open-swarm
|
40
|
+
```
|
41
|
+
*(Using a virtual environment is recommended: `python -m venv .venv && source .venv/bin/activate`)*
|
42
|
+
|
43
|
+
2. **Initial Configuration (First Run):**
|
44
|
+
* The first time you run a `swarm-cli` command that requires configuration (like `run` or `config`), it will automatically create a default `swarm_config.json` at `~/.config/swarm/swarm_config.json` if one doesn't exist.
|
45
|
+
* You **must** set the required environment variables (like `OPENAI_API_KEY`) in your shell for the configuration to work. Create a `.env` file in your working directory or export them:
|
46
|
+
```bash
|
47
|
+
export OPENAI_API_KEY="sk-..."
|
48
|
+
# Add other keys as needed (GROQ_API_KEY, etc.)
|
49
|
+
```
|
50
|
+
* You can customize the configuration further using `swarm-cli config` commands (see `USERGUIDE.md`).
|
51
|
+
|
52
|
+
3. **Add a Blueprint:**
|
53
|
+
* Download or create a blueprint file (e.g., `my_blueprint.py`). Example blueprints are available in the [project repository](https://github.com/matthewhand/open-swarm/tree/main/src/swarm/blueprints).
|
54
|
+
* Add it using `swarm-cli`:
|
55
|
+
```bash
|
56
|
+
# Example: Adding a downloaded blueprint file
|
57
|
+
swarm-cli add ./path/to/downloaded/blueprint_echocraft.py
|
58
|
+
|
59
|
+
# Example: Adding a directory containing a blueprint
|
60
|
+
swarm-cli add ./my_custom_blueprints/agent_smith --name agent_smith
|
61
|
+
```
|
62
|
+
|
63
|
+
4. **Run the Blueprint:**
|
64
|
+
* **Single Instruction:**
|
65
|
+
```bash
|
66
|
+
swarm-cli run echocraft --instruction "Hello from CLI!"
|
67
|
+
```
|
68
|
+
* **Interactive Mode:**
|
69
|
+
```bash
|
70
|
+
swarm-cli run echocraft
|
71
|
+
# Now you can chat with the blueprint interactively
|
72
|
+
```
|
73
|
+
|
74
|
+
5. **(Optional) Install as Command:**
|
75
|
+
```bash
|
76
|
+
swarm-cli install echocraft
|
77
|
+
# Now run (ensure ~/.local/share/swarm/bin is in your PATH):
|
78
|
+
echocraft --instruction "I am a command now!"
|
79
|
+
```
|
80
|
+
|
81
|
+
---
|
82
|
+
|
83
|
+
## Quickstart 2: Deploying `swarm-api` Service (via Docker)
|
84
|
+
|
85
|
+
This section covers deploying the API service using Docker.
|
86
|
+
|
87
|
+
### Option A: Docker Compose (Recommended for Flexibility)
|
88
|
+
|
89
|
+
This method uses `docker-compose.yaml` and is best if you need to customize volumes, environment variables easily, or manage related services (like Redis).
|
90
|
+
|
91
|
+
**Prerequisites:**
|
92
|
+
* Docker ([Install Docker](https://docs.docker.com/engine/install/))
|
93
|
+
* Docker Compose ([Install Docker Compose](https://docs.docker.com/compose/install/))
|
94
|
+
* Git
|
95
|
+
|
96
|
+
**Steps:**
|
97
|
+
|
98
|
+
1. **Clone the Repository:** (Needed for `docker-compose.yaml` and config files)
|
99
|
+
```bash
|
100
|
+
git clone https://github.com/matthewhand/open-swarm.git
|
101
|
+
cd open-swarm
|
102
|
+
```
|
103
|
+
|
104
|
+
2. **Configure Environment:**
|
105
|
+
* Copy `cp .env.example .env` and edit `.env` with your API keys (e.g., `OPENAI_API_KEY`, `SWARM_API_KEY`).
|
106
|
+
|
107
|
+
3. **Prepare Blueprints & Config:**
|
108
|
+
* Place blueprints in `./blueprints`.
|
109
|
+
* Ensure `./swarm_config.json` exists and is configured.
|
110
|
+
|
111
|
+
4. **Configure Overrides (Optional):**
|
112
|
+
* Copy `cp docker-compose.override.yaml.example docker-compose.override.yaml`.
|
113
|
+
* Edit the override file to mount additional volumes, change ports, etc.
|
114
|
+
|
115
|
+
5. **Start the Service:**
|
116
|
+
```bash
|
117
|
+
docker compose up -d
|
118
|
+
```
|
119
|
+
|
120
|
+
6. **Verify API:** (Default port 8000)
|
121
|
+
* Models: `curl http://localhost:8000/v1/models`
|
122
|
+
* Chat: `curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "echocraft", ...}'` (Add `-H "Authorization: Bearer <key>"` if needed).
|
123
|
+
|
124
|
+
### Option B: Direct `docker run` (Simpler for Single Container)
|
125
|
+
|
126
|
+
This method runs the pre-built image directly from Docker Hub. Good for quick tests or simple deployments without cloning the repo. Customization requires careful use of `-v` (volume) and `-e` (environment) flags.
|
127
|
+
|
128
|
+
**Prerequisites:**
|
129
|
+
* Docker ([Install Docker](https://docs.docker.com/engine/install/))
|
130
|
+
|
131
|
+
**Steps:**
|
132
|
+
|
133
|
+
1. **Prepare Local Files (If Customizing):**
|
134
|
+
* Create a directory for your blueprints (e.g., `~/my_swarm_blueprints`).
|
135
|
+
* Create your `swarm_config.json` file locally (e.g., `~/my_swarm_config.json`).
|
136
|
+
* Create a `.env` file locally (e.g., `~/swarm.env`) with your API keys (`OPENAI_API_KEY`, `SWARM_API_KEY`, etc.).
|
137
|
+
|
138
|
+
2. **Run the Container:**
|
139
|
+
```bash
|
140
|
+
docker run -d \
|
141
|
+
--name open-swarm-api \
|
142
|
+
-p 8000:8000 \
|
143
|
+
--env-file ~/swarm.env \
|
144
|
+
-v ~/my_swarm_blueprints:/app/blueprints:ro \
|
145
|
+
-v ~/my_swarm_config.json:/app/swarm_config.json:ro \
|
146
|
+
-v open_swarm_db:/app/db.sqlite3 \
|
147
|
+
--restart unless-stopped \
|
148
|
+
mhand79/open-swarm:latest
|
149
|
+
```
|
150
|
+
* `-d`: Run detached (in background).
|
151
|
+
* `--name`: Assign a name to the container.
|
152
|
+
* `-p 8000:8000`: Map host port 8000 to container port 8000 (adjust if needed).
|
153
|
+
* `--env-file`: Load environment variables from your local file.
|
154
|
+
* `-v ...:/app/blueprints:ro`: Mount your local blueprints directory (read-only). **Required** if you want to use custom blueprints.
|
155
|
+
* `-v ...:/app/swarm_config.json:ro`: Mount your local config file (read-only). **Required** for custom LLM/MCP settings.
|
156
|
+
* `-v open_swarm_db:/app/db.sqlite3`: Use a named Docker volume for the database to persist data.
|
157
|
+
* `--restart unless-stopped`: Automatically restart the container unless manually stopped.
|
158
|
+
* `mhand79/open-swarm:latest`: The image name on Docker Hub.
|
159
|
+
|
160
|
+
3. **Verify API:** (Same as Docker Compose)
|
161
|
+
* Models: `curl http://localhost:8000/v1/models`
|
162
|
+
* Chat: `curl http://localhost:8000/v1/chat/completions ...` (Add `-H "Authorization: Bearer <key>"` if needed).
|
163
|
+
|
164
|
+
---
|
165
|
+
|
166
|
+
## Usage Modes Summary
|
167
|
+
|
168
|
+
* **`swarm-api` (via Docker or `manage.py runserver`):** Exposes blueprints as an OpenAI-compatible REST API. Ideal for integrations. Requires `SWARM_API_KEY` for security in non-local deployments.
|
169
|
+
* **`swarm-cli run` (via PyPI install):** Executes managed blueprints locally, either with a single instruction or in interactive chat mode. Good for testing and local tasks.
|
170
|
+
* **`swarm-cli install` (via PyPI install):** Creates standalone command-line executables from managed blueprints.
|
171
|
+
* **Direct Python Execution (via Git clone):** Running `uv run python <blueprint_file.py>` is mainly for development and testing individual files.
|
172
|
+
|
173
|
+
---
|
174
|
+
|
175
|
+
## Further Documentation
|
176
|
+
|
177
|
+
This README provides a high-level overview and quickstart guides. For more detailed information, please refer to:
|
178
|
+
|
179
|
+
* **User Guide (`USERGUIDE.md`):** Detailed instructions on using `swarm-cli` commands for managing blueprints and configuration locally.
|
180
|
+
* **Development Guide (`DEVELOPMENT.md`):** Information for contributors and developers, including architecture details, testing strategies, project layout, API details, and advanced topics.
|
181
|
+
* **Example Blueprints (`src/swarm/blueprints/README.md`):** A list and description of the example blueprints included with the framework, showcasing various features and integration patterns.
|
182
|
+
|
183
|
+
---
|
184
|
+
|
185
|
+
## Contributing
|
186
|
+
|
187
|
+
Contributions are welcome! Please refer to the `CONTRIBUTING.md` file (if available) or open an issue/pull request on the repository.
|
188
|
+
|
189
|
+
---
|
190
|
+
|
191
|
+
## License
|
192
|
+
|
193
|
+
Open Swarm is provided under the MIT License. Refer to the [LICENSE](LICENSE) file for full details.
|
194
|
+
|
195
|
+
---
|
196
|
+
|
197
|
+
## Acknowledgements
|
198
|
+
|
199
|
+
This project builds upon concepts and code from the `openai-agents` library and potentially other open-source projects. Specific acknowledgements can be found in `DEVELOPMENT.md` or individual source files.
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "open-swarm"
|
7
|
-
version = "0.1.
|
7
|
+
version = "0.1.1743368545"
|
8
8
|
description = "Open Swarm: Orchestrating AI Agent Swarms with Django"
|
9
9
|
readme = "README.md"
|
10
10
|
requires-python = ">=3.10"
|
@@ -58,6 +58,7 @@ dependencies = [
|
|
58
58
|
"openai-agents>=0.0.1",
|
59
59
|
"jinja2>=3.1.6",
|
60
60
|
"drf-spectacular>=0.28.0",
|
61
|
+
"jmespath>=1.0.1",
|
61
62
|
]
|
62
63
|
|
63
64
|
[project.urls]
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import logging
|
2
|
+
import os
|
3
|
+
from rest_framework.authentication import BaseAuthentication, SessionAuthentication
|
4
|
+
# Import BasePermission for creating custom permissions
|
5
|
+
from rest_framework.permissions import BasePermission
|
6
|
+
from rest_framework import exceptions
|
7
|
+
from django.conf import settings
|
8
|
+
from django.utils.translation import gettext_lazy as _
|
9
|
+
# Import AnonymousUser
|
10
|
+
from django.contrib.auth.models import AnonymousUser
|
11
|
+
# Keep get_user_model if CustomSessionAuthentication needs it or for future user mapping
|
12
|
+
from django.contrib.auth import get_user_model
|
13
|
+
|
14
|
+
logger = logging.getLogger('swarm.auth')
|
15
|
+
User = get_user_model()
|
16
|
+
|
17
|
+
# ==============================================================================
|
18
|
+
# Authentication Classes (Determine *who* the user is)
|
19
|
+
# ==============================================================================
|
20
|
+
|
21
|
+
# --- Static Token Authentication ---
|
22
|
+
class StaticTokenAuthentication(BaseAuthentication):
|
23
|
+
"""
|
24
|
+
Authenticates requests based on a static API token passed in a header
|
25
|
+
(Authorization: Bearer <token> or X-API-Key: <token>).
|
26
|
+
|
27
|
+
Returns (AnonymousUser, token) on success. This allows permission classes
|
28
|
+
to check request.auth to see if token authentication succeeded, even though
|
29
|
+
no specific user model is associated with the token.
|
30
|
+
"""
|
31
|
+
keyword = 'Bearer'
|
32
|
+
|
33
|
+
def authenticate(self, request):
|
34
|
+
"""
|
35
|
+
Attempts to authenticate using a static token.
|
36
|
+
"""
|
37
|
+
logger.debug("[Auth][StaticToken] Attempting static token authentication.")
|
38
|
+
# Retrieve the expected token from settings.
|
39
|
+
expected_token = getattr(settings, 'SWARM_API_KEY', None)
|
40
|
+
|
41
|
+
# If no token is configured in settings, this method cannot authenticate.
|
42
|
+
if not expected_token:
|
43
|
+
logger.error("[Auth][StaticToken] SWARM_API_KEY is not set in Django settings. Cannot use static token auth.")
|
44
|
+
return None # Indicate authentication method did not run or failed pre-check
|
45
|
+
|
46
|
+
# Extract the provided token from standard Authorization header or custom X-API-Key header.
|
47
|
+
provided_token = None
|
48
|
+
auth_header = request.META.get('HTTP_AUTHORIZATION', '').split()
|
49
|
+
if len(auth_header) == 2 and auth_header[0].lower() == self.keyword.lower():
|
50
|
+
provided_token = auth_header[1]
|
51
|
+
logger.debug("[Auth][StaticToken] Found token in Authorization header.")
|
52
|
+
else:
|
53
|
+
provided_token = request.META.get('HTTP_X_API_KEY')
|
54
|
+
if provided_token:
|
55
|
+
logger.debug("[Auth][StaticToken] Found token in X-API-Key header.")
|
56
|
+
|
57
|
+
# If no token was found in either header, authentication fails for this method.
|
58
|
+
if not provided_token:
|
59
|
+
logger.debug("[Auth][StaticToken] No token found in relevant headers.")
|
60
|
+
return None # Indicate authentication method did not find credentials
|
61
|
+
|
62
|
+
# Compare the provided token with the expected token.
|
63
|
+
# NOTE: For production, consider using a constant-time comparison function
|
64
|
+
# to mitigate timing attacks if the token is highly sensitive.
|
65
|
+
if provided_token == expected_token:
|
66
|
+
logger.info("[Auth][StaticToken] Static token authentication successful.")
|
67
|
+
# Return AnonymousUser and the token itself as request.auth.
|
68
|
+
# This signals successful authentication via token without linking to a specific User model.
|
69
|
+
return (AnonymousUser(), provided_token)
|
70
|
+
else:
|
71
|
+
# Token was provided but did not match. Raise AuthenticationFailed.
|
72
|
+
logger.warning(f"[Auth][StaticToken] Invalid static token provided.")
|
73
|
+
raise exceptions.AuthenticationFailed(_("Invalid API Key."))
|
74
|
+
|
75
|
+
# --- Custom *Synchronous* Session Authentication ---
|
76
|
+
class CustomSessionAuthentication(SessionAuthentication):
|
77
|
+
"""
|
78
|
+
Standard Django Session Authentication provided by DRF.
|
79
|
+
Relies on Django's session middleware to populate request.user.
|
80
|
+
This class itself is synchronous, but the underlying session loading
|
81
|
+
needs to be handled correctly in async views (e.g., via middleware or wrappers).
|
82
|
+
"""
|
83
|
+
# No override needed unless customizing session behavior.
|
84
|
+
pass
|
85
|
+
|
86
|
+
|
87
|
+
# ==============================================================================
|
88
|
+
# Permission Classes (Determine *if* access is allowed)
|
89
|
+
# ==============================================================================
|
90
|
+
|
91
|
+
class HasValidTokenOrSession(BasePermission):
|
92
|
+
"""
|
93
|
+
Allows access if EITHER:
|
94
|
+
1. Static token authentication succeeded (request.auth is not None).
|
95
|
+
2. Session authentication succeeded (request.user is authenticated).
|
96
|
+
"""
|
97
|
+
message = 'Authentication credentials were not provided or are invalid (Requires valid API Key or active session).'
|
98
|
+
|
99
|
+
def has_permission(self, request, view):
|
100
|
+
"""
|
101
|
+
Checks if the request has valid authentication via token or session.
|
102
|
+
"""
|
103
|
+
# Check if static token authentication was successful.
|
104
|
+
# StaticTokenAuthentication returns (AnonymousUser, token), so request.auth will be the token.
|
105
|
+
has_valid_token = getattr(request, 'auth', None) is not None
|
106
|
+
if has_valid_token:
|
107
|
+
logger.debug("[Perm][TokenOrSession] Access granted via static token (request.auth is set).")
|
108
|
+
return True
|
109
|
+
|
110
|
+
# Check if session authentication was successful.
|
111
|
+
# request.user should be populated by SessionAuthentication/AuthMiddleware.
|
112
|
+
user = getattr(request, 'user', None)
|
113
|
+
has_valid_session = user is not None and user.is_authenticated
|
114
|
+
if has_valid_session:
|
115
|
+
logger.debug(f"[Perm][TokenOrSession] Access granted via authenticated session user: {user}")
|
116
|
+
return True
|
117
|
+
|
118
|
+
# If neither condition is met, deny permission.
|
119
|
+
logger.debug("[Perm][TokenOrSession] Access denied: No valid token (request.auth=None) and no authenticated session user.")
|
120
|
+
return False
|
121
|
+
|