Python SDK
team-harness can be driven programmatically from Python. The SDK uses the silent console by default, so it produces no terminal output.
Basic usage
import asyncio
from team_harness import TeamHarness, TeamHarnessResult
async def main():
harness = TeamHarness(
api_key="sk-or-...",
model="anthropic/claude-sonnet-4",
agents=["codex", "gemini"],
)
result: TeamHarnessResult = await harness.run(
"Write unit tests for src/utils.py using pytest"
)
print(result.text)
for agent in result.agents:
print(f" {agent.id} ({agent.agent_type}): {agent.status}")
asyncio.run(main())Constructor parameters
Every CLI option is available as a constructor parameter:
harness = TeamHarness(
provider="codex", # or "openai_compat" (default)
model="codex-mini-latest",
api_base="https://openrouter.ai/api/v1",
api_key="sk-or-...",
codex_auth_path="~/.codex/auth.json",
agents=["codex", "gemini"], # or "codex,gemini"
max_retries=5,
retry_base_delay_s=1.0,
retry_max_delay_s=30.0,
max_depth=3,
system_prompt="Extra instructions",
system_prompt_file="prompt.txt",
agent_models={"codex": "gpt-5.6-sol"},
agent_reasoning_efforts={"codex": "high"},
output_dir="./_outputs",
cwd="./project",
console_mode="silent", # "silent" | "auto" | "plain" | "rich"
)agent_modelsandagent_reasoning_effortsoverride the resolved worker template defaults for the named agent types. They do not change the coordinator model set bymodel=..., and a per-spawnmodelargument still wins for that one worker.output_diroverrides[coordinator].output_dirfor SDK runs. Each run still creates a child directory named by the team-harness run id.
The result
run() returns a TeamHarnessResult with:
text— the final assistant response.agents— a list ofAgentSummary(id,agent_type,status,exit_code,cwd).run_id— the unique run identifier.
A normal return does not mean every worker succeeded
run() returns a TeamHarnessResult when the coordinator loop ends cleanly. A failed worker does not by itself fail the run — the coordinator may legitimately finish after a worker failed (synthesizing an answer, routing around it, or deciding it has enough). Failed workers survive as entries in result.agents. Do not treat a normal return as task success: inspect each AgentSummary's status and exit_code and apply your own acceptance criteria.
A terminal failure — coordinator API retry exhaustion or a recorded run-log error during the loop — raises TeamHarnessError, and the run log is finalized even in that case. Errors during setup (configuration resolution, client, or auth creation) happen before the run log exists and may surface as other exception types. See Run Logs.