> ## 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.

# State Persistence

> Maintain typed state across workflow executions

Workflows can maintain typed state for the execution.

## Define a state schema

<CodeGroup>
  ```python Python theme={null}
  from polos import WorkflowState

  class ShoppingCartState(WorkflowState):
      items: list[dict] = []
      total: float = 0.0
  ```

  ```typescript TypeScript theme={null}
  import { z } from 'zod';

  const ShoppingCartStateSchema = z.object({
    items: z.array(z.record(z.unknown())).default([]),
    total: z.number().default(0),
  });

  type ShoppingCartState = z.infer<typeof ShoppingCartStateSchema>;
  ```
</CodeGroup>

## Create a stateful workflow

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

  @workflow(id="shopping_cart", state_schema=ShoppingCartState)
  async def shopping_cart(ctx: WorkflowContext, payload: CartPayload):
      if payload.action == "add" and payload.item:
          ctx.state.items.append(payload.item.model_dump())
          ctx.state.total += payload.item.price * payload.item.quantity

      elif payload.action == "remove" and payload.item_id:
          for i, item in enumerate(ctx.state.items):
              if item.get("id") == payload.item_id:
                  ctx.state.total -= item["price"] * item["quantity"]
                  ctx.state.items.pop(i)
                  break

      elif payload.action == "clear":
          ctx.state.items = []
          ctx.state.total = 0.0

      return {"items": ctx.state.items, "total": ctx.state.total}
  ```

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

  const shoppingCartWorkflow = defineWorkflow<CartPayload, ShoppingCartState, CartResult>(
    { id: 'shopping_cart', stateSchema: ShoppingCartStateSchema },
    async (ctx, payload) => {
      if (payload.action === 'add' && payload.item) {
        ctx.state.items.push({
          id: payload.item.id,
          name: payload.item.name,
          price: payload.item.price,
          quantity: payload.item.quantity,
        });
        ctx.state.total += payload.item.price * payload.item.quantity;
      } else if (payload.action === 'remove' && payload.itemId) {
        const idx = ctx.state.items.findIndex((item) => item['id'] === payload.itemId);
        if (idx >= 0) {
          const item = ctx.state.items[idx]!;
          ctx.state.total -= (Number(item['price']) || 0) * (Number(item['quantity']) || 1);
          ctx.state.items.splice(idx, 1);
        }
      } else if (payload.action === 'clear') {
        ctx.state.items = [];
        ctx.state.total = 0;
      }

      return { items: ctx.state.items, total: ctx.state.total };
    },
  );
  ```
</CodeGroup>

## Initialize with state

<CodeGroup>
  ```python Python theme={null}
  # Start workflow with initial state
  handle = await polos.invoke(
      "shopping_cart",
      payload={"action": "add", "item": {...}},
      initial_state={"items": [], "total": 0.0},
  )
  ```

  ```typescript TypeScript theme={null}
  // Start workflow with initial state
  const handle = await polos.invoke(
    'shopping_cart',
    { action: 'add', item: { /* ... */ } },
    { initialState: { items: [], total: 0 } },
  );
  ```
</CodeGroup>

## Run it

<CodeGroup>
  ```bash Python theme={null}
  git clone https://github.com/polos-dev/polos.git
  cd polos/python-examples/10-state-persistence
  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/10-state-persistence
  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/10-state-persistence) | [TypeScript example on GitHub](https://github.com/polos-dev/polos/tree/main/typescript-examples/10-state-persistence)
