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

# Action Log - Web

> Action logs surface a chronological record of agent and system activity.

> [!NOTE]
>
> For development, import `ActionLog` from
> `@servicetitan/anvil2-ai-kit`. For design, find it in the
> [AI Kit Web Component Library file](https://www.figma.com/design/QEIsArLktLeJAaFvcpw3PO/AI-Kit-Web-Component-Library).

ai-kit-action-log

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log?file=src/App.tsx)

```tsx lines theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <ActionLog
      steps={[
        {
          id: "a",
          title: "Looked up the customer account",
          status: "success",
          description: "Retrieved account details and recent payment history.",
        },
        {
          id: "b",
          title: "Pulled the last 20 invoices",
          status: "success",
          description: "Found 3 overdue invoices totaling $1,240.",
        },
        {
          id: "c",
          title: "Drafting the follow-up summary",
          status: "in-progress",
          description: "Summarizing overdue balances and payment history.",
        },
      ]}
    />
  );
}

export default App;
```

## Options

The Action Log supports step statuses, optional descriptions, and per-step expandable details.

### Statuses

ai-kit-action-log-statuses

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-statuses?file=src/App.tsx)

```tsx lines theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <ActionLog
      steps={[
        {
          id: "success",
          title: "Looked up the customer account",
          status: "success",
        },
        {
          id: "in-progress",
          title: "Drafting the follow-up summary",
          status: "in-progress",
        },
        {
          id: "not-started",
          title: "Send the summary to the customer",
          status: "not-started",
        },
        {
          id: "error",
          title: "Charge the saved card",
          status: "error",
        },
      ]}
    />
  );
}

export default App;
```

Four statuses mark each step: success, in-progress, not-started, and error. Success and error use filled markers. In-progress uses a spinning loader. Not-started stays in the subtle foreground.

| Status | When to use |
| - | - |
| Success | The step completed without issues |
| In Progress | The step is actively running |
| Not Started | The step is queued but hasn't begun |
| Error | The step failed and halted the run |

### Descriptions

ai-kit-action-log-descriptions

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-descriptions?file=src/App.tsx)

```tsx lines theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <ActionLog
      steps={[
        {
          id: "a",
          title: "Pulled the last 20 invoices",
          status: "success",
          description: "Found 3 overdue invoices totaling $1,240.",
        },
        {
          id: "b",
          title: "Drafting the follow-up summary",
          status: "in-progress",
          description:
            "Summarizing overdue balances and recent payment history.",
        },
        {
          id: "c",
          title: "Couldn't reach the billing service",
          status: "error",
          description: "Timed out after 30s; the run was halted.",
        },
      ]}
    />
  );
}

export default App;
```

An optional description renders below the step title as body text, providing additional context about what the step found or did. When descriptions are present, the connector line between steps spans a taller area, making the timeline easier to scan. Apply descriptions consistently across a log — mixing steps with and without descriptions creates an uneven vertical rhythm.

### Details

ai-kit-action-log-details

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-details?file=src/App.tsx)

```tsx lines theme={null}
import { ActionLog, Text } from "@servicetitan/anvil2-ai-kit";

const detailsContent = (
  <Text
    variant="body"
    size="compact"
    text="Overdue since April · last payment May 3 · $1,240 across 3 invoices."
  />
);

const steps = [
  {
    id: "a",
    title: "Looked up the customer account",
    status: "success" as const,
    description: "Retrieved account details and recent payment history.",
  },
  {
    id: "b",
    title: "Drafting the follow-up summary",
    status: "in-progress" as const,
    description: "Summarizing overdue balances and recent payment history.",
    details: detailsContent,
  },
  {
    id: "c",
    title: "Send the summary to the customer",
    status: "not-started" as const,
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        gap: 80,
        alignItems: "flex-start",
        padding: "24px 0",
      }}
    >
      {/* Details collapsed */}
      <div style={{ minWidth: 280 }}>
        <ActionLog steps={steps} />
      </div>

      {/* Details open */}
      <div style={{ minWidth: 280 }}>
        <ActionLog steps={steps} />
      </div>
    </div>
  );
}

export default App;
```

A step with a `details` value gains an independent "Show details" disclosure. The details content renders inside a Card below the description and is collapsed by default, keeping the log compact while allowing deeper inspection on demand.

## Behavior

The Action Log uses two levels of disclosure: one for the entire step list and one per step that has details content.

### Expand and Collapse

ai-kit-action-log-expand-and-collapse

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-expand-and-collapse?file=src/App.tsx)

