100 lines
2.4 KiB
PHP
100 lines
2.4 KiB
PHP
<?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;
|
|
}
|
|
}
|