From 163c2fbf21689273ea2410ee9bc58cfcc83b0e75 Mon Sep 17 00:00:00 2001 From: Flatts Date: Thu, 2 Oct 2025 18:06:58 -0400 Subject: [PATCH] feat: add generate_query_embedding method to EmbeddingService Introduced a method for generating and normalizing query embeddings without database writes. Included fallback logic for API key handling, customizable embedding models, and improved error logging for robust operation. --- .../postsecret-ai/src/EmbeddingService.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/wp-content/plugins/postsecret-ai/src/EmbeddingService.php b/wp-content/plugins/postsecret-ai/src/EmbeddingService.php index aed3e7c..b049c89 100644 --- a/wp-content/plugins/postsecret-ai/src/EmbeddingService.php +++ b/wp-content/plugins/postsecret-ai/src/EmbeddingService.php @@ -110,6 +110,38 @@ public static function find_similar(int $secret_id, int $limit = 10, float $min_ return self::find_similar_mysql($secret_id, $limit, $min_score); } + /** + * Generate an embedding for an arbitrary query string (no DB write). + * + * @param string $query Free-text query to embed. + * @param string $api_key OpenAI API key. If empty, falls back to Settings::API_KEY. + * @param string $model Embedding model (default: text-embedding-3-small). + * @return array|null L2-normalized vector or null on failure. + */ + public static function generate_query_embedding(string $query, string $api_key = '', string $model = 'text-embedding-3-small'): ?array + { + $query = trim($query); + if ($query === '') { + return null; + } + + // Allow caller to omit the key; pull from Settings if needed. + if ($api_key === '') { + $api_key = (string)self::opt('API_KEY', ''); + if ($api_key === '') { + error_log('[EmbeddingService] No API key available for generate_query_embedding().'); + return null; + } + } + + $vec = self::generate_embedding($api_key, $model, $query); + if ($vec === null) { + return null; + } + + return self::normalize_vector($vec); + } + // ───────────────────────────────────────────────────────────────────────────── // OpenAI // ─────────────────────────────────────────────────────────────────────────────