strands-swarms 0.1.0__py3-none-any.whl → 0.1.2__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.
@@ -1,265 +1,116 @@
1
- """Orchestrator agent that plans, creates sub-agents, assigns tasks, and synthesizes completion."""
1
+ """Orchestrator agent that plans and creates sub-agents and tasks."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
5
  from typing import TYPE_CHECKING, Any
6
6
 
7
7
  from strands import Agent, tool
8
- from strands.hooks import HookRegistry
9
-
10
- from .events import AgentInfo, AgentSpawnedEvent, PlanningCompletedEvent, TaskCreatedEvent, TaskInfo
11
8
 
12
9
  if TYPE_CHECKING:
13
10
  from strands.models import Model
14
11
 
15
- from .swarm import SwarmConfig
16
-
12
+ from .definition import SwarmDefinition
17
13
 
18
- # --- System Prompt ---
19
14
 
20
15
  ORCHESTRATOR_SYSTEM_PROMPT = """\
21
- You are a workflow orchestrator that plans, creates sub-agents, assigns tasks, and synthesizes completion.
22
-
23
- ## Your Four Responsibilities
24
-
25
- ### 1. Planning
26
- Analyze the request and break it into logical steps. Determine what specialized agents are needed.
27
-
28
- ### 2. Creating Sub-agents
29
- Spawn specialized agents with appropriate tools and models. Each agent should have a focused role.
30
-
31
- ### 3. Assigning Tasks
32
- Create tasks and assign them to agents. Define dependencies when one task needs results from another.
33
-
34
- ### 4. Synthesizing Completion
35
- After all tasks complete, synthesize outputs into a cohesive final response. Be direct - deliver
36
- the result as if you completed the task yourself without mentioning sub-agents or the process.
37
-
38
- ## Your Process
39
-
40
- Think through the problem step-by-step:
41
-
42
- 1. **Analyze the request** - What needs to be done? Break it into logical steps.
43
- 2. **Design agents** - What specialized agents are needed? What tools does each need?
44
- 3. **Plan dependencies** - Which tasks must wait for others? Draw the dependency graph.
45
- 4. **Finalize** - Call finalize_plan when done creating agents and tasks.
46
-
47
- ## Output Format
48
-
49
- Structure your response clearly:
50
-
51
- ```
52
- ### Analysis
53
- [Brief analysis of what's needed]
54
-
55
- ### Agents Needed
56
- [List agents you'll create and why]
57
-
58
- ### Workflow Dependencies
59
- [Show which tasks depend on which, e.g., "write_report waits for research to complete"]
60
-
61
- ### Building Workflow
62
- [Then call the tools]
63
- ```
16
+ You are a workflow orchestrator. Your job is to break down requests into sub-agents and tasks.
64
17
 
65
18
  ## Tools
66
19
 
67
- **spawn_agent(name, role, tools, model)**
68
- - Creates an agent with specific capabilities
20
+ - **spawn_agent(name, role, tools)** - Create a specialized agent
21
+ - **create_task(name, agent_name, description, depends_on)** - Create a task for an agent
22
+ - **finalize_plan()** - Call when done planning
69
23
 
70
- **create_task(name, agent_name, description, depends_on)**
71
- - Creates a task assigned to an agent
72
- - depends_on: list of task names that must finish BEFORE this task starts
24
+ ## Process
73
25
 
74
- **finalize_plan()**
75
- - Signals that planning is complete
76
- - Call this after you've created all agents and tasks
26
+ 1. Analyze what needs to be done
27
+ 2. Create agents with the tools they need
28
+ 3. Create tasks, specifying dependencies if one task needs another's output
29
+ - Important: dependencies must already exist (create dependency tasks first)
30
+ 4. Call finalize_plan()
77
31
 
78
32
  ## Example
79
33
 
