Class: Parse::Embeddings::Jina
- Defined in:
- lib/parse/embeddings/jina.rb
Overview
Jina AI embeddings provider. Wraps ‘POST /v1/embeddings`.
Supported text-capable models:
-
**v5 text family** — ‘jina-embeddings-v5-text-small`, `jina-embeddings-v5-text-nano`.
-
**v5 omni family (text mode)** — ‘jina-embeddings-v5-omni-small`, `jina-embeddings-v5-omni-nano`. These models are multimodal at the network boundary but accept plain-text inputs through this provider just like the text-only variants.
-
v4 — ‘jina-embeddings-v4` (Matryoshka, multimodal; text inputs only here).
-
v3 — ‘jina-embeddings-v3` (Matryoshka, 32–1024).
-
**code embeddings** — ‘jina-code-embeddings-0.5b`, `jina-code-embeddings-1.5b`.
Rerankers (‘jina-reranker-*`), VLM (`jina-vlm`), image-only (`jina-clip-v2`), and `ReaderLM-v2` are NOT exposed through this provider — they don’t fit the ‘embed_text` contract. They’ll surface through forthcoming ‘embed_image` / rerank / generation hooks.
Asymmetric input types
Jina uses a ‘task` request field with the following canonical values (mapped from SDK-canonical `input_type:` Symbols):
-
‘:search_query` → `“retrieval.query”`
-
‘:search_document` → `“retrieval.passage”`
-
‘:classification` → `“classification”`
-
‘:clustering` → `“separation”`
The ‘Provider#supports_input_type?` flag returns `true` here so cache-keying middleware can branch on it. Code-embedding models accept the `task` field and use it to bias the head.
Matryoshka dimensions
‘jina-embeddings-v3`, `jina-embeddings-v4`, and the v5 family support Matryoshka-style output-width truncation via the `dimensions` request field. Pass `dimensions:` to the constructor to set the desired width (must be ≤ the model’s native width).
Defined Under Namespace
Classes: AuthenticationError, BadRequestError, RateLimitError, TransientError
Constant Summary collapse
- DEFAULT_BASE_URL =
"https://api.jina.ai/v1"- DEFAULT_MODEL =
"jina-embeddings-v3"- DEFAULT_TIMEOUT =
30- DEFAULT_OPEN_TIMEOUT =
5- DEFAULT_MAX_RETRIES =
3- DEFAULT_BATCH_SIZE =
100- MAX_RESPONSE_BYTES =
16 * 1024 * 1024
- MODEL_DEFAULT_DIMENSIONS =
Native vector widths. The Matryoshka-capable rows allow the caller to truncate via the ‘dimensions:` kwarg.
{ "jina-embeddings-v5-omni-small" => 1024, "jina-embeddings-v5-omni-nano" => 512, "jina-embeddings-v5-text-small" => 1024, "jina-embeddings-v5-text-nano" => 512, "jina-embeddings-v4" => 2048, "jina-embeddings-v3" => 1024, "jina-code-embeddings-1.5b" => 1024, "jina-code-embeddings-0.5b" => 1024, }.freeze
- MODEL_MAX_INPUT_TOKENS =
{ "jina-embeddings-v5-omni-small" => 32_000, "jina-embeddings-v5-omni-nano" => 32_000, "jina-embeddings-v5-text-small" => 32_000, "jina-embeddings-v5-text-nano" => 32_000, "jina-embeddings-v4" => 32_000, "jina-embeddings-v3" => 8_192, "jina-code-embeddings-1.5b" => 32_000, "jina-code-embeddings-0.5b" => 32_000, }.freeze
- MATRYOSHKA_MODELS =
Models that accept the Matryoshka ‘dimensions` field. Other rows must pass the native width or no override.
%w[ jina-embeddings-v5-omni-small jina-embeddings-v5-omni-nano jina-embeddings-v5-text-small jina-embeddings-v5-text-nano jina-embeddings-v4 jina-embeddings-v3 ].freeze
- INPUT_TYPE_WIRE_VALUES =
Map SDK-canonical input_type symbols to Jina ‘task` strings.
{ search_query: "retrieval.query", search_document: "retrieval.passage", classification: "classification", clustering: "separation", }.freeze
Constants inherited from Provider
Provider::AS_NOTIFICATION_NAME
Instance Method Summary collapse
- #dimensions ⇒ Object
- #embed_batch_size ⇒ Object
-
#embed_text(strings, input_type: :search_document) ⇒ Array<Array<Float>>
Vectors aligned 1:1 with ‘strings`.
-
#initialize(api_key:, model: DEFAULT_MODEL, dimensions: nil, base_url: DEFAULT_BASE_URL, timeout: DEFAULT_TIMEOUT, open_timeout: DEFAULT_OPEN_TIMEOUT, max_retries: DEFAULT_MAX_RETRIES, embed_batch_size: DEFAULT_BATCH_SIZE, allow_faraday_proxy: false, allow_insecure_base_url: false, connection: nil) ⇒ Jina
constructor
A new instance of Jina.
- #inspect_attrs ⇒ Object
- #max_input_tokens ⇒ Object
- #model_name ⇒ Object
- #normalize? ⇒ Boolean
- #supports_input_type? ⇒ Boolean
Methods inherited from Provider
#embed_image, #embed_text_batched, #inspect, #instrument_embed, #modalities, #validate_response!
Constructor Details
#initialize(api_key:, model: DEFAULT_MODEL, dimensions: nil, base_url: DEFAULT_BASE_URL, timeout: DEFAULT_TIMEOUT, open_timeout: DEFAULT_OPEN_TIMEOUT, max_retries: DEFAULT_MAX_RETRIES, embed_batch_size: DEFAULT_BATCH_SIZE, allow_faraday_proxy: false, allow_insecure_base_url: false, connection: nil) ⇒ Jina
Returns a new instance of Jina.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/parse/embeddings/jina.rb', line 132 def initialize( api_key:, model: DEFAULT_MODEL, dimensions: nil, base_url: DEFAULT_BASE_URL, timeout: DEFAULT_TIMEOUT, open_timeout: DEFAULT_OPEN_TIMEOUT, max_retries: DEFAULT_MAX_RETRIES, embed_batch_size: DEFAULT_BATCH_SIZE, allow_faraday_proxy: false, allow_insecure_base_url: false, connection: nil ) validate_api_key!(api_key) validate_model!(model) validate_dimensions!(model, dimensions) sanitized_base_url = validate_base_url!(base_url, allow_insecure_base_url) validate_positive_integer!(:timeout, timeout) validate_positive_integer!(:open_timeout, open_timeout) validate_non_negative_integer!(:max_retries, max_retries) validate_positive_integer!(:embed_batch_size, ) @api_key = api_key @model = model @dimensions = dimensions || MODEL_DEFAULT_DIMENSIONS.fetch(model) @base_url = sanitized_base_url @timeout = timeout @open_timeout = open_timeout @max_retries = max_retries @embed_batch_size = @allow_faraday_proxy = allow_faraday_proxy @connection = connection || build_connection end |
Instance Method Details
#dimensions ⇒ Object
166 167 168 |
# File 'lib/parse/embeddings/jina.rb', line 166 def dimensions @dimensions end |
#embed_batch_size ⇒ Object
174 175 176 |
# File 'lib/parse/embeddings/jina.rb', line 174 def @embed_batch_size end |
#embed_text(strings, input_type: :search_document) ⇒ Array<Array<Float>>
Returns vectors aligned 1:1 with ‘strings`.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/parse/embeddings/jina.rb', line 194 def (strings, input_type: :search_document) unless strings.is_a?(Array) raise ArgumentError, "Parse::Embeddings::Jina#embed_text expects Array<String> (got #{strings.class})." end return [] if strings.empty? strings.each_with_index do |s, i| unless s.is_a?(String) raise ArgumentError, "Parse::Embeddings::Jina#embed_text strings[#{i}] is not a String (#{s.class})." end if s.empty? raise ArgumentError, "Parse::Embeddings::Jina#embed_text strings[#{i}] is empty; Jina rejects empty inputs." end end unless INPUT_TYPE_WIRE_VALUES.key?(input_type) raise ArgumentError, "Parse::Embeddings::Jina#embed_text input_type #{input_type.inspect} not in " \ "#{INPUT_TYPE_WIRE_VALUES.keys.inspect}." end task_value = INPUT_TYPE_WIRE_VALUES[input_type] body = { model: @model, input: strings, task: task_value, embedding_type: "float", } # Forward `dimensions` only for Matryoshka-capable models whose # active width differs from native. Sending it to a non-Matryoshka # model would yield a 400 from Jina. if MATRYOSHKA_MODELS.include?(@model) && @dimensions != MODEL_DEFAULT_DIMENSIONS.fetch(@model) body[:dimensions] = @dimensions end (strings.length, input_type) do |emit_payload| payload = (body) if payload.is_a?(Hash) && payload["usage"].is_a?(Hash) tt = payload["usage"]["total_tokens"] emit_payload[:total_tokens] = tt if tt.is_a?(Integer) && tt >= 0 end vectors = extract_vectors!(payload, strings.length) validate_response!(strings.length, vectors) end end |
#inspect_attrs ⇒ Object
242 243 244 |
# File 'lib/parse/embeddings/jina.rb', line 242 def inspect_attrs super.merge(base: safe_base_host, retries: @max_retries) end |
#max_input_tokens ⇒ Object
178 179 180 |
# File 'lib/parse/embeddings/jina.rb', line 178 def max_input_tokens MODEL_MAX_INPUT_TOKENS[@model] end |
#model_name ⇒ Object
170 171 172 |
# File 'lib/parse/embeddings/jina.rb', line 170 def model_name @model end |
#normalize? ⇒ Boolean
182 183 184 185 |
# File 'lib/parse/embeddings/jina.rb', line 182 def normalize? # Jina's v3/v4/v5 embeddings are documented unit-normalized. true end |
#supports_input_type? ⇒ Boolean
187 188 189 |
# File 'lib/parse/embeddings/jina.rb', line 187 def supports_input_type? true end |