Skip to main content

Andon SDK and CLI (andon-ai)

Andon is a Python SDK for building durable, document-centric workflows with typed steps, LLM agents, human review, and integrations. Authors define the workflow; the Andon platform handles execution, checkpointing, files, and operations.

Installing andon-ai provides the andon command and the andon_dsl Python package. Python 3.13 or newer and uv are required.

Create a workspace

Start in an empty directory:

mkdir claims-workflow
cd claims-workflow
uvx andon-ai init
uv sync

andon init creates andon.toml, a deployable andon/ package, a sample workflow and test, and local project configuration. It preserves files that already exist, so an empty directory is the supported starting point.

The generated AGENTS.md routes coding agents to the authoring contract and tool catalog that match the installed SDK.

Build an email workflow

This workflow reads unread Gmail messages, summarizes them with an agent, and emails the digest. Save it as andon/workflows/inbox.py:

from dataclasses import dataclass

from andon_dsl.agents import Agent, StepContext
from andon_dsl.integrations import ConnectionRef, EmailFilter, EmailMessage, Gmail
from andon_dsl.workflows import map, step, workflow


@dataclass
class InboxInput:
    recipient: str
    limit: int = 10


@dataclass
class EmailSummary:
    sender: str
    subject: str
    summary: str


GMAIL = ConnectionRef(Gmail, "gmail")


summarizer = Agent(
    model_family="small",
    input_type=EmailMessage,
    output_type=EmailSummary,
    system_instructions="Summarize inbound email clearly and concisely.",
)


@step(connections=[GMAIL])
async def read_inbox(ctx: StepContext, input: InboxInput) -> list[EmailMessage]:
    gmail = await ctx.connect(GMAIL)
    return await gmail.list_messages(
        filter=EmailFilter(is_unread=True),
        limit=input.limit,
    )


@step
async def summarize(message: EmailMessage) -> EmailSummary:
    return await summarizer(
        "Summarize this email from {{sender}}.\n"
        "Subject: {{subject}}\n\n"
        "{{body_text}}",
        inputs=message,
    )


@step(connections=[GMAIL])
async def send_digest(
    ctx: StepContext,
    recipient: str,
    summaries: list[EmailSummary],
) -> str:
    gmail = await ctx.connect(GMAIL)
    body = "\n\n".join(
        f"{item.subject} — {item.sender}\n{item.summary}" for item in summaries
    )
    return await gmail.send(
        to=[recipient],
        subject="Andon inbox digest",
        body=body or "No unread messages.",
    )


@workflow()
def process_inbox(input: InboxInput) -> str:
    messages = read_inbox(input)
    summaries = map(summarize, messages)
    return send_digest(input.recipient, summaries)

Declare the workflow in andon.toml:

[[workflows]]
name = "process_inbox"
path = "andon/workflows/inbox.py"

ConnectionRef pairs the expected integration protocol with the configured organization connection name. Reuse the same ref in the decorator grant and ctx.connect(...) so the name and return type have one source of truth.

Core concepts

  • Workflows are declarative graphs of steps and control-flow primitives. Their bodies are traced during deployment and do not run as ordinary Python during workflow execution.
  • Steps are typed Python functions and the durability boundary. Successful results are checkpointed; external side effects should be safe to repeat if an interrupted attempt runs again.
  • Agents are typed LLM-powered components declared at module scope and awaited inside steps. Runtime prompts are Handlebars templates over the agent's typed inputs.
  • Tools and toolsets give agents explicitly selected capabilities. Andon provides platform tools and curated toolsets, and authors can define their own model-callable functions with @tool.
  • Connections provide typed access to organization-configured email through the Gmail protocol without exposing credentials to workflow code.
  • FileRef values represent uploaded files and generated artifacts. Keep documents and large intermediate outputs behind FileRef rather than passing their bytes or full text through step results.

Workflow bodies use primitives such as map, parallel, branch, loop, wait_for_event, wait_for_review, sleep, and run_workflow. Put ordinary Python branching, iteration, parsing, and integration glue inside steps.

Tools and toolsets

Platform tools and curated toolsets are imported from andon_dsl.tools and opted into an agent through tools=[...]. Authors can combine them with their own @tool functions:

from andon_dsl.agents import Agent
from andon_dsl.tools import tool
from andon_dsl.tools.toolsets import document_analysis


@tool
def normalize_vendor_name(name: str) -> str:
    """Return a normalized vendor name for matching."""
    return " ".join(name.lower().split())


analyst = Agent(
    tools=[*document_analysis.tools, normalize_vendor_name],
)

Inspect the installed SDK signatures and toolsets without authentication:

uv run andon tools --offline         # toolsets, signatures, and descriptions
uv run andon tools --offline --json  # the same catalog as structured JSON

Authenticate, synchronize, deploy, and run

Authenticate in the browser. You confirm the organization before Andon creates a 90-day installation credential. The credential lives in the operating system's secure store; only nonsecret profile metadata is written to disk:

andon auth login
andon auth status
andon tools         # organization settings, provider options, and prices
andon tools --json  # the same live catalog as structured JSON

