> ## 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.

# Tell harness observable run

## Overview

`runStream()` gives a PHP caller completed agent-loop checkpoints, while
`onEvent()` receives lifecycle observations in source order. This is the Tell
surface for worker progress, server-sent events, telemetry, and tool/inference
debugging; it does not require parsing TOON, NDJSON, or a trace file.

Consume the generator fully before `getReturn()`. In a durable run this is also
the point at which Tell is allowed to publish the new conversation head.

## Example

```php theme={null}
<?php
require 'examples/boot.php';
require_once dirname(__DIR__).'/Support.php';

use Cognesy\Tell\Tell;
use Cognesy\Tell\TellEvent;
use Cognesy\Tell\TellRequest;

$project = TellHarnessExample::project();
$eventTypes = [];

try {
    $tell = Tell::open($project);
    $stream = $tell->runStream(
        TellRequest::prompt(
            'Inspect the available context, use a tool if one is useful, then '
            .'give a concise report.',
        )
            ->maxSteps(5)
            ->onEvent(
                static function (TellEvent $event) use (&$eventTypes): void {
                    $eventTypes[] = $event->type();
                    echo '[event] '.$event->type()."\n";
                },
            ),
    );

    foreach ($stream as $progress) {
        echo sprintf(
            '[checkpoint] steps=%d tools=%s status=%s%s',
            $progress->stepCount(),
            $progress->hasToolCalls() ? 'yes' : 'no',
            $progress->status()?->value ?? 'unknown',
            PHP_EOL,
        );
    }
    $result = $stream->getReturn();

    echo "\n=== Tell Result ===\n";
    echo $result->text(), "\n";
    echo 'Observed events: '.count($eventTypes)."\n";

    assert(
        $result->isCompleted(),
        'Expected a completed streamed Tell result.',
    );
    assert($eventTypes !== [], 'Expected at least one Tell lifecycle event.');
} finally {
    TellHarnessExample::remove($project);
}
```

## Key Points

* A checkpoint represents a completed agent-loop step, not an arbitrary token.
* `TellEvent::source()` is available when a caller intentionally needs
  provider- or framework-specific fields.
* Event payloads can contain tool or provider data. Project sanitized telemetry
  deliberately instead of forwarding payloads blindly to logs.
