Harden vision vector search and embedding jobs.

Add point search, circuit-breaking, and safer gateway limits so artwork similarity lookups fail closed instead of hanging the request path.
This commit is contained in:
2026-09-20 14:49:19 +02:00
parent 04b8160d9e
commit 1053a38eee
12 changed files with 903 additions and 64 deletions
@@ -56,6 +56,7 @@ function fakeSuccessfulUrlSearch(Artwork $source, Artwork $match): array
{
return [
'https://files.skinbase.org/*' => Http::response('image-bytes', 200, ['Content-Type' => 'image/webp']),
'https://vision.klevze.net/vectors/search/point' => Http::response(['detail' => 'Point not found'], 404),
'https://vision.klevze.net/vectors/search' => Http::response([
'results' => [
['id' => $source->id, 'score' => 1.0],
@@ -70,6 +71,7 @@ it('does not call URL search when file search succeeds and leaves the circuit cl
Http::fake([
'https://files.skinbase.org/*' => Http::response('image-bytes', 200, ['Content-Type' => 'image/webp']),
'https://vision.klevze.net/vectors/search/point' => Http::response(['detail' => 'Point not found'], 404),
'https://vision.klevze.net/vectors/search/file' => Http::response([
'results' => [
['id' => $source->id, 'score' => 1.0],
@@ -143,6 +145,7 @@ it('opens the circuit when both search strategies fail transiently', function ()
Http::fake([
'https://files.skinbase.org/*' => Http::response('image-bytes', 200, ['Content-Type' => 'image/webp']),
'https://vision.klevze.net/vectors/search/point' => Http::response(['detail' => 'Point not found'], 404),
'https://vision.klevze.net/vectors/search/file' => Http::response(['error' => 'down'], 503),
'https://vision.klevze.net/vectors/search' => Http::response(['error' => 'down'], 503),
]);
@@ -353,6 +356,7 @@ it('serves similar-ai from cache without contacting the gateway', function (): v
Http::fake([
'https://files.skinbase.org/*' => Http::response('image-bytes', 200, ['Content-Type' => 'image/webp']),
'https://vision.klevze.net/vectors/search/point' => Http::response(['detail' => 'Point not found'], 404),
'https://vision.klevze.net/vectors/search/file' => Http::response([
'results' => [
['id' => $source->id, 'score' => 1.0],