Skip to content

Commit

Permalink
Sequence docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ddebowczyk committed Mar 17, 2024
1 parent f86bd5c commit e7e5a8c
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 1 deletion.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ function updateUI($person) {
$person = (new Instructor)->request(
messages: "His name is Jason, he is 28 years old.",
responseModel: Person::class,
options: ['stream' => true]
)->onPartialUpdate(
fn($partial) => updateUI($partial)
)->get();
Expand Down Expand Up @@ -248,6 +249,7 @@ var_dump($value);

In this example, we're extracting a single integer value from the text. You can also use `Scalar::string()`, `Scalar::boolean()` and `Scalar::float()` to extract other types of values.


### Extracting Enum Values

Additionally, you can use Scalar adapter to extract one of the provided options by using `Scalar::enum()`.
Expand All @@ -272,6 +274,35 @@ var_dump($value);
// enum(ActivityType:Entertainment)
```

### Extracting Sequences of Objects

Sequence is a wrapper class that can be used to represent a list of objects to
be extracted by Instructor from provided context.

It is usually more convenient not create a dedicated class with a single array
property just to handle a list of objects of a given class.

Additional, unique feature of sequences is that they can be streamed per each
completed item in a sequence, rather than on any property update.

```php
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 Instructor)->respond(
messages: [['role' => 'user', 'content' => $text]],
responseModel: Sequence::of(Person::class),
options: ['stream' => true]
);
```



Expand Down Expand Up @@ -329,6 +360,7 @@ class Event {
}
```


### Complex data extraction

Instructor can retrieve complex data structures from text. Your response model can contain nested objects, arrays, and enums.
Expand Down
66 changes: 66 additions & 0 deletions docs/data_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,70 @@ $age = (new Instructor)->respond(
// expect($age)->toBe('other');
```

### Extracting Sequences of Objects

Sequence is a wrapper class that can be used to represent a list of objects to
be extracted by Instructor from provided context.

It is usually more convenient not create a dedicated class with a single array
property just to handle a list of objects of a given class.

```php
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 Instructor)->respond(
messages: [['role' => 'user', 'content' => $text]],
responseModel: Sequence::of(Person::class),
);
```

Additional, unique feature of sequences is that they can be streamed per each
completed item in a sequence, rather than on any property update.

> **NOTE** This feature requires the `stream` option to be set to `true`.
```php
class Person
{
public string $name;
public int $age;
}

function updateUI(Person $person) {
// add newly extracted person to the UI list
}

$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 Instructor)->request(
messages: [['role' => 'user', 'content' => $text]],
responseModel: Sequence::of(Person::class),
options: ['stream' => true]
)->onEvent(
SequenceUpdated::class,
fn($event) => updateUI($event->item->last()) // get last added object
)->get();
```

Sequences offer array access (via ArrayAccess) and convenience methods
to work with the list of extracted objects.

```php
$list->count(); // returns the number of extracted items
$list->first(); // returns the first extracted item
$list->last(); // returns the last extracted item
$list->get(1); // returns the second extracted item
$list->toArray(); // returns the list of extracted items as an array
```
1 change: 1 addition & 0 deletions docs/hub/partial_updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ TEXT;
$user = (new Instructor)->request(
messages: $text,
responseModel: UserDetail::class,
options: ['stream' => true]
)->onPartialUpdate(partialUpdate(...))->get();

function partialUpdate($partial) {
Expand Down
1 change: 1 addition & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ function updateUI($person) {
$person = (new Instructor)->request(
messages: "His name is Jason, he is 28 years old.",
responseModel: Person::class,
options: ['stream' => true]
)->onPartialUpdate(
fn($partial) => updateUI($partial)
)->get();
Expand Down
1 change: 1 addition & 0 deletions examples/PartialUpdates/run.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function partialUpdate($partial) {
$user = (new Instructor)->request(
messages: $text,
responseModel: UserDetail::class,
options: ['stream' => true],
)->onPartialUpdate(partialUpdate(...))->get();

echo "All tokens received, fully completed object available in `\$user` variable.\n";
Expand Down
1 change: 1 addition & 0 deletions examples/Wiretap/run.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class UserDetail
messages: [["role" => "user", "content" => "Contact our CTO, Jason is -28 years old -- Tom"]],
responseModel: UserDetail::class,
maxRetries: 2,
options: ['stream' => true]
)
;

Expand Down
11 changes: 11 additions & 0 deletions src/Extras/Sequences/Sequence.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,18 @@ public function count(): int {
return count($this->list);
}

public function get(int $index) : mixed {
return $this->list[$index] ?? null;
}

public function first() : mixed {
return $this->list[0] ?? null;
}

public function last() : mixed {
if (empty($this->list)) {
return null;
}
$count = count($this->list);
return $this->list[$count - 1];
}
Expand Down
1 change: 0 additions & 1 deletion src/Instructor.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ public function onError(callable $listener) : self {
}

public function onPartialUpdate(callable $listener) : self {
//$this->request->options['stream'] = true;
$this->onPartialResponse = $listener;
$this->eventDispatcher->addListener(PartialResponseGenerated::class, $this->handlePartialResponse(...));
return $this;
Expand Down

0 comments on commit e7e5a8c

Please sign in to comment.