Skip to main content

band-sdk-core

Shared Band event-payload validation, memory-taxonomy, and inbound-delivery runtime state, compiled from Rust into a native Python extension (import band_sdk_core). Every function is synchronous, pure computation — no network, filesystem, or logging.

band-sdk-core-core (Rust)  -->  band-sdk-core (this package, PyPI)  -->  band-sdk-python

If you're using band-sdk-python, it already depends on this package — you don't need to install it yourself. Install it directly only if you're calling into it without that SDK. Full picture: repository architecture.

Install

pip install band-sdk-core

Wheels are prebuilt (abi3, Python >= 3.11) for Linux (manylinux/musllinux, x86_64/aarch64), macOS (arm64/x86_64), and Windows (amd64/arm64) — no Rust toolchain needed to install.

Quickstart

import band_sdk_core

try:
    payload = band_sdk_core.validate_event_payload("room_deleted", {"id": "room-1"})
except ValueError as e:
    for path, code, message in e.issues:
        print(f"{path}: {code} - {message}")

validate_event_payload is the platform's inbound WebSocket payload policy: normalize a well-formed payload, or reject a malformed one with every violation reported at once, never just the first.

Public surface

validate_event_payload(event_type, raw, trace_context=None)

event_type is a platform name ("message_created", "agent.control", …) or an EventType. raw is a JSON-shaped Python value. Success returns the normalized payload (event_created returns the input unchanged). Failure raises ValueError with .args == (message,) (str(e) is ordinary), .issues (a tuple of (path, code, message)), and .trace_context. There is no custom exception class.

EventType

The closed set of inbound event names.

Delivery-state runtime classes

ClaimRegistry, RetryTracker, ParticipantRoster, and SubscriptionTracker are the inbound-delivery runtime state classes — lifecycle and design decisions live as rustdoc on each type in crates/core/src/runtime/.

A participant is any mapping; add/set_all read id, name, type, handle, description from it and list() returns dicts with exactly those five keys. id is required and must be a string; the other four are each a string or None. A non-mapping value, a missing/non-string id, or another field that is not a string or None raises TypeError. set_all takes an optional trace_context and raises ValueError — leaving the roster unchanged, with .issues and .trace_context attached like validate_event_payload's error — if its snapshot names the same id twice. RetryTracker's max_tracked must be at least 1; 0 raises ValueError. ClaimRegistry's max_completed must be at least 1 too — 0 also raises ValueError.

SubscriptionTracker provides synchronous, transport-independent decisions for agent-topic joins and the two-topic room subscription transaction. It returns opaque integer tickets; callers supply the matching ticket when recording each completion. Failed rollbacks and failed or unknown leaves require explicit reconciliation before a fresh claim is allowed.

SubscriptionTracker lifecycle

from band_sdk_core import LeaveOutcome, RoomStatus, RoomSubscribeResult, SubscriptionTracker

tracker = SubscriptionTracker()
ticket = tracker.begin_room_subscribe("room-1")
if ticket is None:
    raise RuntimeError("room is not claimable")

result = tracker.record_room_participants_join_failed("room-1", ticket, False)
if result is RoomSubscribeResult.RollbackFailed:
    assert tracker.room_status("room-1") is RoomStatus.NeedsReconciliation
    assert tracker.acknowledge_room_reconciled("room-1") is True
    ticket = tracker.begin_room_subscribe("room-1")
    assert ticket is not None
    assert tracker.record_both_room_topics_joined("room-1", ticket) is RoomSubscribeResult.Subscribed
    leave_ticket = tracker.unsubscribe_room("room-1")
    assert leave_ticket is not None
    assert tracker.mark_room_leave_complete("room-1", leave_ticket, LeaveOutcome.Left) is True
else:
    match result:
        case (
            RoomSubscribeResult.Subscribed
            | RoomSubscribeResult.JoinFailed
            | RoomSubscribeResult.RolledBack
            | RoomSubscribeResult.Stale
        ):
            pass
        case _:
            raise AssertionError(f"unhandled subscription result: {result}")

Session — WebSocket reconnect state machine

Session/SessionPolicy are a sans-io session state machine plus reconnect backoff/jitter policy; classify_close/classify_upgrade classify a WebSocket close code or HTTP upgrade-rejection status. Session never sleeps, connects, or closes a socket itself — the caller drives its own transport and reports what happened through on_connected/ on_socket_close/on_upgrade_rejected/on_supersede. Decisions live as rustdoc in crates/core/src/runtime/session.rs.

Session lifecycle

from band_sdk_core import Session, SessionPolicy, SessionState

session = Session(SessionPolicy.default())
epoch = session.begin_attempt(0.0)
assert epoch is not None

connected = session.on_connected(epoch, 0.0)
assert connected.state is SessionState.Up

disconnected = session.on_socket_close(epoch, 5.0, 1006, 0.5)
assert disconnected.state is SessionState.Reconnecting
assert disconnected.retry_after_s is not None

Memory taxonomy

MemorySystem, MemoryType, MemorySegment, MemoryStoreScope, MemoryListScope, MemoryStatus are the canonical memory taxonomy — design decisions live as rustdoc in crates/core/src/memory.rs. Each is a closed set with a wire_name property and a from_wire_name static method (None for an unrecognized string), mirroring EventType.

validate_memory_type_for_system(system, memory_type, trace_context=None)

system/memory_type are each a wire-name string or the matching MemorySystem/MemoryType instance (mirroring validate_event_payload's acceptance of either an event name or an EventType), and it returns None on success. Failure raises ValueError with the same .issues/.trace_context contract as validate_event_payload — an unrecognized system and an unrecognized memory_type are independent issues, both reported when both strings are invalid.

One-shot delivery lifecycle

evaluate_delivery_event, evaluate_next_message, evaluate_drain_candidate, and evaluate_adapter_result are the stateless one-shot delivery lifecycle decisions — design decisions live as rustdoc in crates/core/src/runtime/delivery.rs. Each returns a plain dict tagged by its own "decision" string; there is no cross-invocation state, so there is no class here to construct.

evaluate_delivery_event(event_type, room_id, payload, agent_id, trace_context=None) routes one inbound event: "ignored" for an unrecognized or out-of-scope event_type; "cleanup" for room_removed/room_deleted; "skip_self" or "invocation" for message_created, depending on whether the sender is this agent (sender_type == "Agent" and sender_id == agent_id). message_created delegates to validate_event_payload for payload-shape validation, so a malformed payload raises the same ValueError, and additionally rejects an empty payload["id"] — a message with no identity cannot be claimed or acknowledged. room_removed/room_deleted need no payload shape and read id straight off the raw payload.

room_id resolves from the caller-supplied room_id first, else the payload's own chat_room_id (message events) or id (room events). An empty string counts as absent at both steps. Unresolvable raises ValueError with one issue on path room_id: code missing when the fallback field is absent or empty, wrong_type when it is present but not a string.

evaluate_next_message(triggering_message_id, next_message_id) compares the triggering message against the platform's authoritative "next open message" for a room (already fetched by the caller): "no_pending", "already_processed", or "ready_to_claim".

evaluate_drain_candidate(candidate, seen_ids, agent_id) classifies one already-fetched drain candidate — candidate is a mapping with id, sender_id, sender_type, or None when the fetch returned nothing: "no_candidate", "self_echo" (checked before the snapshot, so an echo never halts a drain), "out_of_snapshot" (stop), or "drain" (continue). The caller's own bounded or unbounded loop owns the cap; this function classifies one candidate per call.

evaluate_adapter_result(room_id, message_id, succeeded) maps an adapter outcome to "processed" or "failed".

is_self_echo(sender_id, sender_type, agent_id) is the one definition of "self echo" (sender_type == "Agent" and sender_id == agent_id) that evaluate_delivery_event and evaluate_drain_candidate use internally, exposed for a host's own call sites that classify a sender without going through either function.

Values across the language boundary

JSON objects become Python dicts. JSON null becomes None. An explicit null stays distinct from an absent key — a distinction the payload validator uses. Values that cannot be converted raise TypeError, which except Exception catches.

Build / test

just check type-checks and lints this crate. Linking the extension happens through uv / maturin (just test-py, just build-py), not cargo test.

just test-py     # uv sync, pytest, isolated wheel install
just build-py    # uv build (wheel only)

Wheels are platform-specific. Recipes use uv and honor UV_PYTHON, or PYTHON / PYTHON_BIN. Windows builds need the MSVC toolchain rustup's default host target uses.

The wheel is abi3 for Python >= 3.11. This is a mixed Python/Rust maturin package: python/band_sdk_core/ holds the typed surface — __init__.pyi, an empty py.typed, and an __init__.py that re-exports the compiled extension and defines the delivery decisions' TypedDict return shapes (pure typing constructs with no pyo3 equivalent). just test-py checks the stub matches the runtime package and that both ship in the wheel.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

band_sdk_core-2.2.0-cp311-abi3-win_arm64.whl (331.3 kB view details)

Uploaded CPython 3.11+Windows ARM64

band_sdk_core-2.2.0-cp311-abi3-win_amd64.whl (348.3 kB view details)

Uploaded CPython 3.11+Windows x86-64

band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_x86_64.whl (743.5 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_aarch64.whl (705.3 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_x86_64.whl (528.2 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ x86-64

band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_aarch64.whl (526.7 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ ARM64

band_sdk_core-2.2.0-cp311-abi3-macosx_11_0_arm64.whl (477.5 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

band_sdk_core-2.2.0-cp311-abi3-macosx_10_12_x86_64.whl (475.9 kB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-win_arm64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 7f49e75f6f890f38ba7366fb9264c8ca01c34f231db7ab8f08f4c6cc9c161295
MD5 8d31d59a639aeec7dcf0b830a76589d4
BLAKE2b-256 79d546a9dce9b20509904d69b181685fd2d1d498c657466dcd58ba0fedb78248

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-win_arm64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 704bff82b7494f1997df1aa20def09d7431075f0ad0a1dd4895a4b916409a9f2
MD5 674dec7f9e8180c28cfdecf5f9d792aa
BLAKE2b-256 0e00c267b0fc208f121ad25b41f41a18c5d77c9280049eae8a359821d37c2a33

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-win_amd64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8688f4c55c7cd778e5bb2846b6ada03e7c392d9eb8565a698fdb3df6e29faa8b
MD5 94ff642a76b7b593b8aab530df865c25
BLAKE2b-256 c78a5bceb2a5732fb51b1fa62d6dea172104ea79080c768a0aa4a4d42ddf5d5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_x86_64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1996fb61fb22d5750df214b3d180e183cdbf3f7e36cea960ca8ca2442a93b888
MD5 a465dffb82a9aaa78f0c38aa60f9fa32
BLAKE2b-256 379a6b19bf76fc55d4f5a1315ac036506aea71c499651b0fbe328004c9e40011

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-musllinux_1_2_aarch64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 431e7185d2a8659371a6fb22aa0a3383e935607d1c8944f488eebf70b0821cf7
MD5 e95220e6348e10b8601efc911e73316a
BLAKE2b-256 611a548e4f355517ee7cd4422906055765b955ec543efc95ef4993ac8a2a84ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_x86_64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9c99fad0f3edb0fc9a9d42079a2be76d573c4dd7a9579ce4b5aea1d5fabaaf9e
MD5 daa6f3de85bafb22c2bc7aa233cd0a2a
BLAKE2b-256 e5d84ec2c9a0b37027072e92dbe2912fce0d593ee88c3f96e1281882429588ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-manylinux_2_28_aarch64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 52c4c6af089e81d877e34b839694e8b01547d0f25891cf1bc9c717cf32278f59
MD5 c449d962039b67a2eba85ad686192b41
BLAKE2b-256 9a1da20cbfce00fd32ec5e1145528138fd2b0d8af12dd09c337a59c6c4b79f69

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file band_sdk_core-2.2.0-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.2.0-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 2eaa8f62a5b806d10993ea4feb73f1c48d3c959b9539bfbcdbd1ffa1f426b998
MD5 9ac5354838140e96b6af1bffc23a6439
BLAKE2b-256 f2b66432cd80745c68517ffb2efb9f8dc5f5d2ad423eaccb002d7a14dd1d28f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.2.0-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: publish.yml on band-ai/band-sdk-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2.4.0

8 files

2.3.0

8 files

This release

2.2.0 This release

8 files

2.1.0

8 files

2.0.0

8 files

1.2.1

8 files

1.2.0

8 files

1.1.0

8 files

1.0.1

8 files

1.0.0

8 files

0.8.0

8 files

0.7.2

8 files

0.7.1

8 files

0.7.0

8 files

0.6.0

8 files

0.5.0

8 files

0.4.1

8 files

0.4.0

8 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page