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

# Label Pages

> Assign zero or more labels to each page independently (multi-label) using an LLM. Consumes ai.parse output; emits per-page labels and a byLabel map (label -> page indices) that supports NON-contiguous selections. Feed byLabel.<label> straight into ai.vision `pageIndices` to inspect scattered pages of a type (e.g. every signature or property-photo page).

`ai.classify-pages`: Assign zero or more labels to each page independently (multi-label) using an LLM. Consumes ai.parse output; emits per-page labels and a byLabel map (label -> page indices) that supports NON-contiguous selections. Feed byLabel.\<label> straight into ai.vision `pageIndices` to inspect scattered pages of a type (e.g. every signature or property-photo page).

## Configuration

Configuration goes inside the step's `with:` block.

<ParamField path="input" type="string" required>
  The ai.parse output to label, e.g. "\{\{ steps.parse.output }}". Each page is labelled independently.
</ParamField>

<ParamField path="labels" type="array<string | object>" required>
  Labels a page can carry. A page may match ZERO, ONE, or MANY of them. Each entry is a bare name (e.g. "photo") or \{ name, description }. Names must be unique.
</ParamField>

<ParamField path="prompt" type="string">
  Extra classification guidance appended to the system prompt.
</ParamField>

<ParamField path="provider" type="string">
  Provider ID from eigenpal.config.yaml. Falls back to the tenant default.
</ParamField>

<ParamField path="model" type="string">
  Model override (advanced).
</ParamField>

<ParamField path="windowTokenBudget" type="integer">
  Per-window token ceiling. Pages are packed into windows under this budget; one LLM call per window. Defaults to env SPLIT\_WINDOW\_TOKEN\_BUDGET (20000).
</ParamField>

## Output

<ResponseField path="pages" type="array<object>" required>
  Every input page, in order, with the labels the model assigned to it.

  <Expandable title="pages properties">
    <ResponseField path="pageIndex" type="integer" required />

    <ResponseField path="labels" type="array<string>" required>
      Labels assigned to this page (possibly empty).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField path="byLabel" type="record<string, array<integer>>" required>
  Label name -> ascending page indices carrying it. Every configured label is present (empty array when no page matched), so dot access is always safe: `&#123;&#123; steps.&lt;step>.output.byLabel.&lt;label> }}` resolves to a number\[] ready for ai.vision `pageIndices`.
</ResponseField>
