PHP code example of claude-php / claude-php-sdk-laravel

1. Go to this page and download the library: Download claude-php/claude-php-sdk-laravel 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/ */

    

claude-php / claude-php-sdk-laravel example snippets


use ClaudePhp\ClaudePhp;

$client = new ClaudePhp(apiKey: $_ENV['ANTHROPIC_API_KEY']);
$response = $client->messages()->create([...]);

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([...]);

use ClaudePhp\ClaudePhp;

public function __construct(private ClaudePhp $claude) {}

// Then use: $this->claude->messages()->create([...]);

use ClaudePhp\Types\ModelParam;

// Adaptive thinking — claude-opus-4-6 decides whether to think
Claude::messages()->create([
    'model'    => ModelParam::MODEL_CLAUDE_OPUS_4_6,
    'thinking' => ['type' => 'adaptive'],
    'messages' => [['role' => 'user', 'content' => 'Design a caching strategy.']],
]);

// Fast-mode inference via beta messages
Claude::beta()->messages()->create([
    'model'   => ModelParam::MODEL_CLAUDE_OPUS_4_6,
    'speed'   => 'fast',
    'messages' => [['role' => 'user', 'content' => 'Classify: spam or not spam?']],
]);

// Code execution, memory, and web fetch server-side tools
Claude::messages()->create([
    'model'   => ModelParam::MODEL_CLAUDE_SONNET_4_5,
    'tools'   => [['name' => 'code_execution', 'type' => 'code_execution_20250825']],
    'messages' => [['role' => 'user', 'content' => 'Compute the 100th prime.']],
]);

use ClaudePhp\Types\ModelParam;

ModelParam::MODEL_CLAUDE_OPUS_4_6    // claude-opus-4-6  (Feb 2026)
ModelParam::MODEL_CLAUDE_SONNET_4_6  // claude-sonnet-4-6
ModelParam::MODEL_CLAUDE_SONNET_4_5  // claude-sonnet-4-5-20250929
ModelParam::MODEL_CLAUDE_HAIKU_4_5   // claude-haiku-4-5-20251001

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [
        ['role' => 'user', 'content' => 'Hello, Claude!']
    ]
]);

echo $response['content'][0]['text'];



namespace App\Http\Controllers;

use ClaudePhp\ClaudePhp;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class ChatController extends Controller
{
    public function __construct(
        private ClaudePhp $claude
    ) {}

    public function chat(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'message' => '         'usage' => $response['usage']
        ]);
    }
}

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'system' => 'You are a helpful assistant that speaks like a pirate. Always end responses with "Arrr!"',
    'messages' => [
        ['role' => 'user', 'content' => 'What is Laravel?']
    ]
]);

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [
        ['role' => 'user', 'content' => 'My name is Alice.'],
        ['role' => 'assistant', 'content' => 'Hello Alice! Nice to meet you. How can I help you today?'],
        ['role' => 'user', 'content' => 'What is my name?']
    ]
]);

// Response: "Your name is Alice..."

use ClaudePhp\Laravel\Facades\Claude;

$stream = Claude::messages()->stream([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [
        ['role' => 'user', 'content' => 'Tell me a story about a brave knight']
    ]
]);

foreach ($stream as $event) {
    $type = $event['type'] ?? '';

    if ($type === 'content_block_delta') {
        echo $event['delta']['text'] ?? '';
        flush();
    }
}

use ClaudePhp\Laravel\Facades\Claude;
use Symfony\Component\HttpFoundation\StreamedResponse;

public function streamChat(Request $request): StreamedResponse
{
    return response()->stream(function () use ($request) {
        $stream = Claude::messages()->stream([
            'model' => 'claude-sonnet-4-5-20250929',
            'max_tokens' => 2048,
            'messages' => [
                ['role' => 'user', 'content' => $request->input('message')]
            ]
        ]);

        foreach ($stream as $event) {
            if (($event['type'] ?? '') === 'content_block_delta') {
                echo "data: " . json_encode(['text' => $event['delta']['text'] ?? '']) . "\n\n";
                ob_flush();
                flush();
            }
        }
    }, 200, [
        'Content-Type' => 'text/event-stream',
        'Cache-Control' => 'no-cache',
        'X-Accel-Buffering' => 'no',
    ]);
}

