<?php
require 'examples/boot.php';
use Cognesy\Agents\AgentLoop;
use Cognesy\Agents\Capability\File\ReadFileTool;
use Cognesy\Agents\Data\AgentState;
use Cognesy\Agents\Events\Support\AgentEventConsoleObserver;
use Cognesy\Messages\Messages;
$workDir = dirname(__DIR__, 3);
// AgentEventConsoleObserver provides detailed event output during iteration
$logger = new AgentEventConsoleObserver(
useColors: true,
showTimestamps: true,
showContinuation: true,
);
$loop = AgentLoop::default()
->withTool(ReadFileTool::inDirectory($workDir))
->wiretap($logger->wiretap());
$state = AgentState::empty()->withMessages(
Messages::fromString('Read the composer.json file and tell me the project name.')
);
echo "=== Stepping through agent loop ===\n\n";
// iterate() yields state after each step; the logger prints events as they fire
$stepNum = 0;
foreach ($loop->iterate($state) as $stepState) {
$stepNum++;
// At yield time the step has been completed, so use lastStep()
$step = $stepState->lastStep();
$hasToolCalls = $step?->hasToolCalls() ?? false;
$tokens = $stepState->usage()->total();
$status = $stepState->status()->value;
// Custom per-step output alongside the logger's event output
$toolsLabel = $hasToolCalls ? 'yes' : 'no';
echo " >> Step {$stepNum}: status={$status}, has_tools={$toolsLabel}, tokens={$tokens}\n\n";
// Early termination example: stop after 5 steps regardless
if ($stepNum >= 5) {
echo "\n[Breaking early after {$stepNum} steps]\n";
break;
}
}
echo "\n=== Final Result ===\n";
$response = $stepState->finalResponse()->toString() ?: 'No response';
echo "Answer: {$response}\n";
echo "Total steps: {$stepState->stepCount()}\n";
echo "Total tokens: {$stepState->usage()->total()}\n";
if ($stepState->status()->value !== 'completed') {
echo "Skipping assertions because execution status is {$stepState->status()->value}.\n";
return;
}
// Assertions
assert($stepNum >= 1, 'Expected at least 1 step from iterate()');
assert(!empty($stepState->currentResponse()->toString()), 'Expected non-empty response');
assert($stepState->usage()->total() > 0, 'Expected token usage > 0');
?>