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

# Build an AI agent on Livepeer

> Build an AI agent using the Eliza framework with Livepeer as the model provider for decentralised GPU inference. Complete tutorial with working code.

export const StyledStep = ({title, icon, titleSize = 'h3', iconColor = null, titleColor = null, children, className = '', style = {}, ...rest}) => {
  const styledTitle = titleColor ? <span style={{
    color: titleColor
  }}>{title}</span> : title;
  return <Step title={styledTitle} icon={icon} iconColor={iconColor || undefined} titleSize={titleSize} className={className} style={style} {...rest}>
      {children}
    </Step>;
};

export const StyledSteps = ({children, iconColor, titleColor, lineColor, iconSize = '24px', className = '', style = {}, ...rest}) => {
  const resolvedIconColor = iconColor || 'var(--accent-dark, #18794E)';
  const resolvedTitleColor = titleColor || 'var(--lp-color-accent)';
  const resolvedLineColor = lineColor || 'var(--lp-color-accent)';
  return <div className={['docs-styled-steps', className].filter(Boolean).join(' ')} style={style} {...rest}>
      <style>{`
        .docs-styled-steps .steps > div > div.absolute > div {
          background-color: ${resolvedIconColor};
        }
        .docs-styled-steps .steps > div > div.w-full > p {
          color: ${resolvedTitleColor};
        }
        .docs-styled-steps .steps > div > div.absolute.w-px {
          background-color: ${resolvedLineColor};
        }
        .docs-styled-steps .steps > div:last-child > div.absolute.w-px::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 50%;
          transform: translateX(-50%);
          width: 6px;
          height: 6px;
          background-color: ${resolvedLineColor};
          transform: translateX(-50%) rotate(45deg);
        }
      `}</style>
      <div>
        <Steps>{children}</Steps>
      </div>
    </div>;
};

