Andon SDK and CLI for authoring, deploying, and running workflows
Project description
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 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
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, "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, "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"
The connection name passed to ctx.connect() refers to Gmail credentials
configured for the current Andon organization. The same name must appear in
the step's connections=[...] allow-list.
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
FileRefrather 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],
)
The installed SDK is the source of truth for platform capabilities:
uv run andon tools # print tools, toolsets, signatures, and descriptions
uv run andon tools --json # emit the same catalog as structured JSON
Validate, deploy, and run
An organization admin creates API keys in the console's
Settings page. Keys carry a role:
admin keys can deploy and activate; operator keys can start and watch
runs. Expose the key to the CLI:
export ANDON_API_KEY="ak-..."
The CLI uses https://app.andonai.com/ by default. Set ANDON_API_URL only
when targeting a different Andon environment.
uv run andon validate
uv run pytest
uv run andon deploy --no-activate
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>
andon validate performs local manifest and static source validation.
andon deploy publishes the full local andon.toml plus andon/ snapshot,
compiles and type-checks its workflows, and activates the deployment unless
--no-activate is passed. Publishing replaces the remote workspace snapshot,
so remote files absent from the local tree are deleted.
andon run starts a deployed workflow. Local paths supplied at typed
FileRef input positions are uploaded before run creation.
Authoring reference
Use the references bundled with the installed SDK before editing a workspace:
uv run andon docs
uv run andon tools
Here uv run executes a command in the workspace environment, while
andon docs prints the complete, version-matched authoring 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 |
The Gmail connection protocol and shared email types for ctx.connect(). |
andon_dsl.errors |
Public authoring and execution error types. |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file andon_ai-0.1.0.tar.gz.
File metadata
- Download URL: andon_ai-0.1.0.tar.gz
- Upload date:
- Size: 101.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38b331f13173603260f2c496154b24df3469c5990f7cf69504ffcc45dd300c34
|
|
| MD5 |
325510c2505aaf2263667d881e44b48d
|
|
| BLAKE2b-256 |
8bedc2aa9775d62f206a3c34bb7935c4a5a2dd694f85861a4dc501c3a33075ee
|
Provenance
The following attestation bundles were made for andon_ai-0.1.0.tar.gz:
Publisher:
publish-sdk.yml on andonhq/andon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
andon_ai-0.1.0.tar.gz -
Subject digest:
38b331f13173603260f2c496154b24df3469c5990f7cf69504ffcc45dd300c34 - Sigstore transparency entry: 2326228793
- Sigstore integration time:
-
Permalink:
andonhq/andon@d6e8766372dcb0365d92bc5ea58da8c8a215627c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/andonhq
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdk.yml@d6e8766372dcb0365d92bc5ea58da8c8a215627c -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file andon_ai-0.1.0-py3-none-any.whl.
File metadata
- Download URL: andon_ai-0.1.0-py3-none-any.whl
- Upload date:
- Size: 117.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b43a95fddaa2780b217b6f8f90a4e272adc8e317bd089f8eb40a1eb07fec7e3
|
|
| MD5 |
eef6dd2b30624350bbf72cd7ed241bf9
|
|
| BLAKE2b-256 |
a337e92c28c8b03c09cd73b50ec3b7f1cadbce65ab8a73124b4184ae0865f8f3
|
Provenance
The following attestation bundles were made for andon_ai-0.1.0-py3-none-any.whl:
Publisher:
publish-sdk.yml on andonhq/andon
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
andon_ai-0.1.0-py3-none-any.whl -
Subject digest:
4b43a95fddaa2780b217b6f8f90a4e272adc8e317bd089f8eb40a1eb07fec7e3 - Sigstore transparency entry: 2326228817
- Sigstore integration time:
-
Permalink:
andonhq/andon@d6e8766372dcb0365d92bc5ea58da8c8a215627c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/andonhq
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdk.yml@d6e8766372dcb0365d92bc5ea58da8c8a215627c -
Trigger Event:
workflow_dispatch
-
Statement type: