settings_resolver = $settings_resolver; } /** * {@inheritDoc} */ public function id(): string { return self::ID; } /** * {@inheritDoc} */ public function is_available(): bool { return '' !== $this->endpoint->base_url(); } /** * {@inheritDoc} */ public function dimensions(): int { $cached = get_option( 'agyl_local_embed_dims' ); return is_array( $cached ) && ( $cached['model'] ?? '' ) === $this->model_id() ? (int) ( $cached['dims'] ?? 0 ) : 0; } /** * {@inheritDoc} */ public function is_multilingual(): bool { return true; // Owner-chosen model; multilingual embeddings are the recommended default. } /** * {@inheritDoc} */ public function embed( array $texts ): array { $base = $this->endpoint->base_url(); if ( '' === $base || ! $texts ) { return array(); } $headers = array(); $sealed = (string) ( $this->settings()['local_api_key'] ?? '' ); $key = '' === $sealed ? '' : (string) ( $this->vault->open( $sealed ) ?? '' ); if ( '' !== $key ) { $headers[] = 'Authorization: Bearer ' . $key; } $out = array(); foreach ( array_chunk( array_values( $texts ), self::MAX_BATCH ) as $batch ) { $body = array( 'input' => array_map( static fn ( $t ): string => mb_substr( (string) $t, 0, self::MAX_CHARS ), $batch ) ); if ( '' !== $this->model_id() ) { $body['model'] = $this->model_id(); } $http = $this->http->post_json( $base . '/v1/embeddings', $headers, $body, 60.0 ); if ( null !== $http['error'] || 200 !== (int) $http['status'] ) { return array(); } $decoded = json_decode( (string) $http['body'], true ); $rows = is_array( $decoded ) ? (array) ( $decoded['data'] ?? array() ) : array(); if ( count( $rows ) !== count( $batch ) ) { return array(); } usort( $rows, static fn ( array $a, array $b ): int => (int) ( $a['index'] ?? 0 ) <=> (int) ( $b['index'] ?? 0 ) ); foreach ( $rows as $row ) { $vector = $row['embedding'] ?? null; if ( ! is_array( $vector ) || ! $vector ) { return array(); } $out[] = array_map( 'floatval', $vector ); } } if ( 0 === $this->dimensions() ) { update_option( 'agyl_local_embed_dims', array( 'model' => $this->model_id(), 'dims' => count( $out[0] ), ), false ); } return $out; } /** * Configured embedding model id ('' = server default). */ private function model_id(): string { return trim( (string) ( $this->settings()['local_embedding_model'] ?? '' ) ); } /** * Current 'models' settings. * * @return array */ private function settings(): array { $settings = ( $this->settings_resolver )(); return is_array( $settings ) ? $settings : array(); } }