ruby_llm_community 1.1.1 → 1.3.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 +4 -4
- data/README.md +25 -7
- data/lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb +127 -67
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt +12 -12
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt +7 -7
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/models_controller.rb.tt +4 -4
- data/lib/generators/ruby_llm/chat_ui/templates/jobs/chat_response_job.rb.tt +6 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_chat.html.erb.tt +4 -4
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_form.html.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/new.html.erb.tt +4 -4
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt +8 -8
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_content.html.erb.tt +1 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_form.html.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt +9 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_tool_calls.html.erb.tt +7 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt +9 -9
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt +4 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt +11 -11
- data/lib/generators/ruby_llm/generator_helpers.rb +131 -87
- data/lib/generators/ruby_llm/install/install_generator.rb +75 -73
- data/lib/generators/ruby_llm/install/templates/add_references_to_chats_tool_calls_and_messages_migration.rb.tt +9 -0
- data/lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt +0 -1
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +3 -3
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +0 -1
- data/lib/generators/ruby_llm/install/templates/initializer.rb.tt +1 -1
- data/lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb +88 -85
- data/lib/generators/ruby_llm/upgrade_to_v1_9/templates/add_v1_9_message_columns.rb.tt +15 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_9/upgrade_to_v1_9_generator.rb +49 -0
- data/lib/ruby_llm/active_record/acts_as.rb +17 -8
- data/lib/ruby_llm/active_record/chat_methods.rb +41 -13
- data/lib/ruby_llm/active_record/message_methods.rb +11 -2
- data/lib/ruby_llm/active_record/model_methods.rb +1 -1
- data/lib/ruby_llm/aliases.json +46 -20
- data/lib/ruby_llm/attachment.rb +8 -0
- data/lib/ruby_llm/chat.rb +13 -2
- data/lib/ruby_llm/configuration.rb +10 -1
- data/lib/ruby_llm/connection.rb +4 -4
- data/lib/ruby_llm/content.rb +23 -0
- data/lib/ruby_llm/message.rb +17 -9
- data/lib/ruby_llm/model/info.rb +4 -0
- data/lib/ruby_llm/models.json +12050 -9940
- data/lib/ruby_llm/models.rb +21 -25
- data/lib/ruby_llm/moderation.rb +56 -0
- data/lib/ruby_llm/provider.rb +29 -1
- data/lib/ruby_llm/providers/anthropic/chat.rb +18 -5
- data/lib/ruby_llm/providers/anthropic/content.rb +44 -0
- data/lib/ruby_llm/providers/anthropic/media.rb +5 -4
- data/lib/ruby_llm/providers/anthropic/models.rb +9 -2
- data/lib/ruby_llm/providers/anthropic/tools.rb +20 -18
- data/lib/ruby_llm/providers/bedrock/media.rb +2 -1
- data/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb +9 -2
- data/lib/ruby_llm/providers/gemini/chat.rb +353 -72
- data/lib/ruby_llm/providers/gemini/media.rb +59 -1
- data/lib/ruby_llm/providers/gemini/tools.rb +146 -25
- data/lib/ruby_llm/providers/gemini/transcription.rb +116 -0
- data/lib/ruby_llm/providers/gemini.rb +2 -1
- data/lib/ruby_llm/providers/gpustack/media.rb +1 -0
- data/lib/ruby_llm/providers/ollama/media.rb +1 -0
- data/lib/ruby_llm/providers/openai/capabilities.rb +15 -7
- data/lib/ruby_llm/providers/openai/chat.rb +7 -3
- data/lib/ruby_llm/providers/openai/media.rb +2 -1
- data/lib/ruby_llm/providers/openai/moderation.rb +34 -0
- data/lib/ruby_llm/providers/openai/streaming.rb +7 -3
- data/lib/ruby_llm/providers/openai/tools.rb +34 -12
- data/lib/ruby_llm/providers/openai/transcription.rb +70 -0
- data/lib/ruby_llm/providers/openai_base.rb +2 -0
- data/lib/ruby_llm/providers/red_candle/capabilities.rb +124 -0
- data/lib/ruby_llm/providers/red_candle/chat.rb +317 -0
- data/lib/ruby_llm/providers/red_candle/models.rb +121 -0
- data/lib/ruby_llm/providers/red_candle/streaming.rb +40 -0
- data/lib/ruby_llm/providers/red_candle.rb +90 -0
- data/lib/ruby_llm/providers/vertexai/transcription.rb +16 -0
- data/lib/ruby_llm/providers/vertexai.rb +3 -0
- data/lib/ruby_llm/railtie.rb +1 -1
- data/lib/ruby_llm/stream_accumulator.rb +8 -12
- data/lib/ruby_llm/tool.rb +126 -0
- data/lib/ruby_llm/transcription.rb +35 -0
- data/lib/ruby_llm/utils.rb +46 -0
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm_community.rb +38 -1
- metadata +35 -3
data/lib/ruby_llm/chat.rb
CHANGED
|
@@ -32,7 +32,7 @@ module RubyLLM
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def ask(message = nil, with: nil, &)
|
|
35
|
-
add_message role: :user, content:
|
|
35
|
+
add_message role: :user, content: build_content(message, with)
|
|
36
36
|
complete(&)
|
|
37
37
|
end
|
|
38
38
|
|
|
@@ -200,7 +200,8 @@ module RubyLLM
|
|
|
200
200
|
@on[:tool_call]&.call(tool_call)
|
|
201
201
|
result = execute_tool tool_call
|
|
202
202
|
@on[:tool_result]&.call(result)
|
|
203
|
-
|
|
203
|
+
tool_payload = result.is_a?(Tool::Halt) ? result.content : result
|
|
204
|
+
content = content_like?(tool_payload) ? tool_payload : tool_payload.to_s
|
|
204
205
|
message = add_message role: :tool, content:, tool_call_id: tool_call.id
|
|
205
206
|
@on[:end_message]&.call(message)
|
|
206
207
|
|
|
@@ -215,5 +216,15 @@ module RubyLLM
|
|
|
215
216
|
args = tool_call.arguments
|
|
216
217
|
tool.call(args)
|
|
217
218
|
end
|
|
219
|
+
|
|
220
|
+
def build_content(message, attachments)
|
|
221
|
+
return message if content_like?(message)
|
|
222
|
+
|
|
223
|
+
Content.new(message, attachments)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def content_like?(object)
|
|
227
|
+
object.is_a?(Content) || object.is_a?(Content::Raw)
|
|
228
|
+
end
|
|
218
229
|
end
|
|
219
230
|
end
|
|
@@ -10,6 +10,7 @@ module RubyLLM
|
|
|
10
10
|
:openai_use_system_role,
|
|
11
11
|
:anthropic_api_key,
|
|
12
12
|
:gemini_api_key,
|
|
13
|
+
:gemini_api_base,
|
|
13
14
|
:vertexai_project_id,
|
|
14
15
|
:vertexai_location,
|
|
15
16
|
:deepseek_api_key,
|
|
@@ -24,11 +25,16 @@ module RubyLLM
|
|
|
24
25
|
:gpustack_api_base,
|
|
25
26
|
:gpustack_api_key,
|
|
26
27
|
:mistral_api_key,
|
|
28
|
+
# Red Candle configuration
|
|
29
|
+
:red_candle_device,
|
|
27
30
|
# Default models
|
|
28
31
|
:default_model,
|
|
29
32
|
:default_embedding_model,
|
|
33
|
+
:default_moderation_model,
|
|
30
34
|
:default_image_model,
|
|
35
|
+
:default_transcription_model,
|
|
31
36
|
# Model registry
|
|
37
|
+
:model_registry_file,
|
|
32
38
|
:model_registry_class,
|
|
33
39
|
# Rails integration
|
|
34
40
|
:use_new_acts_as,
|
|
@@ -46,7 +52,7 @@ module RubyLLM
|
|
|
46
52
|
:log_stream_debug
|
|
47
53
|
|
|
48
54
|
def initialize
|
|
49
|
-
@request_timeout =
|
|
55
|
+
@request_timeout = 300
|
|
50
56
|
@max_retries = 3
|
|
51
57
|
@retry_interval = 0.1
|
|
52
58
|
@retry_backoff_factor = 2
|
|
@@ -55,8 +61,11 @@ module RubyLLM
|
|
|
55
61
|
|
|
56
62
|
@default_model = 'gpt-4.1-nano'
|
|
57
63
|
@default_embedding_model = 'text-embedding-3-small'
|
|
64
|
+
@default_moderation_model = 'omni-moderation-latest'
|
|
58
65
|
@default_image_model = 'gpt-image-1'
|
|
66
|
+
@default_transcription_model = 'whisper-1'
|
|
59
67
|
|
|
68
|
+
@model_registry_file = File.expand_path('models.json', __dir__)
|
|
60
69
|
@model_registry_class = 'Model'
|
|
61
70
|
@use_new_acts_as = false
|
|
62
71
|
|
data/lib/ruby_llm/connection.rb
CHANGED
|
@@ -34,8 +34,7 @@ module RubyLLM
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def post(url, payload, &)
|
|
37
|
-
|
|
38
|
-
@connection.post url, body do |req|
|
|
37
|
+
@connection.post url, payload do |req|
|
|
39
38
|
req.headers.merge! @provider.headers if @provider.respond_to?(:headers)
|
|
40
39
|
yield req if block_given?
|
|
41
40
|
end
|
|
@@ -66,7 +65,7 @@ module RubyLLM
|
|
|
66
65
|
errors: true,
|
|
67
66
|
headers: false,
|
|
68
67
|
log_level: :debug do |logger|
|
|
69
|
-
logger.filter(%r{[A-Za-z0-9+/=]{100,}}, '
|
|
68
|
+
logger.filter(%r{[A-Za-z0-9+/=]{100,}}, '[BASE64 DATA]')
|
|
70
69
|
logger.filter(/[-\d.e,\s]{100,}/, '[EMBEDDINGS ARRAY]')
|
|
71
70
|
end
|
|
72
71
|
end
|
|
@@ -83,9 +82,10 @@ module RubyLLM
|
|
|
83
82
|
end
|
|
84
83
|
|
|
85
84
|
def setup_middleware(faraday)
|
|
85
|
+
faraday.request :multipart
|
|
86
86
|
faraday.request :json
|
|
87
87
|
faraday.response :json
|
|
88
|
-
faraday.adapter
|
|
88
|
+
faraday.adapter :net_http
|
|
89
89
|
faraday.use :llm_errors, provider: @provider
|
|
90
90
|
end
|
|
91
91
|
|
data/lib/ruby_llm/content.rb
CHANGED
|
@@ -53,3 +53,26 @@ module RubyLLM
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
|
+
|
|
57
|
+
module RubyLLM
|
|
58
|
+
class Content
|
|
59
|
+
# Represents provider-specific payloads that should bypass RubyLLM formatting.
|
|
60
|
+
class Raw
|
|
61
|
+
attr_reader :value
|
|
62
|
+
|
|
63
|
+
def initialize(value)
|
|
64
|
+
raise ArgumentError, 'Raw content payload cannot be nil' if value.nil?
|
|
65
|
+
|
|
66
|
+
@value = value
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def format
|
|
70
|
+
@value
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def to_h
|
|
74
|
+
@value
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
data/lib/ruby_llm/message.rb
CHANGED
|
@@ -5,22 +5,22 @@ module RubyLLM
|
|
|
5
5
|
class Message
|
|
6
6
|
ROLES = %i[system user assistant tool].freeze
|
|
7
7
|
|
|
8
|
-
attr_reader :role, :tool_calls, :tool_call_id, :input_tokens, :output_tokens,
|
|
9
|
-
:cached_tokens, :cache_creation_tokens, :reasoning_id
|
|
8
|
+
attr_reader :role, :model_id, :tool_calls, :tool_call_id, :input_tokens, :output_tokens,
|
|
9
|
+
:cached_tokens, :cache_creation_tokens, :raw, :reasoning_id
|
|
10
10
|
attr_writer :content
|
|
11
11
|
|
|
12
12
|
def initialize(options = {})
|
|
13
13
|
@role = options.fetch(:role).to_sym
|
|
14
14
|
@content = normalize_content(options.fetch(:content))
|
|
15
|
+
@model_id = options[:model_id]
|
|
15
16
|
@tool_calls = options[:tool_calls]
|
|
17
|
+
@tool_call_id = options[:tool_call_id]
|
|
16
18
|
@input_tokens = options[:input_tokens]
|
|
17
19
|
@output_tokens = options[:output_tokens]
|
|
18
|
-
@model_id = options[:model_id]
|
|
19
|
-
@tool_call_id = options[:tool_call_id]
|
|
20
20
|
@cached_tokens = options[:cached_tokens]
|
|
21
21
|
@cache_creation_tokens = options[:cache_creation_tokens]
|
|
22
|
-
@reasoning_id = options[:reasoning_id]
|
|
23
22
|
@raw = options[:raw]
|
|
23
|
+
@reasoning_id = options[:reasoning_id]
|
|
24
24
|
|
|
25
25
|
ensure_valid_role
|
|
26
26
|
end
|
|
@@ -46,16 +46,24 @@ module RubyLLM
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def to_h
|
|
49
|
+
content_value = content
|
|
50
|
+
content_value = content_value.to_h if content_value.is_a?(Content) || content_value.is_a?(Content::Raw)
|
|
51
|
+
|
|
52
|
+
tool_calls_value = tool_calls
|
|
53
|
+
if tool_calls_value.is_a?(Hash) && tool_calls_value.values.any?(ToolCall)
|
|
54
|
+
tool_calls_value = tool_calls_value&.transform_values(&:to_h)
|
|
55
|
+
end
|
|
56
|
+
|
|
49
57
|
{
|
|
50
58
|
role: role,
|
|
51
|
-
content:
|
|
52
|
-
|
|
59
|
+
content: content_value,
|
|
60
|
+
model_id: model_id,
|
|
61
|
+
tool_calls: tool_calls_value,
|
|
53
62
|
tool_call_id: tool_call_id,
|
|
54
63
|
input_tokens: input_tokens,
|
|
55
64
|
output_tokens: output_tokens,
|
|
56
|
-
model_id: model_id,
|
|
57
|
-
cache_creation_tokens: cache_creation_tokens,
|
|
58
65
|
cached_tokens: cached_tokens,
|
|
66
|
+
cache_creation_tokens: cache_creation_tokens,
|
|
59
67
|
reasoning_id: reasoning_id
|
|
60
68
|
}.compact
|
|
61
69
|
end
|
data/lib/ruby_llm/model/info.rb
CHANGED
|
@@ -72,6 +72,10 @@ module RubyLLM
|
|
|
72
72
|
pricing.text_tokens.output
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
def provider_class
|
|
76
|
+
RubyLLM::Provider.resolve provider
|
|
77
|
+
end
|
|
78
|
+
|
|
75
79
|
def type # rubocop:disable Metrics/PerceivedComplexity
|
|
76
80
|
if modalities.output.include?('embeddings') && !modalities.output.include?('text')
|
|
77
81
|
'embedding'
|