PHP code example of agentphp / sdk

1. Go to this page and download the library: Download agentphp/sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

agentphp / sdk example snippets


use AgentPHP\Core\AgentBuilder;

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSystemPrompt('You are a helpful assistant.')
    ->build();

$response = $agent->chat('Hello, how are you?');
echo $response->getContent();



gentPHP\Core\AgentBuilder;

// Create an agent with OpenAI
$agent = AgentBuilder::create()
    ->withOpenAI('your-openai-api-key', 'gpt-4')
    ->withSystemPrompt('You are a helpful assistant.')
    ->withName('MyAgent')
    ->build();

// Simple chat
$response = $agent->chat('What is the capital of France?');
echo $response->getContent(); // "The capital of France is Paris."

// Get usage information
$usage = $response->getUsage();
echo "Tokens used: " . $usage->getTotalTokens();

use AgentPHP\Core\AgentBuilder;

// With conversation memory (default)
$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withConversationMemory()
    ->build();

// The agent remembers previous messages
$agent->chat('My name is John');
$response = $agent->chat('What is my name?');
echo $response->getContent(); // "Your name is John."

// With sliding window memory (limits context size)
$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSlidingWindowMemory(4000) // Max 4000 tokens
    ->build();

use AgentPHP\Core\AgentBuilder;
use AgentPHP\Core\AgentConfig;

// Using AgentBuilder (recommended)
$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key', 'gpt-4')
    ->withName('MyAssistant')
    ->withSystemPrompt('You are a coding expert.')
    ->withTemperature(0.7)
    ->withMaxTokens(2000)
    ->withMaxIterations(10)
    ->withTimeout(30)
    ->withStreaming(false)
    ->build();

// Using AgentConfig directly
$config = AgentConfig::fromArray([
    'name' => 'MyAssistant',
    'system_prompt' => 'You are a coding expert.',
    'temperature' => 0.7,
    'max_tokens' => 2000,
    'max_iterations' => 10,
    'timeout' => 30,
    'streaming' => false,
]);

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withConfig($config)
    ->build();



gentPHP\Core\AgentBuilder;
use AgentPHP\Tools\AbstractTool;
use AgentPHP\Tools\ToolSchemaBuilder;

// Define a custom tool
class WeatherTool extends AbstractTool
{
    protected string $name = 'get_weather';
    protected string $description = 'Get the current weather for a location';

