# Background Work

## Workflows

Example AI-generated app code that runs durable multi-step jobs that can sleep
and resume. [View the complete workflows example](https://github.com/rivet-dev/agentos/tree/main/examples/apps-workflows).

Server:

```ts
import { actor, setup } from "rivetkit";
import { workflow } from "rivetkit/workflow";

const job = actor({
	state: {
		id: "",
		status: "queued" as "queued" | "running" | "complete",
	},
	onCreate(c) {
		c.state.id = c.key[0] ?? "";
	},
	actions: {
		inspect: (c) => c.state,
	},
	run: workflow(async (workflowContext) => {
		await workflowContext.step("start", async (c) => {
			c.state.status = "running";
		});
		await workflowContext.sleep("work", 1_000);
		await workflowContext.step("finish", async (c) => {
			c.state.status = "complete";
		});
	}),
});

export const registry = setup({
	use: { job },
});

registry.start();

export default function fetch() {
	return Response.json({
		app: "durable-workflow",
		message: "Use the RivetKit client to create and inspect jobs.",
	});
}
```

Client:

```ts
import type { Deployment } from "@rivet-dev/agentos-apps";
import { createClient } from "rivetkit/client";
import type { registry as appRegistry } from "../fixtures/app/src/index.js";

const response = await fetch("http://localhost:3000/deploy/durable-workflow", {
	method: "POST",
});
if (!response.ok) {
	throw new Error(`deployment failed: ${response.status} ${await response.text()}`);
}
const deployment = (await response.json()) as Deployment;

const client = createClient<typeof appRegistry>({
	namespace: deployment.namespace,
	poolName: deployment.pool,
});

try {
	const job = client.job.getOrCreate(["example-job"]);
	console.log(await job.inspect());
} finally {
	await client.dispose();
}
```

## Cron jobs

AI-generated apps can schedule recurring work from an actor. See
[Cron Jobs](/agentos/docs/cron).

These capabilities use RivetKit and its ordinary DirectActor client. agentOS
Apps does not wrap the client.