80
- For "Research AI and write a report":
81
-
82
- ### Analysis
83
- Need to: 1) Research AI trends, 2) Write a report based on research.
84
- The report cannot be written until research is done.
85
-
86
- ### Agents Needed
87
- - researcher: Gathers information (needs search_web)
88
- - writer: Creates reports (needs write_file)
89
-
90
- ### Workflow Dependencies
91
- research_task → write_task (writer waits for researcher)
92
-
93
- ### Building Workflow
94
- [spawn agents, create tasks with depends_on, finalize_plan]
95
-
96
- Now analyze the request and build the workflow.
97
- """
98
-
99
-
100
- # --- Swarm Config Management ---
101
-
102
- _swarm_config: SwarmConfig | None = None
103
- _hook_registry: HookRegistry | None = None
104
-
105
-
106
- def set_swarm_config(config: SwarmConfig | None, hook_registry: HookRegistry | None = None) -> None:
107
- """Set swarm config and hook registry. Called by DynamicSwarm before orchestration."""
108
- global _swarm_config, _hook_registry
109
- _swarm_config = config
110
- _hook_registry = hook_registry
111
-
34
+ Request: "Research AI trends and write a summary"
112
35
 
113
- def get_swarm_config() -> SwarmConfig:
114
- """Get swarm config, raising RuntimeError if not set."""
115
- if _swarm_config is None:
116
- raise RuntimeError("No swarm config set. Orchestrator tools must be used within DynamicSwarm.")
117
- return _swarm_config
36
+ 1. spawn_agent(name="researcher", role="research specialist", tools=["search_web"])
37
+ 2. spawn_agent(name="writer", role="technical writer", tools=[])
38
+ 3. create_task(name="research", agent_name="researcher", description="Research AI trends")
39
+ 4. create_task(name="write", agent_name="writer", description="Write summary", depends_on=["research"])
40
+ 5. finalize_plan()
118
41
 
42
+ Keep it simple - only create what's necessary."""
119
43
 
120
- def _emit(event: Any) -> None:
121
- if _hook_registry and _hook_registry.has_callbacks():
122
- _hook_registry.invoke_callbacks(event)
123
44
 
45
+ def create_orchestrator_tools(definition: "SwarmDefinition") -> list[Any]:
46
+ """Create orchestrator tools that capture the SwarmDefinition via closure."""
47
+ from .definition import AgentDefinition, TaskDefinition
124
48
 
125
- def _build_agents_info(config: SwarmConfig) -> list[AgentInfo]:
126
- return [
127
- AgentInfo(
128
- name=a.name, role=a.role, tools=a.tools, model=a.model, color=a.color
129
- )
130
- for a in config.agents.values()
131
- ]
132
-
133
-
134
- def _build_tasks_info(config: SwarmConfig) -> list[TaskInfo]:
135
- return [
136
- TaskInfo(
137
- name=t.name, agent=t.agent, description=t.description, depends_on=t.depends_on
138
- )
139
- for t in config.tasks.values()
140
- ]
141
-
142
-
143
- # --- Orchestrator Tools ---
144
-
145
-
146
- @tool
147
- def list_available_tools() -> str:
148
- """List all tools available for spawned agents."""
149
- tools = get_swarm_config().available_tool_names
150
- return "Available tools:\n" + "\n".join(f" - {t}" for t in tools) if tools else "No tools available."
151
-
152
-
153
- @tool
154
- def list_available_models() -> str:
155
- """List all models available for spawned agents."""
156
- models = get_swarm_config().available_model_names
157
- return "Available models:\n" + "\n".join(f" - {m}" for m in models) if models else "No models configured."
158
-
159
-
160
- @tool
161
- def spawn_agent(
162
- name: str,
163
- role: str,
164
- instructions: str = "",
165
- tools: list[str] | None = None,
166
- model: str | None = None,
167
- ) -> str:
168
- """Spawn a new sub-agent with specific capabilities."""
169
- from .swarm import AgentDefinition
170
-
171
- config = get_swarm_config()
172
- definition = AgentDefinition(
173
- name=name,
174
- role=role,
175
- instructions=instructions or None,
176
- tools=tools or [],
177
- model=model,
178
- )
179
-
180
- try:
181
- config.register_agent(definition)
182
- agent_def = config.agents.get(name)
183
- _emit(AgentSpawnedEvent(
49
+ @tool
50
+ def spawn_agent(
51
+ name: str,
52
+ role: str,
53
+ tools: list[str] | None = None,
54
+ instructions: str = "",
55
+ model: str | None = None,
56
+ ) -> str:
57
+ """Create a sub-agent with specific capabilities."""
58
+ agent_def = AgentDefinition(
184
59
  name=name,
185
60
  role=role,
186
61
  instructions=instructions or None,
187
62
  tools=tools or [],
188
63
  model=model,
189
- color=agent_def.color if agent_def else None,
190
- ))
191
- return f"✓ Spawned '{name}' ({role})"
192
- except ValueError as e:
193
- return f"✗ Failed: {e}"
194
-
195
-
196
- @tool
197
- def create_task(
198
- name: str,
199
- agent_name: str,
200
- description: str = "",
201
- depends_on: list[str] | None = None,
202
- ) -> str:
203
- """Create a task and assign it to a spawned agent."""
204
- from .swarm import TaskDefinition
205
-
206
- config = get_swarm_config()
207
- definition = TaskDefinition(
208
- name=name,
209
- agent=agent_name,
210
- description=description or None,
211
- depends_on=depends_on or [],
212
- )
64
+ )
213
65
 
