ruby_conversations 1.0.14 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d6209ce940d83da8e50a14df8ef7b7aa9134676742022cc7fcbe47eaaba94bc
4
- data.tar.gz: 010bf794202f4030e657c4fed0d88e39a8dceac460e9e32ca331cb2d340a020a
3
+ metadata.gz: dd956939c0daaea90e866266a6ab8a5bba2b3ec9bb295c81a6f2e902b163d968
4
+ data.tar.gz: a03a9a78205f79a6d4850cb7cd58ca0fc7413b0754e62563b541b8adc1b32917
5
5
  SHA512:
6
- metadata.gz: 3686165abf53df27c35c84b0e1444e6be18336fcb939aebb36245fa906f72a31eb18468d2d6782d39eafac19ba2f60e4f07ee48a492880a883ec16cf331c376b
7
- data.tar.gz: dac103d0a4ef37ca87e874dd1a36924800aa8c0a96e0ba5798434e7e246a97daad7d79d475d9758798938e0b426d39f0b6bfc146989286a8783ba745708d4480
6
+ metadata.gz: abab8e151b670375b5486c7915eb921f1c24943b6f20d65f56229428d7254afe8ef18d98fe957df82de16e6219d9b4196489044fcee6e04887b201c8b2528833
7
+ data.tar.gz: 3f4e262b42234bb4ed48a18d11a165edc932f75999c64f13afe8aa2b93ccd04b2e4370c3ad4b90470882e299947133831ff712a71d6418a3f36773127b21d7f2
@@ -10,14 +10,30 @@ module RubyConversations
10
10
  validate_conversation_state
11
11
  chat_messages = generate_chat_response(system_message)
12
12
 
13
- if tool.present?
14
- tool_calls = chat_messages.filter { |message| message.tool_calls.present? }
15
- raise "No tool call found for tool '#{tool}'. Please check the prompt." if tool_calls.empty?
16
- end
13
+ validate_tool_calls(chat_messages)
17
14
 
18
15
  store_and_update_conversation(chat_messages)
19
16
  end
20
17
 
18
+ def validate_tool_calls(chat_messages)
19
+ return unless tools_configured?
20
+ return if tool_calls?(chat_messages)
21
+
22
+ raise "No tool call found for tool(s): '#{tool_names}'. Please check the prompt."
23
+ end
24
+
25
+ def tools_configured?
26
+ tool.present? || tools&.present?
27
+ end
28
+
29
+ def tool_names
30
+ tool&.name || tools&.map(&:name)
31
+ end
32
+
33
+ def tool_calls?(chat_messages)
34
+ chat_messages.any? { |message| message.tool_calls.present? }
35
+ end
36
+
21
37
  def llm
22
38
  case model_identifier
23
39
  when 'claude-3-7-sonnet'
@@ -35,7 +51,7 @@ module RubyConversations
35
51
  end
36
52
 
37
53
  def generate_chat_response(system_message)
38
- chat = setup_llm_chat(system_message: system_message)
54
+ setup_llm_chat(system_message: system_message)
39
55
  chat.ask(messages.last.request)
40
56
  chat.messages
41
57
  end
@@ -52,18 +68,17 @@ module RubyConversations
52
68
 
53
69
  def setup_llm_chat(system_message: nil)
54
70
  configure_llm_credentials
55
- build_chat(system_message)
71
+ configure_tools
72
+ chat.add_message(role: :system, content: system_message) if system_message.present?
56
73
  end
57
74
 
58
75
  def update_last_message_response(message, chat_messages)
59
76
  message.response = chat_messages.map(&:to_h).to_json
60
77
  end
61
78
 
62
- def build_chat(system_message)
63
- chat = RubyLLM.chat(model: llm, provider: provider).with_temperature(0.0)
79
+ def configure_tools
64
80
  chat.with_tool(tool) if tool.present?
65
- chat.add_message(role: :system, content: system_message) if system_message.present?
66
- chat
81
+ tools&.each { |tool| chat.with_tool(tool) }
67
82
  end
68
83
  end
69
84
  end
@@ -8,34 +8,40 @@ module RubyConversations
8
8
  module LlmCredentials
9
9
  extend ActiveSupport::Concern
10
10
 
11
- private
11
+ class_methods do
12
+ def configure_llm_credentials
13
+ RubyLLM.configure do |config|
14
+ credentials = provider_credentials
15
+ config.bedrock_region = ENV.fetch('AWS_REGION', 'us-west-2')
16
+ config.bedrock_api_key = credentials[:api_key]
17
+ config.bedrock_secret_key = credentials[:secret_key]
18
+ config.bedrock_session_token = credentials[:session_token]
19
+ end
20
+ end
12
21
 
