Skip to main content

coact

Reuse your "AI stuff" across the layers of the modern agent stack. coact ("co-act" — skills and agents acting as one reusable substrate) turns the skills you already have into agent definitions, and turns those definitions into agents that actually run.

python functions/scripts  →  .claude/skills/  →  .claude/agents/  →  running agents
        (py2mcp, aw)            (skill pkg)        COMPLETE (coact)    REALIZE (coact)

coact owns the two transitions the rest of the ecosystem doesn't:

  • COMPLETE — start from a .claude/skills/ skill and complete it into a .claude/agents/ definition: add the agent-only extras (persona, return contract, tool allowlist, model, memory) that a skill doesn't carry.
  • REALIZE — take a completed definition and produce something that runs, choosing the right backend (the host agent, the Claude Agent SDK, or MCP-exposed tools for a foreign host).

It is glue, not a new framework: it builds on skill (skill data model + registries), aw (the AgenticStep runtime), and py2mcp (Python → MCP). See misc/docs/REUSE.md.

Install

pip install coact            # core: COMPLETE + host realize + analysis (no LLM needed)
pip install coact[sdk]       # + the Claude Agent SDK realize backend (and aw)
pip install coact[mcp]       # + the py2mcp/FastMCP realize backend
pip install coact[litellm]   # + the provider-agnostic LiteLLM realize backend

Quick start

from coact import complete, emit_agent, realize

# 1. Complete a skill into an agent definition (mechanical — no LLM).
agent = complete(".claude/skills/ux-analyst")

# 2. See it: a valid .claude/agents/ markdown file.
print(emit_agent(agent, "claude-agents-md"))

# 3. Realize it the cheap way: materialize files so Claude Code runs it.
realize(agent, backend="host")

Prefer to look before you leap? Everything has a dry-run:

from coact import plan_completion

plan = plan_completion(".claude/skills/ux-analyst")
print(plan.render())   # every synthesized field + WHERE it came from + warnings

That extends to the one backend that touches disk: realize(agent, backend="host", dry_run=True) returns the agent files and skill links it would write — without creating any of them.

A complete, runnable walk through all of this — a real skill → complete → emit → realize(host) → realize(sdk) → estimate/inventory — lives in examples/ (no LLM, no API key needed):

python examples/walkthrough.py

CLI

coact plan      .claude/skills/ux-analyst                 # dry-run with provenance
coact complete  .claude/skills/ux-analyst --dest .claude/agents
coact emit      .claude/skills/ux-analyst --target sdk-agent-dict   # a non-default emit target
coact realize   .claude/skills/ux-analyst --backend host
coact realize   .claude/skills/ux-analyst --backend host --dry-run   # preview; writes nothing
coact diff      .claude/skills/ux-analyst .claude/agents/ux-analyst.md
coact estimate  .claude/agents/a.md .claude/agents/b.md   # the cost gate
coact inventory .                                         # skills + agents + MCP tools
coact back      .claude/agents/ux-analyst.md              # lossy agent → skill stub
coact scaffold  .claude/agents/a.md .claude/agents/b.md   # a starter fleet shim (you own it)

The model in one minute

