v0.14.0 · Apache-2.0

Orchestrate many agents as one deterministic workflow.

CogSynth is a Python SDK for composing agents into a graph — with typed tool-calling, a shared context ledger, and an evaluation harness you run before you ship.

No API keys, no vendor lock-in. Bring your own model.

install + minimal run
$ pip install cogsynth

from cogsynth import Agent, Graph

graph = (
    Graph("research")
    .add(Agent("planner"))
    .add(Agent("writer"))
    .edge("planner", "writer")
)

result = graph.run("Summarize the v0.14 changelog.")
print(result.output)
How it works

One console for the whole graph.

Every node, tool call, and ledger write surfaces in a single orchestration view — schedule, retry, and resume from the same place.

CogSynth agent orchestration console
The model

Agents are nodes. The graph is the product.

CogSynth gives you six primitives. Compose them; the runtime handles scheduling, retries, and state.

Agent graph

Agents are nodes in a graph. Edges define control flow and data flow, so a workflow reads like a wiring diagram instead of a chat transcript.

Graph("review").add(...).edge("a", "b")

Tool-calling

Give an agent typed tools with JSON schemas. Arguments are validated at the boundary, not pasted into a prompt and hoped for.

@Tool def search(query: str) -> list[dict]

Context ledger

One append-only store for shared state across agents. No hidden prompt stuffing, no recomputing what a sibling already produced.

ledger.append(kind="fact", body={...})

Evaluation harness

Run a graph against fixtures and judges. A change that moves a score fails CI before it reaches a user.

harness.evaluate(graph, fixtures)

Orchestration DAG

Execution is a directed acyclic graph. Fan-out and join points are explicit, so concurrency is a property of the graph, not of your luck.

graph.edge("router", ["a", "b"])

Checkpoint & resume

Every node write lands in the ledger. Interrupt a run and resume it without replaying side effects.

ledger.checkpoint() → graph.resume(...)
Quickstart

Three agents, one graph, five minutes.

Build a report pipeline that plans, researches, and writes. Everything below runs with a stock Python 3.11+ interpreter and your own model endpoint.

01install

Install the package and pin a model. CogSynth is provider-agnostic: point it at whatever endpoint you already pay for.

terminal
$ pip install cogsynth
$ export COGSYNTH_MODEL="anthropic/claude-sonnet-4"
$ export ANTHROPIC_API_KEY="sk-..."
02define tools

Tools are ordinary functions. The decorator derives a JSON schema from your type hints, so the model sees a strict contract instead of a prose description.

tools.py
from cogsynth import Tool

@Tool
def web_search(query: str, n: int = 5) -> list[dict]:
    """Search the web and return result snippets."""
    return client.search(query, limit=n)  # your HTTP client here
03compose

Wire the graph. Each agent declares its role, its tools, and which node it hands off to next.

workflow.py
from cogsynth import Agent, Graph
from cogsynth.ledger import ContextLedger
from tools import web_search

ledger = ContextLedger(name="report-builder")

graph = (
    Graph("report-builder", ledger=ledger)
    .add(Agent("planner", instruction="Decompose the task into queries.", tools=[web_search]))
    .add(Agent("researcher", instruction="Run the queries and record findings.", tools=[web_search]))
    .add(Agent("writer", instruction="Turn findings into a tight brief."))
    .edge("planner", "researcher")
    .edge("researcher", "writer")
)
04run

Run it and read the result. RunResult exposes the terminal output, the full context ledger, and per-node timings.

terminal
$ python workflow.py
# planner  → 2 queries        1.2s
# researcher → 4 tool calls    2.9s
# writer   → 1 draft          1.0s

result.output  # → "The v0.14 release adds checkpoint/resume..."
API Reference

The surface is small. Learn it once.

Five public classes cover the whole SDK. Signatures are stable across 0.x; breaking changes are announced in the changelog.

Agent

node Agent(name, instruction, *, tools=None, model=None, temperature=0.0)

A single unit of work in a graph. An agent runs its instruction against the context ledger, may call its tools, and returns a message that downstream nodes read.

paramtypedescription
namestrUnique node identifier within the graph.
instructionstrThe system prompt for this node. Written once, evaluated on every run.
toolslist[Tool]Tools this agent may invoke. Defaults to none.
modelstr | NoneOverride the graph-level model for this node only.
temperaturefloatSampling temperature. Defaults to 0.0 for deterministic runs.

Graph

orchestrator Graph(name, *, ledger=None, max_parallel=8, model=None)

The orchestration DAG. Methods chain so you can build the topology in one expression, or mutate it incrementally.

methodsignaturedescription
addadd(agent: Agent) → GraphRegister a node. Returns self for chaining.
edgeedge(src: str, dst: str | list[str]) → GraphAdd a directed edge. A list of destinations creates a fan-out.
runrun(input: str, *, stream=False) → RunResultTopologically execute the graph and return the terminal result.
resumeresume(run_id: str) → RunResultContinue an interrupted run from its last checkpoint.

