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.4.0-cp311-abi3-win_arm64.whl (333.9 kB view details)

Uploaded CPython 3.11+Windows ARM64

band_sdk_core-2.4.0-cp311-abi3-win_amd64.whl (351.4 kB view details)

Uploaded CPython 3.11+Windows x86-64

band_sdk_core-2.4.0-cp311-abi3-musllinux_1_2_x86_64.whl (746.7 kB view details)

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

band_sdk_core-2.4.0-cp311-abi3-musllinux_1_2_aarch64.whl (709.5 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

band_sdk_core-2.4.0-cp311-abi3-manylinux_2_28_x86_64.whl (530.2 kB view details)

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

band_sdk_core-2.4.0-cp311-abi3-manylinux_2_28_aarch64.whl (531.6 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ ARM64

band_sdk_core-2.4.0-cp311-abi3-macosx_11_0_arm64.whl (479.9 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

band_sdk_core-2.4.0-cp311-abi3-macosx_10_12_x86_64.whl (478.1 kB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

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

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 9ef886e4fb16c69c5bc52604899fdd15bc9c7454368ac917d8951ee925dd1a4b
MD5 e874b546392c93ee6c313624f6d9ecf7
BLAKE2b-256 914eaaf1a48d09a83491a728986b6489c87d0358dcbad3a9e9e8c4e5237646ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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.4.0-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 0be54e857330ccbaa8f4ef0f0ab6ece9b41a99a63c497a3a75b921e9b0a60b91
MD5 1df43e61f6e8c081fb95d003504dc1b9
BLAKE2b-256 3ce1b8d81dd68434bc111a5911f12ea8d8efb9bf30e69d0d917e48c33b3309ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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.4.0-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4cd242dcce22d6d7dceea610fd8b9f62f692f2454e2e9fffabe80d41f2d14bff
MD5 24542936aaf792590a4d773d7aded664
BLAKE2b-256 3494ca8ddd5245218ffe0b3d9293e465203cab034dccd6591b46f8dfc52826e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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.4.0-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 6ef52e2ab0f0eb3bb0b25ff64019d874a465836c75e83d8ba7d1ae3db45a7294
MD5 2217504626c680b88590ecf9a70228e4
BLAKE2b-256 71c1ac462b188bc10bbe0628295cc29a1d3de53c5bef1c5b7a84e62eb227681b

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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.4.0-cp311-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 806f22e63bd1db6e5c6b65ec929315c62aeaacb51c4a8886131025184422ce6d
MD5 8374629022ae28b49183c4a272898cb3
BLAKE2b-256 687ddbe727aee55150e68a7152998fa7e0d3bbabd74fe8b6d49b133ac88e0ff5

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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.4.0-cp311-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cd300c57530dc78f7148e56bb5db0b41f469d6800f69ab8e37612e1fdfc224dd
MD5 a503da9ee496a63ae945e644c2c7beff
BLAKE2b-256 4434a7d00166d645faeabc8a0cf213083e29a014565c2fa1025d7abf1afd9dae

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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.4.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f7d519f7af8338477a937060d1e7f90f855e0fef336045f2cf14b36c334857b6
MD5 740bb79c5fc9d92449c579b7e179ff89
BLAKE2b-256 b3100800f46f29b9e0ad874793a5e2570105aba0d53db46e1969fbd3e8544fe1

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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.4.0-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for band_sdk_core-2.4.0-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8aae6ecf08bc258ce29f923a5dc7ee50bbd3b5c4ab70fcd3db9c038f6ce0d88d
MD5 b63a8816408d1cfb4c5a84ee2cd972ec
BLAKE2b-256 3cc1e83e2bc2640a588da88f3521d35556358ac9c98c593ab455069d5f70bd69

See more details on using hashes here.

Provenance

The following attestation bundles were made for band_sdk_core-2.4.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

This release

2.4.0 This release

8 files

2.3.0

8 files

2.2.0

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