Module: RubyLLM::Protocols::Cohere::Embeddings

Defined in:
lib/ruby_llm/protocols/cohere/embeddings.rb

Overview

Embeddings methods for the Cohere v2 API integration

Constant Summary collapse

DEFAULT_INPUT_TYPE =
'search_document'

Class Method Summary collapse

Class Method Details

.embedding_inputs(text, attachments) ⇒ Object

embed-v4 takes mixed text and images as inputs; text-only requests keep using the simpler texts array every Embed model accepts.

Raises:

  • (ArgumentError)


58
59
60
61
62
63
64
# File 'lib/ruby_llm/protocols/cohere/embeddings.rb', line 58

def embedding_inputs(text, attachments)
  return { texts: Support::Utils.to_safe_array(text).map(&:to_s) } if attachments.empty?

  raise ArgumentError, 'embed one text at a time when embedding attachments' if text.is_a?(Array)

  { inputs: [{ content: Media.format_content(text, attachments) }] }
end

.embedding_urlObject



12
13
14
# File 'lib/ruby_llm/protocols/cohere/embeddings.rb', line 12

def embedding_url(...)
  'v2/embed'
end

.image_embedding_inputs(text, attachments) ⇒ Object

:nodoc:

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
# File 'lib/ruby_llm/protocols/cohere/embeddings.rb', line 39

def image_embedding_inputs(text, attachments) # :nodoc:
  raise ArgumentError, 'Cohere Embed v3 accepts text or an image, not both' unless text.nil? || text == ''
  raise ArgumentError, 'Cohere Embed v3 accepts one image per request' unless attachments.one?
  raise UnsupportedAttachmentError, attachments.first.mime_type unless attachments.first.image?

  { images: ["data:#{attachments.first.mime_type};base64,#{attachments.first.encoded}"] }
end

.parse_embedding_response(response, model:, text:) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/ruby_llm/protocols/cohere/embeddings.rb', line 47

def parse_embedding_response(response, model:, text:)
  data = response.body
  vectors = data.dig('embeddings', 'float')
  vectors = vectors.first if vectors&.length == 1 && !text.is_a?(Array)
  billed = data.dig('meta', 'billed_units') || {}

  Embedding.new(vectors:, model:, input_tokens: billed['input_tokens'])
end

.render_embedding_payload(text, model:, dimensions:, task_type: nil, title: nil, with: [], provider_options: {}) ⇒ Object

rubocop:disable-next Lint/UnusedMethodArgument



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ruby_llm/protocols/cohere/embeddings.rb', line 17

def render_embedding_payload(text, model:, dimensions:, task_type: nil, title: nil, with: [],
                             provider_options: {})
  image_only = with.any? && separate_image_embeddings?(model)
  payload = {
    model: model,
    input_type: task_type || (image_only ? 'image' : DEFAULT_INPUT_TYPE),
    embedding_types: ['float'],
    output_dimension: dimensions
  }.compact

  payload.merge!(image_only ? image_embedding_inputs(text, with) : embedding_inputs(text, with))
  Support::Utils.deep_merge(payload, provider_options)
end

.separate_image_embeddings?(model) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


35
36
37
# File 'lib/ruby_llm/protocols/cohere/embeddings.rb', line 35

def separate_image_embeddings?(model) # :nodoc:
  %w[embed-english-v3.0 embed-multilingual-v3.0].include?(model)
end

.supports_embedding_media?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/ruby_llm/protocols/cohere/embeddings.rb', line 31

def supports_embedding_media?
  true
end