export const CenteredContainer = ({children, maxWidth = "800px", padding = "0", preset = "default", width = "", minWidth = "", marginRight = "", marginBottom = "", textAlign = "", style = {}, className = "", ...rest}) => {
  const presets = {
    default: {},
    fitContent: {
      width: "fit-content",
      minWidth: "fit-content"
    },
    readable70: {
      width: "70%",
      minWidth: "fit-content"
    },
    readable80: {
      width: "80%",
      minWidth: "fit-content"
    },
    readable90: {
      width: "90%"
    },
    wide900: {
      maxWidth: "900px"
    }
  };
  const presetStyle = presets[preset] || presets.default;
  return <div className={className} style={{
    maxWidth: presetStyle.maxWidth || maxWidth,
    margin: "0 auto",
    padding: padding,
    ...presetStyle.width ? {
      width: presetStyle.width
    } : {},
    ...presetStyle.minWidth ? {
      minWidth: presetStyle.minWidth
    } : {},
    ...width ? {
      width
    } : {},
    ...minWidth ? {
      minWidth
    } : {},
    ...marginRight ? {
      marginRight
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...textAlign ? {
      textAlign
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

export const TableCell = ({children, align = "left", header = false, style = {}, className = "", ...rest}) => {
  const Component = header ? "th" : "td";
  return <Component className={className} style={{
    padding: "0.75rem 1rem",
    textAlign: align,
    border: header ? "none" : "1px solid var(--lp-color-border-default)",
    ...style
  }} {...rest}>
      {children}
    </Component>;
};

export const TableRow = ({children, header = false, hover = false, style = {}, className = "", ...rest}) => {
  const rowId = `table-row-${Math.random().toString(36).substr(2, 9)}`;
  return <>
      {hover && <style>{`
          #${rowId}:hover {
            background-color: var(--lp-color-bg-card);
          }
        `}</style>}
      <tr id={rowId} className={className} style={{
    ...header && ({
      backgroundColor: "var(--lp-color-accent-strong)",
      color: "var(--lp-color-on-accent)",
      fontWeight: "bold"
    }),
    ...style
  }} {...rest}>
        {children}
      </tr>
    </>;
};

export const StyledTable = ({children, variant = "default", style = {}, className = "", ...rest}) => {
  const wrapperVariants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)",
      overflow: "hidden"
    },
    bordered: {
      border: "2px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-page)",
      overflow: "hidden"
    },
    minimal: {
      border: "none",
      backgroundColor: "transparent",
      overflow: "visible"
    }
  };
  return <div data-docs-styled-table-shell className={className} style={{
    width: "100%",
    padding: 0,
    margin: 0,
    ...wrapperVariants[variant],
    ...style
  }} {...rest}>
      <table data-docs-styled-table style={{
    width: "100%",
    borderCollapse: "collapse",
    borderSpacing: 0,
    margin: 0,
    backgroundColor: "transparent"
  }}>
        {children}
      </table>
    </div>;
};

<CenteredContainer preset="readable90">
  <Tip>This tutorial walks through building a working Eliza AI agent that routes all inference through Livepeer's decentralised GPU network. Time to complete: approximately 30 minutes.</Tip>
</CenteredContainer>

***

<Note>
  This tutorial is adapted from the [Livepeer Agent SPE guide on Mirror.xyz](https://mirror.xyz/agent-spe.eth/oxs8VxEvKN88IeTwD-YQMucoDGqfNRz_mIlbUKkwOTg), published as part of the Agent SPE incentive programme. The original tutorial was written by the Agent SPE team and made available under an open licence.
</Note>

[Eliza](https://github.com/elizaos/eliza) is an open-source multi-agent framework (ai16z) that supports pluggable model providers. The Livepeer plugin routes Eliza's LLM inference requests to the Livepeer AI Gateway, where they run on decentralised GPU infrastructure instead of centralised cloud providers.

**What you will build:** An Eliza agent that uses Livepeer as its LLM backend, running `meta-llama/Meta-Llama-3.1-8B-Instruct` (or any Ollama-compatible model) on the network.

<CustomDivider />

## Prerequisites

* Node.js 22 or later
* pnpm (`npm install -g pnpm`)
* For development: no API key required (the community Gateway at `dream-gateway.livepeer.cloud` is unauthenticated)
* For production: an API key from a Gateway provider

<CustomDivider />

## Build your agent

<StyledSteps iconColor="var(--lp-color-accent)" titleColor="var(--accent)">
  <StyledStep title="Clone the Eliza repository" icon="download">
    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    git clone https://github.com/elizaos/eliza.git
    cd eliza
    git checkout main
    pnpm install
    pnpm build
    ```
  </StyledStep>

  <StyledStep title="Configure your environment" icon="gear">
    Create a `.env` file in the project root:

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    # .env
    # Livepeer gateway configuration
    LIVEPEER_GATEWAY_URL=https://dream-gateway.livepeer.cloud
    # API key is optional for the community gateway; required for production gateways
    # LIVEPEER_API_KEY=your-api-key-here

    # Agent identity (optional -- Eliza generates defaults if omitted)
    AGENT_NAME=LivepeerAgent
    ```

    The `LIVEPEER_GATEWAY_URL` points to the community Gateway for development. For production, replace with your Gateway provider URL and uncomment `LIVEPEER_API_KEY`.
  </StyledStep>

  <StyledStep title="Create a character file" icon="user">
    Create `characters/my-agent.character.json`:

    ```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    {
      "name": "LivepeerAgent",
      "clients": [],
      "modelProvider": "livepeer",
      "settings": {
        "model": "meta-llama/Meta-Llama-3.1-8B-Instruct",
        "secrets": {}
      },
      "system": "You are a helpful AI assistant running on decentralised GPU infrastructure via the Livepeer network. Answer questions directly and concisely.",
      "bio": [
        "AI assistant powered by decentralised compute",
        "Runs on Livepeer's global GPU network"
      ],
      "lore": [],
      "knowledge": [],
      "messageExamples": [
        [
          {
            "user": "{{user1}}",
            "content": { "text": "What can you help me with?" }
          },
          {
            "user": "LivepeerAgent",
            "content": {
              "text": "I can answer questions, help with code, and discuss topics across many domains. My inference runs on the Livepeer decentralised GPU network."
            }
          }
        ]
      ],
      "topics": ["technology", "AI", "decentralisation", "general knowledge"],
      "adjectives": ["helpful", "precise", "direct"]
    }
    ```

    The `modelProvider: "livepeer"` field tells Eliza to route all inference through the Livepeer plugin. The `model` value in settings must be supported by the Livepeer LLM pipeline: any Ollama-compatible model works, including Llama, Mistral, Gemma, and Qwen variants.
  </StyledStep>

  <StyledStep title="Run the agent" icon="play">
    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    pnpm start --characters="characters/my-agent.character.json"
    ```

    On first run, Eliza initialises the agent, loads the character file, and connects to the Livepeer Gateway. You should see:

    ```
    [INFO] Starting agent: LivepeerAgent
    [INFO] Model provider: livepeer
    [INFO] Gateway: https://dream-gateway.livepeer.cloud
    [INFO] Agent ready
    ```

    If the LLM pipeline is cold (model not yet loaded on any Orchestrator), the first request may take 30-90 seconds. Subsequent requests are fast once the model is warm.
  </StyledStep>

  <StyledStep title="Test the agent" icon="flask">
    With the agent running, open a second terminal and send a test message:

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    curl -X POST http://localhost:3000/message \
      -H "Content-Type: application/json" \
      -d '{"text": "Explain what Livepeer is in one sentence."}'
    ```

    Expected response (content will vary):

    ```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    {
      "text": "Livepeer is a decentralised protocol that provides GPU compute for AI inference and video transcoding, powered by a network of orchestrators staking LPT."
    }
    ```
  </StyledStep>
</StyledSteps>

<CustomDivider />

## Extending the agent

**Switch the model.** Change `settings.model` in your character file to any Ollama-compatible model available on the Livepeer Network. See [model support](/v2/developers/build/ai-and-agents/model-support) for supported variants and warm availability.

**Add memory and knowledge.** Eliza supports RAG (retrieval-augmented generation) via knowledge files and vector stores. Add entries to the `knowledge` array in your character file to give the agent domain-specific context.

**Integrate with Slack or Discord.** The Eliza framework includes client connectors for Slack, Discord, and Twitter. Add `"slack"` or `"discord"` to the `clients` array and configure the respective credentials in `.env`.

**Build a multi-agent swarm.** The SwarmZero framework integrates with Livepeer's inference APIs and supports multi-agent orchestration. See the [SwarmZero Livepeer example](https://docs.swarmzero.ai/examples/swarms/livepeer-youtube-video-generator-swarm) for a working YouTube video generator swarm.

<CustomDivider />

## Supported LLM models

The Livepeer LLM pipeline uses an Ollama-based runner. Any Ollama-compatible model works. Warm models respond immediately; cold models load on the first request (30 seconds to 5 minutes).

| Model                                   | Warm on network | VRAM required |
| --------------------------------------- | --------------- | ------------- |
| `meta-llama/Meta-Llama-3.1-8B-Instruct` | Yes             | 8 GB          |
| `mistralai/Mistral-7B-Instruct-v0.3`    | Check network   | 8 GB          |
| `google/gemma-2-9b-it`                  | Check network   | 10 GB         |
| `Qwen/Qwen2.5-7B-Instruct`              | Check network   | 8 GB          |

<CustomDivider />

## AI agent prompt

```text theme={"theme":{"light":"github-light","dark":"dark-plus"}}
Complete the "Build an AI agent on Livepeer" tutorial as a runnable ElizaOS agent. First verify the current ElizaOS install path from https://github.com/elizaOS/eliza and npm package metadata because the active framework may use bun or the elizaos CLI instead of the older pnpm monorepo flow. Create an agent named LivepeerAgent that routes LLM calls to LIVEPEER_GATEWAY_URL=https://dream-gateway.livepeer.cloud for development, with optional LIVEPEER_API_KEY=<gateway provider bearer token> for production. Add a character file using modelProvider "livepeer" and model "meta-llama/Meta-Llama-3.1-8B-Instruct", run the agent locally, and test it with a curl message asking for a one-sentence Livepeer explanation. Do not require a Livepeer Studio API key.
```

<CustomDivider />

The [Eliza Livepeer plugin tutorial](/v2/developers/build/tutorials/eliza-livepeer-plugin) covers the plugin architecture in more depth, including custom inference routing and multi-pipeline configuration.