```tsx lines theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

const steps = [
  {
    id: "a",
    title: "Looked up the customer account",
    status: "success" as const,
    description: "Retrieved account details and recent payment history.",
  },
  {
    id: "b",
    title: "Pulled the last 20 invoices",
    status: "success" as const,
    description: "Found 3 overdue invoices totaling $1,240.",
  },
  {
    id: "c",
    title: "Drafting the follow-up summary",
    status: "in-progress" as const,
    description: "Summarizing overdue balances and payment history.",
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        gap: 80,
        alignItems: "flex-start",
        padding: "24px 0",
      }}
    >
      {/* Collapsed */}
      <div style={{ minWidth: 280 }}>
        <ActionLog defaultExpanded={false} steps={steps} />
      </div>

      {/* Expanded (default) */}
      <div style={{ minWidth: 280 }}>
        <ActionLog steps={steps} />
      </div>
    </div>
  );
}

export default App;
```

The whole log starts expanded and collapses behind a "Show steps" / "Hide steps" toggle. Collapsing the log hides all step rows but preserves the expanded or collapsed state of any individual details disclosures.

### Overflow

ai-kit-action-log-overflow

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-overflow?file=src/App.tsx)

```tsx lines theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ maxWidth: "20rem" }}>
      <ActionLog
        steps={[
          {
            id: "a",
            title:
              "Reconciled every line item on Invoice #37482915 against the signed service agreement",
            status: "success",
            description:
              "Compared parts, labor, and adjuster notes line by line, then flagged three entries that didn't match the agreed scope of work for a human to review.",
          },
        ]}
      />
    </div>
  );
}

export default App;
```

Long titles and descriptions wrap to multiple lines within the content column. The connector line extends to match the full height of each step, regardless of how much text wraps.

## Usage Guidelines

### When to Use

Use the Action Log when:

* **Agent steps** – The agent or system runs a sequence of steps, and users benefit from seeing each step in order with its status.
* **Evidence behind a response** – Users need to see how the agent arrived at its conclusion.
* **Failed runs** – A step fails and halts the run, and users need to see which step failed and what came before it.

### When not to use

Avoid using the Action Log for:

* **Source attribution** – Use a [Citation](https://anvil.servicetitan.com/docs/components/citation/web.md) to attribute a specific claim in agent text to its source.

## Keyboard Interaction

Users can navigate and operate the Action Log using standard keyboard controls.

| Key | Description |
| - | - |
| Tab | Moves focus to the next disclosure trigger |
| Enter / Space | Toggles the focused disclosure open or closed |

## Code

**Implementation**

ai-kit-action-log

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log?file=src/App.tsx)

```tsx lines expandable theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <ActionLog
      steps={[
        {
          id: "a",
          title: "Looked up the customer account",
          status: "success",
          description: "Retrieved account details and recent payment history.",
        },
        {
          id: "b",
          title: "Pulled the last 20 invoices",
          status: "success",
          description: "Found 3 overdue invoices totaling $1,240.",
        },
        {
          id: "c",
          title: "Drafting the follow-up summary",
          status: "in-progress",
          description: "Summarizing overdue balances and payment history.",
        },
      ]}
    />
  );
}

export default App;
```

## Common Examples

To use the `ActionLog`, pass configured steps through the required `steps` prop. Each step requires a stable `id` and a `title`.

```tsx theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function ExampleComponent() {
  return (
    <ActionLog
      steps={[
        { id: "lookup", title: "Looked up the account", status: "success" },
        {
          id: "summary",
          title: "Drafting the summary",
          status: "in-progress",
        },
      ]}
    />
  );
}
```

### Statuses

`status` selects the marker. `"success"` and `"error"` use filled icons. `"in-progress"` uses a spinning loader. `"not-started"` stays in the subtle foreground.

ai-kit-action-log-statuses

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-statuses?file=src/App.tsx)

```tsx lines expandable theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <ActionLog
      steps={[
        {
          id: "success",
          title: "Looked up the customer account",
          status: "success",
        },
        {
          id: "in-progress",
          title: "Drafting the follow-up summary",
          status: "in-progress",
        },
        {
          id: "not-started",
          title: "Send the summary to the customer",
          status: "not-started",
        },
        {
          id: "error",
          title: "Charge the saved card",
          status: "error",
        },
      ]}
    />
  );
}

export default App;
```

### Descriptions and details

Use `description` for supporting plain text. Use `details` for rendered content that appears inside an independently collapsible `Card`.

ai-kit-action-log-descriptions

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-descriptions?file=src/App.tsx)

```tsx lines expandable theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <ActionLog
      steps={[
        {
          id: "a",
          title: "Pulled the last 20 invoices",
          status: "success",
          description: "Found 3 overdue invoices totaling $1,240.",
        },
        {
          id: "b",
          title: "Drafting the follow-up summary",
          status: "in-progress",
          description:
            "Summarizing overdue balances and recent payment history.",
        },
        {
          id: "c",
          title: "Couldn't reach the billing service",
          status: "error",
          description: "Timed out after 30s; the run was halted.",
        },
      ]}
    />
  );
}

export default App;
```

ai-kit-action-log-details

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-details?file=src/App.tsx)

