ruby_llm 0.1.0.pre14 → 0.1.0.pre16
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 +4 -4
- data/.overcommit.yml +1 -1
- data/README.md +3 -3
- data/lib/ruby_llm/active_record/acts_as.rb +34 -25
- data/lib/ruby_llm/chat.rb +6 -7
- data/lib/ruby_llm/railtie.rb +3 -3
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm.rb +11 -26
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85ade36a78c5038ed31c362682ee1e81cba3b952e278ce092c93d3695740e2a1
|
4
|
+
data.tar.gz: 572e88e7f493f9d125873c9a3ba07d014302c480246d3b7b0b326e1d44924f30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 370a6e32a748d7119a3af729e0a43cdb9f4b80d60e09d959e425a28b0c4ecad8ca9e3a1f3aec6ba279039e40b2129c49e56641e041622f3268c72624d17ebc9d
|
7
|
+
data.tar.gz: 2295e3a850d514eb60964d3bdc47ee9682ba8b630010661efe8374ca468a81edb10617a10484a70ba47df2db8547856246c470160e8d87c157bdaccae2c8b5c6
|
data/.overcommit.yml
CHANGED
data/README.md
CHANGED
@@ -167,7 +167,7 @@ class CreateMessages < ActiveRecord::Migration[8.0]
|
|
167
167
|
t.references :chat
|
168
168
|
t.string :role
|
169
169
|
t.text :content
|
170
|
-
t.json :tool_calls
|
170
|
+
t.json :tool_calls, default: {}
|
171
171
|
t.string :tool_call_id
|
172
172
|
t.integer :input_tokens
|
173
173
|
t.integer :output_tokens
|
@@ -182,14 +182,14 @@ Then in your models:
|
|
182
182
|
|
183
183
|
```ruby
|
184
184
|
class Chat < ApplicationRecord
|
185
|
-
acts_as_chat
|
185
|
+
acts_as_chat
|
186
186
|
|
187
187
|
# Optional: Add Turbo Streams support
|
188
188
|
broadcasts_to ->(chat) { "chat_#{chat.id}" }
|
189
189
|
end
|
190
190
|
|
191
191
|
class Message < ApplicationRecord
|
192
|
-
acts_as_message
|
192
|
+
acts_as_message
|
193
193
|
end
|
194
194
|
```
|
195
195
|
|
@@ -9,7 +9,7 @@ module RubyLLM
|
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
11
|
class_methods do
|
12
|
-
def acts_as_chat(message_class:)
|
12
|
+
def acts_as_chat(message_class: 'Message') # rubocop:disable Metrics/MethodLength
|
13
13
|
include ChatMethods
|
14
14
|
|
15
15
|
has_many :messages,
|
@@ -17,16 +17,23 @@ module RubyLLM
|
|
17
17
|
class_name: message_class.to_s,
|
18
18
|
dependent: :destroy
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
delegate :complete,
|
21
|
+
:with_tool,
|
22
|
+
:with_tools,
|
23
|
+
:with_model,
|
24
|
+
:with_temperature,
|
25
|
+
:on_new_message,
|
26
|
+
:on_end_message,
|
27
|
+
:add_message,
|
28
|
+
to: :to_llm
|
22
29
|
end
|
23
30
|
|
24
|
-
def acts_as_message(chat_class:)
|
31
|
+
def acts_as_message(chat_class: 'Chat')
|
25
32
|
include MessageMethods
|
26
33
|
|
27
34
|
belongs_to :chat, class_name: chat_class.to_s
|
28
35
|
|
29
|
-
|
36
|
+
delegate :tool_call?, :tool_result?, :tool_results, to: :to_llm
|
30
37
|
end
|
31
38
|
end
|
32
39
|
end
|
@@ -36,34 +43,33 @@ module RubyLLM
|
|
36
43
|
module ChatMethods
|
37
44
|
extend ActiveSupport::Concern
|
38
45
|
|
39
|
-
def
|
40
|
-
|
41
|
-
chat = RubyLLM.chat(model: model_id)
|
46
|
+
def to_llm
|
47
|
+
chat = RubyLLM.chat(model: model_id)
|
42
48
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
# Load existing messages into chat
|
50
|
+
messages.each do |msg|
|
51
|
+
chat.add_message(msg.to_llm)
|
52
|
+
end
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
# Set up message persistence
|
55
|
+
chat.on_new_message { persist_new_message }
|
56
|
+
.on_end_message { |msg| persist_message_completion(msg) }
|
57
|
+
end
|
51
58
|
|
52
|
-
|
53
|
-
|
59
|
+
def ask(message, &block)
|
60
|
+
message = { role: :user, content: message }
|
61
|
+
messages.create!(**message)
|
62
|
+
chat.complete(&block)
|
54
63
|
end
|
55
64
|
|
56
|
-
|
65
|
+
alias say ask
|
57
66
|
|
58
|
-
|
59
|
-
return unless message
|
67
|
+
private
|
60
68
|
|
69
|
+
def persist_new_message
|
61
70
|
messages.create!(
|
62
|
-
role:
|
63
|
-
content:
|
64
|
-
tool_calls: message.tool_calls,
|
65
|
-
tool_call_id: message.tool_call_id,
|
66
|
-
model_id: message.model_id
|
71
|
+
role: :assistant,
|
72
|
+
content: String.new
|
67
73
|
)
|
68
74
|
end
|
69
75
|
|
@@ -71,8 +77,11 @@ module RubyLLM
|
|
71
77
|
return unless message
|
72
78
|
|
73
79
|
messages.last.update!(
|
80
|
+
role: message.role,
|
74
81
|
content: message.content,
|
82
|
+
model_id: message.model_id,
|
75
83
|
tool_calls: message.tool_calls,
|
84
|
+
tool_call_id: message.tool_call_id,
|
76
85
|
input_tokens: message.input_tokens,
|
77
86
|
output_tokens: message.output_tokens
|
78
87
|
)
|
data/lib/ruby_llm/chat.rb
CHANGED
@@ -87,6 +87,12 @@ module RubyLLM
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
def add_message(message_or_attributes)
|
91
|
+
message = message_or_attributes.is_a?(Message) ? message_or_attributes : Message.new(message_or_attributes)
|
92
|
+
messages << message
|
93
|
+
message
|
94
|
+
end
|
95
|
+
|
90
96
|
private
|
91
97
|
|
92
98
|
def handle_tool_calls(response, &block)
|
@@ -104,13 +110,6 @@ module RubyLLM
|
|
104
110
|
tool.call(args)
|
105
111
|
end
|
106
112
|
|
107
|
-
def add_message(message_or_attributes)
|
108
|
-
message = message_or_attributes.is_a?(Message) ? message_or_attributes : Message.new(message_or_attributes)
|
109
|
-
# TODO: callback
|
110
|
-
messages << message
|
111
|
-
message
|
112
|
-
end
|
113
|
-
|
114
113
|
def add_tool_result(tool_use_id, result)
|
115
114
|
add_message(
|
116
115
|
role: :tool,
|
data/lib/ruby_llm/railtie.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
module RubyLLM
|
4
4
|
# Rails integration for RubyLLM
|
5
5
|
class Railtie < Rails::Railtie
|
6
|
-
initializer 'ruby_llm.
|
7
|
-
ActiveSupport.on_load
|
8
|
-
|
6
|
+
initializer 'ruby_llm.active_record' do
|
7
|
+
ActiveSupport.on_load :active_record do
|
8
|
+
include RubyLLM::ActiveRecord::ActsAs
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/ruby_llm/version.rb
CHANGED
data/lib/ruby_llm.rb
CHANGED
@@ -7,6 +7,15 @@ require 'logger'
|
|
7
7
|
require 'event_stream_parser'
|
8
8
|
require 'securerandom'
|
9
9
|
|
10
|
+
loader = Zeitwerk::Loader.for_gem
|
11
|
+
loader.inflector.inflect(
|
12
|
+
'ruby_llm' => 'RubyLLM',
|
13
|
+
'llm' => 'LLM',
|
14
|
+
'openai' => 'OpenAI',
|
15
|
+
'api' => 'API'
|
16
|
+
)
|
17
|
+
loader.setup
|
18
|
+
|
10
19
|
# A delightful Ruby interface to modern AI language models.
|
11
20
|
# Provides a unified way to interact with models from OpenAI, Anthropic and others
|
12
21
|
# with a focus on developer happiness and convention over configuration.
|
@@ -34,40 +43,16 @@ module RubyLLM
|
|
34
43
|
@logger ||= Logger.new(
|
35
44
|
$stdout,
|
36
45
|
progname: 'RubyLLM',
|
37
|
-
level: ENV['RUBY_LLM_DEBUG']
|
46
|
+
level: ENV['RUBY_LLM_DEBUG'] ? Logger::DEBUG : Logger::INFO
|
38
47
|
)
|
39
48
|
end
|
40
49
|
end
|
41
50
|
end
|
42
51
|
|
43
|
-
loader = Zeitwerk::Loader.for_gem
|
44
|
-
|
45
|
-
# Add lib directory to the load path
|
46
|
-
loader.push_dir(File.expand_path('..', __dir__))
|
47
|
-
|
48
|
-
# Configure custom inflections
|
49
|
-
loader.inflector.inflect(
|
50
|
-
'ruby_llm' => 'RubyLLM',
|
51
|
-
'llm' => 'LLM',
|
52
|
-
'openai' => 'OpenAI',
|
53
|
-
'api' => 'API'
|
54
|
-
)
|
55
|
-
|
56
|
-
# Ignore Rails-specific files and specs
|
57
|
-
loader.ignore("#{__dir__}/ruby_llm/railtie.rb")
|
58
|
-
loader.ignore("#{__dir__}/ruby_llm/active_record")
|
59
|
-
loader.ignore(File.expand_path('../spec', __dir__).to_s)
|
60
|
-
|
61
|
-
loader.enable_reloading if ENV['RUBY_LLM_DEBUG']
|
62
|
-
|
63
|
-
loader.setup
|
64
|
-
loader.eager_load if ENV['RUBY_LLM_DEBUG']
|
65
|
-
|
66
52
|
RubyLLM::Provider.register :openai, RubyLLM::Providers::OpenAI
|
67
53
|
RubyLLM::Provider.register :anthropic, RubyLLM::Providers::Anthropic
|
68
54
|
|
69
|
-
|
70
|
-
if defined?(Rails)
|
55
|
+
if defined?(Rails::Railtie)
|
71
56
|
require 'ruby_llm/railtie'
|
72
57
|
require 'ruby_llm/active_record/acts_as'
|
73
58
|
end
|