    public function getParameters(): array
    {
        return ToolSchemaBuilder::create()
            ->addString('location', 'City name', ssistant with weather capabilities.')
    ->withTool(new WeatherTool())
    ->withRetry(3, 1000, 2.0)
    ->withConversationMemory()
    ->build();

// Chat
$response = $agent->chat('What is the weather in Paris?');
echo $response->getContent();

// config/app.php
'providers' => [
    AgentPHP\Framework\Laravel\AgentServiceProvider::class,
],

'aliases' => [
    'Agent' => AgentPHP\Framework\Laravel\Facades\Agent::class,
],

// config/agent.php
return [
    'default' => env('AGENT_PROVIDER', 'openai'),

    'name' => env('AGENT_NAME', 'AgentPHP'),
    'system_prompt' => env('AGENT_SYSTEM_PROMPT', 'You are a helpful assistant.'),

    'providers' => [
        'openai' => [
            'api_key' => env('OPENAI_API_KEY'),
            'model' => env('OPENAI_MODEL', 'gpt-4'),
            'timeout' => 30,
        ],
        'anthropic' => [
            'api_key' => env('ANTHROPIC_API_KEY'),
            'model' => env('ANTHROPIC_MODEL', 'claude-3-sonnet-20240229'),
        ],
        'google' => [
            'api_key' => env('GOOGLE_API_KEY'),
            'model' => env('GOOGLE_MODEL', 'gemini-pro'),
        ],
    ],

    'memory' => [
        'driver' => 'conversation', // or 'sliding_window'
        'max_tokens' => 4000,
    ],

    'middleware' => [
        'logging' => ['enabled' => true, 'level' => 'debug'],
        'retry' => ['enabled' => true, 'max_retries' => 3],
        'rate_limit' => ['enabled' => false, 'max_requests' => 60],
    ],

    'human_loop' => [
        'enabled' => false,
        'timeout' => 300,
    ],

    'tools' => [
        // \App\Tools\SearchTool::class,
    ],
];

use AgentPHP\Framework\Laravel\Facades\Agent;

// Simple chat
$response = Agent::chat('Hello!');
echo $response->getContent();

// With streaming
$stream = Agent::chatStream('Tell me a story');
foreach ($stream->getChunks() as $chunk) {
    echo $chunk->getContent();
}

// Get conversation history
$history = Agent::getHistory();

// Reset conversation
Agent::reset();

use AgentPHP\Core\Agent;

class ChatController extends Controller
{
    public function __construct(
        private Agent $agent
    ) {}

    public function chat(Request $request)
    {
        $response = $this->agent->chat($request->input('message'));

        return response()->json([
            'message' => $response->getContent(),
            'usage' => $response->getUsage()->toArray(),
        ]);
    }
}

use AgentPHP\Core\AgentBuilder;

class CustomAgentController extends Controller
{
    public function chat(Request $request)
    {
        // Create a custom agent instance
        $agent = AgentBuilder::create()
            ->withOpenAI(config('agent.providers.openai.api_key'))
            ->withSystemPrompt('You are a customer service agent.')
            ->withTemperature(0.5)
            ->withTool(new SearchTool())
            ->withLogging(app('log'))
            ->build();

        return response()->json([
            'response' => $agent->chat($request->input('message'))->getContent(),
        ]);
    }
}

use AgentPHP\Core\Agent;

class ChatController extends Controller
{
    public function __construct(
        private Agent $agent
    ) {
        // Register tools directly on the agent
        $this->agent->addTools([
            new \App\Tools\WeatherTool(),
            new \App\Tools\CalculatorTool(),
            new \App\Tools\SearchTool(),
        ]);
    }

    public function chat(Request $request)
    {
        $response = $this->agent->chat($request->input('message'));
        return response()->json(['message' => $response->getContent()]);
    }
}

$this->agent->addTool(new WeatherTool());

// In AppServiceProvider
use AgentPHP\Tools\ToolRegistry;

public function boot(ToolRegistry $registry)
{
    $registry->register(new \App\Tools\SearchTool());
}

use AgentPHP\Core\Agent;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;

public function stream(Request $request): StreamedResponse
{
    $message = $request->input('message');

    return new StreamedResponse(function () use ($message) {
        $agent = app(Agent::class);
        $stream = $agent->chatStream($message);

        foreach ($stream->getChunks() as $chunk) {
            if ($chunk->hasContent()) {
                echo "data: " . json_encode(['content' => $chunk->getContent()]) . "\n\n";
                ob_flush();
                flush();
            }

            if ($chunk->isDone()) {
                break;
            }
        }

        echo "data: [DONE]\n\n";
        ob_flush();
        flush();
    }, 200, [
        'Content-Type' => 'text/event-stream',
        'Cache-Control' => 'no-cache',
        'Connection' => 'keep-alive',
        'X-Accel-Buffering' => 'no',
    ]);
}

// config/bundles.php
return [
    // ...
    AgentPHP\Framework\Symfony\AgentBundle::class => ['all' => true],
];

use AgentPHP\Core\Agent;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

class ChatController extends AbstractController
{
    public function __construct(
        private Agent $agent
    ) {}

    public function chat(Request $request): JsonResponse
    {
        $message = $request->request->get('message');
        $response = $this->agent->chat($message);

        return $this->json([
            'message' => $response->getContent(),
            'usage' => $response->getUsage()->toArray(),
        ]);
    }
}

use AgentPHP\Core\Agent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;

public function stream(Request $request): StreamedResponse
{
    $message = $request->request->get('message');

    return new StreamedResponse(function () use ($message) {
        $stream = $this->agent->chatStream($message);

        foreach ($stream->getChunks() as $chunk) {
            if ($chunk->hasContent()) {
                echo "data: " . json_encode(['content' => $chunk->getContent()]) . "\n\n";
                ob_flush();
                flush();
            }

            if ($chunk->isDone()) {
                break;
            }
        }

        echo "data: [DONE]\n\n";
        ob_flush();
        flush();
    }, 200, [
        'Content-Type' => 'text/event-stream',
        'Cache-Control' => 'no-cache',
        'Connection' => 'keep-alive',
        'X-Accel-Buffering' => 'no',
    ]);
}

use AgentPHP\Core\AgentBuilder;

class CustomAgentService
{
    public function createSpecializedAgent(): Agent
    {
        return AgentBuilder::create()
            ->withAnthropic($_ENV['ANTHROPIC_API_KEY'], 'claude-3-opus-20240229')
            ->withSystemPrompt('You are an expert programmer.')
            ->withTemperature(0.3)
            ->withMaxTokens(4000)
            ->build();
    }
}

use AgentPHP\Core\AgentBuilder;

$agent = AgentBuilder::create()
    ->withOpenAI(
        apiKey: 'your-api-key',
        model: 'gpt-4',              // or gpt-4-turbo, gpt-3.5-turbo
        baseUrl: null,               // Custom base URL (optional)
        organization: null           // Organization ID (optional)
    )
    ->build();

// Or with ProviderConfig
use AgentPHP\Providers\OpenAIProvider;
use AgentPHP\Providers\ProviderConfig;

$config = new ProviderConfig([
    'api_key' => 'your-api-key',
    'model' => 'gpt-4-turbo',
    'base_url' => 'https://api.openai.com/v1',
    'organization' => 'org-xxx',
    'timeout' => 30,
]);

$provider = new OpenAIProvider($config);
$agent = AgentBuilder::create()
    ->withCustomProvider($provider)
    ->build();

use AgentPHP\Core\AgentBuilder;

$agent = AgentBuilder::create()
    ->withAnthropic(
        apiKey: 'your-api-key',
        model: 'claude-3-opus-20240229'  // or claude-3-sonnet, claude-3-haiku
    )
    ->build();

// Available models:
// - claude-3-opus-20240229 (most capable)
// - claude-3-sonnet-20240229 (balanced)
// - claude-3-haiku-20240307 (fastest)

use AgentPHP\Core\AgentBuilder;

$agent = AgentBuilder::create()
    ->withGoogle(
        apiKey: 'your-api-key',
        model: 'gemini-pro'  // or gemini-pro-vision
    )
    ->build();

use AgentPHP\Contracts\ProviderInterface;
use AgentPHP\Core\AgentBuilder;
use AgentPHP\Core\ChatResponse;

class MyCustomProvider implements ProviderInterface
{
    public function getName(): string
    {
        return 'custom';
    }

    public function chat(array $messages, array $options = []): ChatResponse
    {
        // Your implementation
    }

    public function chatStream(array $messages, callable $callback, array $options = []): ChatResponse
    {
        // Your streaming implementation
    }

    // ... other interface methods
}

$agent = AgentBuilder::create()
    ->withCustomProvider(new MyCustomProvider())
    ->build();

use AgentPHP\Providers\ProviderFactory;

// Create provider by name
$provider = ProviderFactory::create('openai', [
    'api_key' => 'your-key',
    'model' => 'gpt-4',
]);

$provider = ProviderFactory::create('anthropic', [
    'api_key' => 'your-key',
    'model' => 'claude-3-sonnet-20240229',
]);

use AgentPHP\Core\AgentBuilder;

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSystemPrompt('You are a helpful assistant that speaks formally.')
    ->build();

$systemPrompt = <<<PROMPT
You are an expert customer service agent for TechCorp.

Your responsibilities:
- Answer questions about our products
- Help troubleshoot technical issues
- Process refund requests when appropriate

Guidelines:
- Always be polite and professional
- If you don't know something, say so
- Never share confidential information
- Escalate to a human agent for complex issues

Available products:
- TechWidget Pro (\$99)
- TechGadget Plus (\$149)
- TechService Premium (monthly subscription)
PROMPT;

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSystemPrompt($systemPrompt)
    ->build();

$userName = 'John';
$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSystemPrompt("You are helping user: {$userName}")
    ->build();

// Or update at runtime
$agent->setSystemPrompt("New context: User is a premium member.");

$userLanguage = 'es';
$systemPrompt = match($userLanguage) {
    'es' => 'Eres un asistente util. Responde siempre en espanol.',
    'fr' => 'Vous etes un assistant utile. Repondez toujours en francais.',
    default => 'You are a helpful assistant. Always respond in English.',
};

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSystemPrompt($systemPrompt)
    ->build();

function getSystemPromptForRole(string $role): string
{
    return match($role) {
        'developer' => 'You are a senior software developer. Provide code examples and technical explanations.',
        'teacher' => 'You are a patient teacher. Explain concepts simply and use analogies.',
        'analyst' => 'You are a data analyst. Focus on facts, statistics, and data-driven insights.',
        default => 'You are a helpful assistant.',
    };
}

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSystemPrompt(getSystemPromptForRole('developer'))
    ->build();

use AgentPHP\Tools\AbstractTool;
use AgentPHP\Tools\ToolSchemaBuilder;

class WeatherTool extends AbstractTool
{
    protected string $name = 'get_weather';
    protected string $description = 'Get the current weather for a location';

    public function getParameters(): array
    {
        return ToolSchemaBuilder::create()
            ->addString('location', 'The city and country',   $location = $arguments['location'];
        $unit = $arguments['unit'] ?? 'celsius';

        // Call weather API
        $weather = $this->fetchWeather($location, $unit);

        return [
            'temperature' => $weather['temp'],
            'condition' => $weather['condition'],
            'humidity' => $weather['humidity'],
        ];
    }

    private function fetchWeather(string $location, string $unit): array
    {
        // Your API implementation
        return [
            'temp' => 22,
            'condition' => 'sunny',
            'humidity' => 45,
        ];
    }
}

use AgentPHP\Core\AgentBuilder;

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withTool(new WeatherTool())
    ->withTool(new SearchTool())
    ->withTool(new CalculatorTool())
    ->build();

// Or register multiple at once
$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withTools([
        new WeatherTool(),
        new SearchTool(),
        new CalculatorTool(),
    ])
    ->build();

use AgentPHP\Tools\ToolSchemaBuilder;

$schema = ToolSchemaBuilder::create()
    // String with validation
    ->addString('email', 'User email address', ', 'User age',  'List of tags', itemType: 'string')

    // Nested object
    ->addObject('address', 'Shipping address', [
        'street' => ['type' => 'string', 'description' => 'Street address'],
        'city' => ['type' => 'string', 'description' => 'City'],
        'zip' => ['type' => 'string', 'description' => 'ZIP code'],
    ])

    ->build();

class DeleteUserTool extends AbstractTool
{
    protected string $name = 'delete_user';
    protected string $description = 'Permanently delete a user account';
    protected bool $ ->addString('reason', 'Reason for deletion',     'deleted' => true,
            'user_id' => $userId,
        ];
    }
}

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withSystemPrompt('You can help users check the weather.')
    ->withTool(new WeatherTool())
    ->build();

// The agent will automatically use the tool when appropriate
$response = $agent->chat('What is the weather in Paris?');
echo $response->getContent();
// "The current weather in Paris is 22C and sunny with 45% humidity."

// Check if tools were used
if ($response->hasToolCalls()) {
    foreach ($response->getToolCalls() as $call) {
        echo "Tool used: " . $call->getName();
    }
}

use AgentPHP\Tools\ToolRegistry;

$registry = new ToolRegistry();

// Register tools
$registry->register(new WeatherTool());
$registry->register(new SearchTool());

// Check if tool exists
if ($registry->has('get_weather')) {
    $tool = $registry->get('get_weather');
}

// Get all tool names
$names = $registry->names(); // ['get_weather', 'search']

// Get tools requiring approval
$sensitiveTools = $registry->getRequiringApproval();

// Filter tools
$readOnlyTools = $registry->filter(fn($tool) => !$tool->

use AgentPHP\Tools\ToolExecutor;

$executor = new ToolExecutor($registry);

// Execute a specific tool
$result = $executor->executeByName('get_weather', [
    'location' => 'Tokyo',
    'unit' => 'celsius',
]);

if ($result->isSuccess()) {
    echo $result->getResultAsString();
} else {
    echo "Error: " . $result->getError();
}


// File: cli_stream.php

r;

// Create agent
$agent = AgentBuilder::create()
    ->withOpenAI(getenv('OPENAI_API_KEY'), 'gpt-4')
    ->withSystemPrompt('You are a helpful assistant.')
    ->build();

echo "Assistant: ";

// Get the stream
$stream = $agent->chatStream('Tell me a short story about a robot');

// Process each chunk as it arrives
foreach ($stream->getChunks() as $chunk) {
    // Check if chunk has text content
    if ($chunk->hasContent()) {
        echo $chunk->getContent();

        // Force output to display immediately
        if (function_exists('ob_flush')) {
            @ob_flush();
        }
        flush();
    }
}

echo "\n\n--- Stream complete ---\n";


// File: stream.php

ilder;

// Disable output buffering
if (ob_get_level()) {
    ob_end_clean();
}

// Set SSE headers
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header('X-Accel-Buffering: no'); // Required for nginx

// Get message from request
$message = $_GET['message'] ?? $_POST['message'] ?? 'Hello';

// Create agent
$agent = AgentBuilder::create()
    ->withOpenAI(getenv('OPENAI_API_KEY'), 'gpt-4')
    ->withSystemPrompt('You are a helpful assistant.')
    ->build();

try {
    $stream = $agent->chatStream($message);

    foreach ($stream->getChunks() as $chunk) {
        if ($chunk->hasContent()) {
            // Send SSE data
            echo "data: " . json_encode([
                'type' => 'content',
                'content' => $chunk->getContent()
            ]) . "\n\n";

            flush();
        }

        // Check for errors
        if ($chunk->isError()) {
            echo "data: " . json_encode([
                'type' => 'error',
                'message' => $chunk->getContent()
            ]) . "\n\n";
            flush();
            break;
        }
    }

    // Send completion signal
    echo "data: " . json_encode(['type' => 'done']) . "\n\n";
    flush();

} catch (\Exception $e) {
    echo "data: " . json_encode([
        'type' => 'error',
        'message' => $e->getMessage()
    ]) . "\n\n";
    flush();
}


// File: api_stream.php

r;

// Handle CORS if needed
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

// Disable output buffering
while (ob_get_level()) {
    ob_end_clean();
}

// Set SSE headers
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header('X-Accel-Buffering: no');

// Get JSON body
$input = json_decode(file_get_contents('php://input'), true);
$message = $input['message'] ?? 'Hello';

$agent = AgentBuilder::create()
    ->withOpenAI(getenv('OPENAI_API_KEY'), 'gpt-4')
    ->build();

$stream = $agent->chatStream($message);

foreach ($stream->getChunks() as $chunk) {
    if ($chunk->hasContent()) {
        echo "data: " . json_encode(['content' => $chunk->getContent()]) . "\n\n";
        flush();
    }
}

echo "data: [DONE]\n\n";
flush();

foreach ($stream->getChunks() as $chunk) {
    // Get text content
    $text = $chunk->getContent();
    $text = $chunk->getText();  // Alias

    // Check what type of chunk this is
    $chunk->hasContent();       // Has text content?
    $chunk->isContent();        // Is a content chunk?
    $chunk->isDone();           // Is the final chunk?
    $chunk->isError();          // Is an error chunk?
    $chunk->isFinal();          // Is done, stop, or error?

    // For tool calls during streaming
    $chunk->hasToolCall();      // Has complete tool call?
    $chunk->hasToolCallDelta(); // Has partial tool call data?
    $chunk->getToolCall();      // Get ToolCall object
    $chunk->getToolCallDelta(); // Get partial tool call array

    // Metadata
    $chunk->getType();          // 'content', 'tool_call', 'done', 'error', etc.
    $chunk->getIndex();         // Chunk index number
    $chunk->getFinishReason();  // 'stop', 'length', 'tool_calls', etc.
    $chunk->getModel();         // Model name (usually in first/last chunk)
    $chunk->getUsage();         // Usage stats (usually in last chunk)
}

$stream = $agent->chatStream('Tell me about PHP');
$fullText = '';

// Collect all chunks
foreach ($stream->getChunks() as $chunk) {
    if ($chunk->hasContent()) {
        $content = $chunk->getContent();
        echo $content;  // Stream to output
        $fullText .= $content;  // Collect for later
    }
}

// After streaming, you have the complete text
echo "\n\nComplete response length: " . strlen($fullText) . " characters\n";

// OpenAI
$agent = AgentBuilder::create()
    ->withOpenAI(getenv('OPENAI_API_KEY'), 'gpt-4')
    ->build();

// Anthropic
$agent = AgentBuilder::create()
    ->withAnthropic(getenv('ANTHROPIC_API_KEY'), 'claude-3-sonnet-20240229')
    ->build();

// Google
$agent = AgentBuilder::create()
    ->withGoogle(getenv('GOOGLE_API_KEY'), 'gemini-pro')
    ->build();

// Same streaming code works for all providers
$stream = $agent->chatStream('Hello!');
foreach ($stream->getChunks() as $chunk) {
    echo $chunk->getContent();
}

try {
    $stream = $agent->chatStream('Tell me a story');

    foreach ($stream->getChunks() as $chunk) {
        if ($chunk->isError()) {
            throw new \Exception('Stream error: ' . $chunk->getContent());
        }

        echo $chunk->getContent();
    }
} catch (\AgentPHP\Exceptions\ProviderException $e) {
    echo "Provider error: " . $e->getMessage();
} catch (\AgentPHP\Exceptions\RateLimitException $e) {
    echo "Rate limited. Retry after: " . $e->getRetryAfter() . " seconds";
} catch (\Exception $e) {
    echo "Error: " . $e->getMessage();
}

use AgentPHP\Core\AgentBuilder;
use Psr\Log\LoggerInterface;

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withLogging($logger, 'info')  // PSR-3 logger
    ->build();

// Or with Laravel
$agent = AgentBuilder::create()
    ->withOpenAI(config('agent.providers.openai.api_key'))
    ->withLogging(app('log'), 'debug')
    ->build();

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withRetry(
        maxRetries: 3,        // Number of retry attempts
        delay: 1000,          // Initial delay in milliseconds
        multiplier: 2.0       // Exponential backoff multiplier
    )
    ->build();

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withRateLimit(
        maxRequests: 60,      // Maximum requests
        window: 60            // Time window in seconds
    )
    ->build();

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withTimeout(30)  // 30 seconds timeout
    ->build();

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withLogging($logger)
    ->withRetry(3, 1000, 2.0)
    ->withRateLimit(60, 60)
    ->withTimeout(30)
    ->build();

use AgentPHP\Contracts\MiddlewareInterface;
use AgentPHP\Core\ChatRequest;
use AgentPHP\Core\ChatResponse;

class MetricsMiddleware implements MiddlewareInterface
{
    public function __construct(
        private MetricsService $metrics
    ) {}

    public function process(ChatRequest $request, callable $next): ChatResponse
    {
        $startTime = microtime(true);

        try {
            // Call next middleware/handler
            $response = $next($request);

            // Record success metrics
            $duration = microtime(true) - $startTime;
            $this->metrics->record('chat.success', $duration);
            $this->metrics->increment('chat.tokens', $response->getUsage()->getTotalTokens());

            return $response;

        } catch (\Exception $e) {
            // Record error metrics
            $this->metrics->increment('chat.errors');
            throw $e;
        }
    }
}

// Use the middleware
$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withMiddleware(new MetricsMiddleware($metricsService))
    ->build();

class AuthenticationMiddleware implements MiddlewareInterface
{
    public function process(ChatRequest $request, callable $next): ChatResponse
    {
        // Check if user is authenticated
        if (!$this->auth->check()) {
            throw new UnauthorizedException('User must be authenticated');
        }

        // Check rate limits for user
        $userId = $this->auth->id();
        if ($this->rateLimiter->tooManyAttempts($userId, 100)) {
            throw new RateLimitException('Too many requests');
        }

        $this->rateLimiter->hit($userId);

        return $next($request);
    }
}

class ContentFilterMiddleware implements MiddlewareInterface
{
    private array $blockedWords = ['spam', 'inappropriate'];

    public function process(ChatRequest $request, callable $next): ChatResponse
    {
        // Filter input
        $messages = $request->getMessages();
        foreach ($messages as $message) {
            if ($this->containsBlockedContent($message['content'] ?? '')) {
                throw new ContentPolicyException('Message contains blocked content');
            }
        }

        $response = $next($request);

        // Filter output
        $content = $response->getContent();
        if ($this->containsBlockedContent($content)) {
            throw new ContentPolicyException('Response contains blocked content');
        }

        return $response;
    }

    private function containsBlockedContent(string $text): bool
    {
        foreach ($this->blockedWords as $word) {
            if (stripos($text, $word) !== false) {
                return true;
            }
        }
        return false;
    }
}

use AgentPHP\Core\AgentBuilder;
use AgentPHP\HumanLoop\ApprovalHandler;

$approvalHandler = ApprovalHandler::create();

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withHumanApproval($approvalHandler)
    ->withTool(new DeleteUserTool())  // 

use AgentPHP\Contracts\HumanLoopInterface;
use AgentPHP\Tools\ToolCall;

class SlackApprovalHandler implements HumanLoopInterface
{
    public function requestApproval(ToolCall $call): bool
    {
        // Send Slack notification
        $this->slack->send([
            'channel' => '#approvals',
            'text' => "Approval needed for: {$call->getName()}",
            'data' => $call->getArguments(),
        ]);

        // Wait for response (implement your logic)
        return $this->waitForApproval($call->getId());
    }

    public function onApproved(ToolCall $call): void
    {
        $this->slack->send([
            'channel' => '#approvals',
            'text' => "Approved: {$call->getName()}",
        ]);
    }

    public function onDenied(ToolCall $call, string $reason): void
    {
        $this->slack->send([
            'channel' => '#approvals',
            'text' => "Denied: {$call->getName()} - {$reason}",
        ]);
    }
}

$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->withAutoApproval()  // Skip approval in development
    ->build();

// Or skip approval for specific tools
$agent = AgentBuilder::create()
    ->withOpenAI('your-api-key')
    ->skipApproval()  // Skip all approvals
    ->build();

use AgentPHP\Exceptions\AgentException;
use AgentPHP\Exceptions\ProviderException;
use AgentPHP\Exceptions\RateLimitException;
use AgentPHP\Exceptions\TimeoutException;
use AgentPHP\Exceptions\ToolException;
use AgentPHP\Exceptions\ValidationException;

try {
    $response = $agent->chat('Hello');
} catch (RateLimitException $e) {
    // Handle rate limiting
    $retryAfter = $e->getRetryAfter();
    sleep($retryAfter);

} catch (TimeoutException $e) {
    // Handle timeout
    echo "Request timed out after {$e->getTimeout()} seconds";

} catch (ToolException $e) {
    // Handle tool errors
    echo "Tool '{$e->getToolName()}' failed: {$e->getMessage()}";

} catch (ValidationException $e) {
    // Handle validation errors
    foreach ($e->getErrors() as $field => $error) {
        echo "{$field}: {$error}";
    }

} catch (ProviderException $e) {
    // Handle provider-specific errors
    echo "Provider error: {$e->getMessage()}";

} catch (AgentException $e) {
    // Handle all other agent errors
    echo "Agent error: {$e->getMessage()}";
}
bash
php artisan vendor:publish --tag=agent-config
bash
php cli_stream.php
nginx
location /stream.php {
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 3600s;

    # If using FastCGI
    fastcgi_buffering off;
    fastcgi_keep_conn on;
}