Skip to main content

A framework to build powerful AI agent teams.

Project description

🐮 Calfkit

Build powerful AI agents that automatically discover each other and collaborate.

License PyPI version PyPI downloads Python versions codecov Ask DeepWiki

Calfkit agents dynamically find each other at runtime and choreograph work. No hard-coded orchestrator or extra wiring. The framework for building free-flowing and powerful multi-agent teams.


Installation

pip install calfkit

Quickstart

An agent (that can discover other agents)

from calfkit import Agent, Handoff, Messaging, Tools, OpenAIResponsesModelClient

general = Agent(
    name="general",
    description="Answers simple questions and routes requests to whoever can handle it.",
    system_prompt="You are a general assistant. Defer technical questions to other agents.",
    model_client=OpenAIResponsesModelClient(model_name="gpt-5.4-mini"),
    peers=[
        Messaging(discover=True),  # discover and delegate to any agent at runtime
        Handoff(discover=True),  # discover and hand off to any agent at runtime
    ],
)

Runtime discoverability allows you to add new agents and tools to the team at any time

from calfkit import Agent, agent_tool, Tools, ToolContext, OpenAIResponsesModelClient

finance = Agent(
    name="finance",
    description="Answers the user's personal finance questions.",
    system_prompt="You are the personal finance specialist. Use tools to look up user data.",
    model_client=OpenAIResponsesModelClient(model_name="gpt-5.4-mini"),
    tools=[Tools(discover=True)],   # discover and use any tool at runtime
)

@agent_tool
def lookup_account_balance(ctx: ToolContext) -> str:
    """Look up the user's current account balance in USD."""
    return f"Account balance: ${ctx.deps.get('balance', '0.00')}"

Running your agents

Agents sit on a mesh. Set the CALFKIT_MESH_URL environment variable.

Start the general assistant independently. Assuming it's saved in general_help.py.

# using the ck CLI
ck run general_help:general

Separately, start the finance agent and the lookup_account_balance tool node. Assuming it's saved in finance_help.py.

ck run finance_help:finance finance_help:lookup_account_balance

Ask the general assistant a question. Notice it's able to dynamically discover and consult the finance agent for help without any hard-coded configuration of finance agent's existence.

import asyncio
from calfkit import Client

async def main():
    async with Client.connect() as client:
        result = await client.agent(name="general").execute(
            "Do I have enough money to afford a new car?"
        )
        print(result.output)
        # LOL nah twin

if __name__ == "__main__":
    asyncio.run(main())
python ask.py

Calfkit agents discover and communicate over an agent mesh, provided by either Calfkit Cloud (in alpha) or your own self-hosted version.

Start one locally with Docker:

git clone https://github.com/calf-ai/calfkit-broker && cd calfkit-broker && make dev-up

Or skip the self-hosting with Calfkit Cloud — a fully-managed agent mesh your agents can join from anywhere.

Why Calfkit?

  • Dynamic agent-to-agent discovery and collaboration. Agents find each other at runtime and work together — messaging each other and handing off tasks — so you build multi-agent systems without complex wiring or orchestration, and extend team capabilities at any time.
  • No bottleneck, no single point of failure. Every agent runs and scales as an independent microservice, so your agent teams are resilient and scalable from day one.
  • Act on live data in realtime. Agents are event-driven so they act on realtime data streams, sending live results wherever they're needed — build agents that work like continuous workflows, not one-off requests.

Examples

See examples/ for more examples.

Agent teams — dynamic multi-agent choreography with Messaging, Handoff, and runtime discovery:

  • Internal help desk — a front desk that discovers expert teams at runtime (discover=True) and either messages them or hands off a task; deploy a new expert and it's reachable next turn, no code change.
  • Newsroom — an editor consults a researcher and a fact-checker (messaging), then hands off to a writer — both peer verbs in one run.
  • Expense approval — a request climbs a team_leaddirectorvp handoff chain until someone is authorized to clear it.
  • Launch review — a release manager fans out to engineering, security, and legal (messaging), then synthesizes a go/no-go itself.

