open-swarm 0.1.1743368545__py3-none-any.whl → 0.1.1743371918__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.1743368545.dist-info → open_swarm-0.1.1743371918.dist-info}/METADATA +1 -1
- {open_swarm-0.1.1743368545.dist-info → open_swarm-0.1.1743371918.dist-info}/RECORD +7 -7
- swarm/blueprints/echocraft/blueprint_echocraft.py +51 -24
- swarm/extensions/blueprint/blueprint_base.py +96 -145
- {open_swarm-0.1.1743368545.dist-info → open_swarm-0.1.1743371918.dist-info}/WHEEL +0 -0
- {open_swarm-0.1.1743368545.dist-info → open_swarm-0.1.1743371918.dist-info}/entry_points.txt +0 -0
- {open_swarm-0.1.1743368545.dist-info → open_swarm-0.1.1743371918.dist-info}/licenses/LICENSE +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.1743371918
|
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
|
@@ -26,7 +26,7 @@ swarm/blueprints/django_chat/blueprint_django_chat.py,sha256=jROcPgqNJZv2E2efCoG
|
|
26
26
|
swarm/blueprints/django_chat/urls.py,sha256=TTTF3pgymvCYbuxpwi4WRBPv8ftQNH4pEoURT8sEVAg,147
|
27
27
|
swarm/blueprints/django_chat/views.py,sha256=MUKjXXjXsq8jMZtAb4RR9g2mEYrwFemN6Bqxpeyi7p4,1299
|
28
28
|
swarm/blueprints/django_chat/templates/django_chat/django_chat_webpage.html,sha256=wAEOI4Wg0JJ8drXaOcr2Pel6lW3JSHmyIpbocLS5tI8,1649
|
29
|
-
swarm/blueprints/echocraft/blueprint_echocraft.py,sha256=
|
29
|
+
swarm/blueprints/echocraft/blueprint_echocraft.py,sha256=6xQT9qb2mIf28TAj1N4lWN1PzTq4CWVmPeTG_3Flrpc,2740
|
30
30
|
swarm/blueprints/family_ties/apps.py,sha256=EjV7AxDNsLM4gsLr_qMEiLAVbERuo1ZsdU9vPtOEYAY,287
|
31
31
|
swarm/blueprints/family_ties/blueprint_family_ties.py,sha256=XVcSZNHmqQNqyjDZM36wtUh2V2Qx2_lComjD7E7er1A,7986
|
32
32
|
swarm/blueprints/family_ties/models.py,sha256=C3_okdVVYuu9xOpoKRsaLoGrM2775cS_cU4UKYAkJ9s,903
|
@@ -53,7 +53,7 @@ swarm/blueprints/whiskeytango_foxtrot/blueprint_whiskeytango_foxtrot.py,sha256=i
|
|
53
53
|
swarm/extensions/__init__.py,sha256=SadbzfxckByaaqzuKPfXMvqmj45-dcMlavlfQYhGnzE,56
|
54
54
|
swarm/extensions/blueprint/__init__.py,sha256=VHSlq8q3AeclMsp63f8RXc3vhcZyzHH0uEaYV6AW-ZI,1841
|
55
55
|
swarm/extensions/blueprint/agent_utils.py,sha256=YWpANYTaFKAK4inWSirRlvzbHwQAH1wNkgW0esHKIeg,542
|
56
|
-
swarm/extensions/blueprint/blueprint_base.py,sha256=
|
56
|
+
swarm/extensions/blueprint/blueprint_base.py,sha256=xuwGq2tAGGevpXVkh_bfIuw1RYRJupeTHKPp8EfvEwI,5145
|
57
57
|
swarm/extensions/blueprint/blueprint_discovery.py,sha256=oU7q1JeVMP5k52hfTGObDy1Jn2v5lJRufz9BNvP3W58,5531
|
58
58
|
swarm/extensions/blueprint/blueprint_utils.py,sha256=Ef_pu-RYomqzFjMg6LOSPSdbYFCbYXjEoSvK1OT49Eo,702
|
59
59
|
swarm/extensions/blueprint/cli_handler.py,sha256=ri812w0w2JzXtLSmwfSbpJCCveokgABnTfZEv4Iup2Y,9250
|
@@ -253,8 +253,8 @@ swarm/views/message_views.py,sha256=sDUnXyqKXC8WwIIMAlWf00s2_a2T9c75Na5FvYMJwBM,
|
|
253
253
|
swarm/views/model_views.py,sha256=aAbU4AZmrOTaPeKMWtoKK7FPYHdaN3Zbx55JfKzYTRY,2937
|
254
254
|
swarm/views/utils.py,sha256=geX3Z5ZDKFYyXYBMilc-4qgOSjhujK3AfRtvbXgFpXk,3643
|
255
255
|
swarm/views/web_views.py,sha256=ExQQeJpZ8CkLZQC_pXKOOmdnEy2qR3wEBP4LLp27DPU,7404
|
256
|
-
open_swarm-0.1.
|
257
|
-
open_swarm-0.1.
|
258
|
-
open_swarm-0.1.
|
259
|
-
open_swarm-0.1.
|
260
|
-
open_swarm-0.1.
|
256
|
+
open_swarm-0.1.1743371918.dist-info/METADATA,sha256=zGZTjlRSbmYI4EgXVdxetl4cB-LyroVU8o6YDW2Cfic,13680
|
257
|
+
open_swarm-0.1.1743371918.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
258
|
+
open_swarm-0.1.1743371918.dist-info/entry_points.txt,sha256=LudR3dBqGnglrE1n2zAeWo38Ck0m57sKPW36KfK-pzo,71
|
259
|
+
open_swarm-0.1.1743371918.dist-info/licenses/LICENSE,sha256=BU9bwRlnOt_JDIb6OT55Q4leLZx9RArDLTFnlDIrBEI,1062
|
260
|
+
open_swarm-0.1.1743371918.dist-info/RECORD,,
|
@@ -1,6 +1,10 @@
|
|
1
|
+
|
2
|
+
# --- Content for src/swarm/blueprints/echocraft/blueprint_echocraft.py ---
|
1
3
|
import logging
|
2
|
-
from typing import
|
3
|
-
#
|
4
|
+
from typing import List, Dict, Any, AsyncGenerator
|
5
|
+
import uuid # Import uuid to generate IDs
|
6
|
+
import time # Import time for timestamp
|
7
|
+
|
4
8
|
from swarm.extensions.blueprint.blueprint_base import BlueprintBase
|
5
9
|
|
6
10
|
logger = logging.getLogger(__name__)
|
@@ -8,37 +12,60 @@ logger = logging.getLogger(__name__)
|
|
8
12
|
class EchoCraftBlueprint(BlueprintBase):
|
9
13
|
"""
|
10
14
|
A simple blueprint that echoes the last user message.
|
15
|
+
Used for testing and demonstrating basic blueprint structure.
|
11
16
|
"""
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
}
|
20
|
-
|
21
|
-
# *** Make run async and use yield ***
|
22
|
-
async def run(self, messages: List[Dict[str, str]]) -> AsyncGenerator[Dict[str, Any], None]:
|
17
|
+
|
18
|
+
# No specific __init__ needed beyond the base class unless adding more params
|
19
|
+
# def __init__(self, blueprint_id: str, **kwargs):
|
20
|
+
# super().__init__(blueprint_id=blueprint_id, **kwargs)
|
21
|
+
# logger.info(f"EchoCraftBlueprint '{self.blueprint_id}' initialized.")
|
22
|
+
|
23
|
+
async def run(self, messages: List[Dict[str, Any]], **kwargs: Any) -> AsyncGenerator[Dict[str, Any], None]:
|
23
24
|
"""
|
24
|
-
|
25
|
+
Echoes the content of the last message with role 'user'.
|
26
|
+
Yields a final message in OpenAI ChatCompletion format.
|
25
27
|
"""
|
26
28
|
logger.info(f"EchoCraftBlueprint run called with {len(messages)} messages.")
|
27
|
-
|
29
|
+
|
30
|
+
last_user_message_content = "No user message found."
|
28
31
|
for msg in reversed(messages):
|
29
32
|
if msg.get("role") == "user":
|
30
|
-
|
31
|
-
logger.debug(f"Found last user message: {
|
33
|
+
last_user_message_content = msg.get("content", "(empty content)")
|
34
|
+
logger.debug(f"Found last user message: {last_user_message_content}")
|
32
35
|
break
|
33
36
|
|
34
|
-
|
35
|
-
logger.info(f"EchoCraftBlueprint yielding: {
|
37
|
+
echo_content = f"Echo: {last_user_message_content}"
|
38
|
+
logger.info(f"EchoCraftBlueprint yielding: {echo_content}")
|
39
|
+
|
40
|
+
# --- Format the final output as an OpenAI ChatCompletion object ---
|
41
|
+
completion_id = f"chatcmpl-echo-{uuid.uuid4()}"
|
42
|
+
created_timestamp = int(time.time())
|
36
43
|
|
37
|
-
|
38
|
-
|
39
|
-
"
|
40
|
-
|
41
|
-
|
44
|
+
final_message_chunk = {
|
45
|
+
"id": completion_id,
|
46
|
+
"object": "chat.completion",
|
47
|
+
"created": created_timestamp,
|
48
|
+
"model": self.llm_profile_name, # Use profile name as model identifier
|
49
|
+
"choices": [
|
50
|
+
{
|
51
|
+
"index": 0,
|
52
|
+
"message": {
|
53
|
+
"role": "assistant",
|
54
|
+
"content": echo_content,
|
55
|
+
},
|
56
|
+
"finish_reason": "stop",
|
57
|
+
"logprobs": None, # Add null logprobs if needed
|
58
|
+
}
|
59
|
+
],
|
60
|
+
# Add usage stats if desired/possible
|
61
|
+
# "usage": {
|
62
|
+
# "prompt_tokens": 0,
|
63
|
+
# "completion_tokens": 0,
|
64
|
+
# "total_tokens": 0
|
65
|
+
# }
|
42
66
|
}
|
67
|
+
yield final_message_chunk
|
68
|
+
# --- End formatting change ---
|
69
|
+
|
43
70
|
logger.info("EchoCraftBlueprint run finished.")
|
44
71
|
|
@@ -1,160 +1,111 @@
|
|
1
|
+
|
2
|
+
# --- Content for src/swarm/extensions/blueprint/blueprint_base.py ---
|
1
3
|
import logging
|
2
|
-
import
|
3
|
-
import inspect
|
4
|
-
from typing import Dict, List, Any, AsyncGenerator, Optional, Type
|
4
|
+
import json
|
5
5
|
from abc import ABC, abstractmethod
|
6
|
-
from
|
6
|
+
from typing import Dict, Any, Optional, List, AsyncGenerator
|
7
7
|
from pathlib import Path
|
8
|
-
import
|
9
|
-
# *** Import Django settings ***
|
10
|
-
from django.conf import settings
|
11
|
-
|
12
|
-
# *** REMOVE SwarmConfig import from apps.py ***
|
13
|
-
# from swarm.apps import SwarmConfig
|
8
|
+
from django.apps import apps # Import Django apps registry
|
14
9
|
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
# *** LLMRegistry doesn't exist yet - Comment out import ***
|
19
|
-
# from swarm.llm.llm_registry import LLMRegistry # Example path - CHANGE ME!
|
10
|
+
# Keep the function import
|
11
|
+
from swarm.extensions.config.config_loader import get_profile_from_config
|
20
12
|
|
21
13
|
logger = logging.getLogger(__name__)
|
22
14
|
|
23
15
|
class BlueprintBase(ABC):
|
24
16
|
"""
|
25
|
-
Abstract base class for all blueprints.
|
26
|
-
Ensures common interface and configuration handling.
|
27
|
-
"""
|
28
|
-
metadata: Dict[str, Any] = {}
|
17
|
+
Abstract base class for all Swarm blueprints.
|
29
18
|
|
30
|
-
|
31
|
-
|
19
|
+
Defines the core interface for blueprint initialization and execution.
|
20
|
+
"""
|
21
|
+
def __init__(self, blueprint_id: str, config_path: Optional[Path] = None):
|
32
22
|
"""
|
33
|
-
|
34
|
-
|
23
|
+
Initializes the blueprint.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
blueprint_id: A unique identifier for this blueprint instance.
|
27
|
+
config_path: Optional path to a specific swarm_config.json file.
|
28
|
+
If None, the standard search logic will be used.
|
35
29
|
"""
|
36
|
-
if
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
self,
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
self._configure() # This sets self.config attributes from settings
|
51
|
-
|
52
|
-
# Now setup others that might depend on config
|
53
|
-
self._setup_llm() # Uses self.config attributes
|
54
|
-
self._setup_jinja() # Uses class path
|
55
|
-
|
56
|
-
# Logging Adjustment
|
57
|
-
# Check config *after* it has been loaded by _configure
|
58
|
-
# Use self.is_debug which should be set in _configure
|
59
|
-
if hasattr(self, 'is_debug') and self.is_debug:
|
60
|
-
log_level_int = logging.DEBUG
|
61
|
-
if logging.root.level > log_level_int:
|
62
|
-
logger.info(f"Root logger level is {logging.getLevelName(logging.root.level)}. Lowering to DEBUG due to config.")
|
63
|
-
logging.root.setLevel(log_level_int)
|
64
|
-
|
65
|
-
# Ensure llm_profile_name is set by _setup_llm before logging it
|
66
|
-
# Add check if llm_profile_name exists before logging
|
67
|
-
profile_name_to_log = getattr(self, 'llm_profile_name', 'N/A')
|
68
|
-
logger.info(f"Initialized blueprint '{self.metadata.get('name', self.__class__.__name__)}' with profile '{profile_name_to_log}'")
|
69
|
-
|
70
|
-
def _configure(self):
|
71
|
-
"""Placeholder: Sets config attributes based on django.conf.settings."""
|
72
|
-
logger.debug("BlueprintBase._configure accessing django.conf.settings")
|
73
|
-
# *** Access settings directly (temporary) ***
|
74
|
-
# This assumes swarm_config.json content is NOT yet loaded into settings
|
75
|
-
# We'll rely on defaults or potentially fail in _setup_llm
|
76
|
-
self.is_debug = getattr(settings, 'DEBUG', False)
|
77
|
-
# Store blueprint-specific parts for convenience - these won't exist in settings yet!
|
78
|
-
self.blueprint_config = {} # Placeholder
|
79
|
-
self.blueprint_defaults = {} # Placeholder
|
80
|
-
logger.warning("_configure is using placeholders. Swarm config file content is not loaded here.")
|
81
|
-
|
82
|
-
|
83
|
-
def _setup_llm(self):
|
84
|
-
"""Sets up the LLM provider based on configuration stored in self.config."""
|
85
|
-
# *** Access settings directly (temporary) ***
|
86
|
-
# Get default profile name from settings if defined, else 'default'
|
87
|
-
default_profile = getattr(settings, 'DEFAULT_LLM_PROFILE', 'default')
|
88
|
-
self.llm_profile_name = self.blueprint_config.get('llm_profile', default_profile) # Use placeholder blueprint_config
|
89
|
-
logger.debug(f"Getting LLM profile details for '{self.llm_profile_name}'.")
|
90
|
-
|
91
|
-
# *** This part will likely fail or use defaults as swarm_config isn't in settings ***
|
92
|
-
# Attempt to get profiles from settings if they were somehow loaded there
|
93
|
-
all_llm_profiles = getattr(settings, 'LLM_PROFILES', {})
|
94
|
-
profile_data = all_llm_profiles.get(self.llm_profile_name)
|
95
|
-
|
96
|
-
if profile_data is None:
|
97
|
-
logger.warning(f"LLM profile '{self.llm_profile_name}' not found in django settings. LLM will not be available.")
|
98
|
-
self.llm_profile = {} # Set empty profile
|
99
|
-
self.llm = None # Set LLM to None
|
100
|
-
return # Exit setup early
|
101
|
-
|
102
|
-
logger.debug(f"Using LLM profile '{self.llm_profile_name}' from settings.")
|
103
|
-
self.llm_profile = profile_data
|
104
|
-
# *** LLMRegistry doesn't exist yet - Comment out usage and set placeholder ***
|
105
|
-
# self.llm = LLMRegistry.get_llm(self.llm_profile)
|
106
|
-
self.llm = None # Placeholder until registry is implemented
|
107
|
-
logger.warning("LLMRegistry not implemented. self.llm set to None.")
|
108
|
-
|
109
|
-
|
110
|
-
@staticmethod
|
111
|
-
def _substitute_env_vars(data: Any) -> Any:
|
112
|
-
"""Recursively substitutes environment variables in strings."""
|
113
|
-
if isinstance(data, dict):
|
114
|
-
return {k: BlueprintBase._substitute_env_vars(v) for k, v in data.items()}
|
115
|
-
if isinstance(data, list):
|
116
|
-
return [BlueprintBase._substitute_env_vars(item) for item in data]
|
117
|
-
if isinstance(data, str):
|
118
|
-
return os.path.expandvars(data)
|
119
|
-
return data
|
120
|
-
|
121
|
-
def _setup_jinja(self):
|
122
|
-
"""Sets up Jinja2 environment."""
|
30
|
+
if not blueprint_id:
|
31
|
+
raise ValueError("blueprint_id cannot be empty or None") # Add validation
|
32
|
+
self.blueprint_id = blueprint_id
|
33
|
+
self.config_path = config_path # Note: config_path is currently unused if we rely on AppConfig
|
34
|
+
self._config: Optional[Dict[str, Any]] = None
|
35
|
+
self._llm_profile_name: Optional[str] = None
|
36
|
+
self._llm_profile_data: Optional[Dict[str, Any]] = None
|
37
|
+
self._markdown_output: bool = True # Default
|
38
|
+
|
39
|
+
logger.info(f"Initializing blueprint '{self.blueprint_id}' (Type: {self.__class__.__name__})")
|
40
|
+
self._load_and_process_config()
|
41
|
+
|
42
|
+
def _load_and_process_config(self):
|
43
|
+
"""Loads the main Swarm config and extracts relevant settings."""
|
123
44
|
try:
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
if
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
45
|
+
# --- Get config from the AppConfig instance ---
|
46
|
+
app_config_instance = apps.get_app_config('swarm')
|
47
|
+
# Assuming the loaded config is stored in an attribute named 'config'
|
48
|
+
# Adjust 'config' if your AppConfig uses a different attribute name
|
49
|
+
if not hasattr(app_config_instance, 'config') or not app_config_instance.config:
|
50
|
+
logger.error("Swarm configuration not found on AppConfig instance. Was ready() called?")
|
51
|
+
raise ValueError("Swarm configuration unavailable via AppConfig.")
|
52
|
+
self._config = app_config_instance.config
|
53
|
+
# --- End change ---
|
54
|
+
|
55
|
+
logger.debug(f"Blueprint '{self.blueprint_id}' using loaded Swarm config.")
|
56
|
+
|
57
|
+
# Determine LLM profile
|
58
|
+
self._llm_profile_name = self._config.get("settings", {}).get("default_llm_profile", "default")
|
59
|
+
logger.debug(f"Attempting to use LLM profile: '{self._llm_profile_name}'")
|
60
|
+
|
61
|
+
# Get substituted profile data
|
62
|
+
self._llm_profile_data = get_profile_from_config(self._config, self._llm_profile_name)
|
63
|
+
logger.info(f"Successfully loaded LLM profile '{self._llm_profile_name}'. Provider: {self._llm_profile_data.get('provider')}")
|
64
|
+
|
65
|
+
# Get markdown setting
|
66
|
+
blueprint_specific_settings = self._config.get("blueprints", {}).get(self.blueprint_id, {})
|
67
|
+
global_markdown_setting = self._config.get("settings", {}).get("default_markdown_output", True)
|
68
|
+
self._markdown_output = blueprint_specific_settings.get("markdown_output", global_markdown_setting)
|
69
|
+
logger.debug(f"Markdown output for '{self.blueprint_id}': {self._markdown_output}")
|
70
|
+
|
71
|
+
except ValueError as e:
|
72
|
+
logger.error(f"Configuration error for blueprint '{self.blueprint_id}': {e}", exc_info=True)
|
73
|
+
raise
|
136
74
|
except Exception as e:
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
75
|
+
logger.error(f"Unexpected error loading config for blueprint '{self.blueprint_id}': {e}", exc_info=True)
|
76
|
+
raise
|
77
|
+
|
78
|
+
@property
|
79
|
+
def config(self) -> Dict[str, Any]:
|
80
|
+
"""Returns the loaded and processed Swarm configuration."""
|
81
|
+
if self._config is None:
|
82
|
+
raise RuntimeError("Configuration accessed before initialization or after failure.")
|
83
|
+
return self._config
|
84
|
+
|
85
|
+
@property
|
86
|
+
def llm_profile(self) -> Dict[str, Any]:
|
87
|
+
"""Returns the loaded and processed LLM profile data for this blueprint."""
|
88
|
+
if self._llm_profile_data is None:
|
89
|
+
raise RuntimeError("LLM profile accessed before initialization or after failure.")
|
90
|
+
return self._llm_profile_data
|
91
|
+
|
92
|
+
@property
|
93
|
+
def llm_profile_name(self) -> str:
|
94
|
+
"""Returns the name of the LLM profile being used."""
|
95
|
+
if self._llm_profile_name is None:
|
96
|
+
raise RuntimeError("LLM profile name accessed before initialization or after failure.")
|
97
|
+
return self._llm_profile_name
|
98
|
+
|
99
|
+
@property
|
100
|
+
def should_output_markdown(self) -> bool:
|
101
|
+
"""Returns whether the blueprint should format output as Markdown."""
|
102
|
+
return self._markdown_output
|
103
|
+
|
104
|
+
@abstractmethod
|
105
|
+
async def run(self, messages: List[Dict[str, Any]], **kwargs: Any) -> AsyncGenerator[Dict[str, Any], None]:
|
106
|
+
"""
|
107
|
+
The main execution method for the blueprint.
|
108
|
+
"""
|
109
|
+
raise NotImplementedError("Subclasses must implement the 'run' method.")
|
110
|
+
yield {}
|
160
111
|
|
File without changes
|
{open_swarm-0.1.1743368545.dist-info → open_swarm-0.1.1743371918.dist-info}/entry_points.txt
RENAMED
File without changes
|
{open_swarm-0.1.1743368545.dist-info → open_swarm-0.1.1743371918.dist-info}/licenses/LICENSE
RENAMED
File without changes
|