Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3922cc5
Add Bedrock embedding support via InvokeModel API
cgmoore120 Mar 12, 2026
3045d86
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Mar 12, 2026
9e8b905
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Mar 17, 2026
0d4b2ba
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Mar 24, 2026
5c46b86
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Apr 1, 2026
cbd64fc
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Apr 6, 2026
43e7b4e
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Apr 10, 2026
df29acb
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Apr 16, 2026
d597ad2
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 May 6, 2026
afd5a65
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 May 6, 2026
429f1ca
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 May 6, 2026
216ef30
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 May 6, 2026
4b6935e
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 May 7, 2026
cf9b8f9
Merge branch 'main' into add-bedrock-embedding-support
crmne May 12, 2026
fd38dbe
Merge remote-tracking branch 'upstream/main' into add-bedrock-embeddi…
cgmoore120 Jun 16, 2026
99d21f4
Add VCR cassettes for Bedrock Titan embedding specs
cgmoore120 Jun 16, 2026
9ee2a63
Remove unused parse_embedding_response from Bedrock embeddings
cgmoore120 Jun 16, 2026
5cb3599
Fix test pollution from RubyLLM.logger spec leaving config nil
cgmoore120 Jun 17, 2026
299bb11
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Jun 18, 2026
579ef9c
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Jun 23, 2026
2b292ef
Move Bedrock embeddings into Converse protocol
crmne Jun 23, 2026
e62b640
Merge branch 'main' into add-bedrock-embedding-support
cgmoore120 Jun 23, 2026
0574803
Merge branch 'main' into add-bedrock-embedding-support
crmne Jul 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions lib/ruby_llm/protocols/converse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Protocols
# The AWS Bedrock Converse API. Requests are SigV4-signed by the provider.
class Converse < Protocol
include Converse::Chat
include Converse::Embeddings
include Converse::Media
include Converse::Streaming

Expand All @@ -18,12 +19,17 @@ def self.reasoning_embedded?(model)
private

def sync_response(payload, additional_headers = {})
response = signed_post(completion_url, payload, additional_headers)
parse_completion_response(response)
end

def signed_post(url, payload, additional_headers = {})
body = JSON.generate(payload)
response = @connection.post(completion_url, payload) do |req|
req.headers.merge!(@provider.sign_headers('POST', completion_url, body))

@connection.post(url, payload) do |req|
req.headers.merge!(@provider.sign_headers('POST', url, body))
req.headers.merge!(additional_headers) unless additional_headers.empty?
end
parse_completion_response(response)
end
end
end
Expand Down
41 changes: 41 additions & 0 deletions lib/ruby_llm/protocols/converse/embeddings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

module RubyLLM
module Protocols
class Converse
# Embeddings methods for Bedrock's InvokeModel API.
module Embeddings
def embed(text, model:, dimensions:)
responses = [text].flatten.map do |value|
payload = render_embedding_payload(value, model:, dimensions:)
signed_post(embedding_url(model:), payload)
end

parse_embedding_responses(responses, model:, text:)
end

private

def embedding_url(model:)
"/model/#{model}/invoke"
end

def render_embedding_payload(text, model:, dimensions:) # rubocop:disable Lint/UnusedMethodArgument
{
inputText: text.to_s,
dimensions: dimensions,
normalize: true
}.compact
end

def parse_embedding_responses(responses, model:, text:)
vectors = responses.map { |response| response.body['embedding'] }
input_tokens = responses.sum { |response| response.body['inputTextTokenCount'] || 0 }
vectors = vectors.first unless text.is_a?(Array)

Embedding.new(vectors:, model:, input_tokens:)
end
end
end
end
end

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions spec/ruby_llm/embedding_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
it "#{provider}/#{model} can handle a single text with custom dimensions" do
skip 'Mistral does not support custom dimensions' if provider == :mistral
skip 'Azure Cohere embeddings do not support custom dimensions' if provider == :azure
skip 'Bedrock Titan only supports dimensions of 256, 512, or 1024' if provider == :bedrock

embedding = RubyLLM.embed(test_text, model: model, provider: provider, dimensions: test_dimensions)
expect(embedding.vectors).to be_an(Array)
Expand All @@ -42,6 +43,7 @@
it "#{provider}/#{model} can handle multiple texts with custom dimensions" do
skip 'Mistral does not support custom dimensions' if provider == :mistral
skip 'Azure Cohere embeddings do not support custom dimensions' if provider == :azure
skip 'Bedrock Titan only supports dimensions of 256, 512, or 1024' if provider == :bedrock

embeddings = RubyLLM.embed(test_texts, model: model, provider: provider, dimensions: test_dimensions)
expect(embeddings.vectors).to be_an(Array)
Expand Down
13 changes: 7 additions & 6 deletions spec/ruby_llm_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
let(:log_file) { double }
let(:log_level) { double }

before do
described_class.instance_variable_set(:@config, nil)
described_class.instance_variable_set(:@logger, nil)
end

after do
around do |example|
original_config = described_class.instance_variable_get(:@config)
original_logger = described_class.instance_variable_get(:@logger)
described_class.instance_variable_set(:@config, nil)
described_class.instance_variable_set(:@logger, nil)
example.run
ensure
described_class.instance_variable_set(:@config, original_config)
described_class.instance_variable_set(:@logger, original_logger)
end

context 'with configuration options' do
Expand Down
1 change: 1 addition & 0 deletions spec/support/models_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def filter_local_providers(models)

EMBEDDING_MODELS = [
{ provider: :azure, model: 'Cohere-embed-v3-english' },
{ provider: :bedrock, model: 'amazon.titan-embed-text-v2:0' },
{ provider: :gemini, model: 'gemini-embedding-001' },
{ provider: :mistral, model: 'mistral-embed' },
{ provider: :openai, model: 'text-embedding-3-small' },
Expand Down
Loading