> ## Documentation Index
> Fetch the complete documentation index at: https://polos.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflow Basics

> Create durable workflows with automatic retry

Workflows are durable functions with automatic retry and state management.

## Simple workflow

<CodeGroup>
  ```python Python theme={null}
  from polos import workflow, WorkflowContext
  from pydantic import BaseModel

  class OrderPayload(BaseModel):
      order_id: str
      items: list[str]
      total: float

  @workflow(id="process_order")
  async def process_order(ctx: WorkflowContext, payload: OrderPayload):
      # Steps are automatically retried on failure
      await ctx.step.run("validate", validate_order, payload)
      await ctx.step.run("reserve", reserve_inventory, payload.items)
      await ctx.step.run("charge", process_payment, payload.total)

      # Deterministic UUID (same on replay)
      confirmation = await ctx.step.uuid("confirmation")

      return {"status": "completed", "confirmation": confirmation}
  ```

  ```typescript TypeScript theme={null}
  import { defineWorkflow } from '@polos/sdk';

  interface OrderPayload {
    orderId: string;
    items: string[];
    total: number;
  }

  const processOrder = defineWorkflow<OrderPayload, unknown, Record<string, unknown>>(
    { id: 'process_order' },
    async (ctx, payload) => {
      // Steps are automatically retried on failure
      await ctx.step.run('validate', () => validateOrder(payload));
      await ctx.step.run('reserve', () => reserveInventory(payload.items));
      await ctx.step.run('charge', () => processPayment(payload.total));

      // Deterministic UUID (same on replay)
      const confirmation = await ctx.step.uuid('confirmation');

      return { status: 'completed', confirmation };
    },
  );
  ```
</CodeGroup>

## Custom retry settings

<CodeGroup>
  ```python Python theme={null}
  await ctx.step.run(
      "unreliable_api",
      call_external_api,
      data,
      max_retries=5,
      base_delay=2.0,
      max_delay=30.0,
  )
  ```

  ```typescript TypeScript theme={null}
  await ctx.step.run(
    'unreliable_api',
    () => callExternalApi(data),
    {
      maxRetries: 5,
      baseDelay: 2000,   // ms
      maxDelay: 30000,    // ms
    },
  );
  ```
</CodeGroup>

## Deterministic operations

<CodeGroup>
  ```python Python theme={null}
  # These return the same value on replay
  random_value = await ctx.step.random("coin_flip")
  unique_id = await ctx.step.uuid("order_id")
  timestamp = await ctx.step.now("created_at")
  ```

  ```typescript TypeScript theme={null}
  // These return the same value on replay
  const randomValue = await ctx.step.random('coin_flip');
  const uniqueId = await ctx.step.uuid('order_id');
  const timestamp = await ctx.step.now('created_at');
  ```
</CodeGroup>

## Wait for time

<CodeGroup>
  ```python Python theme={null}
  await ctx.step.wait_for("cooldown", seconds=60)
  ```

  ```typescript TypeScript theme={null}
  await ctx.step.waitFor('cooldown', { seconds: 60 });
  ```
</CodeGroup>

## Run it

<CodeGroup>
  ```bash Python theme={null}
  git clone https://github.com/polos-dev/polos.git
  cd polos/python-examples/08-workflow-basics
  cp .env.example .env  # Add your POLOS_PROJECT_ID and API key
  uv sync
  python main.py
  ```

  ```bash TypeScript theme={null}
  git clone https://github.com/polos-dev/polos.git
  cd polos/typescript-examples/08-workflow-basics
  cp .env.example .env  # Add your POLOS_PROJECT_ID and API key
  npm install
  npx tsx main.ts
  ```
</CodeGroup>

Open [http://localhost:5173](http://localhost:5173) to view your agents and workflows, run them from the UI, and see execution traces.

[Python example on GitHub](https://github.com/polos-dev/polos/tree/main/python-examples/08-workflow-basics) | [TypeScript example on GitHub](https://github.com/polos-dev/polos/tree/main/typescript-examples/08-workflow-basics)