```tsx lines expandable theme={null}
import { ActionLog, Text } from "@servicetitan/anvil2-ai-kit";

const detailsContent = (
  <Text
    variant="body"
    size="compact"
    text="Overdue since April · last payment May 3 · $1,240 across 3 invoices."
  />
);

const steps = [
  {
    id: "a",
    title: "Looked up the customer account",
    status: "success" as const,
    description: "Retrieved account details and recent payment history.",
  },
  {
    id: "b",
    title: "Drafting the follow-up summary",
    status: "in-progress" as const,
    description: "Summarizing overdue balances and recent payment history.",
    details: detailsContent,
  },
  {
    id: "c",
    title: "Send the summary to the customer",
    status: "not-started" as const,
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        gap: 80,
        alignItems: "flex-start",
        padding: "24px 0",
      }}
    >
      {/* Details collapsed */}
      <div style={{ minWidth: 280 }}>
        <ActionLog steps={steps} />
      </div>

      {/* Details open */}
      <div style={{ minWidth: 280 }}>
        <ActionLog steps={steps} />
      </div>
    </div>
  );
}

export default App;
```

### Expansion

The step list starts expanded. Set `defaultExpanded={false}` to start collapsed. Each step's details remain independently controlled.

ai-kit-action-log-expand-and-collapse

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-action-log-expand-and-collapse?file=src/App.tsx)

```tsx lines expandable theme={null}
import { ActionLog } from "@servicetitan/anvil2-ai-kit";

const steps = [
  {
    id: "a",
    title: "Looked up the customer account",
    status: "success" as const,
    description: "Retrieved account details and recent payment history.",
  },
  {
    id: "b",
    title: "Pulled the last 20 invoices",
    status: "success" as const,
    description: "Found 3 overdue invoices totaling $1,240.",
  },
  {
    id: "c",
    title: "Drafting the follow-up summary",
    status: "in-progress" as const,
    description: "Summarizing overdue balances and payment history.",
  },
];

function App() {
  return (
    <div
      style={{
        display: "flex",
        gap: 80,
        alignItems: "flex-start",
        padding: "24px 0",
      }}
    >
      {/* Collapsed */}
      <div style={{ minWidth: 280 }}>
        <ActionLog defaultExpanded={false} steps={steps} />
      </div>

      {/* Expanded (default) */}
      <div style={{ minWidth: 280 }}>
        <ActionLog steps={steps} />
      </div>
    </div>
  );
}

export default App;
```

### Heading level

Set `titleLevel` to fit the surrounding document outline. The main steps toggle uses one level above it, and details toggles use one level below it. Step titles remain body text.

## Internationalization

`ActionLog` owns these localized labels:

* `ai-kit.actionLog.showSteps`
* `ai-kit.actionLog.hideSteps`
* `ai-kit.actionLog.showDetails`
* `ai-kit.actionLog.hideDetails`
* `ai-kit.actionLog.statusNotStarted`
* `ai-kit.actionLog.statusInProgress`
* `ai-kit.actionLog.statusSuccess`
* `ai-kit.actionLog.statusError`

Localize step titles and descriptions before passing them in `steps`. Mount `AiKitIntlProvider` inside `CartoTheme` to switch the built-in labels.

## React Accessibility

* Status markers include localized screen-reader-only labels and do not imply form semantics.
* The ordered list preserves step sequence.
* Show steps, Hide steps, Show details, and Hide details expose disclosure state through accessible buttons.
* Stable step `id` values preserve each details disclosure when steps stream or re-render.

**ActionLog Props**

```tsx theme={null}
<ActionLog
  steps={steps}
  titleLevel={4}
  defaultExpanded
/>
```

## `ActionLog` Props

The `ActionLog` accepts the following props and forwards remaining `<div>` attributes except `children` and `style`.

**steps** `ActionLogStep[]` *required*

Steps to render from top to bottom.

**className** `string`

Class merged onto the log container.

**defaultExpanded** `boolean` (default: true)

Whether the step list starts expanded.

**titleLevel** `3 | 4 | 5 | 6` (default: 4)

Anchor heading level for the surrounding disclosure structure.

**ActionLogStep**

```tsx theme={null}
const step: ActionLogStep = {
  id: "summary",
  title: "Drafting the summary",
  description: "Reading the last 20 invoices.",
  status: "in-progress",
  details: <Text text="Found 3 overdue invoices." />,
};
```

## `ActionLogStep`

**id** `string` *required*

Stable identity used as the React key and to preserve disclosure state.

**title** `string` *required*

Plain-text step name.

**description** `string`

Supporting text rendered beneath the title.

**details** `ReactNode`

Extra content revealed through a per-step details disclosure.

**status** `"not-started" | "in-progress" | "success" | "error"` (default: not-started)

Visual status and localized screen-reader label.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.