Skip to main content

A lightweight Python framework for building multi-agent workflows with structured state transfer protocols.

Project description

HandoffKit

Structured state transfer for multi-agent Python workflows.

Build agent chains where each agent receives a clear contract: task, decisions, files, errors, next steps, and metadata. No messy context soup.

Tests PyPI Python versions License

pip install handoffkit

What It Is

HandoffKit is a lightweight Python framework for building multi-agent AI workflows where agents pass structured state instead of free-text summaries.

Most multi-agent demos do this:

Agent A -> "Here is roughly what happened..." -> Agent B

HandoffKit does this:

Architect
  task: "Build a calculator CLI"
  decisions: ["Use argparse", "Keep operations pure"]
  files: ["calculator.py", "test_calculator.py"]
  next_steps: ["Implement CLI", "Run pytest"]
        |
        v
Coder
  receives HandoffState, not a vague paragraph
        |
        v
Tester
  receives decisions, files, errors, and test evidence

That makes agent workflows easier to inspect, test, replay, and improve.

What 0.3.0 Adds

HandoffKit 0.3.0 adds a real tool execution loop:

  • ToolCall and ToolResult models,
  • ToolRegistry for registering and executing tools by name,
  • Agent.run_with_tools() for structured tool loops,
  • deterministic local tool execution with EchoProvider,
  • provider JSON tool-call mode for fake or real providers,
  • basic safety checks for shell and write operations,
  • ToolExecutionReport with JSON and Markdown export.

Why HandoffKit?

Multi-agent systems break when context handoffs are vague. One agent makes a decision, another agent never sees it. One agent finds an error, the next agent gets only a polished summary. Files, constraints, and validation evidence vanish.

HandoffKit gives you:

  • Agent: a small role-based agent abstraction.
  • HandoffState: a JSON-friendly contract between agents.
  • HandoffProtocol: protocol modes for different transfer styles.
  • Team: sequential multi-agent execution.
  • tool: typed Python tools with schema metadata.
  • EchoProvider: deterministic local provider for tests and demos.
  • OllamaProvider: local Ollama integration.
  • OpenAIProvider: OpenAI and OpenAI-compatible APIs.

Core Concept

from handoffkit import Agent, HandoffProtocol

architect = Agent("Architect", "Create implementation plans.")
coder = Agent("Coder", "Implement from structured handoff state.")

protocol = HandoffProtocol(mode="hybrid_state")

state = protocol.transfer(
    from_agent=architect,
    to_agent=coder,
    task="Create a small Python CLI calculator with tests.",
    summary="Build a dependency-free CLI with pytest coverage.",
    decisions=["Use argparse.", "Keep calculator operations pure."],
    important_files=["calculator.py", "test_calculator.py"],
    next_steps=["Implement code.", "Run pytest."],
)

state.validate()
print(state.to_json())

Protocols

Mode What it passes Best for
natural Human-readable summary Simple demos and debugging
compressed Compact summary Token-sensitive transfers
hybrid_min Task, summary, next steps Lightweight structured chains
hybrid_state Full state contract Replayable, testable workflows

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 API key required. By default, HandoffKit uses EchoProvider, so examples and tests run locally and deterministically.

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))

Output:

{
    "name": "add",
    "description": "Add two numbers.",
    "parameters": {
        "type": "object",
        "properties": {
            "a": {"type": "integer"},
            "b": {"type": "integer"},
        },
        "required": ["a", "b"],
    },
}

Tool Execution Loop

Register Python tools, let an agent create structured ToolCall objects, execute them through a ToolRegistry, and receive structured ToolResult objects.

from handoffkit import Agent
from handoffkit.tools.filesystem import list_files, read_file

agent = Agent(
    name="FileAgent",
    role="Use tools to inspect files.",
    tools=[read_file, list_files],
)

result = agent.run_with_tools("read file README.md")
print(result.final_output)
print(result.tool_results)

