name: cave-teams
description: Build and run programmable agent teams with cave-teams — the provider-agnostic version of Claude Code Teams. Use when the user wants to wire multiple agents together, run agents in sequence or parallel, build a multi-agent pipeline/workflow, make a "team" of coding agents (Claude Code, Codex, MiniMax, or any), loop an agent until a check passes, run a contest between agents, or compose agents with the >> / | DSL. Triggers: "agent team", "multi-agent", "orchestrate agents", "wire these agents", "run agents in parallel", "cave-teams", "agent pipeline", "agent workflow".
cave-teams — program agent teams for any coding agent
cave-teams lets you wire AI agents together with a tiny algebra and run them. It is the
programmable, provider-agnostic version of Claude Code Teams: the leaves can be any agent
(Claude Code, Codex, MiniMax, a model call, a shell command, a Python function), and you control
the flow with code. CAVE = Coding Agent Virtualization Environment.
The one idea
Everything is the same shape — a Link. An agent is a Link, a team is a Link, a whole world
is a Link. A composition of Links is a Link, so teams nest inside teams forever. That is why two
operators are enough to wire anything: agent = team = world.
pip install cave-teams # pulls cave-harness (the CAVE runtime) + pydantic + universal-chain-ontology
The two operators (the DSL)
Importing cave_teams installs >> and | on every agent:
import cave_teams
from cave_teams import AgentLink
research = AgentLink("research", "Find 3 key facts about the topic.")
writer = AgentLink("writer", "Turn the facts into one punchy paragraph.")
team = research >> writer
flow = a | b | c
pipeline = research >> (security | perf | tests) >> ship
a >> b — run a, then b. b reads a's output from the context.
a | b — run a and b concurrently on the same input; their outputs merge.
Make an agent (the leaf)
A leaf reads its input from the context and writes its reply back. Pick the backend:
from cave_teams import AgentLink
a = AgentLink("name", "system prompt", backend="claude-p", model="claude-sonnet-4-6")
b = AgentLink("name", "system prompt", backend="minimax", model="MiniMax-M2.7-highspeed")
c = AgentLink("coder", runtime=my_runtime)
from cave_teams import lift
d = lift(my_existing_agent)
Run it
result = await team.execute({"goal": "the topic or task"})
print(result.status)
print(result.context["output"])
print(result.context["output:writer"])
The context is a dict threaded through the team. Each Link reads output (or goal/input at the
start) and writes output + output:<name>.
Compose beyond order/parallel
from cave_teams import gate, tournament, team, choice, dove
draft = gate(writer, critic_gate)
best = tournament(candidates, judge)
crew = team(research >> writer)
routed = choice([(is_code, coder), (is_doc, writer)], default=triage)
piped = a >> dove(D) >> b
For the gate, the evaluator must set context["approved"] (wrap a critic agent so its verdict
becomes that flag). Each pattern has its own skill — cave-sequential, cave-parallel,
cave-branch, cave-gate, cave-conditions (the message state machine), cave-dovetail,
cave-dag, cave-blackboard, cave-tournament, cave-evolve, cave-season,
cave-world, cave-sim, cave-metacog — and the cave skill drives any of them from
data (and is the proven-team / golden library). Full API: reference.md in this skill folder.
What this replaces
| You used to… | With cave-teams |
|---|
| write callbacks/queues to wire agents | a >> b / a | b |
| hand-roll a retry/approval loop | gate(worker, critic_gate) |
| be stuck with Claude Code Teams' fixed flow | program the flow yourself, for any agent |
| be locked to one vendor | swap the model/agent, keep the wiring |