A SKILL.md is procedural knowledge injected into the caller's turn; a subagent is a separate worker with its own context, persona, tools, model, and a defined return value. They overlap heavily — an agent is mostly a skill plus a thin "extras" envelope. COMPLETE synthesizes that envelope; the two extras that actually matter are:

  1. the persona (system prompt / identity), and
  2. the return contract (a schema so a manager can consume the agent's output).

coact keeps the skill on disk as the single source of truth and makes the agent reference it by name — it never copies a skill body into an agent. One AgentDefinition object serializes to both the filesystem .claude/agents/*.md and the Agent SDK form.

The coact: frontmatter (optional)

To make the lift reproducible, a skill may carry an additive coact: block (ignored by every other tool). When present it wins over policy; when absent coact infers + reports what it guessed.

---
name: ux-analyst
description: Analyze a captured UX evidence bundle for usability issues.
coact:
  tools: [Read, Grep, Glob]
  model: sonnet
  memory: project
  returns:
    schema_ref: ov.schemas:UxFindings
  mcp:
    - module: ov.analyzers
      functions: [score_contrast, find_tap_targets]
---

Realization backends

backend what "running" means cost
host (default) materialize .claude/agents/*.md + link skills; the host agent (Claude Code) executes cheapest — no fan-out
sdk a RunnableAgent backed by the Claude Agent SDK that satisfies aw.AgenticStep (execute(input, context) -> (artifact, info)), so it drops into aw workflows in-process
mcp expose a skill's declared Python tools as a FastMCP server (via py2mcp) for any MCP client tool server
litellm a RunnableLLMAgent (also aw.AgenticStep) backed by LiteLLM — realize the same definition against any provider (OpenAI, Gemini, Mistral, Ollama, …); proof the definition isn't Anthropic-specific in-process
agent_step = realize(agent, backend="sdk")          # aw-compatible runnable
artifact, info = agent_step.execute(task, context={})

server = realize(".claude/skills/ux-analyst", backend="mcp")   # FastMCP handle

# same definition, a different provider — map model selectors however you like
llm_step = realize(agent, backend="litellm", model_map={"sonnet": "openai/gpt-4o"})
artifact, info = llm_step.execute(task)             # info["backend"] == "litellm"

Two boundaries to know

  • Topology is out of scope. A subagent definition can't express graphs, conditional edges, or cycles, and subagents can't spawn subagents. coact emits definitions + tool/MCP wiring and stops. Multi-agent orchestration is left to the host's manager or a thin shim you own (against the Agent SDK or aw's workflow chaining) — coact is not LangGraph.

  • A running fleet is an optimization, not a default. Multi-agent fan-out costs roughly an order of magnitude more tokens, and the premium is worst on interdependent tasks. So backend="host" (one agent runs the skills) is the default, and coact estimate shows the tradeoff before you spawn a fleet:

    from coact import estimate
    print(estimate([agent_a, agent_b]).render())
    

    If you do decide to fan out, scaffold_fleet emits a starter Python shim wiring the realized agents under an aw coordinator — a sequential hand-off you then reshape. It's the one topology-adjacent thing coact writes, and only a starter: coact emits it once and never runs it (the topology stays yours).

    from coact import scaffold_fleet
    scaffold_fleet([agent_a, agent_b], dest="fleet.py")   # a runnable starter you own
    

Design notes

  • No LLM on any mechanical path; persona drafting is optional and injected (complete(skill, llm=...)), never a hard provider dependency.
  • Open-closed registries for emit targets (claude-agents-md, sdk-agent-dict, plus crewai / openai-tools auto-registered when aw is installed) and realization backends — register your own without touching core.
  • Decisions are recorded in misc/docs/DECISIONS.md; the build brief is misc/docs/COACT_SPEC.md.

Metadata

Release files for coact 0.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for coact 0.0.4
File Size Uploaded
coact-0.0.4.tar.gz 122.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for coact 0.0.4
File Interpreter ABI Platform
coact-0.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 183.2 kB

Release files / coact-0.0.4.tar.gz

Download URL coact-0.0.4.tar.gz
Size 122.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4a4f8c9c362218a38823a29e171d5157aa0efbd4fa7f437c1531e16f136d1b69
BLAKE2b-256 checksum
How to use checksums
21b4ed8cb00969919d4d515a02b791729482cffc699d08e939b3c0f89eab5614
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / coact-0.0.4-py3-none-any.whl

Download URL coact-0.0.4-py3-none-any.whl
Size 60.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5cef96017a651efb62c76677c429917272f69e00abe6c9decaaa797cc6257273
BLAKE2b-256 checksum
How to use checksums
1f55c059e5357adcda2ca11377ca18cfee40b21f63405cbe3775b39e79ecbcb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.0.4 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page