use ClaudePhp\Laravel\Facades\Claude;

// From URL
$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'image',
                    'source' => [
                        'type' => 'url',
                        'url' => 'https://example.com/image.jpg'
                    ]
                ],
                [
                    'type' => 'text',
                    'text' => 'What do you see in this image?'
                ]
            ]
        ]
    ]
]);

// From base64
$imageData = base64_encode(file_get_contents(storage_path('app/photo.jpg')));

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'image',
                    'source' => [
                        'type' => 'base64',
                        'media_type' => 'image/jpeg',
                        'data' => $imageData
                    ]
                ],
                [
                    'type' => 'text',
                    'text' => 'Describe this image in detail.'
                ]
            ]
        ]
    ]
]);

use ClaudePhp\Laravel\Facades\Claude;

$pdfData = base64_encode(file_get_contents(storage_path('app/document.pdf')));

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 4096,
    'messages' => [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'document',
                    'source' => [
                        'type' => 'base64',
                        'media_type' => 'application/pdf',
                        'data' => $pdfData
                    ]
                ],
                [
                    'type' => 'text',
                    'text' => 'Summarize the key points of this document.'
                ]
            ]
        ]
    ]
]);

use ClaudePhp\Laravel\Facades\Claude;

$tools = [
    [
        'name' => 'get_weather',
        'description' => 'Get the current weather in a given location',
        'input_schema' => [
            'type' => 'object',
            'properties' => [
                'location' => [
                    'type' => 'string',
                    'description' => 'City and country, e.g. London, UK'
                ],
                'unit' => [
                    'type' => 'string',
                    'enum' => ['celsius', 'fahrenheit'],
                    'description' => 'Temperature unit'
                ]
            ],
            's' => 1024,
    'tools' => $tools,
    'messages' => [
        ['role' => 'user', 'content' => "What's the weather in Tokyo?"]
    ]
]);

// Check if Claude wants to use a tool
foreach ($response['content'] as $block) {
    if ($block['type'] === 'tool_use') {
        $toolName = $block['name'];
        $toolInput = $block['input'];
        $toolUseId = $block['id'];

        // Execute your tool and get result
        $result = match($toolName) {
            'get_weather' => getWeather($toolInput['location'], $toolInput['unit'] ?? 'celsius'),
            'search_products' => searchProducts($toolInput),
            default => ['error' => 'Unknown tool']
        };

        // Continue conversation with tool result
        $followUp = Claude::messages()->create([
            'model' => 'claude-sonnet-4-5-20250929',
            'max_tokens' => 1024,
            'tools' => $tools,
            'messages' => [
                ['role' => 'user', 'content' => "What's the weather in Tokyo?"],
                ['role' => 'assistant', 'content' => $response['content']],
                [
                    'role' => 'user',
                    'content' => [
                        [
                            'type' => 'tool_result',
                            'tool_use_id' => $toolUseId,
                            'content' => json_encode($result)
                        ]
                    ]
                ]
            ]
        ]);
    }
}

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 16000,
    'thinking' => [
        'type' => 'enabled',
        'budget_tokens' => 10000  // Tokens allocated for reasoning
    ],
    'messages' => [
        ['role' => 'user', 'content' => 'Prove that there are infinitely many prime numbers.']
    ]
]);

foreach ($response['content'] as $block) {
    if ($block['type'] === 'thinking') {
        // Claude's internal reasoning process
        echo "Thinking: " . substr($block['thinking'], 0, 500) . "...\n\n";
    } elseif ($block['type'] === 'text') {
        // Final answer
        echo "Answer: " . $block['text'];
    }
}

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [
        [
            'role' => 'user',
            'content' => 'Extract the following info as JSON:
                Name: John Smith
                Email: [email protected]
                Age: 30
                Skills: PHP, Laravel, JavaScript

                Return a JSON object with keys: name, email, age, skills (as array)'
        ]
    ]
]);

