swarmstate 0.1.0__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.
- swarmstate-0.1.0/.github/workflows/ci.yml +69 -0
- swarmstate-0.1.0/.github/workflows/release.yml +84 -0
- swarmstate-0.1.0/.gitignore +23 -0
- swarmstate-0.1.0/CLAUDE.md +247 -0
- swarmstate-0.1.0/Cargo.lock +269 -0
- swarmstate-0.1.0/Cargo.toml +28 -0
- swarmstate-0.1.0/LICENSE +21 -0
- swarmstate-0.1.0/PKG-INFO +95 -0
- swarmstate-0.1.0/README.md +60 -0
- swarmstate-0.1.0/pyproject.toml +48 -0
- swarmstate-0.1.0/python/swarmstate/__init__.py +25 -0
- swarmstate-0.1.0/python/swarmstate/_core.pyi +86 -0
- swarmstate-0.1.0/python/swarmstate/py.typed +0 -0
- swarmstate-0.1.0/rust/src/codec.rs +191 -0
- swarmstate-0.1.0/rust/src/lib.rs +45 -0
- swarmstate-0.1.0/rust/src/store.rs +385 -0
- swarmstate-0.1.0/tests/test_smoke.py +19 -0
- swarmstate-0.1.0/tests/test_store.py +168 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
rust:
|
|
15
|
+
name: Rust core (cargo test)
|
|
16
|
+
runs-on: ${{ matrix.os }}
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
24
|
+
- uses: Swatinem/rust-cache@v2
|
|
25
|
+
- name: cargo test
|
|
26
|
+
run: cargo test --all --verbose
|
|
27
|
+
|
|
28
|
+
python:
|
|
29
|
+
name: Python API (pytest)
|
|
30
|
+
runs-on: ${{ matrix.os }}
|
|
31
|
+
strategy:
|
|
32
|
+
fail-fast: false
|
|
33
|
+
matrix:
|
|
34
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
35
|
+
python-version: ["3.9", "3.13"]
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
39
|
+
- uses: Swatinem/rust-cache@v2
|
|
40
|
+
- uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: ${{ matrix.python-version }}
|
|
43
|
+
- name: Install test deps
|
|
44
|
+
run: python -m pip install --upgrade pip pytest
|
|
45
|
+
- name: Build and install swarmstate (maturin backend)
|
|
46
|
+
run: python -m pip install .
|
|
47
|
+
- name: pytest
|
|
48
|
+
run: pytest -q
|
|
49
|
+
|
|
50
|
+
lint:
|
|
51
|
+
name: Lint (ruff + cargo fmt)
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
56
|
+
with:
|
|
57
|
+
components: rustfmt, clippy
|
|
58
|
+
- uses: actions/setup-python@v5
|
|
59
|
+
with:
|
|
60
|
+
python-version: "3.13"
|
|
61
|
+
- name: cargo fmt --check
|
|
62
|
+
run: cargo fmt --all -- --check
|
|
63
|
+
- name: cargo clippy
|
|
64
|
+
run: cargo clippy --all-targets -- -D warnings
|
|
65
|
+
- name: ruff
|
|
66
|
+
run: |
|
|
67
|
+
python -m pip install --upgrade pip ruff
|
|
68
|
+
ruff check python tests
|
|
69
|
+
ruff format --check python tests
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Builds cross-platform abi3 wheels + sdist and publishes to PyPI via
|
|
4
|
+
# Trusted Publishing (OIDC — no API token stored in the repo).
|
|
5
|
+
#
|
|
6
|
+
# Trigger:
|
|
7
|
+
# - publishing a GitHub Release -> build + publish to PyPI
|
|
8
|
+
# - manual "Run workflow" -> build + publish (after PyPI is configured)
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
release:
|
|
12
|
+
types: [published]
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
wheels:
|
|
20
|
+
name: wheels (${{ matrix.platform.target }} · ${{ matrix.platform.runner }})
|
|
21
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
platform:
|
|
26
|
+
- { runner: ubuntu-latest, target: x86_64, manylinux: auto }
|
|
27
|
+
- { runner: ubuntu-latest, target: aarch64, manylinux: auto }
|
|
28
|
+
# Both macOS wheels build on the arm64 runner; x86_64 is
|
|
29
|
+
# cross-compiled to avoid the scarce Intel (macos-13) runners.
|
|
30
|
+
- { runner: macos-14, target: x86_64, manylinux: "" }
|
|
31
|
+
- { runner: macos-14, target: aarch64, manylinux: "" }
|
|
32
|
+
- { runner: windows-latest, target: x64, manylinux: "" }
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
- uses: actions/setup-python@v5
|
|
36
|
+
with:
|
|
37
|
+
python-version: "3.13"
|
|
38
|
+
- name: Build wheels
|
|
39
|
+
uses: PyO3/maturin-action@v1
|
|
40
|
+
with:
|
|
41
|
+
target: ${{ matrix.platform.target }}
|
|
42
|
+
manylinux: ${{ matrix.platform.manylinux }}
|
|
43
|
+
args: --release --out dist
|
|
44
|
+
sccache: "true"
|
|
45
|
+
- uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: wheels-${{ matrix.platform.runner }}-${{ matrix.platform.target }}
|
|
48
|
+
path: dist
|
|
49
|
+
|
|
50
|
+
sdist:
|
|
51
|
+
name: source distribution
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- name: Build sdist
|
|
56
|
+
uses: PyO3/maturin-action@v1
|
|
57
|
+
with:
|
|
58
|
+
command: sdist
|
|
59
|
+
args: --out dist
|
|
60
|
+
- uses: actions/upload-artifact@v4
|
|
61
|
+
with:
|
|
62
|
+
name: wheels-sdist
|
|
63
|
+
path: dist
|
|
64
|
+
|
|
65
|
+
publish:
|
|
66
|
+
name: Publish to PyPI
|
|
67
|
+
needs: [wheels, sdist]
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
# A dedicated environment lets PyPI scope the trusted publisher.
|
|
70
|
+
environment:
|
|
71
|
+
name: pypi
|
|
72
|
+
url: https://pypi.org/project/swarmstate/
|
|
73
|
+
permissions:
|
|
74
|
+
id-token: write # required for OIDC Trusted Publishing
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/download-artifact@v4
|
|
77
|
+
with:
|
|
78
|
+
pattern: wheels-*
|
|
79
|
+
merge-multiple: true
|
|
80
|
+
path: dist
|
|
81
|
+
- name: Publish to PyPI
|
|
82
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
83
|
+
with:
|
|
84
|
+
packages-dir: dist
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Rust
|
|
2
|
+
/target
|
|
3
|
+
Cargo.lock
|
|
4
|
+
|
|
5
|
+
# Python
|
|
6
|
+
.venv/
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*.so
|
|
10
|
+
*.pyd
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.ruff_cache/
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
|
|
17
|
+
# maturin
|
|
18
|
+
/wheels
|
|
19
|
+
|
|
20
|
+
# OS / editor
|
|
21
|
+
.DS_Store
|
|
22
|
+
.idea/
|
|
23
|
+
.vscode/
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# CLAUDE.md — swarmstate
|
|
2
|
+
|
|
3
|
+
> Master guide for building **swarmstate** from scratch. This file lives at the repository root and is the
|
|
4
|
+
> single source of truth for any development session with Claude Code. Read it fully before writing any code.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 0. How to use this file
|
|
9
|
+
|
|
10
|
+
- **Package name:** `swarmstate` (PyPI + import). If it needs to change, change it **only here** and propagate:
|
|
11
|
+
`PACKAGE_NAME=swarmstate`, `IMPORT_NAME=swarmstate`, `RUST_CRATE=swarmstate_core`, `GH_REPO=<org>/swarmstate`.
|
|
12
|
+
- The repository will be hosted under a **dedicated GitHub organization** (e.g. `github.com/swarmstate/...`).
|
|
13
|
+
The org and an **empty repo** are created by the maintainer beforehand; do not scaffold until they exist and
|
|
14
|
+
this file has been placed at the repo root.
|
|
15
|
+
- Work in small, verifiable increments. After each milestone, run the test suite and the benchmarks.
|
|
16
|
+
- Do not invent LangGraph/CrewAI APIs: whenever you touch their interface, **verify the real signatures** against
|
|
17
|
+
the version pinned in `pyproject.toml` before implementing an adapter.
|
|
18
|
+
- The top priority is that `pip install swarmstate` works with **no compiler** (prebuilt `abi3` wheels). Compiling
|
|
19
|
+
Rust is only for development (`maturin develop`).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. What swarmstate is (vision)
|
|
24
|
+
|
|
25
|
+
`swarmstate` is a **state and checkpointing backend with a Rust core and a Python API** for multi-agent systems.
|
|
26
|
+
It is not an orchestration framework and does **not** compete with LangGraph, CrewAI, or AutoGen: it is the fast
|
|
27
|
+
engine that sits **underneath** them, the same way Polars became the fast engine underneath workloads that used
|
|
28
|
+
to run on pandas.
|
|
29
|
+
|
|
30
|
+
**The pain it solves (production engineering teams):**
|
|
31
|
+
|
|
32
|
+
1. **State lock-in across frameworks.** Today, if you migrate from CrewAI to LangGraph you lose the accumulated
|
|
33
|
+
state. `swarmstate` provides a store with a framework-agnostic format: any agent reads/writes the same state.
|
|
34
|
+
2. **Checkpointing cost and latency.** LangGraph's per-node checkpointing backed by SQLite/Postgres becomes a
|
|
35
|
+
bottleneck at scale. `swarmstate` implements LangGraph's checkpointer interface with a Rust backend (fast
|
|
36
|
+
serialization, incremental snapshots, GIL released on hot paths).
|
|
37
|
+
3. **Deterministic routing that is currently paid for in tokens.** Many "which agent gets control next" decisions
|
|
38
|
+
don't need an LLM — they are rules over a dependency graph. `swarmstate` exposes a native Rust handoff graph
|
|
39
|
+
that resolves those transitions in microseconds.
|
|
40
|
+
|
|
41
|
+
**Target user:** the engineer with a *"checkpoint latency"* ticket or an orchestration bill that doesn't add up.
|
|
42
|
+
The sales pitch is **a number in a benchmark**, not an idea.
|
|
43
|
+
|
|
44
|
+
**Positioning (one line):**
|
|
45
|
+
> Drop-in state backend for LangGraph, CrewAI & custom agent loops — Rust core, framework-agnostic, built for production.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 2. Reference library model (turboswarm)
|
|
50
|
+
|
|
51
|
+
We deliberately mirror the DNA of `turboswarm` (same intended author/style):
|
|
52
|
+
|
|
53
|
+
- **Rust compute core, Python API** via **PyO3 + maturin**.
|
|
54
|
+
- **`cp39-abi3`** cross-platform wheels (Linux x86_64/aarch64, macOS x86_64/arm64, Windows amd64) — one build
|
|
55
|
+
serves Python 3.9+.
|
|
56
|
+
- README structure: title + one sentence → **Installation** → **Usage** (short runnable examples) →
|
|
57
|
+
**parameter table** → **Result object** → **Integrations** (drop-in with the existing stack) →
|
|
58
|
+
**Documentation** → **License (MIT)**.
|
|
59
|
+
- **Optional extras** with lazy imports: `swarmstate[langgraph]`, `[crewai]`, `[redis]`, `[all]`.
|
|
60
|
+
- **Documentation with MkDocs Material**: narrative guide + API reference, served via a `scripts/build-docs.sh --serve` script.
|
|
61
|
+
- Clear technical prose, reproducible `seed`-based examples, focus on **variant comparison and visible benchmarks**.
|
|
62
|
+
- **MIT** license.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. Architecture
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
swarmstate/ # repo root (GH_REPO)
|
|
70
|
+
├─ Cargo.toml # Rust core crate (RUST_CRATE = swarmstate_core)
|
|
71
|
+
├─ pyproject.toml # maturin as build backend
|
|
72
|
+
├─ rust/ # or src/ at root depending on maturin layout
|
|
73
|
+
│ └─ src/
|
|
74
|
+
│ ├─ lib.rs # #[pymodule] — exports classes to Python
|
|
75
|
+
│ ├─ store.rs # concurrent KV store + incremental snapshots
|
|
76
|
+
│ ├─ checkpoint.rs # Checkpoint/CheckpointTuple types, serialization
|
|
77
|
+
│ ├─ graph.rs # handoff/dependency graph (DAG), cycle detection
|
|
78
|
+
│ └─ codec.rs # serialization (msgpack/bincode) — fast and stable
|
|
79
|
+
├─ python/
|
|
80
|
+
│ └─ swarmstate/
|
|
81
|
+
│ ├─ __init__.py # public API: Store, Checkpointer, HandoffGraph
|
|
82
|
+
│ ├─ _core.pyi # type stubs for the Rust module (typing for users)
|
|
83
|
+
│ ├─ integrations/
|
|
84
|
+
│ │ ├─ __init__.py
|
|
85
|
+
│ │ ├─ langgraph.py # SwarmStateSaver(BaseCheckpointSaver) — DROP-IN, flagship piece
|
|
86
|
+
│ │ ├─ crewai.py # state/memory adapter for CrewAI
|
|
87
|
+
│ │ └─ redis.py # optional persistent backend
|
|
88
|
+
│ └─ py.typed
|
|
89
|
+
├─ tests/
|
|
90
|
+
├─ benchmarks/ # comparisons vs SqliteSaver / in-memory dict
|
|
91
|
+
├─ docs/ # MkDocs Material
|
|
92
|
+
├─ scripts/
|
|
93
|
+
│ └─ build-docs.sh
|
|
94
|
+
├─ .github/workflows/
|
|
95
|
+
│ ├─ ci.yml # Rust + Python tests on every push
|
|
96
|
+
│ └─ release.yml # maturin build of abi3 wheels + publish to PyPI (OIDC)
|
|
97
|
+
├─ README.md
|
|
98
|
+
├─ LICENSE # MIT
|
|
99
|
+
└─ CLAUDE.md # this file
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Rust core design principles:**
|
|
103
|
+
|
|
104
|
+
- Hot logic (serialization, snapshot diffs, graph traversal) lives **entirely in Rust**.
|
|
105
|
+
- Release the **GIL** (`py.allow_threads`) on any operation that doesn't touch Python objects.
|
|
106
|
+
- State serializes to bytes with a stable codec (**msgpack**) so it is readable from any language/framework.
|
|
107
|
+
- The Python API is thin: ergonomic wrappers over the PyO3 classes, with complete type hints.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 4. Target public API (first design; iterate)
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import swarmstate as ss
|
|
115
|
+
|
|
116
|
+
# --- Framework-agnostic store -----------------------------------------------
|
|
117
|
+
store = ss.Store() # in-memory; ss.Store(backend="redis", url=...) optional
|
|
118
|
+
store.set("workflow", "onboarding", {"step": 3, "data": {...}})
|
|
119
|
+
snap = store.snapshot() # immutable, cheap snapshot
|
|
120
|
+
val = store.get("workflow", "onboarding")
|
|
121
|
+
store.restore(snap) # rollback
|
|
122
|
+
|
|
123
|
+
# --- Handoff graph (deterministic transitions, no LLM) ----------------------
|
|
124
|
+
g = ss.HandoffGraph()
|
|
125
|
+
g.add_edge("triage", "billing", when="category == 'billing'")
|
|
126
|
+
nxt = g.route("triage", state={"category": "billing"}) # -> "billing", resolved in Rust
|
|
127
|
+
|
|
128
|
+
# --- Drop-in checkpointer for LangGraph -------------------------------------
|
|
129
|
+
from swarmstate.integrations.langgraph import SwarmStateSaver
|
|
130
|
+
graph = builder.compile(checkpointer=SwarmStateSaver()) # replaces SqliteSaver, 1 line
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Parameter table (turboswarm style) — document like this in the README:**
|
|
134
|
+
|
|
135
|
+
| Component | Parameter | Default | Description |
|
|
136
|
+
| ----------------- | ------------ | -------------- | ------------------------------------------------------- |
|
|
137
|
+
| `Store` | `backend` | `"memory"` | `"memory"`, `"redis"` (extra), future `"disk"` |
|
|
138
|
+
| `Store` | `codec` | `"msgpack"` | state serialization (stable across languages) |
|
|
139
|
+
| `Store` | `max_history`| `None` | number of retained snapshots (None = unlimited) |
|
|
140
|
+
| `HandoffGraph` | `on_cycle` | `"error"` | `"error"` or `"allow"` on cycle detection |
|
|
141
|
+
| `SwarmStateSaver` | `store` | `Store()` | underlying store; shareable across graphs |
|
|
142
|
+
| `SwarmStateSaver` | `serde` | auto | (de)serialization compatible with LangGraph |
|
|
143
|
+
|
|
144
|
+
**`Snapshot` object:** `.id`, `.timestamp`, `.keys`, `.size_bytes`, `.parent` (for incremental diffs).
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 5. Implementation roadmap (milestones)
|
|
149
|
+
|
|
150
|
+
Work in this order. Do not move to the next milestone without green tests.
|
|
151
|
+
|
|
152
|
+
**M0 — Scaffolding**
|
|
153
|
+
- [ ] Initialize a maturin project (`maturin new`, mixed Rust+Python layout) with `IMPORT_NAME`.
|
|
154
|
+
- [ ] `pyproject.toml` with maturin backend, `abi3-py39`, extras `[langgraph]/[crewai]/[redis]/[docs]/[all]`.
|
|
155
|
+
- [ ] `maturin develop` compiles and `import swarmstate` works. A trivial test passes.
|
|
156
|
+
|
|
157
|
+
**M1 — Rust store**
|
|
158
|
+
- [ ] Concurrent KV store (namespace + key -> value bytes) with msgpack codec.
|
|
159
|
+
- [ ] Cheap immutable snapshots + `restore()`. Incremental diffs between snapshots.
|
|
160
|
+
- [ ] Release the GIL on set/get/snapshot. Concurrency tests.
|
|
161
|
+
|
|
162
|
+
**M2 — HandoffGraph in Rust**
|
|
163
|
+
- [ ] DAG with conditional edges; a simple, safe condition evaluator (no Python `eval`).
|
|
164
|
+
- [ ] Deterministic `route()`; cycle detection; traversal in Rust.
|
|
165
|
+
|
|
166
|
+
**M3 — LangGraph adapter (flagship piece)**
|
|
167
|
+
- [ ] `SwarmStateSaver` implements the real `BaseCheckpointSaver` interface
|
|
168
|
+
(`put`, `put_writes`, `get_tuple`, `list`, and async variants). **Verify signatures against the pinned version.**
|
|
169
|
+
- [ ] Integration test: a minimal LangGraph graph persists and resumes with `SwarmStateSaver`.
|
|
170
|
+
|
|
171
|
+
**M4 — Benchmarks (the selling argument)**
|
|
172
|
+
- [ ] `benchmarks/`: `SwarmStateSaver` vs `SqliteSaver` (checkpoint latency p50/p99, throughput).
|
|
173
|
+
- [ ] Store vs pure in-memory dict and vs Redis. Produce reproducible charts.
|
|
174
|
+
- [ ] Aim to show a clear improvement (communication target: 10x+ in checkpoint latency vs SQLite).
|
|
175
|
+
|
|
176
|
+
**M5 — CrewAI adapter + persistence**
|
|
177
|
+
- [ ] CrewAI state/memory adapter that shares the same `Store` (demonstrate state portability).
|
|
178
|
+
- [ ] Optional `redis` backend under the extra.
|
|
179
|
+
|
|
180
|
+
**M6 — Docs + CI + release**
|
|
181
|
+
- [ ] MkDocs Material: guide + API reference + benchmarks page.
|
|
182
|
+
- [ ] CI: Rust tests (`cargo test`) + Python tests (`pytest`) on Linux/macOS/Windows.
|
|
183
|
+
- [ ] `release.yml`: `maturin build` of cross-platform abi3 wheels + publish to PyPI via **Trusted Publishing (OIDC)**.
|
|
184
|
+
- [ ] Publish `0.1.0`. Polished README with the benchmark highlighted at the top.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 6. Toolchain and commands
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# development environment
|
|
192
|
+
python -m venv .venv && source .venv/bin/activate
|
|
193
|
+
pip install maturin
|
|
194
|
+
maturin develop --release # compiles the Rust core and installs it
|
|
195
|
+
|
|
196
|
+
# tests
|
|
197
|
+
cargo test # Rust core
|
|
198
|
+
pytest -q # Python API + integrations
|
|
199
|
+
|
|
200
|
+
# benchmarks
|
|
201
|
+
python benchmarks/run.py # generates metrics and charts
|
|
202
|
+
|
|
203
|
+
# docs
|
|
204
|
+
pip install -e ".[docs]"
|
|
205
|
+
./scripts/build-docs.sh --serve # http://127.0.0.1:8000
|
|
206
|
+
|
|
207
|
+
# release (local sanity check)
|
|
208
|
+
maturin build --release # produces abi3 wheels
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Versions/standards:**
|
|
212
|
+
- Python `>=3.9`, `cp39-abi3` wheels.
|
|
213
|
+
- PyO3 + maturin (latest stable). Rust edition 2021+.
|
|
214
|
+
- Complete type hints + `py.typed`. `ruff` for Python-side lint/format.
|
|
215
|
+
- Pin `langgraph` and `crewai` versions in the extras and in CI; the adapters depend on their APIs.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 7. Quality rules
|
|
220
|
+
|
|
221
|
+
- **Zero install friction:** if a user needs a Rust compiler for `pip install`, it's a bug.
|
|
222
|
+
- **Reproducibility:** every example and benchmark accepts a `seed`/deterministic config.
|
|
223
|
+
- **Never break the drop-in:** `SwarmStateSaver` must be swappable for `SqliteSaver` with no other code change.
|
|
224
|
+
- **Honest benchmarks:** document hardware, versions, and whether the cache is warm. No inflated numbers.
|
|
225
|
+
- **Stable state format:** the codec must not change incompatibly across minor versions.
|
|
226
|
+
- **Security:** `HandoffGraph` conditions are evaluated in a bounded mini-evaluator in Rust, never with `eval()`.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 8. Launch strategy (context, non-blocking)
|
|
231
|
+
|
|
232
|
+
- The first public artifact should be a **short technical post with the benchmark**, not a buried README:
|
|
233
|
+
"swap your LangGraph checkpointer for this backend and cut checkpoint latency by Nx".
|
|
234
|
+
- Shipping a working end-to-end example adapter is what drives shares on HN/Twitter.
|
|
235
|
+
- Publish wheels for all platforms from `0.1.0`: friction kills early traction.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 9. Pre-release checklist
|
|
240
|
+
|
|
241
|
+
- [ ] `cargo test` and `pytest` green on all 3 platforms.
|
|
242
|
+
- [ ] abi3 wheels built for Linux (x86_64/aarch64), macOS (x86_64/arm64), Windows (amd64).
|
|
243
|
+
- [ ] `import swarmstate` works in a clean venv **without** a Rust toolchain.
|
|
244
|
+
- [ ] README examples run without error.
|
|
245
|
+
- [ ] Benchmark updated and linked from the README.
|
|
246
|
+
- [ ] Version bumped in `Cargo.toml` and `pyproject.toml` (must match).
|
|
247
|
+
- [ ] Docs deployed.
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "autocfg"
|
|
7
|
+
version = "1.5.1"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "bitmaps"
|
|
13
|
+
version = "2.1.0"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
|
|
16
|
+
dependencies = [
|
|
17
|
+
"typenum",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[[package]]
|
|
21
|
+
name = "cfg-if"
|
|
22
|
+
version = "1.0.4"
|
|
23
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
24
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "heck"
|
|
28
|
+
version = "0.5.0"
|
|
29
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
30
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
31
|
+
|
|
32
|
+
[[package]]
|
|
33
|
+
name = "im"
|
|
34
|
+
version = "15.1.0"
|
|
35
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
36
|
+
checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9"
|
|
37
|
+
dependencies = [
|
|
38
|
+
"bitmaps",
|
|
39
|
+
"rand_core",
|
|
40
|
+
"rand_xoshiro",
|
|
41
|
+
"sized-chunks",
|
|
42
|
+
"typenum",
|
|
43
|
+
"version_check",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[[package]]
|
|
47
|
+
name = "indoc"
|
|
48
|
+
version = "2.0.7"
|
|
49
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
50
|
+
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
51
|
+
dependencies = [
|
|
52
|
+
"rustversion",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[[package]]
|
|
56
|
+
name = "libc"
|
|
57
|
+
version = "0.2.186"
|
|
58
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
59
|
+
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|
60
|
+
|
|
61
|
+
[[package]]
|
|
62
|
+
name = "memoffset"
|
|
63
|
+
version = "0.9.1"
|
|
64
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
65
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
66
|
+
dependencies = [
|
|
67
|
+
"autocfg",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[[package]]
|
|
71
|
+
name = "num-traits"
|
|
72
|
+
version = "0.2.19"
|
|
73
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
74
|
+
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
75
|
+
dependencies = [
|
|
76
|
+
"autocfg",
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[[package]]
|
|
80
|
+
name = "once_cell"
|
|
81
|
+
version = "1.21.4"
|
|
82
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
83
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
84
|
+
|
|
85
|
+
[[package]]
|
|
86
|
+
name = "portable-atomic"
|
|
87
|
+
version = "1.13.1"
|
|
88
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
89
|
+
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
|
90
|
+
|
|
91
|
+
[[package]]
|
|
92
|
+
name = "proc-macro2"
|
|
93
|
+
version = "1.0.106"
|
|
94
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
95
|
+
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
96
|
+
dependencies = [
|
|
97
|
+
"unicode-ident",
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
[[package]]
|
|
101
|
+
name = "pyo3"
|
|
102
|
+
version = "0.23.5"
|
|
103
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
104
|
+
checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872"
|
|
105
|
+
dependencies = [
|
|
106
|
+
"cfg-if",
|
|
107
|
+
"indoc",
|
|
108
|
+
"libc",
|
|
109
|
+
"memoffset",
|
|
110
|
+
"once_cell",
|
|
111
|
+
"portable-atomic",
|
|
112
|
+
"pyo3-build-config",
|
|
113
|
+
"pyo3-ffi",
|
|
114
|
+
"pyo3-macros",
|
|
115
|
+
"unindent",
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
[[package]]
|
|
119
|
+
name = "pyo3-build-config"
|
|
120
|
+
version = "0.23.5"
|
|
121
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
122
|
+
checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb"
|
|
123
|
+
dependencies = [
|
|
124
|
+
"once_cell",
|
|
125
|
+
"target-lexicon",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
[[package]]
|
|
129
|
+
name = "pyo3-ffi"
|
|
130
|
+
version = "0.23.5"
|
|
131
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
132
|
+
checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d"
|
|
133
|
+
dependencies = [
|
|
134
|
+
"libc",
|
|
135
|
+
"pyo3-build-config",
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
[[package]]
|
|
139
|
+
name = "pyo3-macros"
|
|
140
|
+
version = "0.23.5"
|
|
141
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
142
|
+
checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da"
|
|
143
|
+
dependencies = [
|
|
144
|
+
"proc-macro2",
|
|
145
|
+
"pyo3-macros-backend",
|
|
146
|
+
"quote",
|
|
147
|
+
"syn",
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
[[package]]
|
|
151
|
+
name = "pyo3-macros-backend"
|
|
152
|
+
version = "0.23.5"
|
|
153
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
154
|
+
checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028"
|
|
155
|
+
dependencies = [
|
|
156
|
+
"heck",
|
|
157
|
+
"proc-macro2",
|
|
158
|
+
"pyo3-build-config",
|
|
159
|
+
"quote",
|
|
160
|
+
"syn",
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
[[package]]
|
|
164
|
+
name = "quote"
|
|
165
|
+
version = "1.0.46"
|
|
166
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
167
|
+
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
|
168
|
+
dependencies = [
|
|
169
|
+
"proc-macro2",
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
[[package]]
|
|
173
|
+
name = "rand_core"
|
|
174
|
+
version = "0.6.4"
|
|
175
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
176
|
+
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
177
|
+
|
|
178
|
+
[[package]]
|
|
179
|
+
name = "rand_xoshiro"
|
|
180
|
+
version = "0.6.0"
|
|
181
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
182
|
+
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
|
|
183
|
+
dependencies = [
|
|
184
|
+
"rand_core",
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
[[package]]
|
|
188
|
+
name = "rmp"
|
|
189
|
+
version = "0.8.15"
|
|
190
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
191
|
+
checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c"
|
|
192
|
+
dependencies = [
|
|
193
|
+
"num-traits",
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
[[package]]
|
|
197
|
+
name = "rmpv"
|
|
198
|
+
version = "1.3.1"
|
|
199
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
200
|
+
checksum = "7a4e1d4b9b938a26d2996af33229f0ca0956c652c1375067f0b45291c1df8417"
|
|
201
|
+
dependencies = [
|
|
202
|
+
"rmp",
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
[[package]]
|
|
206
|
+
name = "rustversion"
|
|
207
|
+
version = "1.0.22"
|
|
208
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
209
|
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
210
|
+
|
|
211
|
+
[[package]]
|
|
212
|
+
name = "sized-chunks"
|
|
213
|
+
version = "0.6.5"
|
|
214
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
215
|
+
checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e"
|
|
216
|
+
dependencies = [
|
|
217
|
+
"bitmaps",
|
|
218
|
+
"typenum",
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
[[package]]
|
|
222
|
+
name = "swarmstate_core"
|
|
223
|
+
version = "0.1.0"
|
|
224
|
+
dependencies = [
|
|
225
|
+
"im",
|
|
226
|
+
"pyo3",
|
|
227
|
+
"rmpv",
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
[[package]]
|
|
231
|
+
name = "syn"
|
|
232
|
+
version = "2.0.118"
|
|
233
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
234
|
+
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
|
235
|
+
dependencies = [
|
|
236
|
+
"proc-macro2",
|
|
237
|
+
"quote",
|
|
238
|
+
"unicode-ident",
|
|
239
|
+
]
|
|
240
|
+
|
|
241
|
+
[[package]]
|
|
242
|
+
name = "target-lexicon"
|
|
243
|
+
version = "0.12.16"
|
|
244
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
245
|
+
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
246
|
+
|
|
247
|
+
[[package]]
|
|
248
|
+
name = "typenum"
|
|
249
|
+
version = "1.20.1"
|
|
250
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
251
|
+
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
|
252
|
+
|
|
253
|
+
[[package]]
|
|
254
|
+
name = "unicode-ident"
|
|
255
|
+
version = "1.0.24"
|
|
256
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
257
|
+
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
258
|
+
|
|
259
|
+
[[package]]
|
|
260
|
+
name = "unindent"
|
|
261
|
+
version = "0.2.4"
|
|
262
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
263
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
264
|
+
|
|
265
|
+
[[package]]
|
|
266
|
+
name = "version_check"
|
|
267
|
+
version = "0.9.5"
|
|
268
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
269
|
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|