Skip to main content

An air-traffic-control protocol for coordinating irreversible actions across multi-agent LLM systems, with a LangGraph adapter.

Project description

Tower

CI PyPI License: MIT Python 3.12+

An air-traffic-control-inspired coordination layer for multi-agent LLM systems that perform irreversible actions (charging a card, sending an email, writing to one customer's record). Instead of a generic lock, agents file a flight plan declaring intent before acting; Tower clears it immediately or holds it if another agent is already mid-action on the same resource. Handoffs between agents are verified with a mandatory readback step, so silently-dropped context is caught before it causes a wrong action.

For the design rationale, the data behind the problem, how this differs from related research, and benchmark results, see docs/DESIGN.md.

Features

  • Flight plans -- declare intent on a resource before acting; get cleared or held, never a silent race.
  • Handoff + readback verification -- the receiving agent restates a handoff's key facts; Tower checks it against the source before anything proceeds.
  • Emergency priority -- a plan can preempt the normal queue and flag the audit log for immediate human attention.
  • Two backends, one interface -- an embedded (in-process, zero infrastructure) backend and a distributed (FastAPI + Postgres) backend for agents spread across processes or machines.
  • LangGraph adapter -- wrap a node with @tower_guarded and it files, awaits, and reports its own lifecycle automatically.
  • Black box -- every filing, clearance, hold, handoff, and readback verdict is recorded, independent of any single agent run.

Requirements

  • Python 3.12+
  • Docker, only if you want the distributed (Postgres-backed) backend

Install

pip install tower-protocol                    # core protocol + embedded backend
pip install tower-protocol[langgraph]         # + the LangGraph adapter
pip install tower-protocol[distributed]       # + the FastAPI/Postgres backend
pip install tower-protocol[all]               # everything

From source, using uv:

git clone https://github.com/YamenHassan17/tower-protocol
cd tower-protocol
uv sync --all-extras

Quickstart -- embedded backend (no infrastructure needed)

import asyncio
from tower import EmbeddedTowerBackend, FlightPlan

async def main():
    tower = EmbeddedTowerBackend()
    plan = await tower.file_plan(
        FlightPlan(agent_id="agent-a", resource_key="stripe:charge:cust_1", action="charge_card")
    )
    print(plan.status)  # "cleared" -- nothing else is using this resource

asyncio.run(main())

Quickstart -- LangGraph

from tower.langgraph import tower_guarded

@tower_guarded(tower, agent_id="billing-agent", action="charge_card", resource_key="stripe:charge:cust_1")
async def charge_customer(state: dict) -> dict:
    ...  # your node's real logic -- unchanged, Tower wraps around it

See examples/research_scenario.py for a full runnable graph: two agents contend for a shared resource, and a deliberately incomplete handoff gets caught by readback verification.

uv run python examples/research_scenario.py

Running the distributed backend

docker compose up -d postgres
uv run uvicorn "tower.distributed.app:create_app" --factory --reload

Set TOWER_DATABASE_URL if you're not using the default docker-compose.yml Postgres (postgresql+asyncpg://tower:tower@localhost:5433/tower).

Development

docker compose up -d postgres   # required for the distributed backend tests
uv sync --all-extras
uv run ruff check .             # lint
uv run mypy                     # type check
uv run pytest -q                # full test suite
Test file What it covers
tests/test_embedded_backend.py The core protocol in-process: uncontested clearance, hold-then-release, cross-resource independence, emergency bypass, readback match/mismatch.
tests/test_distributed_backend.py The same properties over real HTTP against a real Postgres container, plus a genuine 8-way concurrent race to prove row-locking (not app logic) serializes conflicting filings.
tests/test_research_scenario.py The full LangGraph example end-to-end: exactly one of two concurrent search agents holds, and the deliberately incomplete handoff is caught.

Regenerate the benchmark charts in docs/assets/ with:

uv run python benchmarks/run_benchmarks.py

Project layout

src/tower/
  core/         backend-agnostic protocol: FlightPlan, HandoffPacket, conflict
                detection, readback verification, the AuditLog interface
  backends/     embedded (in-process, asyncio.Lock) backend
  distributed/  FastAPI service + Postgres-backed store          [extra: distributed]
  langgraph/    tower_guarded() node decorator, send_handoff()/verify_handoff() [extra: langgraph]
examples/       a full runnable LangGraph scenario
benchmarks/     scripts that measure the real system and produce docs/assets/*.png
tests/          the test suite described above
docs/           design rationale, related work, results

Contributing

Issues and PRs welcome. Please run ruff check ., mypy, and pytest -q before submitting.

License

MIT © Yamen AlBarghouthi

Project details


Download files

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

Source Distribution

tower_protocol-0.1.0.tar.gz (15.6 kB view details)

Uploaded Source

Built Distribution

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

tower_protocol-0.1.0-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file tower_protocol-0.1.0.tar.gz.

File metadata

  • Download URL: tower_protocol-0.1.0.tar.gz
  • Upload date:
  • Size: 15.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tower_protocol-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dd924e41d343d52b369554eeff43976deb84aa98232a86e4b98a220421193d20
MD5 2704321ecc0ac5e326240eb131ca92df
BLAKE2b-256 97fcd11542960d3fa1aaf48416d3f5d4394bd70529405a65a54ca6213624fda8

See more details on using hashes here.

File details

Details for the file tower_protocol-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: tower_protocol-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tower_protocol-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 182c5788d8f474417363330f65ddf97968dd0a59433cc7636383044129e6605e
MD5 f7b891ddbefb5911013ae8d1722c1df1
BLAKE2b-256 17d4889afa7345b56dee2dbb62cf70bfec3697bfda4ed2e7ffa868cfa33218b6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page