swarmkit 0.1.34__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.
@@ -0,0 +1,193 @@
1
+ """Type definitions for Swarm abstractions."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import (
5
+ Any,
6
+ Callable,
7
+ Dict,
8
+ List,
9
+ Literal,
10
+ Optional,
11
+ Type,
12
+ TypeVar,
13
+ Union,
14
+ )
15
+
16
+ from ..config import SandboxProvider, AgentConfig, WorkspaceMode
17
+ from ..retry import RetryConfig
18
+
19
+
20
+ # =============================================================================
21
+ # TYPE VARIABLES
22
+ # =============================================================================
23
+
24
+ T = TypeVar('T')
25
+
26
+ # =============================================================================
27
+ # FILE MAP
28
+ # =============================================================================
29
+
30
+ FileMap = Dict[str, Union[str, bytes]]
31
+
32
+ # =============================================================================
33
+ # CONFIGURATION
34
+ # =============================================================================
35
+
36
+ @dataclass
37
+ class SwarmConfig:
38
+ """Configuration for Swarm instance.
39
+
40
+ All fields are optional - TS SDK resolves defaults from environment:
41
+ - agent defaults to SWARMKIT_API_KEY env var with 'claude' type
42
+ - sandbox defaults to E2B with E2B_API_KEY env var
43
+ """
44
+ agent: Optional[AgentConfig] = None
45
+ sandbox: Optional[SandboxProvider] = None
46
+ tag: str = "swarm"
47
+ concurrency: int = 4
48
+ timeout_ms: int = 3_600_000 # 1 hour
49
+ workspace_mode: WorkspaceMode = "knowledge"
50
+ retry: Optional[RetryConfig] = None
51
+ """Default retry configuration for all operations (per-operation config takes precedence)."""
52
+ mcp_servers: Optional[Dict[str, Any]] = None
53
+ """Default MCP servers for all operations (per-operation config takes precedence)."""
54
+
55
+
56
+ # Callback types for BestOf
57
+ OnCandidateCompleteCallback = Callable[[int, int, Literal["success", "error"]], None]
58
+ """(item_index, candidate_index, status)"""
59
+
60
+ OnJudgeCompleteCallback = Callable[[int, int, str], None]
61
+ """(item_index, winner_index, reasoning)"""
62
+
63
+
64
+ @dataclass
65
+ class BestOfConfig:
66
+ """Configuration for bestOf operation."""
67
+ judge_criteria: str
68
+ n: Optional[int] = None
69
+ task_agents: Optional[List[AgentConfig]] = None
70
+ judge_agent: Optional[AgentConfig] = None
71
+ mcp_servers: Optional[Dict[str, Any]] = None
72
+ """MCP servers for candidates (defaults to operation mcp_servers)."""
73
+ judge_mcp_servers: Optional[Dict[str, Any]] = None
74
+ """MCP servers for judge (defaults to mcp_servers)."""
75
+ on_candidate_complete: Optional[OnCandidateCompleteCallback] = None
76
+ """Callback when a candidate completes."""
77
+ on_judge_complete: Optional[OnJudgeCompleteCallback] = None
78
+ """Callback when judge completes."""
79
+
80
+
81
+ # Callback types for Verify
82
+ OnWorkerCompleteCallback = Callable[[int, int, Literal["success", "error"]], None]
83
+ """(item_index, attempt, status)"""
84
+
85
+ OnVerifierCompleteCallback = Callable[[int, int, bool, Optional[str]], None]
86
+ """(item_index, attempt, passed, feedback)"""
87
+
88
+
89
+ @dataclass
90
+ class VerifyConfig:
91
+ """Configuration for verify operation.
92
+
93
+ Verify provides LLM-as-judge quality verification with retry loop.
94
+ If verification fails, the worker is re-run with feedback from the verifier.
95
+ """
96
+ criteria: str
97
+ """Verification criteria - what the output must satisfy."""
98
+ max_attempts: int = 3
99
+ """Maximum attempts with feedback (default: 3). Includes initial attempt."""
100
+ verifier_agent: Optional[AgentConfig] = None
101
+ """Optional: override agent for verifier."""
102
+ verifier_mcp_servers: Optional[Dict[str, Any]] = None
103
+ """MCP servers for verifier (defaults to operation mcp_servers)."""
104
+ on_worker_complete: Optional[OnWorkerCompleteCallback] = None
105
+ """Callback invoked after each worker completion (before verification)."""
106
+ on_verifier_complete: Optional[OnVerifierCompleteCallback] = None
107
+ """Callback invoked after each verifier completion."""
108
+
109
+
110
+ # =============================================================================
111
+ # METADATA
112
+ # =============================================================================
113
+
114
+ OperationType = Literal["map", "filter", "reduce", "bestof-cand", "bestof-judge", "verify"]
115
+
116
+
117
+ @dataclass
118
+ class BaseMeta:
119
+ """Base metadata for all operations."""
120
+ run_id: str
121
+ operation: OperationType
122
+ tag: str
123
+ sandbox_id: str
124
+
125
+
126
+ @dataclass
127
+ class IndexedMeta(BaseMeta):
128
+ """Metadata for indexed operations (map, filter, bestof-cand)."""
129
+ index: int
130
+
131
+
132
+ @dataclass
133
+ class ReduceMeta(BaseMeta):
134
+ """Metadata for reduce operation."""
135
+ input_count: int
136
+ input_indices: List[int]
137
+
138
+
139
+ @dataclass
140
+ class JudgeMeta(BaseMeta):
141
+ """Metadata for bestOf judge."""
142
+ candidate_count: int
143
+
144
+
145
+ @dataclass
146
+ class VerifyMeta(BaseMeta):
147
+ """Metadata for verify operation."""
148
+ attempts: int
149
+ """Total verification attempts made."""
150
+
151
+
152
+ # =============================================================================
153
+ # PROMPT TYPES
154
+ # =============================================================================
155
+
156
+ PromptFn = Callable[[FileMap, int], str]
157
+ Prompt = Union[str, PromptFn]
158
+
159
+
160
+ # =============================================================================
161
+ # ITEM INPUT (for chaining)
162
+ # =============================================================================
163
+
164
+ # Forward reference - actual SwarmResult defined in results.py
165
+ # ItemInput can be a FileMap or a SwarmResult from a previous operation
166
+ ItemInput = Union[FileMap, Any] # Any here will be SwarmResult at runtime
167
+
168
+
169
+ # =============================================================================
170
+ # SCHEMA TYPE
171
+ # =============================================================================
172
+
173
+ # Schema can be a Pydantic model, dataclass, or JSON Schema dict
174
+ SchemaType = Union[Type[Any], Dict[str, Any]]
175
+
176
+
177
+ # =============================================================================
178
+ # JUDGE DECISION
179
+ # =============================================================================
180
+
181
+ @dataclass
182
+ class JudgeDecision:
183
+ """Fixed schema for bestOf judge output."""
184
+ winner: int
185
+ reasoning: str
186
+
187
+
188
+ @dataclass
189
+ class VerifyDecision:
190
+ """Fixed schema for verify output."""
191
+ passed: bool
192
+ reasoning: str
193
+ feedback: Optional[str] = None
swarmkit/utils.py ADDED
@@ -0,0 +1,82 @@
1
+ """File utilities for SwarmKit SDK."""
2
+
3
+ import base64
4
+ import os
5
+ from pathlib import Path
6
+ from typing import Any, Dict, Union
7
+
8
+
9
+ def _filter_none(d: Dict[str, Any]) -> Dict[str, Any]:
10
+ """Filter out None values from a dict. Used for building RPC params."""
11
+ return {k: v for k, v in d.items() if v is not None}
12
+
13
+
14
+ def _encode_files_for_transport(
15
+ files: Dict[str, Union[str, bytes]]
16
+ ) -> Dict[str, Dict[str, str]]:
17
+ """Encode files dict for JSON-RPC transport.
18
+
19
+ Handles both text (str) and binary (bytes) content with appropriate encoding.
20
+ Uses 'content' field consistently for both input and output files.
21
+ """
22
+ result = {}
23
+ for name, file_content in files.items():
24
+ if isinstance(file_content, bytes):
25
+ result[name] = {
26
+ 'content': base64.b64encode(file_content).decode('utf-8'),
27
+ 'encoding': 'base64'
28
+ }
29
+ else:
30
+ result[name] = {'content': file_content, 'encoding': 'text'}
31
+ return result
32
+
33
+
34
+ def read_local_dir(local_path: str, recursive: bool = False) -> Dict[str, bytes]:
35
+ """Read files from a local directory into a dict for upload.
36
+
37
+ Args:
38
+ local_path: Path to local directory
39
+ recursive: Include subdirectories (default: False)
40
+
41
+ Returns:
42
+ Dict mapping relative paths to file content as bytes
43
+ """
44
+ result: Dict[str, bytes] = {}
45
+ root = Path(local_path)
46
+
47
+ paths = root.rglob('*') if recursive else root.iterdir()
48
+
49
+ for p in paths:
50
+ if p.is_file():
51
+ result[str(p.relative_to(root))] = p.read_bytes()
52
+
53
+ return result
54
+
55
+
56
+ def save_local_dir(local_path: str, files: Dict[str, Union[str, bytes]]) -> None:
57
+ """Save files dict to a local directory, creating nested directories as needed.
58
+
59
+ Args:
60
+ local_path: Base directory to save files to
61
+ files: Dict mapping relative paths to content (from get_output_files().files or other source)
62
+
63
+ Example:
64
+ >>> output = await agent.get_output_files(recursive=True)
65
+ >>> save_local_dir('./output', output.files)
66
+ # Creates: ./output/file.txt, ./output/subdir/nested.txt, etc.
67
+ """
68
+ for name, content in files.items():
69
+ file_path = os.path.join(local_path, name)
70
+ parent = os.path.dirname(file_path)
71
+
72
+ # Create parent directories if needed
73
+ if parent:
74
+ os.makedirs(parent, exist_ok=True)
75
+
76
+ # Write content
77
+ if isinstance(content, bytes):
78
+ with open(file_path, 'wb') as f:
79
+ f.write(content)
80
+ else:
81
+ with open(file_path, 'w', encoding='utf-8') as f:
82
+ f.write(content)
@@ -0,0 +1,80 @@
1
+ Metadata-Version: 2.4
2
+ Name: swarmkit
3
+ Version: 0.1.34
4
+ Summary: Pythonic wrapper around the TypeScript SwarmKit SDK for multi-agent orchestration in E2B sandboxes
5
+ Author-email: "Swarmlink, Inc." <brandomagnani@swarmlink.ai>
6
+ License: Proprietary Beta Evaluation License - See LICENSE file
7
+ Project-URL: Homepage, https://github.com/brandomagnani/swarmkit.git
8
+ Project-URL: Repository, https://github.com/brandomagnani/swarmkit.git
9
+ Keywords: ai,agents,sandbox,e2b,orchestration,codex,claude,gemini
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: Other/Proprietary License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
22
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
23
+ Requires-Dist: python-dotenv>=1.0.0; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # SwarmKit Python SDK
27
+
28
+ SwarmKit lets you run and orchestrate terminal-based AI agents in secure sandboxes with built-in observability.
29
+
30
+ ## Get Started
31
+
32
+ 1. Get your **SwarmKit API key** at [dashboard.swarmlink.ai](https://dashboard.swarmlink.ai/) (new users: [request access](https://dashboard.swarmlink.ai/request-access) first)
33
+
34
+ 2. Get an **E2B API key** at [e2b.dev](https://e2b.dev) for sandbox execution
35
+
36
+ 3. Install the SDK:
37
+ ```bash
38
+ pip install swarmkit
39
+ ```
40
+ **Note:** Requires [Node.js 18+](https://nodejs.org/) (the SDK uses a lightweight Node.js bridge).
41
+
42
+ 4. Check out the [official documentation](https://github.com/brandomagnani/swarmkit/tree/main/docs) and [cookbooks](https://github.com/brandomagnani/swarmkit/tree/main/cookbooks) to start shipping with SwarmKit!
43
+
44
+ ## Streaming Events
45
+
46
+ You can subscribe to streaming events:
47
+
48
+ - `stdout`: Raw NDJSON output from the agent/CLI (may arrive in chunks).
49
+ - `stderr`: Process stderr (may arrive in chunks).
50
+ - `content`: Parsed ACP-style events (messages, tool calls, plan updates).
51
+
52
+ ### Large Outputs
53
+
54
+ The Node bridge enforces per-event size limits for responsiveness.
55
+
56
+ - `stdout`/`stderr` are chunked when very large; your callback receives each chunk normally.
57
+ - `content` events are lossless: if a payload is too large to stream safely, you receive a truncated preview plus a `ref` to a local JSON file containing the full payload.
58
+
59
+ Example:
60
+
61
+ ```py
62
+ def on_content(evt):
63
+ if evt.get("truncated") and evt.get("ref"):
64
+ full_update = open(evt["ref"]["path"], "r", encoding="utf-8").read()
65
+ # full_update is the original ACP update JSON
66
+
67
+ swarmkit.on("content", on_content)
68
+ ```
69
+
70
+ ## Reporting Bugs
71
+
72
+ We welcome your feedback. File a [GitHub issue](https://github.com/brandomagnani/swarmkit/issues) to report bugs or request features.
73
+
74
+ ## Connect on Discord
75
+
76
+ Join the [SwarmKit Developers Discord](https://discord.gg/Q36D8dGyNF) to connect with other developers using SwarmKit. Get help, share feedback, and discuss your projects with the community.
77
+
78
+ ## License
79
+
80
+ See [LICENSE](https://github.com/brandomagnani/swarmkit/blob/main/LICENSE) for details.
@@ -0,0 +1,29 @@
1
+ bridge/__init__.py,sha256=oakDP-wspBW61TEuKMKb4fwHRWqX0MJMtwJONqk_664,165
2
+ bridge/dist/bridge.bundle.cjs,sha256=4Sng2mj48hT9SRQvB962vVZXSaaeBOfDjBWX04KFuBE,3170378
3
+ swarmkit/__init__.py,sha256=Bftb7kCJLI48PhkCpQzGxAbbjlVscIaD_krgjNVgTvE,3048
4
+ swarmkit/agent.py,sha256=LMJZJ_shgrXG4T3twYa3fpH8K8NTsuYwgxL7t40IpX8,18265
5
+ swarmkit/bridge.py,sha256=u6MK4Q3RTqjFwHDgic0u0pHL4wOVMq2MzHynL-oR8CY,17546
6
+ swarmkit/config.py,sha256=0WXesMF1RuoHEQ0-0XDDunMe_dJy-0qocAxoEG2f5Ck,2687
7
+ swarmkit/results.py,sha256=aP4TvXDfk75AQCt1GVuiMn3nMi-fhWLOJpaSQ6fcCH4,1245
8
+ swarmkit/retry.py,sha256=8yeqW4qogNpf1tTCts-XrC5jVzvlFp1Crg12qrFTeTA,4631
9
+ swarmkit/schema.py,sha256=hmmpBxdsI7FWNf7Gd8dDhIWICwVcowodMQ0mKiu9_xs,2988
10
+ swarmkit/utils.py,sha256=h7o9hisfFSHhmqzNDT5ZSpAeLCyudayT14BT8W_O-Pw,2638
11
+ swarmkit/pipeline/__init__.py,sha256=FfRHkWeY1p7YruUJ9cqKlO64mkOngKyxi3GRaADU0ns,1134
12
+ swarmkit/pipeline/pipeline.py,sha256=dPcOZM7WgmzfwtsMJmntwCJdY1dAG8ZCWxw0Bmw--bk,18756
13
+ swarmkit/pipeline/types.py,sha256=UfnMjfQZGqr6Z5IwnzNTw2K67pVeiYCDRd30PDDnzkA,7816
14
+ swarmkit/prompts/__init__.py,sha256=k9eJNq4NlaZvgGWLH6KPfT0UxI4jLqanJHWV_Jx7VvQ,4731
15
+ swarmkit/prompts/agent_md/judge.md,sha256=RbBH58q-A_7ZyG3vMGEMMUI1V7owhvK17qAnjkFPdQs,1019
16
+ swarmkit/prompts/agent_md/reduce.md,sha256=nzG5cuIfoHhp-m80Z2CUA9kBYjggtagX1tA_ERPx2rs,117
17
+ swarmkit/prompts/agent_md/verify.md,sha256=96tNr4UOp8c64xqC6kSJPnH4RHW27l88oJRsU8lUYAY,1012
18
+ swarmkit/prompts/user/judge.md,sha256=voZSLTXCte2-94D_Wx0JrCPKjv093DBrnBrnkzQy5Tg,111
19
+ swarmkit/prompts/user/retry_feedback.md,sha256=-dUWfAbknKsrPArHd38jE1ShQ-3quKInrhcm6x1W4fc,237
20
+ swarmkit/prompts/user/verify.md,sha256=Tuq8FQotrBTFOm_lngEpNx8j7l12J96QrVKPnmuxQpU,109
21
+ swarmkit/swarm/__init__.py,sha256=3qLm8TqAPbcpXH7vuWLr3IqJ7bUj9hz_qpCdTjBjln4,1430
22
+ swarmkit/swarm/results.py,sha256=vNWCOkJ_fnEUsCipWq7xAADxg4hJdV3Wh4YI57drR8s,4516
23
+ swarmkit/swarm/swarm.py,sha256=196wqLvgWzl94WIGwx1E3Uc1Wp6KbdUeEwpS8nlHnvs,66672
24
+ swarmkit/swarm/types.py,sha256=JDNGcGXOnyzKmmahFlwmOZ_0xhyk3Of64e_A02EMZY4,6128
25
+ swarmkit-0.1.34.dist-info/licenses/LICENSE,sha256=QLecPBFjABXODzKI22IEci6OaBCjpOVdCYgtmXVKXBY,799
26
+ swarmkit-0.1.34.dist-info/METADATA,sha256=MgYFx84vA-mv1k3aHtlKmNFSq4JLGO9C9rtmP97Q_bY,3258
27
+ swarmkit-0.1.34.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
+ swarmkit-0.1.34.dist-info/top_level.txt,sha256=-3mxmF3ggfuPa9StJHAdsaGjGmb26BhWwKs6s2kjz74,16
29
+ swarmkit-0.1.34.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,24 @@
1
+ SWARMKIT PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2025 Swarmlink, Inc. All rights reserved.
4
+
5
+ BETA EVALUATION LICENSE
6
+
7
+ The SwarmKit SDK is provided for evaluation and beta testing purposes only.
8
+
9
+ PERMITTED:
10
+ - Install SwarmKit via npm/PyPI for evaluation and development
11
+ - Build applications using the SwarmKit SDK during the beta period
12
+ - Deploy applications using the SwarmKit SDK to production
13
+
14
+ PROHIBITED:
15
+ - Redistribute the SwarmKit SDK itself
16
+ - Reverse engineer, decompile, or extract source code from the SDK
17
+ - Create derivative works of the SwarmKit SDK
18
+ - Use SwarmKit in competing products or services
19
+
20
+ NO WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS" FOR BETA EVALUATION.
21
+
22
+ This license may be revised upon general availability.
23
+
24
+ For licensing inquiries, contact: brandomagnani@swarmlink.ai
@@ -0,0 +1,2 @@
1
+ bridge
2
+ swarmkit