$data = json_decode($response['content'][0]['text'], true);

use ClaudePhp\Laravel\Facades\Claude;

// Cache large system prompts or context for efficiency
$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'system' => [
        [
            'type' => 'text',
            'text' => $largeSystemPrompt, // Your extensive instructions
            'cache_control' => ['type' => 'ephemeral']
        ]
    ],
    'messages' => [
        ['role' => 'user', 'content' => 'Process this request...']
    ]
]);

// Subsequent requests with same cached content are faster and cheaper

use ClaudePhp\Laravel\Facades\Claude;

$models = Claude::models()->list();

foreach ($models['data'] as $model) {
    echo "Model: {$model['id']}\n";
    echo "  Display Name: {$model['display_name']}\n";
    echo "  Created: {$model['created_at']}\n\n";
}

use ClaudePhp\Laravel\Facades\Claude;

// Get the async proxy for concurrent operations
$async = Claude::async();

// Create multiple requests concurrently
$promise1 = $async->messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [['role' => 'user', 'content' => 'Summarize quantum physics']]
]);

$promise2 = $async->messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [['role' => 'user', 'content' => 'Explain machine learning']]
]);

// Wait for both to complete
$response1 = $promise1->await();
$response2 = $promise2->await();

use ClaudePhp\Laravel\Facades\Claude;

// Create a batch of requests for high-volume processing
$batch = Claude::beta()->messages()->batches()->create([
    'requests' => [
        [
            'custom_id' => 'request-1',
            'params' => [
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => 1024,
                'messages' => [
                    ['role' => 'user', 'content' => 'Translate to French: Hello world']
                ]
            ]
        ],
        [
            'custom_id' => 'request-2',
            'params' => [
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => 1024,
                'messages' => [
                    ['role' => 'user', 'content' => 'Translate to Spanish: Hello world']
                ]
            ]
        ]
    ]
]);

// Check batch status
$status = Claude::beta()->messages()->batches()->retrieve($batch['id']);

// List all batches
$batches = Claude::beta()->messages()->batches()->list();

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 4096,
    'tools' => [
        [
            'type' => 'web_search_20250305',
            'name' => 'web_search',
            'max_uses' => 5
        ]
    ],
    'messages' => [
        ['role' => 'user', 'content' => 'What are the latest developments in PHP 8.4?']
    ]
]);

use ClaudePhp\Laravel\Facades\Claude;

$response = Claude::messages()->create([
    'model' => 'claude-sonnet-4-5-20250929',
    'max_tokens' => 1024,
    'messages' => [
        ['role' => 'user', 'content' => 'Hello, Claude!']
    ]
]);

$usage = $response['usage'];
echo "Input tokens: {$usage['input_tokens']}\n";
echo "Output tokens: {$usage['output_tokens']}\n";
echo "Total tokens: " . ($usage['input_tokens'] + $usage['output_tokens']) . "\n";

// With caching
if (isset($usage['cache_creation_input_tokens'])) {
    echo "Cache creation tokens: {$usage['cache_creation_input_tokens']}\n";
}
if (isset($usage['cache_read_input_tokens'])) {
    echo "Cache read tokens: {$usage['cache_read_input_tokens']}\n";
}



namespace App\Services;

use ClaudePhp\ClaudePhp;

class ReActAgent
{
    private array $tools;
    private array $messages = [];

    public function __construct(
        private ClaudePhp $claude,
        private int $maxIterations = 10
    ) {
        $this->tools = $this->defineTools();
    }

    public function run(string $task): string
    {
        $this->messages = [['role' => 'user', 'content' => $task]];
        $iteration = 0;

        while ($iteration < $this->maxIterations) {
            $iteration++;

            // REASON: Ask Claude to analyze the situation
            $response = $this->claude->messages()->create([
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => 4096,
                'system' => 'You are a helpful assistant. Use tools when needed to solve problems.',
                'messages' => $this->messages,
                'tools' => $this->tools
            ]);

            // Add assistant response to history
            $this->messages[] = ['role' => 'assistant', 'content' => $response['content']];

            // COMPLETE: Check if task is finished
            if ($response['stop_reason'] === 'end_turn') {
                return $this->extractText($response);
            }

            // ACT: Execute any requested tools
            if ($response['stop_reason'] === 'tool_use') {
                $toolResults = $this->executeTools($response['content']);

                // OBSERVE: Add tool results to conversation
                $this->messages[] = ['role' => 'user', 'content' => $toolResults];

                // Continue loop to get Claude's response to tool results
                continue;
            }

            // Unexpected stop reason - break to avoid infinite loop
            break;
        }

        return 'Max iterations reached without completion.';
    }

    private function executeTools(array $content): array
    {
        $results = [];

        foreach ($content as $block) {
            if ($block['type'] === 'tool_use') {
                $result = $this->executeTool($block['name'], $block['input']);
                $results[] = [
                    'type' => 'tool_result',
                    'tool_use_id' => $block['id'],
                    'content' => is_string($result) ? $result : json_encode($result)
                ];
            }
        }

        return $results;
    }

    private function executeTool(string $name, array $input): mixed
    {
        return match ($name) {
            'calculate' => $this->calculate($input['expression']),
            'search_database' => $this->searchDatabase($input['query']),
            'get_current_time' => now()->toDateTimeString(),
            default => "Unknown tool: {$name}"
        };
    }

    private function calculate(string $expression): string
    {
        // Use a safe math parser in production!
        try {
            $result = eval("return {$expression};");
            return (string) $result;
        } catch (\Throwable $e) {
            return "Error: {$e->getMessage()}";
        }
    }

    private function searchDatabase(string $query): array
    {
        // Your database search logic
        return \App\Models\Product::search($query)->take(5)->get()->toArray();
    }

    private function defineTools(): array
    {
        return [
            [
                'name' => 'calculate',
                'description' => 'Perform mathematical calculations',
                'input_schema' => [
                    'type' => 'object',
                    'properties' => [
                        'expression' => [
                            'type' => 'string',
                            'description' => 'Math expression (e.g., "25 * 4 + 10")'
                        ]
                    ],
                    '

use App\Services\ReActAgent;

class AgentController extends Controller
{
    public function solve(Request $request, ReActAgent $agent)
    {
        $result = $agent->run($request->input('task'));

        return response()->json(['result' => $result]);
    }
}



namespace App\Services;

use App\Models\Order;
use App\Models\Customer;
use ClaudePhp\ClaudePhp;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;

class CustomerServiceAgent
{
    private array $tools;

    public function __construct(
        private ClaudePhp $claude
    ) {
        $this->tools = [
            [
                'name' => 'lookup_customer',
                'description' => 'Look up customer information by email or ID',
                'input_schema' => [
                    'type' => 'object',
                    'properties' => [
                        'identifier' => ['type' => 'string', 'description' => 'Customer email or ID']
                    ],
                    'schema' => [
                    'type' => 'object',
                    'properties' => [
                        'product_sku' => ['type' => 'string', 'description' => 'Product SKU']
                    ],
                    'messages = [['role' => 'user', 'content' => $inquiry]];
        $iterations = 0;

        while ($iterations < 8) {
            $iterations++;

            $response = $this->claude->messages()->create([
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => 4096,
                'system' => $context . 'Use available tools to help resolve customer inquiries. Be helpful and thorough.',
                'messages' => $messages,
                'tools' => $this->tools
            ]);

            $messages[] = ['role' => 'assistant', 'content' => $response['content']];

            // COMPLETE: Task finished
            if ($response['stop_reason'] === 'end_turn') {
                return [
                    'response' => $this->extractText($response),
                    'iterations' => $iterations,
                    'tools_used' => $this->countToolUses($messages)
                ];
            }

            // ACT & OBSERVE: Execute tools and continue
            if ($response['stop_reason'] === 'tool_use') {
                $results = [];
                foreach ($response['content'] as $block) {
                    if ($block['type'] === 'tool_use') {
                        $results[] = [
                            'type' => 'tool_result',
                            'tool_use_id' => $block['id'],
                            'content' => json_encode($this->executeTool($block['name'], $block['input']))
                        ];
                    }
                }
                $messages[] = ['role' => 'user', 'content' => $results];
                continue; // Get Claude's response to tool results
            }

            // Unexpected stop reason
            break;
        }

        return ['response' => 'Unable to complete request.', 'iterations' => $iterations];
    }

    private function executeTool(string $name, array $input): mixed
    {
        return match ($name) {
            'lookup_customer' => $this->lookupCustomer($input['identifier']),
            'get_order_history' => $this->getOrderHistory($input['customer_id'], $input['limit'] ?? 5),
            'check_inventory' => $this->checkInventory($input['product_sku']),
            'create_support_ticket' => $this->createTicket($input),
            default => ['error' => 'Unknown tool']
        };
    }

    private function lookupCustomer(string $identifier): array
    {
        $customer = Customer::where('email', $identifier)
            ->orWhere('id', $identifier)
            ->first();

        return $customer ? $customer->toArray() : ['error' => 'Customer not found'];
    }

    private function getOrderHistory(int $customerId, int $limit): array
    {
        return Order::where('customer_id', $customerId)
            ->with('items')
            ->latest()
            ->take($limit)
            ->get()
            ->toArray();
    }

    private function checkInventory(string $sku): array
    {
        return Cache::remember("inventory_{$sku}", 300, function () use ($sku) {
            // Your inventory check logic
            return ['sku' => $sku, 'quantity' => rand(0, 100), 'status' => 'in_stock'];
        });
    }

    private function createTicket(array $input): array
    {
        $ticket = \App\Models\SupportTicket::create([
            'customer_id' => $input['customer_id'],
            'subject' => $input['subject'],
            'description' => $input['description'],
            'priority' => $input['priority'] ?? 'medium',
            'status' => 'open'
        ]);

        return ['ticket_id' => $ticket->id, 'status' => 'created'];
    }

    private function extractText(array $response): string
    {
        foreach ($response['content'] as $block) {
            if ($block['type'] === 'text') {
                return $block['text'];
            }
        }
        return '';
    }

    private function countToolUses(array $messages): int
    {
        $count = 0;
        foreach ($messages as $msg) {
            if (is_array($msg['content'] ?? null)) {
                foreach ($msg['content'] as $block) {
                    if (($block['type'] ?? '') === 'tool_use') {
                        $count++;
                    }
                }
            }
        }
        return $count;
    }
}



namespace App\Services\Agents;

use ClaudePhp\ClaudePhp;
use Illuminate\Support\Facades\Log;

class AgentFramework
{
    private array $state = [];
    private array $agents = [];

    public function __construct(
        private ClaudePhp $claude
    ) {}

    public function registerAgent(string $name, array $tools, string $systemPrompt): self
    {
        $this->agents[$name] = [
            'tools' => $tools,
            'system' => $systemPrompt
        ];
        return $this;
    }

    public function execute(string $goal): array
    {
        Log::info("Agent Framework: Starting goal", ['goal' => $goal]);

        // Step 1: Decompose the goal into subtasks
        $subtasks = $this->decompose($goal);

        // Step 2: Execute each subtask
        $results = [];
        foreach ($subtasks as $i => $subtask) {
            Log::info("Executing subtask", ['index' => $i, 'task' => $subtask['task']]);

            $agentName = $subtask['agent'] ?? 'default';
            $result = $this->runAgent($agentName, $subtask['task']);

            $results[] = $result;
            $this->state["subtask_{$i}"] = $result;
        }

        // Step 3: Synthesize final result
        $finalResult = $this->synthesize($goal, $results);

        return [
            'goal' => $goal,
            'subtasks' => $subtasks,
            'results' => $results,
            'final_result' => $finalResult,
            'state' => $this->state
        ];
    }

    private function decompose(string $goal): array
    {
        $response = $this->claude->messages()->create([
            'model' => 'claude-sonnet-4-5-20250929',
            'max_tokens' => 2048,
            'thinking' => ['type' => 'enabled', 'budget_tokens' => 3000],
            'messages' => [[
                'role' => 'user',
                'content' => "Break this goal into 2-4 concrete subtasks. Format as numbered list.\n\nGoal: {$goal}"
            ]]
        ]);

        return $this->parseSubtasks($this->extractText($response));
    }

    private function runAgent(string $agentName, string $task): string
    {
        $agent = $this->agents[$agentName] ?? $this->agents['default'] ?? null;

        if (!$agent) {
            return "No agent available for: {$agentName}";
        }

        $messages = [['role' => 'user', 'content' => $task]];
        $iteration = 0;

        while ($iteration < 10) {
            $iteration++;

            $params = [
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => 4096,
                'system' => $agent['system'],
                'messages' => $messages,
            ];

            if (!empty($agent['tools'])) {
                $params['tools'] = $agent['tools'];
            }

            $response = $this->claude->messages()->create($params);
            $messages[] = ['role' => 'assistant', 'content' => $response['content']];

            // COMPLETE: Task finished
            if ($response['stop_reason'] === 'end_turn') {
                return $this->extractText($response);
            }

            // ACT & OBSERVE: Execute tools and continue loop
            if ($response['stop_reason'] === 'tool_use') {
                $results = $this->executeTools($response['content']);
                $messages[] = ['role' => 'user', 'content' => $results];
                continue;
            }

            // Unexpected stop reason
            break;
        }

        return 'Agent reached iteration limit.';
    }

    private function synthesize(string $goal, array $results): string
    {
        $resultsText = collect($results)
            ->map(fn($r, $i) => ($i + 1) . ". {$r}")
            ->implode("\n\n");

        $response = $this->claude->messages()->create([
            'model' => 'claude-sonnet-4-5-20250929',
            'max_tokens' => 2048,
            'messages' => [[
                'role' => 'user',
                'content' => "Original goal: {$goal}\n\nSubtask results:\n{$resultsText}\n\nProvide a synthesized final answer."
            ]]
        ]);

        return $this->extractText($response);
    }

    private function executeTools(array $content): array
    {
        $results = [];
        foreach ($content as $block) {
            if ($block['type'] === 'tool_use') {
                // Implement your tool execution logic
                $results[] = [
                    'type' => 'tool_result',
                    'tool_use_id' => $block['id'],
                    'content' => json_encode(['status' => 'executed'])
                ];
            }
        }
        return $results;
    }

    private function parseSubtasks(string $text): array
    {
        $subtasks = [];
        foreach (explode("\n", $text) as $line) {
            if (preg_match('/^\d+\.\s+(.+)$/', trim($line), $matches)) {
                $subtasks[] = ['task' => $matches[1], 'agent' => 'default'];
            }
        }
        return $subtasks ?: [['task' => $text, 'agent' => 'default']];
    }

    private function extractText(array $response): string
    {
        foreach ($response['content'] as $block) {
            if ($block['type'] === 'text') {
                return $block['text'];
            }
        }
        return '';
    }

    public function getState(): array
    {
        return $this->state;
    }
}

use App\Services\Agents\AgentFramework;

class ResearchController extends Controller
{
    public function analyze(Request $request, AgentFramework $framework)
    {
        // Register specialized agents
        $framework
            ->registerAgent('default', [], 'You are a helpful research assistant.')
            ->registerAgent('calculator', [
                [
                    'name' => 'calculate',
                    'description' => 'Perform calculations',
                    'input_schema' => [
                        'type' => 'object',
                        'properties' => [
                            'expression' => ['type' => 'string']
                        ],
                        '

use ClaudePhp\Laravel\Facades\Claude;
use Symfony\Component\HttpFoundation\StreamedResponse;

public function streamAgent(Request $request): StreamedResponse
{
    return response()->stream(function () use ($request) {
        $task = $request->input('task');
        $messages = [['role' => 'user', 'content' => $task]];
        $tools = $this->getTools();

        for ($i = 0; $i < 10; $i++) {
            // Stream: Send iteration marker
            echo "data: " . json_encode(['type' => 'iteration', 'number' => $i + 1]) . "\n\n";
            ob_flush(); flush();

            $stream = Claude::messages()->stream([
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => 4096,
                'messages' => $messages,
                'tools' => $tools
            ]);

            $fullContent = [];
            $stopReason = null;

            foreach ($stream as $event) {
                $type = $event['type'] ?? '';

                if ($type === 'content_block_delta' && isset($event['delta']['text'])) {
                    // Stream text to client
                    echo "data: " . json_encode([
                        'type' => 'text',
                        'content' => $event['delta']['text']
                    ]) . "\n\n";
                    ob_flush(); flush();
                }

                if ($type === 'message_delta') {
                    $stopReason = $event['delta']['stop_reason'] ?? null;
                }

                if ($type === 'content_block_start' || $type === 'content_block_delta') {
                    // Accumulate for history
                    // ... accumulation logic
                }
            }

            if ($stopReason === 'end_turn') {
                echo "data: " . json_encode(['type' => 'complete']) . "\n\n";
                break;
            }

            if ($stopReason === 'tool_use') {
                echo "data: " . json_encode(['type' => 'tool_execution']) . "\n\n";
                ob_flush(); flush();

                // Execute tools and continue loop
                // ... tool execution logic
            }
        }

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

use ClaudePhp\Laravel\Facades\Claude;

class ReasoningAgent
{
    public function solve(string $problem): array
    {
        $messages = [['role' => 'user', 'content' => $problem]];
        $thinkingHistory = [];
        $iteration = 0;

        while ($iteration < 5) {
            $iteration++;

            $response = Claude::messages()->create([
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => 16000,
                'thinking' => [
                    'type' => 'enabled',
                    'budget_tokens' => 8000
                ],
                'messages' => $messages,
                'tools' => $this->getTools()
            ]);

            // Capture thinking for analysis
            foreach ($response['content'] as $block) {
                if ($block['type'] === 'thinking') {
                    $thinkingHistory[] = [
                        'iteration' => $iteration,
                        'thinking' => $block['thinking']
                    ];
                }
            }

            $messages[] = ['role' => 'assistant', 'content' => $response['content']];

            // COMPLETE: Problem solved
            if ($response['stop_reason'] === 'end_turn') {
                return [
                    'answer' => $this->extractText($response),
                    'thinking_steps' => count($thinkingHistory),
                    'thinking_history' => $thinkingHistory,
                    'iterations' => $iteration
                ];
            }

            // ACT & OBSERVE: Execute tools and continue reasoning
            if ($response['stop_reason'] === 'tool_use') {
                $results = $this->executeTools($response['content']);
                $messages[] = ['role' => 'user', 'content' => $results];
                continue;
            }

            // Unexpected stop reason
            break;
        }

        return ['answer' => 'Could not solve within iteration limit.'];
    }

    // ... helper methods
}



namespace App\Jobs;

use ClaudePhp\ClaudePhp;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class ProcessWithClaude implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        private string $content,
        private int $userId
    ) {}

    public function handle(ClaudePhp $claude): void
    {
        $response = $claude->messages()->create([
            'model' => 'claude-sonnet-4-5-20250929',
            'max_tokens' => 2048,
            'messages' => [
                ['role' => 'user', 'content' => $this->content]
            ]
        ]);

        // Store result...
        \App\Models\AiResponse::create([
            'user_id' => $this->userId,
            'response' => $response['content'][0]['text']
        ]);
    }
}



namespace App\Console\Commands;

use ClaudePhp\ClaudePhp;
use Illuminate\Console\Command;

class AskClaude extends Command
{
    protected $signature = 'claude:ask {question}';
    protected $description = 'Ask Claude a question';

    public function handle(ClaudePhp $claude): int
    {
        $question = $this->argument('question');

        $this->info("Asking Claude: {$question}");
        $this->newLine();

        $response = $claude->messages()->create([
            'model' => 'claude-sonnet-4-5-20250929',
            'max_tokens' => 2048,
            'messages' => [
                ['role' => 'user', 'content' => $question]
            ]
        ]);

        $this->line($response['content'][0]['text']);

        return Command::SUCCESS;
    }
}



namespace App\Services;

use ClaudePhp\ClaudePhp;
use Illuminate\Support\Facades\Cache;

class AiService
{
    public function __construct(
        private ClaudePhp $claude
    ) {}

    public function summarize(string $text, int $maxLength = 200): string
    {
        $cacheKey = 'summary_' . md5($text);

        return Cache::remember($cacheKey, 3600, function () use ($text, $maxLength) {
            $response = $this->claude->messages()->create([
                'model' => 'claude-sonnet-4-5-20250929',
                'max_tokens' => $maxLength,
                'system' => 'You are a summarization expert. Provide concise summaries.',
                'messages' => [
                    ['role' => 'user', 'content' => "Summarize this: {$text}"]
                ]
            ]);

            return $response['content'][0]['text'];
        });
    }

    public function translate(string $text, string $targetLanguage): string
    {
        $response = $this->claude->messages()->create([
            'model' => 'claude-sonnet-4-5-20250929',
            'max_tokens' => 2048,
            'messages' => [
                ['role' => 'user', 'content' => "Translate to {$targetLanguage}: {$text}"]
            ]
        ]);

        return $response['content'][0]['text'];
    }
}

use ClaudePhp\Laravel\Facades\Claude;

public function test_chat_endpoint(): void
{
    Claude::shouldReceive('messages->create')
        ->once()
        ->andReturn([
            'id' => 'msg_123',
            'type' => 'message',
            'role' => 'assistant',
            'content' => [
                ['type' => 'text', 'text' => 'Mocked response']
            ],
            'model' => 'claude-sonnet-4-5-20250929',
            'stop_reason' => 'end_turn',
            'usage' => [
                'input_tokens' => 10,
                'output_tokens' => 5
            ]
        ]);

    $response = $this->postJson('/api/chat', [
        'message' => 'Hello'
    ]);

    $response->assertOk()
        ->assertJsonPath('response', 'Mocked response');
}

use ClaudePhp\ClaudePhp;
use Mockery;

public function test_with_dependency_injection(): void
{
    $mockClaude = Mockery::mock(ClaudePhp::class);
    $mockMessages = Mockery::mock();

    $mockClaude->shouldReceive('messages')->andReturn($mockMessages);
    $mockMessages->shouldReceive('create')->andReturn([
        'content' => [['type' => 'text', 'text' => 'Test response']]
    ]);

    $this->app->instance(ClaudePhp::class, $mockClaude);

    // Your test...
}

use ClaudePhp\Laravel\Facades\Claude;
use ClaudePhp\Exceptions\AuthenticationException;
use ClaudePhp\Exceptions\RateLimitException;
use ClaudePhp\Exceptions\ApiException;
use ClaudePhp\Exceptions\InvalidRequestException;
use Illuminate\Support\Facades\Log;

try {
    $response = Claude::messages()->create([
        'model' => 'claude-sonnet-4-5-20250929',
        'max_tokens' => 1024,
        'messages' => [
            ['role' => 'user', 'content' => 'Hello!']
        ]
    ]);
} catch (AuthenticationException $e) {
    // Invalid API key
    Log::error('Claude authentication failed', ['error' => $e->getMessage()]);
    abort(500, 'AI service configuration error');

} catch (RateLimitException $e) {
    // Rate limited - implement retry logic
    $retryAfter = $e->retryAfter ?? 60;
    Log::warning('Claude rate limited', ['retry_after' => $retryAfter]);

    // Optionally dispatch to queue for later
    ProcessWithClaude::dispatch($content)->delay(now()->addSeconds($retryAfter));

} catch (InvalidRequestException $e) {
    // Bad request parameters
    Log::error('Invalid Claude request', ['error' => $e->getMessage()]);
    abort(400, 'Invalid request');

} catch (ApiException $e) {
    // General API error
    Log::error('Claude API error', [
        'message' => $e->getMessage(),
        'code' => $e->getCode()
    ]);
    abort(503, 'AI service temporarily unavailable');
}
bash
composer 
bash
php artisan vendor:publish --tag=claude-config