Skip to content

Tell Harness: Configure an Embedded Tell Instance

Overview

Build one isolated Tell object graph, replace a typed capability before resolution, and run through the stable SDK contract. This is the programmable path for applications that need more control than the standard defaults.

Example

<?php
require 'examples/boot.php';
require_once dirname(__DIR__).'/Support.php';

use Cognesy\Agents\Drivers\Testing\FakeAgentDriver;
use Cognesy\Tell\Composition\Standalone\StandaloneTellBuilder;
use Cognesy\Tell\Core\Contract\Observation\CanObserveTellExecution;
use Cognesy\Tell\Core\Paths\TellPaths;
use Cognesy\Tell\Data\TellEventEnvelope;
use Cognesy\Tell\Data\TellRequest;

$project = TellHarnessExample::project();
$events = new ArrayObject;
$observer = new class($events) implements CanObserveTellExecution {
    public function __construct(private ArrayObject $events) {}

    public function observe(TellEventEnvelope $event): void
    {
        $this->events->append($event->toArray());
    }
};
$paths = new TellPaths(
    packageAgents: dirname(__DIR__, 3).'/packages/tell/resources/agents',
    home: $project.'/.tell-host-example',
);
$tell = StandaloneTellBuilder::in($project, $paths)
    ->withObserver($observer)
    ->withDriverFactory(static fn () => FakeAgentDriver::fromResponses(
        'application-controlled answer',
    ))
    ->build();

try {
    $result = $tell->run(TellRequest::prompt('Run configured Tell.'));

    echo trim($result->text())."\n";
    echo 'Observed events: '.count($events)."\n";

    assert(trim($result->text()) === 'application-controlled answer');
    assert(count($events) > 0);
} finally {
    TellHarnessExample::remove($project);
}
?>

Key Points

  • StandaloneTellBuilder owns one private container and returns Tell, never the container or a generic service host.
  • Typed replacements and factories are registered before build(); the builder rejects mutation or a second build after resolution.
  • Create a fresh builder for each Tell instance. Their drivers, observers, cancellation sources, and mutable state are not shared.
  • Standard Tell owns no disposable resources. The finally block here only removes the example's temporary project.