Adapters¶
Claudeway is the coordination layer other frameworks don't have. The adapters below make that layer drop into the frameworks you may already be using — without forcing you to rewrite your app around a new SDK.
Two adapters ship today. Both keep the core claudeway package
dependency-free: the host framework is imported lazily, so pip install
claudeway never pulls LangGraph or Nostr in.
Buzz adapter (Nostr transport)¶
Buzz is the room agents talk in. Claudeway is how they agree.
Buzz shipped July 2026 with an explicit gap: "orchestration resides in the
agents themselves." It offloads coordination to "external harnesses" via
buzz-acp. That's the seam the Buzz adapter fills.
The adapter isn't a separate package — it's the Nostr NIP-78
transport. A signed Claudeway consensus
receipt renders as a kind: 30078 event that lands in any Nostr relay,
including Buzz rooms. Agents already monitoring a room see the consensus
event; the BIP-340 signature means anyone in the room can verify it wasn't
tampered with.
from claudeway.transports import to_nostr_event
event = to_nostr_event(
receipt,
private_key_hex=nostr_key,
d_tag="room-42", # addressable: replaces prior events with the same d-tag
)
# publish `event` to your relay of choice — relay.damus.io, your own relay,
# or a private Buzz community relay.
End-to-end demo¶
examples/buzz_consensus_demo.py
runs the full loop: three Claude agents reach consensus, the receipt is
signed, a NIP-78 event is produced and published to a relay, then read back
and verified. The demo runs offline (mock agents) or online (real Swarm).
Verify it yourself¶
The events Claudeway emits verify under the reference Nostr CLI:
See TESTLOG.md
for the four-layer evidence trail: BIP-340 KAT vectors, the test suite,
nak verify, and the end-to-end demo.
LangGraph adapter¶
LangGraph makes you wire coordination by hand. The adapter is the seam.
LangGraph is production-grade orchestration, but its coordination story is "build it yourself": you wire state reducers, fan-out/fan-in nodes, checkpoints, and synthesis logic per graph. The Claudeway adapter collapses all of that into one node that produces a signed agreement the agents actually reached.
from langgraph.graph import StateGraph
from claudeway.adapters.langgraph import make_consensus_node
swarm = ... # your Claudeway Swarm
graph = StateGraph(dict)
graph.add_node("consensus", make_consensus_node(swarm))
graph.set_entry_point("consensus")
graph.set_exit_point("consensus")
app = graph.compile()
result = await app.ainvoke({"question": "Should we ship v0.3.0 today?"})
# result carries the signed consensus receipt
Two entry points¶
The adapter ships two functions, both compile-once (per LangGraph project guidance — never compile inside a node, never return a subgraph from a node):
make_consensus_node(swarm)— returns an async node function youadd_node()into your ownStateGraph. Use this when you own the graph.build_consensus_graph(swarm)— returns a prebuiltCompiledStateGraph:{"question": str}in, signed agreement out. Use standalone, oradd_node()the compiled graph into a parent graph.
State schema¶
The node composes with chat-style graphs out of the box:
messagesaccumulates via LangGraph'sadd_messagesreducer.- Scalar fields (
question,consensus,agreement,disagreed,receipt) overwrite — each run is the latest consensus.
Install¶
Pulls langgraph>=0.2.0 and langchain-core>=0.3.0. The import is lazy;
without the extra, import claudeway never touches LangGraph.
Live demo¶
examples/langgraph_adapter_demo.py
runs the adapter end-to-end with real Claude agents. The LangGraph
integration test is opt-in (set CLAUDEWAY_TEST_LANGGRAPH=1).
Adapter design rules¶
Both adapters follow the same invariants:
- Lazy host imports. The core
claudewaypackage never imports the host framework. Install the extra only if you need the adapter. - Async→sync bridge is always a fresh worker thread. When wrapping an
async
Swarm.processcall into a sync surface, never reuse the caller's event loop — it self-deadlocks underpytest-asyncio, CrewAI's async runtime, and LangGraph's async executor. Always spawn a daemon thread with its own loop andjoin()from the caller. Seeclaudeway/adapters/crewai.py:_run_syncfor the canonical pattern. - Rebuild
AgentResponseobjects from dict forms before signing.Swarmstoresresult.to_dict(), butConsensusReceipt.from_resultreadsr.agent_nameon each response. Adapters rebuild the typed objects before signing rather than mutatingConsensusResult.to_dict().
Follow these if you write your own adapter (A2A, AutoGen, etc.).