Tool

function Tool(fn) · @Tool

Wraps a plain function into a model-callable tool. The JSON schema is derived from annotations and the docstring; arguments are validated before the function runs, and failures are returned to the agent as structured errors rather than thrown into the transcript.

ContextLedger

state ContextLedger(name, *, storage=None)

An append-only, queryable store of everything a run has produced. Agents read from and write to it through the SDK; you never assemble the shared context by hand.

methodsignaturedescription
appendappend(kind: str, body: dict, *, node: str) → EntryWrite a typed entry (fact, finding, draft, …).
queryquery(kind: str | None = None, node: str | None = None) → list[Entry]Read entries back, filtered by type or producer.
checkpointcheckpoint() → strPersist the ledger and return a run id usable by Graph.resume.

EvaluationHarness

testing EvaluationHarness(judges: list[Judge] | None = None)

Replays a graph against fixture inputs and scores each output with deterministic judges. Use it in CI; a regression in a scored behavior fails the run before the change ships.

methodsignaturedescription
evaluateevaluate(graph: Graph, fixtures: list[Fixture]) → ReportRun every fixture through the graph and score the outputs.
Use cases

Where a graph beats a loop.

Each pattern below is a topology, not a prompt. Swap the model, keep the edges.

Research pipelines

Plan → search → synthesize. The planner emits queries, the researcher records findings in the ledger, the writer composes the brief. Deterministic handoff at every edge.

planner → researcher ⇉ writer

Support triage

Route the ticket, call a policy tool, draft the reply. A fan-out edge lets the router split to lookup and policy in parallel, then rejoin at the drafter.

router ⇉ [lookup, policy] → draft

Code review & docs

One node reviews the diff against repo rules; another regenerates the docstring contract. Both read the same ledger, so the doc change always matches the reviewed code.

review → docs

Structured extraction

Extract typed records from messy inputs with strict tool schemas. The harness scores field accuracy against fixtures, so you tune the prompt without regressing the parser.

extract → validate → emit
Engineering blog

Notes from the build.

Design decisions and gotchas from developing an orchestration runtime.

Changelog

Versioned, dated, readable.

Follows Keep a Changelog. Breaking changes land in minor releases during 0.x and are called out explicitly.

v0.14.0minor
  • Graph.resume() and ContextLedger.checkpoint() for interrupt-and-resume runs.
  • run(stream=True) emits per-node progress events.
  • Breaking: RunResult.output is now a str, not a Message.
v0.13.1patch
  • Fix: parallel fan-out could drop tool-call arguments when two branches resolved in the same tick.
v0.13.0minor
  • EvaluationHarness gains first-class Judge objects (regex, exact-match, and model-as-judge).
  • Fixtures may declare expected fields; missing fields are reported, not ignored.
v0.12.0minor
  • Context ledger checkpointing to a pluggable storage backend (default: SQLite file).
  • ContextLedger.query() accepts kind and node filters.
v0.11.0minor
  • Parallel fan-out: a single edge may target multiple nodes via edge(src, [a, b]).
v0.10.0initial
  • First public release: Agent, Graph, Tool, and ContextLedger.
Testimonials

Engineers using the graph.

“The context ledger is the part we actually trust. We stopped concatenating state into prompts and our review pass got faster.”
Fatima Al-Sayed
Fatima Al-Sayed
VP Engineering, analytics
“Swapping the model underneath a workflow is a one-line change now. Our tools keep their schemas and the eval harness catches the rest.”
George Thompson
George Thompson
Staff Engineer, fintech
Team

The people behind CogSynth.

A small team building a deterministic runtime for multi-agent Python. Six of us, one graph at a time.

Jonas Berg
Jonas Berg
Co-founder & CEO

Previously led orchestration infrastructure at a large cloud provider. Sets the roadmap and keeps the SDK honest about what “deterministic” means.

Mei Lin
Mei Lin
Co-founder & CTO

Distributed systems and LLM tooling. Designed the graph runtime and the append-only context ledger that every run writes through.

Arjun Mehta
Arjun Mehta
Staff Engineer, Graph Runtime

Owns scheduling, retries, and checkpoint/resume. Obsessed with making fan-out and joins behave the same on a laptop and in CI.

Sofia Rossi
Sofia Rossi
Staff Engineer, Developer Experience

Runs the docs, the quickstart, and the API surface. If a workflow takes more than five minutes to explain, it gets rewritten.

Tomás Rivera
Tomás Rivera
Staff Engineer, Tooling & Inference

Builds the typed tool-calling layer and the provider integrations. Makes schemas survive a model swap.

Nadia Rahman
Nadia Rahman
Head of Evaluation

Owns the evaluation harness and the judge library. A regression that moves a score never reaches a user on her watch.