Send AgentCtrl telemetry to Langfuse
Overview¶
This example combines the built-in AgentCtrlConsoleLogger with an inline
Langfuse connection. You still see the live execution locally, and the same run
is also emitted as correlated telemetry through the AgentCtrl projector.
Key concepts:
- explicit LangfuseConfig / LangfuseHttpTransport / LangfuseExporter setup
- AgentCtrlConsoleLogger: local execution visibility
- AgentCtrlTelemetryProjector: correlates the full run by executionId
- executeStreaming(): shows progress as the CLI agent works
- bash tool calls: make the telemetry trace reflect multi-step repository inspection
- Telemetry::flush(): sends the final telemetry batch
Example¶
<?php
require 'examples/boot.php';
use Cognesy\AgentCtrl\AgentCtrl;
use Cognesy\AgentCtrl\Broadcasting\AgentCtrlConsoleLogger;
use Cognesy\AgentCtrl\OpenAICodex\Domain\Enum\SandboxMode;
use Cognesy\AgentCtrl\Telemetry\AgentCtrlTelemetryProjector;
use Cognesy\Config\Env;
use Cognesy\Telemetry\Adapters\Langfuse\LangfuseConfig;
use Cognesy\Telemetry\Adapters\Langfuse\LangfuseExporter;
use Cognesy\Telemetry\Adapters\Langfuse\LangfuseHttpTransport;
use Cognesy\Telemetry\Application\Registry\TraceRegistry;
use Cognesy\Telemetry\Application\Telemetry;
use Cognesy\Telemetry\Application\Projector\RuntimeEventBridge;
$serviceName = 'examples.d10.telemetry-langfuse';
$baseUrl = (string) Env::get('LANGFUSE_BASE_URL', '');
if ($baseUrl === '') {
throw new RuntimeException('Set LANGFUSE_BASE_URL in .env to run this example.');
}
$publicKey = (string) Env::get('LANGFUSE_PUBLIC_KEY', '');
if ($publicKey === '') {
throw new RuntimeException('Set LANGFUSE_PUBLIC_KEY in .env to run this example.');
}
$secretKey = (string) Env::get('LANGFUSE_SECRET_KEY', '');
if ($secretKey === '') {
throw new RuntimeException('Set LANGFUSE_SECRET_KEY in .env to run this example.');
}
$hub = new Telemetry(
registry: new TraceRegistry(),
exporter: new LangfuseExporter(
transport: new LangfuseHttpTransport(new LangfuseConfig(
baseUrl: $baseUrl,
publicKey: $publicKey,
secretKey: $secretKey,
)),
),
);
$bridge = new RuntimeEventBridge(new AgentCtrlTelemetryProjector($hub));
$logger = new AgentCtrlConsoleLogger(
useColors: true,
showTimestamps: true,
showToolArgs: true,
showStreaming: false,
);
$workDir = dirname(__DIR__, 3);
echo "=== Agent Execution Log ===\n\n";
$prompt = <<<'PROMPT'
Inspect this repository using the bash tool.
Requirements:
- Use bash at least 3 separate times.
- Do not combine commands with && or ;.
- Run these as separate bash calls:
1. pwd
2. ls examples/D10_AgentCtrl
3. rg -n "Telemetry" examples/D10_AgentCtrl
Then explain in two short sentences what the AgentCtrl telemetry examples demonstrate.
PROMPT;
$response = AgentCtrl::codex()
->wiretap($logger->wiretap())
->wiretap($bridge->handle(...))
->withSandbox(SandboxMode::ReadOnly)
->inDirectory($workDir)
->executeStreaming($prompt);
$hub->flush();
$toolNames = array_map(
static fn($toolCall): string => $toolCall->tool,
$response->toolCalls,
);
$toolCallCount = count($toolNames);
echo "\n=== Result ===\n";
if (!$response->isSuccess()) {
echo "Error: Command failed with exit code {$response->exitCode}\n";
exit(1);
}
echo "Answer: {$response->text()}\n";
echo "Execution ID: {$response->executionId()}\n";
echo "Tools used: " . implode(' > ', $toolNames) . "\n";
echo "Total tool calls: {$toolCallCount}\n";
if ($response->sessionId() !== null) {
echo "Session ID: {$response->sessionId()}\n";
}
echo "Telemetry: flushed to Langfuse\n";
assert($response->text() !== '');
assert($toolCallCount >= 3);
?>