214
- try:
215
- config.register_task(definition)
216
- _emit(TaskCreatedEvent(
66
+ try:
67
+ definition.register_agent(agent_def)
68
+ return f"Created agent '{name}' ({role})"
69
+ except ValueError as e:
70
+ return f"Error: {e}"
71
+
72
+ @tool
73
+ def create_task(
74
+ name: str,
75
+ agent_name: str,
76
+ description: str = "",
77
+ depends_on: list[str] | None = None,
78
+ ) -> str:
79
+ """Create a task assigned to a sub-agent.
80
+
81
+ Note: any tasks listed in depends_on must already exist (create dependency tasks first).
82
+ """
83
+ task_def = TaskDefinition(
217
84
  name=name,
218
85
  agent=agent_name,
219
86
  description=description or None,
220
87
  depends_on=depends_on or [],
221
- ))
222
- return f"✓ Created '{name}' -> '{agent_name}'"
223
- except ValueError as e:
224
- return f"✗ Failed: {e}"
225
-
226
-
227
- @tool
228
- def get_planning_status() -> str:
229
- """Get current planning status - agents and tasks defined so far."""
230
- return get_swarm_config().get_summary()
231
-
232
-
233
- @tool
234
- def finalize_plan() -> str:
235
- """Signal that planning is complete. Call after creating all agents and tasks."""
236
- config = get_swarm_config()
237
-
238
- _emit(PlanningCompletedEvent(
239
- entry_task=None,
240
- agents=_build_agents_info(config),
241
- tasks=_build_tasks_info(config),
242
- ))
243
- return f"✓ Planning complete.\n\n{config.get_summary()}"
88
+ )
244
89
 
90
+ try:
91
+ definition.register_task(task_def)
92
+ deps = f" (after: {depends_on})" if depends_on else ""
93
+ return f"Created task '{name}' -> {agent_name}{deps}"
94
+ except ValueError as e:
95
+ return f"Error: {e}"
245
96
 
246
- # --- Agent Factory ---
97
+ @tool
98
+ def finalize_plan() -> str:
99
+ """Signal that planning is complete."""
100
+ return f"Plan finalized.\n{definition.get_summary()}"
247
101
 
248
- ORCHESTRATOR_TOOLS = [
249
- list_available_tools,
250
- list_available_models,
251
- spawn_agent,
252
- create_task,
253
- get_planning_status,
254
- finalize_plan,
255
- ]
102
+ return [spawn_agent, create_task, finalize_plan]
256
103
 
257
104
 
