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

# Sequences

When the LLM response contains a list of items rather than a single object, use the `Sequence` wrapper. It saves you from creating a dedicated class with a single array property just to hold a list.

## Basic Usage

Pass `Sequence::of(ClassName::class)` as the response model to extract a typed collection.

```php theme={null}
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Instructor\Extras\Sequence\Sequence;

class Person {
    public string $name;
    public int $age;
}

$text = <<<TEXT
    Jason is 25 years old. Jane is 18 yo. John is 30 years old
    and Anna is 2 years younger than him.
TEXT;

$list = (new StructuredOutput)->with(
    messages: $text,
    responseModel: Sequence::of(Person::class),
)->get();
// @doctest id="88eb"
```

The returned `$list` is a `Sequence` instance containing fully validated `Person` objects.

## Working with Sequences

`Sequence` implements `ArrayAccess` and `IteratorAggregate`, so you can use it like an array. It also provides convenience methods for common operations.

```php theme={null}
$list->count();       // Number of extracted items
$list->first();       // First item
$list->last();        // Last item
$list->get(1);        // Item at index 1
$list->all();         // All items as a plain array
$list->toArray();     // Alias for all()

// Iterate directly
foreach ($list as $person) {
    echo $person->name;
}

// Array access
$person = $list[0];
// @doctest id="8064"
```

## Streaming Sequences

One of the most powerful features of sequences is streaming completed items. While `partials()` yields the entire object on every property change, `sequence()` yields only when a new item in the list is fully populated.

```php theme={null}
$stream = (new StructuredOutput)
    ->with(
        messages: $text,
        responseModel: Sequence::of(Person::class),
    )
    ->stream();

foreach ($stream->sequence() as $person) {
    // Each yield is an individual completed item
    echo "Extracted: {$person->name}\n";
}

// Get the final, fully validated sequence
$people = $stream->finalValue();
// @doctest id="068f"
```

This is ideal for progressive UI updates -- you can render each person in a list as soon as the LLM finishes generating their data, without waiting for the entire response.

Keep in mind that items yielded during streaming are deserialized but not yet validated. Only the final sequence returned by `finalValue()` is fully validated.

## Named Sequences

You can provide a name and description to give the LLM more context about what the collection represents.

```php theme={null}
$list = (new StructuredOutput)->with(
    messages: $transcript,
    responseModel: Sequence::of(
        class: ActionItem::class,
        name: 'meetingActionItems',
        description: 'Action items extracted from a meeting transcript',
    ),
)->get();
// @doctest id="ab85"
```

## Combining with Output Formats

You can combine sequences with output formats. For example, to get the sequence data as a plain array of arrays:

```php theme={null}
$data = (new StructuredOutput)
    ->withResponseModel(Sequence::of(Person::class))
    ->intoArray()
    ->with(messages: $text)
    ->get();

// Result: ['list' => [['name' => 'Jason', 'age' => 25], ...]]
// @doctest id="b19c"
```