andon auth login --with-api-key imports a key created in Settings from a no-echo prompt or stdin. auth list, auth use, and auth logout manage organization-bound profiles. Browser credentials are revoked on logout by default. auth status shows stored device and expiry metadata only when the selected profile supplies the authenticated credential.

ANDON_API_KEY remains the noninteractive headless and CI override. The CLI uses https://app.andonai.com/ by default; --profile selects an organization and --api-url targets another environment without sending a stored credential to a different origin. --no-input and ANDON_NON_INTERACTIVE=1 prohibit prompts and browser launches; JSON output also implies no-input unless --input is explicit.

Pull an existing workspace, or keep the unbound workspace created by init:

uv run andon pull
uv run andon status

A first pull onto a local draft merges the two trees. When the same file differs on both sides, keep the version you want, then review andon workspace reconcile --dry-run and apply its --plan command. This keeps your conflict resolutions, applies nonconflicting incoming changes, and records the remote head as your baseline.

uv run andon validate
uv run pytest
uv run andon push --message "Save review changes"
uv run andon deploy
uv run andon deployments activate <deployment-id> --dry-run
uv run andon deployments activate <deployment-id> --plan <plan-id>
uv run andon run process_inbox \
  --deployment-id <deployment-id> \
  --input-json '{"recipient":"ops@example.com","limit":10}'
uv run andon runs watch <run-id>
uv run andon runs show <run-id>
uv run andon runs show <run-id> <invocation-id>
uv run andon files download andon://runs/<run-id>/send_digest/step-output/digest.md

andon validate performs local manifest and static source validation. andon pull and andon push track the remote workspace head in ignored .andon/ state. andon deploy safely saves changed local source, compiles it, and creates an inactive deployment. Activation is explicit. Destructive operations use a content-addressed dry-run plan; applying --plan verifies the same local snapshot, identity, workspace head, and active deployment that were reviewed. Use the exact apply_command returned by the preview so every operation-shaping argument is repeated safely.

Use andon workspace history, workspace show, and workspace diff to inspect saved source. A historical pull is detached. workspace restore --revision or --deployment appends the selected tree as a new head; it does not rewrite history. pull --discard-local, push --replace-remote, reconciliation, restore, and activation require an exact reviewed plan in no-input mode.

If an inspectable domain mutation response is lost, the CLI reports ambiguous_outcome and exact inspection commands. It never automatically resubmits the mutation. Inspect the current workspace, deployment, run, or event state and create a fresh plan before another write. Input-file upload response loss reports an ordinary retryable network_error because the run does not exist yet.

andon run starts a deployed workflow. Local paths supplied at typed FileRef input positions are uploaded before run creation; andon files upload returns a reusable ref instead. andon runs show <run-id> summarizes step status and errors; add its invocation ID to inspect recorded input/output, error and artifact refs, or page through map/loop children. andon files download saves any andon:// output locally after verifying the server's digest.

Authoring reference

Use the references bundled with the installed SDK before editing a workspace:

uv run andon docs
uv run andon tools --offline

Here uv run executes a command in the workspace environment, while andon docs prints the complete, version-matched workspace authoring, synchronization, and recovery contract to the terminal. It is separate from andon run <workflow>, which starts a workflow run.

The authoring contract covers workflow restrictions, primitives, durable identity, retries, agent settings, files, reference data, testing, and other sharp edges. The generated andon/AGENTS.md points coding agents to this contract and the installed tool catalog.

Public imports

Package Purpose
andon_dsl.workflows Workflow and step decorators plus control-flow primitives.
andon_dsl.agents Agent declarations, prompt content, contexts, model settings, and usage limits.
andon_dsl.tools User-authored tools and platform tool stubs; curated bundles live in andon_dsl.tools.toolsets.
andon_dsl.resources FileRef, document result types, reference data helpers, and schema extensions.
andon_dsl.integrations Typed ConnectionRef bindings, provider protocols, and shared integration types.
andon_dsl.errors Public authoring and execution error types.

Release files for andon-ai 0.5.0

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

Source distribution (sdist)

Source distribution for andon-ai 0.5.0
File Size Uploaded
andon_ai-0.5.0.tar.gz 141.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for andon-ai 0.5.0
File Interpreter ABI Platform
andon_ai-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 302.2 kB

Release files / andon_ai-0.5.0.tar.gz

Download URL andon_ai-0.5.0.tar.gz
Size 141.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6c26b5d2a7c96c2af825fcd32297f733aa4a410425d51bb3ee5cee8f22a23f60
BLAKE2b-256 checksum
How to use checksums
6199c64ffc08c06e96219e0124eb61cc65e78380866946b118bbc68f37e7425c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Release files / andon_ai-0.5.0-py3-none-any.whl

Download URL andon_ai-0.5.0-py3-none-any.whl
Size 160.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
80e120be457363f948c1649b9ba19c0e036f485025453b6518b1e0e0d3dd6ecb
BLAKE2b-256 checksum
How to use checksums
8c1b7b5d6061161864272ea78007c69b2d0da1887b52a266d9d073d825eee071
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

This release

0.5.0 This release

2 release files

0.2.0

2 release files

0.1.0

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