Module: RubyLLM::BedrockInvoke

Defined in:
lib/ruby_llm-bedrock_invoke.rb,
lib/ruby_llm/bedrock_invoke/signing.rb,
lib/ruby_llm/bedrock_invoke/version.rb,
lib/ruby_llm/bedrock_invoke/deferred.rb,
lib/ruby_llm/bedrock_invoke/protocol_v2.rb,
lib/ruby_llm/bedrock_invoke/raw_content.rb,
lib/ruby_llm/bedrock_invoke/tool_search.rb,
lib/ruby_llm/bedrock_invoke/capabilities.rb,
lib/ruby_llm/bedrock_invoke/event_stream.rb,
lib/ruby_llm/bedrock_invoke/stream_state.rb,
lib/ruby_llm/bedrock_invoke/block_collector.rb

Overview

Anthropic Claude on AWS Bedrock via InvokeModel — tool search (deferred tool loading), structured outputs, prompt caching and streaming inside the AWS data boundary, authenticated with the standard AWS credential chain.

Defined Under Namespace

Modules: Capabilities, ConfigurationRedaction, Deferred, EventStream, Signing, ToolSearch Classes: BlockCollector, Error, Protocol, RawContent, StreamState

Constant Summary collapse

CONFIGURATION_OPTIONS =
%i[
  bedrock_invoke_region
  bedrock_invoke_api_base
  bedrock_invoke_credential_provider
].freeze
RAW_BLOCKS_IVAR =

Where a response carried server-managed tool-search blocks (server_tool_use / tool_search_tool_result), the full content-block array is preserved for verbatim replay. On 1.x it rides in the message content as RawContent; on 2.0 (String-only content) it rides in this ivar and is re-injected by the protocol when rendering history.

:@bedrock_invoke_raw_blocks
VERSION =
'0.1.0.pre.1'

Class Method Summary collapse

Class Method Details

.budget_thinking_payload(thinking) ⇒ Object

Bedrock Claude supports budget-based extended thinking only (the adaptive/effort API is not available on Bedrock). Assumed-exist models carry no registry reasoning_options, so the providers bypass the registry gates and emit this payload directly.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/ruby_llm-bedrock_invoke.rb', line 57

def self.budget_thinking_payload(thinking)
  return nil unless thinking.respond_to?(:enabled?) && thinking.enabled?

  effort = thinking.respond_to?(:effort) ? thinking.effort&.to_s : nil
  return nil if effort == 'none'

  budget = thinking.respond_to?(:budget) ? thinking.budget : thinking
  unless budget.is_a?(Integer)
    raise ArgumentError,
          'Bedrock InvokeModel supports budget-based thinking only; adaptive/effort thinking ' \
          'is not available on Bedrock. Use with_thinking(budget: N).'
  end

  { type: 'enabled', budget_tokens: budget }
end

.defer(tool) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ruby_llm/bedrock_invoke/deferred.rb', line 24

def self.defer(tool)
  if tool.is_a?(Class)
    # Chat#with_tools instantiates classes, so extending the class object
    # would be silently lost. Fail loudly instead.
    raise ArgumentError,
          'Pass a tool instance to RubyLLM::BedrockInvoke.defer (e.g. defer(MyTool.new)), ' \
          'or include RubyLLM::BedrockInvoke::Deferred in the tool class.'
  end

  tool.extend(Deferred) unless ToolSearch.deferred?(tool)
  tool
end

.escape_model_id(model_id) ⇒ Object

Bedrock routes /model/modelId/... with the id as a single path label; ARN-based ids (inference profiles, application inference profiles, imported models) contain '/' and ':' and must be percent-encoded the way the official AWS SDK encodes them.



49
50
51
# File 'lib/ruby_llm-bedrock_invoke.rb', line 49

def self.escape_model_id(model_id)
  ERB::Util.url_encode(model_id.to_s)
end

.raw_blocks(message) ⇒ Object

The preserved Anthropic content blocks for a message, or nil. Works on both RubyLLM generations.



37
38
39
40
41
42
43
# File 'lib/ruby_llm-bedrock_invoke.rb', line 37

def self.raw_blocks(message)
  if defined?(RawContent) && message.content.is_a?(RawContent)
    message.content.value
  elsif message.instance_variable_defined?(RAW_BLOCKS_IVAR)
    message.instance_variable_get(RAW_BLOCKS_IVAR)
  end
end

.register!Object



79
80
81
82
# File 'lib/ruby_llm-bedrock_invoke.rb', line 79

def self.register!
  register_configuration_options!
  RubyLLM::Provider.register :bedrock_invoke, RubyLLM::Providers::BedrockInvoke
end

.register_configuration_options!Object

1.16+ and 2.0 register configuration_options automatically inside Provider.register; older 1.x needs the accessors added by hand.



96
97
98
99
100
101
102
# File 'lib/ruby_llm-bedrock_invoke.rb', line 96

def self.register_configuration_options!
  RubyLLM::Configuration.prepend(ConfigurationRedaction) unless v2_architecture?
  return if RubyLLM::Configuration.respond_to?(:register_provider_options)

  missing = CONFIGURATION_OPTIONS.reject { |key| RubyLLM::Configuration.method_defined?(key) }
  RubyLLM::Configuration.attr_accessor(*missing) if missing.any?
end

.v2_architecture?Boolean

RubyLLM 2.0 split providers (where/auth) from protocols (wire format); 1.x providers are monolithic. Detect which world we're in at require time.

Returns:

  • (Boolean)


75
76
77
# File 'lib/ruby_llm-bedrock_invoke.rb', line 75

def self.v2_architecture?
  defined?(RubyLLM::Protocol) ? true : false
end