<?php
require 'examples/boot.php';
use Cognesy\AgentCtrl\AgentCtrl;
use Cognesy\AgentCtrl\Broadcasting\AgentCtrlConsoleLogger;
use Cognesy\AgentCtrl\Gemini\Domain\Enum\ApprovalMode;
// Console logger for execution lifecycle visibility
$logger = new AgentCtrlConsoleLogger(
useColors: true,
showTimestamps: true,
showToolArgs: true,
);
$textChunks = [];
$toolCalls = [];
echo "=== Agent Execution Log ===\n\n";
$response = AgentCtrl::gemini()
->wiretap($logger->wiretap())
->withModel('flash')
->withApprovalMode(ApprovalMode::AutoEdit)
->inDirectory(getcwd())
->onText(function (string $text) use (&$textChunks) {
$textChunks[] = $text;
echo $text;
})
->onToolUse(function (string $tool, array $input, ?string $output) use (&$toolCalls) {
$target = $input['command'] ?? $input['file_path'] ?? $input['path'] ?? $input['pattern'] ?? '';
if (strlen($target) > 40) {
$target = '...' . substr($target, -37);
}
$toolCalls[] = $tool;
echo "\n >> [{$tool}] {$target}\n";
})
->executeStreaming('Read the first 5 lines of composer.json in this directory and describe what you see.');
if (!$response->isSuccess()) {
echo "Error: Command failed with exit code {$response->exitCode}\n";
exit(1);
}
$streamedText = implode('', $textChunks);
$usage = $response->usage();
assert($streamedText !== '', 'Expected Gemini to stream non-empty text');
assert($streamedText === $response->text(), 'Expected streamed text to match the final response');
assert(in_array('read_file', $toolCalls, true), 'Expected Gemini to call read_file');
assert($usage !== null, 'Expected Gemini to return token usage');
assert($usage->input > 0, 'Expected positive input token usage');
assert($usage->output > 0, 'Expected positive output token usage');
echo "\n=== Result ===\n";
echo "Tools used: " . implode(' > ', $toolCalls) . "\n";
echo "Total tool calls: " . count($toolCalls) . "\n";
echo "Tokens: {$usage->input} in / {$usage->output} out\n";
?>