Class: Prescient::Provider::HuggingFace
- Includes:
- HTTParty
- Defined in:
- lib/prescient/provider/huggingface.rb
Overview
Hugging Face router-backed Inference Providers API adapter.
Constant Summary collapse
- FEATURE_EXTRACTION_PATH =
Router path for the Hugging Face feature-extraction provider.
'/hf-inference/models/%<model>s/pipeline/feature-extraction'- CHAT_COMPLETIONS_PATH =
OpenAI-compatible router path for Hugging Face chat completions.
'/v1/chat/completions'- MODEL_LIST_PATH =
OpenAI-compatible router path for listing available chat models.
'/v1/models'- EMBEDDING_DIMENSIONS =
Known embedding dimensions for commonly used models.
{ 'sentence-transformers/all-MiniLM-L6-v2' => 384, 'sentence-transformers/all-mpnet-base-v2' => 768, 'sentence-transformers/all-roberta-large-v1' => 1024, }.freeze
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#generate_embedding(text, **options) ⇒ Array<Float>
Generate an embedding through Hugging Face feature extraction.
-
#generate_response(prompt, context_items = [], **options) ⇒ Hash
Generate text through a Hugging Face text-generation model.
-
#health_check ⇒ Hash
Check availability of the configured embedding and text models.
-
#initialize(**options) ⇒ HuggingFace
constructor
A new instance of HuggingFace.
-
#list_models ⇒ Array<Hash>
Return the configured Hugging Face models.
- #validate_configuration! ⇒ Object protected
Methods inherited from Base
#available?, #build_prompt, #clean_text, #default_context_configs, #default_prompt_templates, #extract_embedding_text, #extract_text_values, #format_context_item, #handle_errors, #validate_embedding_dimensions
Constructor Details
#initialize(**options) ⇒ HuggingFace
Returns a new instance of HuggingFace.
30 31 32 33 34 |
# File 'lib/prescient/provider/huggingface.rb', line 30 def initialize(**) super @provider_name = 'Hugging Face' self.class.default_timeout(@options[:timeout] || 60) end |
Instance Method Details
#generate_embedding(text, **options) ⇒ Array<Float>
Generate an embedding through Hugging Face feature extraction.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/prescient/provider/huggingface.rb', line 39 def (text, **) handle_errors do clean_text_input = clean_text(text) = [:model] || @options[:embedding_model] response = self.class.post(FEATURE_EXTRACTION_PATH % { model: }, headers: { 'Content-Type' => 'application/json', 'Authorization' => "Bearer #{@options[:api_key]}", }, body: { inputs: clean_text_input }.to_json) validate_response!(response, 'embedding generation') # HuggingFace returns embeddings as nested arrays, get the first one = response.parsed_response = .first if .is_a?(Array) && .first.is_a?(Array) raise Prescient::InvalidResponseError, 'No embedding returned' unless .is_a?(Array) expected_dimensions = EMBEDDING_DIMENSIONS[] || @options[:embedding_dimensions] unless expected_dimensions raise Prescient::Error, "Embedding dimensions are required for model #{}" end (, expected_dimensions) end end |
#generate_response(prompt, context_items = [], **options) ⇒ Hash
Generate text through a Hugging Face text-generation model.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/prescient/provider/huggingface.rb', line 73 def generate_response(prompt, context_items = [], **) handle_errors do formatted_prompt = build_prompt(prompt, context_items) response = self.class.post(CHAT_COMPLETIONS_PATH, headers: { 'Content-Type' => 'application/json', 'Authorization' => "Bearer #{@options[:api_key]}", }, body: { model: [:model] || @options[:chat_model], messages: [{ role: 'user', content: formatted_prompt }], max_tokens: [:max_tokens] || 2000, temperature: [:temperature] || 0.7, top_p: [:top_p] || 0.9, }.to_json) validate_response!(response, 'text generation') parsed_response = response.parsed_response generated_text = parsed_response.dig('choices', 0, 'message', 'content') if parsed_response.is_a?(Hash) raise Prescient::InvalidResponseError, 'No response generated' unless generated_text { response: generated_text.strip, model: [:model] || @options[:chat_model], provider: 'huggingface', processing_time: nil, metadata: { usage: parsed_response['usage'], finish_reason: parsed_response.dig('choices', 0, 'finish_reason'), }, } end end |
#health_check ⇒ Hash
Check availability of the configured embedding and text models.
The embedding model is checked against the model metadata API on
huggingface.co, while the chat model is checked against the router's
OpenAI-compatible /v1/models listing. ready requires both checks to
succeed.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/prescient/provider/huggingface.rb', line 117 def health_check handle_errors do = self.class.get("https://huggingface.co/api/models/#{@options[:embedding_model]}", headers: { 'Authorization' => "Bearer #{@options[:api_key]}" }) chat_response = self.class.get(MODEL_LIST_PATH, headers: { 'Authorization' => "Bearer #{@options[:api_key]}" }) = .success? chat_models = chat_response.parsed_response['data'] || [] chat_healthy = chat_response.success? && chat_models.any? { |model| model['id'] == @options[:chat_model] } { status: && chat_healthy ? 'healthy' : 'partial', provider: 'huggingface', reachable: true, embedding_model: { name: @options[:embedding_model], available: , }, chat_model: { name: @options[:chat_model], available: chat_healthy, }, ready: && chat_healthy, } end rescue Prescient::Error => e { status: 'unavailable', provider: 'huggingface', reachable: false, error: e.class.name, message: e., ready: false, } end |
#list_models ⇒ Array<Hash>
Return the configured Hugging Face models.
This method does not query the Hugging Face APIs. It reflects the current adapter configuration only.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/prescient/provider/huggingface.rb', line 160 def list_models # HuggingFace doesn't provide a simple API to list all models # Return the configured models [ { name: @options[:embedding_model], type: 'embedding', dimensions: EMBEDDING_DIMENSIONS[@options[:embedding_model]], }, { name: @options[:chat_model], type: 'text-generation', }, ] end |
#validate_configuration! ⇒ Object (protected)
178 179 180 181 182 183 |
# File 'lib/prescient/provider/huggingface.rb', line 178 def validate_configuration! = [:api_key, :embedding_model, :chat_model].select { |opt| @options[opt].nil? } return unless .any? raise Prescient::Error, "Missing required options: #{.join(', ')}" end |