13
- def configure_llm_credentials
14
- RubyLLM.configure do |config|
15
- credentials = provider_credentials
16
- config.bedrock_region = ENV.fetch('AWS_REGION', 'us-west-2')
17
- config.bedrock_api_key = credentials[:api_key]
18
- config.bedrock_secret_key = credentials[:secret_key]
19
- config.bedrock_session_token = credentials[:session_token]
22
+ private
23
+
24
+ def env_credentials
25
+ {
26
+ api_key: ENV.fetch('AWS_ACCESS_KEY_ID', nil),
27
+ secret_key: ENV.fetch('AWS_SECRET_ACCESS_KEY', nil),
28
+ session_token: ENV.fetch('AWS_SESSION_TOKEN', nil)
29
+ }
20
30
  end
21
- end
22
31
 
23
- def env_credentials
24
- {
25
- api_key: ENV.fetch('AWS_ACCESS_KEY_ID', nil),
26
- secret_key: ENV.fetch('AWS_SECRET_ACCESS_KEY', nil),
27
- session_token: ENV.fetch('AWS_SESSION_TOKEN', nil)
28
- }
32
+ def provider_credentials
33
+ credential_provider = AwsCredentialProvider.instance
34
+ credential_provider.refresh_if_expired!
35
+ {
36
+ api_key: credential_provider.access_key_id,
37
+ secret_key: credential_provider.secret_access_key,
38
+ session_token: credential_provider.session_token
39
+ }
40
+ end
29
41
  end
30
42
 
31
- def provider_credentials
32
- credential_provider = AwsCredentialProvider.instance
33
- credential_provider.refresh_if_expired!
34
- {
35
- api_key: credential_provider.access_key_id,
36
- secret_key: credential_provider.secret_access_key,
37
- session_token: credential_provider.session_token
38
- }
43
+ def configure_llm_credentials
44
+ self.class.configure_llm_credentials
39
45
  end
40
46
  end
41
47
  end
@@ -13,8 +13,8 @@ module RubyConversations
13
13
  include RubyConversations::Concerns::MessageProcessing
14
14
 
15
15
  # Define attributes needed for API interaction & local state
16
- attr_accessor :id, :conversationable_type, :conversationable_id, :conversationable,
17
- :messages, :tool, :created_at, :updated_at
16
+ attr_accessor :chat, :id, :conversationable_type, :conversationable_id, :conversationable,
17
+ :messages, :tool, :tools, :created_at, :updated_at, :persist
18
18
 
19
19
  # Validations
20
20
  validates :messages, presence: { message: 'At least one message is required' }, on: :update
@@ -28,9 +28,21 @@ module RubyConversations
28
28
  # Extract nested attributes before super tries to assign them
29
29
  messages_attrs = attributes.delete(:messages) || attributes.delete('messages') ||
30
30
  attributes.delete(:messages_attributes) || attributes.delete('messages_attributes') || []
31
+ # Extract persist flag, default to false
32
+ @persist = attributes.delete(:persist) || attributes.delete('persist') || false
31
33
 
32
34
  super # Initialize with remaining attributes using ActiveModel::Model
33
35
  initialize_messages(messages_attrs)
36
+
37
+ build_chat
38
+ end
39
+
40
+ def build_chat
41
+ @chat = if @persist && RubyConversations.configuration.persistence_model
42
+ resolve_persistence_model.create!(model_id: llm, provider: provider)
43
+ else
44
+ RubyLLM.chat(model: llm, provider: provider).with_temperature(0.0)
45
+ end
34
46
  end
35
47
 
36
48
  def model_identifier
@@ -58,6 +70,19 @@ module RubyConversations
58
70
 
59
71
  private
60
72
 
73
+ def resolve_persistence_model
74
+ model_config = RubyConversations.configuration.persistence_model
75
+ unless model_config.is_a?(String)
76
+ raise ConfigurationError, "Invalid persistence_model configured: Must be a String, got #{model_config.class}"
77
+ end
78
+
79
+ model_config.safe_constantize || raise(ConfigurationError,
80
+ "Invalid persistence_model configured: '#{model_config}' could not be resolved.")
81
+ rescue NameError => e
82
+ # Catch potential NameError from constantize if the class name is invalid
83
+ raise ConfigurationError, "Invalid persistence_model configured: #{e.message}"
84
+ end
85
+
61
86
  def base_attributes
62
87
  {
63
88
  id: id
@@ -3,7 +3,7 @@
3
3
  module RubyConversations
4
4
  # Configuration options for RubyConversations
5
5
  class Configuration
6
- attr_accessor :api_url, :jwt_secret, :default_llm_model, :default_llm_provider
6
+ attr_accessor :api_url, :jwt_secret, :default_llm_model, :default_llm_provider, :persistence_model
7
7
 
8
8
  def initialize
9
9
  @default_llm_model = 'claude-3-7-sonnet'
@@ -2,8 +2,8 @@
2
2
 
3
3
  module RubyConversations
4
4
  MAJOR = 1
5
- MINOR = 0
6
- PATCH = 14
5
+ MINOR = 1
6
+ PATCH = 0
7
7
 
8
8
  VERSION = "#{RubyConversations::MAJOR}.#{RubyConversations::MINOR}.#{RubyConversations::PATCH}".freeze
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_conversations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.14
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Shippy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-17 00:00:00.000000000 Z
11
+ date: 2025-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport