1. Go to this page and download the library: Download bherila/genai-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/ */
bherila / genai-laravel example snippets
use Bherila\GenAiLaravel\GenAiRequest;
use Bherila\GenAiLaravel\Clients\GenAiClientFactory;
$client = GenAiClientFactory::make('anthropic'); // or 'bedrock', 'gemini'
$response = GenAiRequest::with($client)
->system('You are a financial analyst.')
->withFile(base64_encode(file_get_contents($path)), 'application/pdf')
->prompt('Extract key figures.')
->generate();
echo $response->text;
// or
foreach ($response->toolCalls as $call) {
// ['name' => 'extract_data', 'input' => [...]]
}
// Different tenants, different providers — call site is identical
$client = match ($user->ai_provider) {
'anthropic' => new AnthropicClient(apiKey: $user->anthropic_key, model: 'claude-sonnet-4-6'),
'bedrock' => new BedrockClient(apiKey: $creds->key, modelId: $creds->model, region: 'us-east-1'),
default => new GeminiClient(apiKey: $user->gemini_key),
};
$response = GenAiRequest::with($client)
->system($systemPrompt)
->withFiles($files) // [['base64' => '...', 'mimeType' => 'application/pdf'], ...]
->prompt($userPrompt)
->tools($toolConfig)
->generate();
use Bherila\GenAiLaravel\Schema;
use Bherila\GenAiLaravel\ToolChoice;
use Bherila\GenAiLaravel\ToolConfig;
use Bherila\GenAiLaravel\ToolDefinition;
$toolConfig = new ToolConfig(
tools: [
new ToolDefinition(
name: 'extract_invoice',
description: 'Extract invoice fields',
inputSchema: Schema::object([
'vendor' => Schema::string('Vendor name'),
'amount' => Schema::number('Total amount due'),
'due_date' => Schema::string('Due date in YYYY-MM-DD'),
],
$messages = [['role' => 'user', 'content' => [ContentBlock::text($prompt)]]];
// Note the parameter: an arrow function captures by value at definition, so a
// closure over $messages would resend the first turn forever.
$ask = static fn (array $history) => GenAiRequest::with($client)
->messages($history)
->tools($toolConfig)
->generate();
$response = $ask($messages);
while ($response->hasToolCalls()) {
$messages[] = $response->assistantMessage();
$results = [];
foreach ($response->toolCalls as $call) {
$results[] = ContentBlock::toolResultFor($call, $myTools->run($call['name'], $call['input']));
}
$messages[] = ['role' => 'user', 'content' => $results];
$response = $ask($messages);
}
echo $response->text;
ToolChoice::auto() // model decides whether to call a tool
ToolChoice::any() // model must call at least one tool
ToolChoice::none() // model must not call any tool
ToolChoice::tool('my_fn') // model must call this specific tool
use Bherila\GenAiLaravel\Contracts\GenAiClient;
class MyService
{
public function __construct(private readonly GenAiClient $ai) {}
public function analyse(string $text): string
{
return GenAiRequest::with($this->ai)
->prompt($text)
->generate()
->text;
}
}
use Bherila\GenAiLaravel\Facades\GenAi;
$raw = GenAi::converse($system, $messages, $toolConfig); // $system is a string
$text = GenAi::extractText($raw);
$usage = GenAi::extractUsage($raw);
use Bherila\GenAiLaravel\Clients\GenAiClientFactory;
use Bherila\GenAiLaravel\Credentials\AnthropicCredentials;
use Bherila\GenAiLaravel\Credentials\BedrockCredentials;
use Bherila\GenAiLaravel\Credentials\GeminiCredentials;
$client = GenAiClientFactory::make(
credentials: new GeminiCredentials(apiKey: $user->gemini_key),
);
// Region and model travel with the credentials where they need to:
$client = GenAiClientFactory::make(
credentials: new BedrockCredentials(
apiKey: $tenant->bedrock_token,
region: $tenant->aws_region,
model: $tenant->bedrock_model,
),
);
$client = GenAiClientFactory::make(
credentials: new AnthropicCredentials(apiKey: $tenant->anthropic_key),
);
$response = GenAiRequest::with($client)->prompt('...')->generate();
$response->usage->inputTokens; // non-cached prompt tokens
$response->usage->outputTokens; // completion tokens
$response->usage->totalTokens;
$response->usage->cacheReadInputTokens; // served from prompt cache
$response->usage->cacheCreationInputTokens; // written to prompt cache
$response->usage->raw; // provider-specific payload
// Estimate cost in USD given per-million-token prices for the model you used.
$cost = $response->usage->estimatedCostUsd(
inputPerMillion: 3.00,
outputPerMillion: 15.00,
cacheReadPerMillion: 0.30,
cacheCreationPerMillion: 3.75,
);
use Bherila\GenAiLaravel\Http\RetryStrategy;
new AnthropicClient(
apiKey: '...',
retry: new RetryStrategy(maxAttempts: 1), // disable retries
);
$client = GenAiClientFactory::make('anthropic'); // or 'bedrock', 'gemini'
foreach ($client->listModels() as $model) {
$model->id; // call-ready identifier
$model->name; // human-readable display name
$model->provider; // "anthropic" | "bedrock" | "gemini"
$model->description; // free-form, when provided
$model->inputTokenLimit; // context window, when advertised
$model->outputTokenLimit; // max completion tokens, when advertised
$model->inputCostPerMillionTokens; // null — no provider returns pricing
$model->outputCostPerMillionTokens; // null — no provider returns pricing
$model->raw; // provider-specific entry
}
$client::maxInlineFileBytes('application/pdf'); // decoded bytes for one inline block
$client::maxUploadedFileBytes(); // decoded bytes via the File API, null when there is none
$client::maxInlineBlocksPerMessage($mime); // blocks of that kind per message, null when uncapped
$client::maxRequestBytes(); // whole serialized request, null when uncapped
$client::supportsFileApi(); // whether uploadFile() will work at all
use Bherila\GenAiLaravel\Clients\AnthropicClient;
use Bherila\GenAiLaravel\FileConversion\ConversionLimits;
use Bherila\GenAiLaravel\FileConversion\SpreadsheetToText;
$limits = new ConversionLimits(maxInputBytes: 8 * 1024 * 1024, maxSeconds: 15.0);
// One conversion.
SpreadsheetToText::convert($base64, $mime, $limits);
// Every conversion this client runs on your behalf.
$client = new AnthropicClient(apiKey: $key, conversionLimits: $limits);
use Bherila\GenAiLaravel\GenAiRequest;
use Bherila\GenAiLaravel\Mcp\EnqueueOptions;
use Bherila\GenAiLaravel\Mcp\McpClientFactory;
use Bherila\GenAiLaravel\Mcp\StoredAttachment;
$client = app(McpClientFactory::class)->forMailbox($mailbox);
$pending = GenAiRequest::with($client)
->system('You are a financial analyst.')
->withStoredAttachment(new StoredAttachment(
name: 'report.pdf',
mimeType: 'application/pdf',
size: $document->size,
sha256: $document->sha256,
hostReference: "document:{$document->id}",
))
->prompt('Extract the key figures.')
->tools($toolConfig)
->enqueue(new EnqueueOptions(
queue: 'documents',
idempotencyKey: "report:{$report->id}",
priority: 10,
));
$pending->id;
$pending->status();
$pending->response(); // null until completed, then a normal GenAiResponse
use Illuminate\Support\Facades\Schedule;
Schedule::command('genai:mcp:deliver')->everyMinute()->withoutOverlapping();
Schedule::command('genai:mcp:prune')->daily();