258
- def create_orchestrator_agent(model: Model | None = None) -> Agent:
259
- """Create orchestrator agent that plans, creates sub-agents, assigns tasks, and synthesizes completion."""
105
+ def create_orchestrator_agent(
106
+ definition: "SwarmDefinition",
107
+ model: "Model | None" = None,
108
+ ) -> Agent:
109
+ """Create the orchestrator agent."""
260
110
  return Agent(
261
111
  name="orchestrator",
262
112
  system_prompt=ORCHESTRATOR_SYSTEM_PROMPT,
263
113
  model=model,
264
- tools=ORCHESTRATOR_TOOLS,
114
+ tools=create_orchestrator_tools(definition),
115
+ callback_handler=None,
265
116
  )
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.4
2
+ Name: strands-swarms
3
+ Version: 0.1.2
4
+ Summary: Task-based workflow orchestration for Strands Agents
5
+ Project-URL: Homepage, https://github.com/JackXu0/strands-swarms
6
+ Project-URL: Issues, https://github.com/JackXu0/strands-swarms/issues
7
+ Author-email: Zhuocheng Xu <zhuocheng.xu@icloud.com>
8
+ License: Apache-2.0
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: strands-agents>=0.1.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: mypy>=1.15.0; extra == 'dev'
24
+ Requires-Dist: pytest-asyncio>=1.0.0; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.13.0; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # strands-swarms
30
+
31
+ [![CI](https://github.com/JackXu0/strands-swarms/actions/workflows/ci.yml/badge.svg)](https://github.com/JackXu0/strands-swarms/actions/workflows/ci.yml)
32
+ [![PyPI](https://img.shields.io/pypi/v/strands-swarms)](https://pypi.org/project/strands-swarms/)
33
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
34
+
35
+ **Turn natural language into multi-agent workflows — automatically.**
36
+
37
+ Give `DynamicSwarm` a query, and it automatically plans the workflow, spawns specialized agents, and executes tasks with dependencies. No manual graph configuration or agent wiring required.
38
+
39
+ ```python
40
+ swarm = DynamicSwarm(available_tools={...}, available_models={...})
41
+ result = swarm.execute("Research AI trends and write a summary report")
42
+ # → Spawns researcher + writer agents, handles dependencies, returns final report
43
+ ```
44
+
45
+ ## Inspiration
46
+
47
+ This project is inspired by [Kimi K2.5's Agent Swarm](https://www.kimi.com/blog/kimi-k2-5.html) — where a trainable orchestrator dynamically creates and coordinates sub-agents without predefined roles or workflows. The goal is to build an open-source foundation for training orchestrators that can spin up agent swarms on the fly.
48
+
49
+ ## How It Works
50
+
51
+ ![Architecture](assets/architecture.png)
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ pip install strands-swarms
57
+ ```
58
+
59
+ ## Quick Start
60
+
61
+ ```python
62
+ from strands import tool
63
+ from strands.models import BedrockModel
64
+ from strands_swarms import DynamicSwarm
65
+
66
+ # Define your tools
67
+ @tool
68
+ def search_web(query: str) -> str:
69
+ """Search the web for information."""
70
+ return f"[Search Results for '{query}']\n- Result 1: Latest developments..."
71
+
72
+ @tool
73
+ def analyze_data(data: str) -> str:
74
+ """Analyze data and extract insights."""
75
+ return f"[Analysis]\nKey insights: ..."
76
+
77
+ @tool
78
+ def write_file(path: str, content: str) -> str:
79
+ """Write content to a file."""
80
+ return f"Successfully wrote {len(content)} characters to {path}"
81
+
82
+ # Configure models
83
+ powerful_model = BedrockModel(model_id="us.anthropic.claude-3-opus-20240229-v1:0")
84
+ fast_model = BedrockModel(model_id="us.anthropic.claude-3-5-haiku-20241022-v1:0")
85
+
86
+ # Create the swarm
87
+ swarm = DynamicSwarm(
88
+ available_tools={
89
+ "search_web": search_web,
90
+ "analyze_data": analyze_data,
91
+ "write_file": write_file,
92
+ },
93
+ available_models={
94
+ "powerful": powerful_model,
95
+ "fast": fast_model,
96
+ },
97
+ orchestrator_model=powerful_model,
98
+ default_agent_model="fast",
99
+ )
100
+
101
+ # Execute with natural language
102
+ result = swarm.execute("Research the latest AI trends and write a summary report")
103
+
104
+ print(f"Status: {result.status}")
105
+ print(f"Agents spawned: {result.agents_spawned_count}")
106
+ for agent in result.agents_spawned:
107
+ print(f" - {agent.name}: {agent.role}")
108
+ print(f"Tasks created: {result.tasks_created_count}")
109
+ for task in result.tasks_created:
110
+ depends = f" (depends: [{', '.join(task.depends_on)}])" if task.depends_on else ""
111
+ print(f" - {task.name} -> {task.agent}{depends}")
112
+ print(f"Final response: {result.final_response}")
113
+ ```
114
+ <details>
115
+ <summary>Example output (see examples/simple.py)</summary>
116
+
117
+ ```
118
+ Status: Status.COMPLETED
119
+ Agents spawned: 2
120
+ - researcher: AI trends researcher
121
+ - writer: AI trends summary writer
122
+ Tasks created: 3
123
+ - web_research -> researcher
124
+ - analyze_trends -> researcher (depends: [web_research])
125
+ - write_summary -> writer (depends: [analyze_trends])
126
+ Final response: <thinking>
127
+ The job is complete. The researchers gathered comprehensive information on the latest AI trends through web searches, analyzed that information to identify the most important developments and themes, and the writer put it together into a clear summary report touching on:
128
+
129
+ - Major AI breakthroughs in the last year across language, vision, multimodal and generative models
130
+ - Potential applications of these advancing AI capabilities
131
+ - Rapid growth in enterprise adoption and startup investment
132
+ - Key technical challenges like robustness, interpretability and scalability
133
+ - Important societal and ethical considerations around safety, bias and responsible use
134
+ - Longer-term possibilities around artificial general intelligence
135
+
136
+ The report provides a succinct yet informative overview of the state of the art in AI and the key trends shaping the field. It directly addresses the original request, so no further analysis or synthesis is needed. The final report can be delivered as-is to the human who made the request.
137
+ </thinking>
138
+
139
+ Here is a summary report on the latest trends in artificial intelligence:
140
+
141
+ Artificial intelligence continues to progress rapidly, with significant developments over the past year in areas like natural language processing, computer vision, multimodal learning, and generative AI. Powerful language models can now engage in human-like dialogue and assist with writing. AI systems can perceive and reason jointly about text, images, audio and video. New generative models can create highly realistic images from textual descriptions. And AI has achieved human-level performance on complex strategy games.
142
+
143
+ These advances open up transformative potential applications — enhancing creative workflows, accelerating scientific discovery, enabling more natural human-computer interaction. Enterprises across sectors are increasingly adopting AI technologies, and venture capital investment into AI startups reached record levels in 2022.
144
+
145
+ However, key technical challenges remain in making AI systems more robust, interpretable and scalable. Important societal considerations are also in play around AI ethics, safety, bias and responsible use. Longer-term, some believe AI could progress toward human-level artificial general intelligence, though this remains a future possibility.
146
+
147
+ In summary, AI capabilities are advancing quickly, with potentially profound impacts across domains in the coming years. Ongoing research aims to further enhance performance while addressing crucial challenges. Organizations will need to balance leveraging AI's competitive advantages with deploying it in a trustworthy manner. The field's rapid progress looks set to continue — and to reshape the world in the process.
148
+ ```
149
+
150
+ </details>
151
+
152
+ ## Status & Roadmap
153
+
154
+ > **Current version: Rollout-only**
155
+ >
156
+ > This release supports **rollout execution** (string-in, string-out) — ideal for inference and deployment.
157
+ >
158
+ > **Coming soon:** RL support via [strands-sglang](https://github.com/strands-agents/strands-sglang) integration.
159
+
160
+ - [x] Rollout execution — string-in, string-out multi-agent workflows
161
+ - [x] Dynamic orchestration — automatic agent creation and task assignment
162
+ - [ ] Streaming trajectory output — consume `stream_async()`
163
+ - [ ] RL support — training and fine-tuning via strands-sglang
164
+
165
+ ## Contributing
166
+
167
+ Contributions welcome! Please feel free to submit issues and pull requests.
168
+
169
+ ## License
170
+
171
+ Apache-2.0
@@ -0,0 +1,8 @@
1
+ strands_swarms/__init__.py,sha256=S082nMANh4fzbXmUlhrK_TGKwuHsZM-TzLQ9p6y9Zr8,2252
2
+ strands_swarms/definition.py,sha256=k6LLrci6gZwfTKZaHXmVYGSNglN7u-ErtjJYut-83Mw,5475
3
+ strands_swarms/dynamic_swarm.py,sha256=c0hEMlleP6z1v9CMXT4fZGzlIqjmkrsCZSP59NFZg08,15512
4
+ strands_swarms/orchestrator.py,sha256=ILpw5c6Cy-5EfElVXp6qvlfMDmhP8VEjid5d83FyvmI,3558
5
+ strands_swarms-0.1.2.dist-info/METADATA,sha256=HihoCAsx-evgp0xyq0FpXirqsiHxiJw54LZHwYyYh7k,8056
6
+ strands_swarms-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
7
+ strands_swarms-0.1.2.dist-info/licenses/LICENSE,sha256=fw8CKBXZ_-V6K5pxfUmJP3e_7QUvFq8XncuZ27tvarg,10177
8
+ strands_swarms-0.1.2.dist-info/RECORD,,