A lightweight Python framework for building multi-agent workflows with structured state transfer protocols.
Project description
HandoffKit
HandoffKit helps developers build reliable multi-agent AI workflows by letting agents transfer structured state instead of messy free-text context.
What Problem It Solves
Multi-agent systems often lose useful context at the exact moment one agent hands work to another. A prose summary may omit files, decisions, constraints, errors, and next steps. That makes workflows hard to test, replay, inspect, and improve.
HandoffKit gives you a small Python API for making those handoffs explicit:
- agents run with pluggable providers,
- tools expose metadata and JSON-schema-style parameter schemas,
- handoffs move through
HandoffState, - protocols choose how much state to preserve,
- team workflows can be tested locally with no API key.
Why HandoffKit Exists
Most agent demos pass free text between roles. Real workflows need a clearer contract. HandoffKit is intentionally lightweight: it does not try to be a full orchestration platform, but it gives developers reliable primitives for state transfer, tool description, and sequential agent collaboration.
The default EchoProvider makes examples and tests deterministic. You can later swap in providers such as Ollama or OpenAI.
Installation
From PyPI after publication:
pip install handoffkit
For local development:
pip install -e ".[dev]"
Quickstart
from handoffkit import Agent
agent = Agent(
name="Planner",
role="Create concise implementation plans."
)
print(agent.run("Create a plan for a Python CLI app with tests."))
No provider is required for local demos. If none is configured, HandoffKit uses EchoProvider.
Tool Schema Example
from handoffkit import tool
@tool
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
print(add.to_schema())
print(add.run(a=2, b=3))
Schema output:
{
"name": "add",
"description": "Add two numbers.",
"parameters": {
"type": "object",
"properties": {
"a": {"type": "integer"},
"b": {"type": "integer"},
},
"required": ["a", "b"],
},
}
Supported schema types include str, int, float, bool, list, and dict.
HandoffState Example
from handoffkit import HandoffState
state = HandoffState(
task="Prepare a Python package for release.",
from_agent="Architect",
to_agent="Coder",
summary="Package needs tests, CI, and metadata validation.",
decisions=["Keep runtime dependencies empty."],
important_files=["pyproject.toml", "README.md"],
errors=[],
next_steps=["Run pytest.", "Build wheel.", "Run twine check."],
metadata={"mode": "hybrid_state"},
)
state.validate()
print(state.to_json())
validate() raises HandoffValidationError when required fields are empty or state fields have the wrong shape.
Protocol Comparison
HandoffKit ships four protocol modes:
| Mode | Shape | Use case |
|---|---|---|
natural |
Human-readable handoff summary | Debugging and simple collaboration |
compressed |
Short compact summary | Token-sensitive handoffs |
hybrid_min |
Task, summary, next steps | Minimal structured transfer |
hybrid_state |
Full state with decisions, files, errors, metadata | Workflows that need replayable state |
from handoffkit import Agent, HandoffProtocol
architect = Agent("Architect", "Create technical plans.")
coder = Agent("Coder", "Implement from handoff state.")
protocol = HandoffProtocol(mode="hybrid_state")
state = protocol.transfer(
from_agent=architect,
to_agent=coder,
task="Prepare a package release.",
summary="Use typed package metadata, tests, CI, and twine validation.",
decisions=["Keep package runtime dependency-free."],
important_files=["pyproject.toml", "README.md"],
next_steps=["Implement changes.", "Run pytest and twine check."],
)
print(state.to_json())
Architect -> Coder -> Tester Example
Run the local example:
python examples/coding_team.py
The example shows:
- Architect receives a task.
- Architect produces decisions and next steps.
- Coder receives
HandoffState. - Coder produces simulated implementation output.
- Tester receives state from Coder.
- Tester produces a final result.
It runs without an API key using EchoProvider.
Real Task Demo
Run a reproducible multi-agent task that generates a tiny calculator CLI, tests it, and writes Markdown and JSON evidence:
python examples/real_task_calculator.py
The demo creates:
examples/output/calculator_cli/calculator.pyexamples/output/calculator_cli/test_calculator.pyexamples/output/calculator_cli/README.mdreports/real_task_calculator.mdreports/real_task_calculator.json
It uses EchoProvider by default, so it works without network access. If
OPENAI_API_KEY is configured, it tries an OpenAI-compatible provider through
OPENAI_BASE_URL and prefers gpt-5.4 before falling back to gpt-4o-mini.
Providers
Built-in providers:
EchoProvider: deterministic local responses for tests and examples.OllamaProvider: calls a local Ollama server.OpenAIProvider: calls the OpenAI API when configured.
Ollama example:
ollama pull llama3.1
ollama serve
python examples/ollama_agent.py --model llama3.1
OpenAI usage requires OPENAI_API_KEY in your environment.
OpenAI-compatible Providers
OpenAIProvider can call OpenAI-compatible chat-completions APIs by setting a custom base URL and model.
PowerShell example:
$env:OPENAI_API_KEY="..."
$env:OPENAI_BASE_URL="https://api.freemodel.dev/v1"
$env:OPENAI_MODEL="gpt-4o-mini"
python examples/freemodel_openai_compatible.py
Optional real API tests are skipped unless explicitly enabled:
$env:HANDOFFKIT_RUN_API_TESTS="1"
$env:OPENAI_API_KEY="..."
$env:OPENAI_BASE_URL="https://api.freemodel.dev/v1"
$env:OPENAI_MODEL="gpt-4o-mini"
pytest tests_api -q
Use a temporary or scoped token for provider experiments. Do not commit API keys.
Development
Install development dependencies:
pip install -e ".[dev]"
Run checks:
ruff check .
pytest -q
python -m build
python -m twine check dist/*
Useful CLI commands:
handoffkit --version
handoffkit demo
Publishing
Validate before publishing:
pytest -q
python -m build
python -m twine check dist/*
Publish only after validating the target repository and token:
python -m twine upload dist/*
Inspiration
This package is inspired by the research and reproducibility repository DaosPath/state-transfer-protocols, especially its comparison of natural, compressed, hybrid_min, and hybrid_state handoff protocols for multilingual multi-agent workflows.
HandoffKit is a developer library, not a copy of that repository.
Roadmap
- richer contract validators,
- better tool schema coverage,
- provider adapters,
- structured tool calling loops,
- handoff quality metrics,
- memory integrations,
- benchmark-inspired examples,
- multi-agent workflow templates.
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file handoffkit-0.2.0.tar.gz.
File metadata
- Download URL: handoffkit-0.2.0.tar.gz
- Upload date:
- Size: 33.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed0da6304879ddf90ff1cfe628a0fe1f7b6862c9cacc0a4e0bd567a415235a4f
|
|
| MD5 |
63e79c46e1641a3c45718ad128d05a41
|
|
| BLAKE2b-256 |
897233bdf8813289f4cc6ff3ac02b59b3fc7975e6bd5d176c2931c8ad46c8c46
|
File details
Details for the file handoffkit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: handoffkit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 25.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e59d86c00a8ad28a775ae188bb4d3274170fac540e81bcca5867857182cf3b0d
|
|
| MD5 |
f8e25575f5a8b7928bb2bd285f7022a4
|
|
| BLAKE2b-256 |
524aea8716939c6b5017b717c954c8468912b309d0a333eb32c06bb0aefce55e
|