where('text_hash', $hash)->first(); if ($cached !== null) { return $cached->embedding; } $baseUrl = rtrim((string) config('services.ollama.base_url'), '/'); try { $response = Http::timeout((int) config('services.ollama.timeout', 30)) ->post($baseUrl.'/api/embeddings', [ 'model' => config('services.ollama.embed_model', 'nomic-embed-text'), 'prompt' => $text, ]) ->throw() ->json(); } catch (Throwable $e) { throw new OllamaUnavailableException('Ollama embedding endpoint is unavailable', 0, $e); } $embedding = $response['embedding'] ?? []; if (!is_array($embedding) || $embedding === []) { throw new OllamaUnavailableException('Ollama embedding response did not include a valid embedding'); } EmbeddingCache::query()->updateOrCreate( ['text_hash' => $hash], ['text' => $text, 'embedding' => $embedding] ); return $embedding; } }