Upload beautify

This commit is contained in:
2026-02-14 15:14:12 +01:00
parent e129618910
commit 79192345e3
249 changed files with 24436 additions and 1021 deletions

View File

@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace App\Services\Vision;
use Illuminate\Support\Facades\Http;
final class ArtworkEmbeddingClient
{
/**
* @return array<int, float>
*/
public function embed(string $imageUrl, int $artworkId, string $sourceHash): array
{
$base = trim((string) config('vision.clip.base_url', ''));
if ($base === '') {
return [];
}
$endpoint = (string) config('recommendations.embedding.endpoint', '/embed');
$url = rtrim($base, '/') . '/' . ltrim($endpoint, '/');
$timeout = (int) config('recommendations.embedding.timeout_seconds', 8);
$connectTimeout = (int) config('recommendations.embedding.connect_timeout_seconds', 2);
$retries = (int) config('recommendations.embedding.retries', 1);
$delay = (int) config('recommendations.embedding.retry_delay_ms', 200);
$response = Http::acceptJson()
->connectTimeout(max(1, $connectTimeout))
->timeout(max(1, $timeout))
->retry(max(0, $retries), max(0, $delay), throw: false)
->post($url, [
'image_url' => $imageUrl,
'artwork_id' => $artworkId,
'hash' => $sourceHash,
]);
if (! $response->ok()) {
return [];
}
return $this->extractEmbedding($response->json());
}
/**
* @param mixed $json
* @return array<int, float>
*/
private function extractEmbedding(mixed $json): array
{
$candidate = null;
if (is_array($json) && $this->isNumericVector($json)) {
$candidate = $json;
} elseif (is_array($json) && isset($json['embedding']) && is_array($json['embedding'])) {
$candidate = $json['embedding'];
} elseif (is_array($json) && isset($json['data']['embedding']) && is_array($json['data']['embedding'])) {
$candidate = $json['data']['embedding'];
}
if (! is_array($candidate) || ! $this->isNumericVector($candidate)) {
return [];
}
$vector = array_map(static fn ($value): float => (float) $value, $candidate);
$dim = count($vector);
$minDim = (int) config('recommendations.embedding.min_dim', 64);
$maxDim = (int) config('recommendations.embedding.max_dim', 4096);
if ($dim < $minDim || $dim > $maxDim) {
return [];
}
return $vector;
}
/**
* @param array<mixed> $arr
*/
private function isNumericVector(array $arr): bool
{
if ($arr === []) {
return false;
}
foreach ($arr as $value) {
if (! is_numeric($value)) {
return false;
}
}
return true;
}
}