Skip to main content
A play runs a workflow over a data model, emitting a run for each row that changes. Where a tool is triggered on demand, a play continuously watches its model and fires when matching changes occur. You define one with definePlay.

Define a play

plays/onboarding.ts
import { definePlay, defineWorkflow } from "@cargo-ai/cdk";
import { z } from "zod";
import { contacts } from "../models/contacts";
import { enrich } from "../tools/enrich";

const onboardRow = defineWorkflow(
  "onboard-contact",
  {
    input: z.object({ email: z.string() }),
    output: z.object({ welcomed: z.boolean(), message: z.string() }),
    uses: { enrich },
  },
  ({ input, uses, ai }) => {
    const enriched = uses.enrich({ email: input.email });
    const message = ai(
      `Draft a one-line welcome for ${input.email} at ${enriched.company}.`,
    );
    return { welcomed: true, message };
  },
);

export const onboarding = definePlay("onboarding", {
  model: contacts,                    // the model whose rows drive it
  workflow: onboardRow,               // per-row automation, deployed as the release
  changeKinds: ["added", "updated"],  // which row changes fire a run
  runCreationRule: "always",
  schedule: { type: "realtime" },     // fire as rows change; see below for other types
});
The per-row workflow is deployed as the play’s release. changeKinds and schedule control when runs are created. schedule accepts one of:
typeFires…
realtimeas the model’s rows change (the reactive default for row-driven plays)
cronon a cron expression — { type: "cron", cron: "0 * * * *" }
dbtafter a dbt job completes
dependencyafter another play finishes — { type: "dependency", play: upstream }
watchon a watched external schedule
realtime and watch are distinct: realtime reacts to row changes in the model, while watch follows an externally managed schedule.

Deploy and trigger

cargo-ai cdk deploy
cargo-ai orchestration play list                 # → workflowUuid, segmentUuid
cargo-ai orchestration batch create \
  --workflow-uuid <uuid> \
  --data '{"kind":"segment","segmentUuid":"<uuid>"}' \
  --wait-until-finished
Plays always use batch create, never run createrun create on a play’s workflow returns a playNotCompatible error.

Fallbacks and health

Add fallback paths so a failed step doesn’t fail the whole run (notify, try an alternative provider, write defaults, or skip and continue). Watch success rate and set batch-health alerts. See Triggering for schedules and enrolment, and Monitoring for records and metrics.

Using the UI

See Using the UI for the visual play editor — publishing, manual enrolment, re-running failed runs, and fallback configuration.