More examples:

  • Streaming intermediate work — a trip-planner agent whose preamble, tool calls, and tool results stream to the caller via handle.stream(), for a live view of a run's progress.
  • Agent, tool & consumer — a weather agent and its get_weather tool deployed as separate services and invoked over the broker, with a consumer node tapping the agent's output stream.
  • Multi-agent panel — three persona agents (optimist, skeptic, pragmatist) debate over one shared transcript, each automatically seeing the thread from its own point of view.
  • MCP toolbox — give an agent a live web-fetch tool from an MCP server, deployed as its own node and referenced by name — the agent's code never imports it.

Documentation

In-repo documentation lives under docs/.

New to building agent teams? Start with the tutorial Build a multi-agent support desk — build and run three agents that discover each other and collaborate by messaging and handoff.

How-to guides — goal-oriented walkthroughs:

  • How to call agents from a client — the agent(name) gateway and its send / start / execute triad, multi-turn conversations, runtime dependency injection (deps), temporary instructions, streaming a run's intermediate steps live with handle.stream(), the events() firehose, and the typed client errors.
  • How to tap a topic with a consumer node — terminal sinks that run arbitrary Python against every event on a topic; tap an agent's publish_topic to log, persist, or fan out.
  • How to guard and transform node invocations — guard an invocation with before_node (transform the input, short-circuit the body, or raise to block), and validate or reshape its output with after_node.
  • How to handle errors and faults — recover from a failed node or callee with on_node_error / on_callee_error, mint typed faults with NodeFaultError, and inspect an ErrorReport.
  • How to let agents discover and use tools at runtime — reference deployed function tool nodes by name (or every live one with discover=True) with Tools; agents discover their schemas at runtime, so an agent's deployment never imports the tool's code.
  • How to give agents MCP tools — deploy an MCPToolboxNode fronting an MCP server and pass it to agents like a tool node; tools are discovered and kept fresh across processes automatically.
  • How to let agents find and reach each other at runtime — agents discover each other by name (no hardcoded addresses) and collaborate two ways: consult a peer and keep control (Messaging), or transfer control to a specialist (Handoff).
  • Worker lifecycle & embedding — open long-lived resources at startup and close them on shutdown, publish presence events, and run with run(), the embeddable start()/stop(), or async with worker:.

Reference:

  • API reference — the public surface re-exported from the top-level calfkit package, with the key entry-point signatures.
  • CLI reference — the ck run and ck topics commands.
  • Topic provisioning — the experimental, opt-in topic-creation helper for dev/CI.

Contributing

Issues and pull requests are welcome. Please open an issue to discuss substantial changes before sending a PR.

See CONTRIBUTING.md for development setup, the quality gates (make fix / make check / make test), PR conventions, and how to write and run tests — including the real-broker integration tests.

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.

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

calfkit-0.12.2.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

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

calfkit-0.12.2-py3-none-any.whl (771.5 kB view details)

Uploaded Python 3

File details

Details for the file calfkit-0.12.2.tar.gz.

File metadata

  • Download URL: calfkit-0.12.2.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for calfkit-0.12.2.tar.gz
Algorithm Hash digest
SHA256 b84415e9924495e97cf654525c6a05fa1b75802ec62cc799e0f56f9895c7e562
MD5 1ec1717ebe8216b69b9cf14039814cfe
BLAKE2b-256 f7b9b66d6d7d54805d014d8c2ee1371a006ad21f257e3d1f3d7dac9385906fa9

See more details on using hashes here.

Provenance

The following attestation bundles were made for calfkit-0.12.2.tar.gz:

Publisher: release.yml on calf-ai/calfkit-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file calfkit-0.12.2-py3-none-any.whl.

File metadata

  • Download URL: calfkit-0.12.2-py3-none-any.whl
  • Upload date:
  • Size: 771.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for calfkit-0.12.2-py3-none-any.whl
Algorithm Hash digest
SHA256 eef0d41049f192887a0ccc73b202ef6d266ac8ceee3cbf6f5453eb9b832d112e
MD5 6c58b824a4cffbaa1183bb19b3c6d29a
BLAKE2b-256 78bb3624e96ecdf0ceda6deb7451eb3a0e5fa2e9326165633530fadf772e72d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for calfkit-0.12.2-py3-none-any.whl:

Publisher: release.yml on calf-ai/calfkit-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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