There are two modes:

  • Deterministic/local mode: with EchoProvider, HandoffKit handles simple tasks such as read file README.md, list files ., write file ..., or run command .... This is honest local automation, not hidden AI reasoning.
  • Provider JSON mode: if a provider returns JSON with tool_calls, HandoffKit executes those tools and feeds results into the next step until the provider returns {"final": "..."} or max_steps is reached.

Provider tool-call JSON:

{
  "tool_calls": [
    {
      "tool_name": "read_file",
      "arguments": {
        "path": "README.md"
      }
    }
  ],
  "final": null
}

Safety:

  • dangerous shell commands such as rm -rf, del /s, format, shutdown, reboot, mkfs, and diskpart are blocked;
  • when require_approval=True, write and shell tools return approval_required instead of executing.

Real Task Demo

HandoffKit includes a reproducible real task demo:

python examples/real_task_calculator.py

It runs this workflow:

Architect -> Coder -> Tester -> Reporter

Task:

Create a tiny Python CLI calculator with add, subtract, multiply and divide
operations, plus tests.

The demo creates a real generated project:

examples/output/calculator_cli/
  calculator.py
  test_calculator.py
  README.md

It also writes reproducibility reports:

reports/real_task_calculator.md
reports/real_task_calculator.json

The generated project is tested with pytest, and the report captures command, cwd, return code, stdout, stderr, files created, provider used, model used, and handoff flow.

Providers

Local deterministic provider

from handoffkit import Agent

agent = Agent("Planner", "Plan work.")
print(agent.run("Prepare a package release."))

Ollama

ollama pull llama3.1
ollama serve
python examples/ollama_agent.py --model llama3.1

OpenAI-compatible APIs

$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 temporary or scoped provider tokens. Do not commit API keys.

CLI

handoffkit --version
handoffkit demo

Examples

python examples/simple_agent.py
python examples/handoff_demo.py
python examples/coding_team.py
python examples/tool_schema_demo.py
python examples/tool_execution_demo.py
python examples/fake_provider_tool_call_demo.py
python examples/real_task_calculator.py

Development

git clone https://github.com/DaosPath/handoffkit.git
cd handoffkit
pip install -e ".[dev]"

Run checks:

ruff check .
pytest -q
python -m build
python -m twine check dist/*

Publishing

Build and validate:

python -m build
python -m twine check dist/*

Upload to TestPyPI first:

python -m twine upload --repository testpypi dist/*

Upload to PyPI only after TestPyPI install verification:

python -m twine upload dist/*

Inspiration

HandoffKit 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 multi-agent workflows.

HandoffKit is a developer library, not a copy of that repository.

Roadmap

  • richer contract validators,
  • broader 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


Download files

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

Source Distribution

handoffkit-0.3.0.tar.gz (39.9 kB view details)

Uploaded Source

Built Distribution

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

handoffkit-0.3.0-py3-none-any.whl (29.8 kB view details)

Uploaded Python 3

File details

Details for the file handoffkit-0.3.0.tar.gz.

File metadata

  • Download URL: handoffkit-0.3.0.tar.gz
  • Upload date:
  • Size: 39.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for handoffkit-0.3.0.tar.gz
Algorithm Hash digest
SHA256 f2e9c160bc0610f8e16aa83d9d9ccb546e6e1943447f1d3f4a9d71325ae2534d
MD5 a9315d031b25ec634316ed93f0726280
BLAKE2b-256 0d60fd01e349c0a8444e2bdc1376479a5607126e2afe3b99df00228cacd3c846

See more details on using hashes here.

File details

Details for the file handoffkit-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: handoffkit-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 29.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for handoffkit-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b23efd8916e811d197dae8a25513e0d1e4a2a022cbd26d8dd26384943730679b
MD5 4965290306c2d0000c80984864a538f6
BLAKE2b-256 956c9335fd7c4f784e9a07826c71e2b1c69c7672403f5204e97fc4ffce589471

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