Zero Learning Curve
Clean, typed, idiomatic APIs in Python, TypeScript, and Rust. No DSL, no YAML — just familiar patterns.
Zero Learning Curve
Clean, typed, idiomatic APIs in Python, TypeScript, and Rust. No DSL, no YAML — just familiar patterns.
Library Not Platform
pip install sayiir, pnpm add sayiir, or add a Cargo dep. No orchestrator to deploy.
Native Rust Performance
Rust core, no replay overhead. JSON by default, swap to zero-copy rkyv or any binary codec.
Built for the Edge
First-class Cloudflare Workers runtime. Checkpoint-and-exit across requests, D1 persistence, cron-driven resume — durable orchestration that fits short-lived runtimes.
Durable AI Agents
Long-running, retry-heavy, human-in-the-loop. Run RAG pipelines and agent loops that survive evictions, park on signals, and resume on cron.
Pluggable & Lightweight
Swap backends, codecs, runners. InMemory for tests, Postgres for production, D1 on the edge.
from sayiir import task, Flow, run_workflow
@taskdef fetch_user(user_id: int) -> dict: return {"id": user_id, "name": "Alice"}
@taskdef send_email(user: dict) -> str: return f"Sent welcome to {user['name']}"
workflow = Flow("welcome").then(fetch_user).then(send_email).build()result = run_workflow(workflow, 42)import { task, flow, runWorkflow } from "sayiir";
const fetchUser = task("fetch-user", (userId: number) => { return { id: userId, name: "Alice" };});
const sendEmail = task("send-email", (user: { id: number; name: string }) => { return `Sent welcome to ${user.name}`;});
const workflow = flow<number>("welcome") .then(fetchUser) .then(sendEmail) .build();
const result = await runWorkflow(workflow, 42);use sayiir_runtime::prelude::*;
#[task(timeout = "30s", retries = 3)]async fn fetch_user(id: u64) -> Result<User, BoxError> { db.get_user(id).await}
#[task]async fn send_email(user: User) -> Result<(), BoxError> { email_service.send_welcome(&user).await}
let workflow = workflow! { name: "welcome", steps: [fetch_user, send_email]}.unwrap();import { task, flow, Engine } from "@sayiir/cloudflare";
const fetchUser = task("fetch-user", async (id: number) => { const res = await fetch(`https://api.example.com/users/${id}`); return res.json() as Promise<{ id: number; name: string }>;});
const sendEmail = task("send-email", async (user: { id: number; name: string }) => `Sent welcome to ${user.name}`);
const onboarding = flow<number>("onboarding").then(fetchUser).then(sendEmail).build();
export default { async fetch(request: Request, env: { DB: D1Database }): Promise<Response> { const engine = await Engine.create(env.DB); const instanceId = `onboard-${crypto.randomUUID()}`; return Response.json(await engine.run(onboarding, instanceId, 42)); }, // Cron resume sweeps parked + evicted instances back to life async scheduled(_e: ScheduledEvent, env: { DB: D1Database }): Promise<void> { const engine = await Engine.create(env.DB); await engine.resumeAll(onboarding); },};Rust/WASM core, D1 persistence, signal/delay parking, cron-driven resume. No external orchestrator, no separate database.
Sayiir Server — Coming Soon
Same workflows, same code — plus a managed platform with a web dashboard, multi-tenancy, scheduled triggers, observability, and Kubernetes-native deployment. Learn more →