1
0
cms11/app/Services/AI/AIHandler.php

100 lines
2.4 KiB
PHP
Raw Normal View History

2024-05-16 22:20:21 +02:00
<?php
namespace App\Services\AI;
use App\Services\AI\Contracts\ProvidesAIServices;
use Exception;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
class AIHandler
{
const string SERVICE_DESCRIBE_IMAGE = 'describeImage';
const string SERVICE_SUMMARIZE_CONTENT = 'summarizeContent';
protected $providers = [];
protected $data = [];
protected $context = [];
protected $method;
/**
* Select one or multiple providers and models to send requests
*/
public function providers(string|array|ProvidesAIServices $providers)
{
if (is_string($providers)) {
$providers = [static::make($providers)];
} elseif ($providers instanceof ProvidesAIServices) {
$providers = [$providers];
}
$this->providers = $providers;
return $this;
}
/**
* Instanciate a class for specified provider
*/
public static function make(string $providerName): ProvidesAIServices
{
$providerClass = config(sprintf('ai.providers.%s.handler', $providerName));
if (empty($providerClass)) {
throw new Exception(sprintf('Unknown AI provider: %s', $providerName));
}
return new $providerClass(config(sprintf('ai.providers.%s', $providerName)));
}
/**
* Perform the request. If many providers were selected, and if
* $concurrent is false, requests are sent sequentially. Otherwise, all
* providers will be queried at once. Beware of performances!
*/
public function run($concurrent = false)
{
if ($concurrent) {
$responses = $this->runConcurrently();
} else {
$responses = $this->runSequentially();
}
return Arr::undot(
array_map(
fn ($response) => $response->json(),
$responses
)
);
}
/**
* Run requests concurrently
*/
protected function runConcurrently()
{
return Http::pool(fn ($pool) => array_map(
fn ($provider) => $provider->prepareRequest($pool),
$this->providers
));
}
/**
* Run requests sequentially
*/
protected function runSequentially()
{
$responses = [];
foreach ($this->providers as $provider) {
$responses = $provider->sendRequest();
}
return $responses;
}
}