ruby_llm_community 0.0.6 → 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 +4 -4
- data/README.md +20 -3
- data/lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb +127 -0
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt +39 -0
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt +24 -0
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/models_controller.rb.tt +14 -0
- data/lib/generators/ruby_llm/chat_ui/templates/jobs/chat_response_job.rb.tt +12 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_chat.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_form.html.erb.tt +29 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/new.html.erb.tt +11 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt +23 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_form.html.erb.tt +21 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt +10 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt +9 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt +30 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt +18 -0
- data/lib/generators/ruby_llm/install/install_generator.rb +227 -0
- data/lib/generators/ruby_llm/install/templates/chat_model.rb.tt +2 -2
- data/lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt +4 -4
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +8 -7
- data/lib/generators/ruby_llm/install/templates/create_models_migration.rb.tt +43 -0
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +6 -5
- data/lib/generators/ruby_llm/install/templates/initializer.rb.tt +10 -4
- data/lib/generators/ruby_llm/install/templates/message_model.rb.tt +4 -3
- data/lib/generators/ruby_llm/install/templates/model_model.rb.tt +3 -0
- data/lib/generators/ruby_llm/install/templates/tool_call_model.rb.tt +2 -2
- data/lib/generators/ruby_llm/upgrade_to_v1_7/templates/migration.rb.tt +137 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb +170 -0
- data/lib/ruby_llm/active_record/acts_as.rb +112 -332
- data/lib/ruby_llm/active_record/acts_as_legacy.rb +403 -0
- data/lib/ruby_llm/active_record/chat_methods.rb +336 -0
- data/lib/ruby_llm/active_record/message_methods.rb +72 -0
- data/lib/ruby_llm/active_record/model_methods.rb +84 -0
- data/lib/ruby_llm/aliases.json +130 -11
- data/lib/ruby_llm/aliases.rb +7 -25
- data/lib/ruby_llm/attachment.rb +22 -0
- data/lib/ruby_llm/chat.rb +10 -17
- data/lib/ruby_llm/configuration.rb +11 -12
- data/lib/ruby_llm/connection.rb +4 -4
- data/lib/ruby_llm/connection_multipart.rb +19 -0
- data/lib/ruby_llm/content.rb +5 -2
- data/lib/ruby_llm/embedding.rb +1 -2
- data/lib/ruby_llm/error.rb +0 -8
- data/lib/ruby_llm/image.rb +23 -8
- data/lib/ruby_llm/image_attachment.rb +30 -0
- data/lib/ruby_llm/message.rb +7 -7
- data/lib/ruby_llm/model/info.rb +12 -10
- data/lib/ruby_llm/model/pricing.rb +0 -3
- data/lib/ruby_llm/model/pricing_category.rb +0 -2
- data/lib/ruby_llm/model/pricing_tier.rb +0 -1
- data/lib/ruby_llm/models.json +4705 -2144
- data/lib/ruby_llm/models.rb +56 -35
- data/lib/ruby_llm/provider.rb +14 -12
- data/lib/ruby_llm/providers/anthropic/capabilities.rb +1 -46
- data/lib/ruby_llm/providers/anthropic/chat.rb +2 -2
- data/lib/ruby_llm/providers/anthropic/media.rb +1 -2
- data/lib/ruby_llm/providers/anthropic/tools.rb +1 -2
- data/lib/ruby_llm/providers/anthropic.rb +1 -2
- data/lib/ruby_llm/providers/bedrock/chat.rb +2 -4
- data/lib/ruby_llm/providers/bedrock/media.rb +0 -1
- data/lib/ruby_llm/providers/bedrock/models.rb +19 -3
- data/lib/ruby_llm/providers/bedrock/streaming/base.rb +0 -12
- data/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb +0 -7
- data/lib/ruby_llm/providers/bedrock/streaming/message_processing.rb +0 -12
- data/lib/ruby_llm/providers/bedrock/streaming/payload_processing.rb +0 -12
- data/lib/ruby_llm/providers/bedrock/streaming/prelude_handling.rb +0 -13
- data/lib/ruby_llm/providers/bedrock/streaming.rb +0 -18
- data/lib/ruby_llm/providers/bedrock.rb +1 -2
- data/lib/ruby_llm/providers/deepseek/capabilities.rb +1 -2
- data/lib/ruby_llm/providers/deepseek/chat.rb +0 -1
- data/lib/ruby_llm/providers/gemini/capabilities.rb +28 -100
- data/lib/ruby_llm/providers/gemini/chat.rb +57 -29
- data/lib/ruby_llm/providers/gemini/embeddings.rb +0 -2
- data/lib/ruby_llm/providers/gemini/images.rb +1 -2
- data/lib/ruby_llm/providers/gemini/media.rb +1 -2
- data/lib/ruby_llm/providers/gemini/models.rb +1 -2
- data/lib/ruby_llm/providers/gemini/streaming.rb +15 -1
- data/lib/ruby_llm/providers/gemini/tools.rb +0 -5
- data/lib/ruby_llm/providers/gpustack/chat.rb +11 -1
- data/lib/ruby_llm/providers/gpustack/media.rb +45 -0
- data/lib/ruby_llm/providers/gpustack/models.rb +44 -9
- data/lib/ruby_llm/providers/gpustack.rb +1 -0
- data/lib/ruby_llm/providers/mistral/capabilities.rb +2 -10
- data/lib/ruby_llm/providers/mistral/chat.rb +0 -2
- data/lib/ruby_llm/providers/mistral/embeddings.rb +0 -3
- data/lib/ruby_llm/providers/mistral/models.rb +0 -1
- data/lib/ruby_llm/providers/ollama/chat.rb +0 -1
- data/lib/ruby_llm/providers/ollama/media.rb +2 -7
- data/lib/ruby_llm/providers/ollama/models.rb +36 -0
- data/lib/ruby_llm/providers/ollama.rb +1 -0
- data/lib/ruby_llm/providers/openai/capabilities.rb +3 -16
- data/lib/ruby_llm/providers/openai/chat.rb +1 -3
- data/lib/ruby_llm/providers/openai/embeddings.rb +0 -3
- data/lib/ruby_llm/providers/openai/images.rb +73 -3
- data/lib/ruby_llm/providers/openai/media.rb +4 -5
- data/lib/ruby_llm/providers/openai/response.rb +121 -29
- data/lib/ruby_llm/providers/openai/response_media.rb +3 -3
- data/lib/ruby_llm/providers/openai/streaming.rb +110 -47
- data/lib/ruby_llm/providers/openai/tools.rb +12 -7
- data/lib/ruby_llm/providers/openai.rb +1 -3
- data/lib/ruby_llm/providers/openai_base.rb +2 -2
- data/lib/ruby_llm/providers/openrouter/models.rb +1 -16
- data/lib/ruby_llm/providers/perplexity/capabilities.rb +0 -1
- data/lib/ruby_llm/providers/perplexity/chat.rb +0 -1
- data/lib/ruby_llm/providers/perplexity.rb +1 -5
- data/lib/ruby_llm/providers/vertexai/chat.rb +14 -0
- data/lib/ruby_llm/providers/vertexai/embeddings.rb +32 -0
- data/lib/ruby_llm/providers/vertexai/models.rb +130 -0
- data/lib/ruby_llm/providers/vertexai/streaming.rb +14 -0
- data/lib/ruby_llm/providers/vertexai.rb +55 -0
- data/lib/ruby_llm/providers/xai/capabilities.rb +166 -0
- data/lib/ruby_llm/providers/xai/chat.rb +15 -0
- data/lib/ruby_llm/providers/xai/models.rb +48 -0
- data/lib/ruby_llm/providers/xai.rb +46 -0
- data/lib/ruby_llm/railtie.rb +20 -4
- data/lib/ruby_llm/stream_accumulator.rb +68 -10
- data/lib/ruby_llm/streaming.rb +16 -25
- data/lib/ruby_llm/tool.rb +2 -19
- data/lib/ruby_llm/tool_call.rb +0 -9
- data/lib/ruby_llm/utils.rb +5 -9
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm_community.rb +8 -5
- data/lib/tasks/models.rake +549 -0
- data/lib/tasks/release.rake +37 -2
- data/lib/tasks/ruby_llm.rake +15 -0
- data/lib/tasks/vcr.rake +2 -9
- metadata +44 -6
- data/lib/generators/ruby_llm/install/templates/INSTALL_INFO.md.tt +0 -108
- data/lib/generators/ruby_llm/install_generator.rb +0 -121
- data/lib/tasks/aliases.rake +0 -235
- data/lib/tasks/models_docs.rake +0 -224
- data/lib/tasks/models_update.rake +0 -108
data/lib/ruby_llm/streaming.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RubyLLM
|
4
|
-
# Handles streaming responses from AI providers.
|
5
|
-
# chunked responses, accumulate content, and handle provider-specific streaming formats.
|
6
|
-
# Each provider implements provider-specific parsing while sharing common stream handling
|
7
|
-
# patterns.
|
4
|
+
# Handles streaming responses from AI providers.
|
8
5
|
module Streaming
|
9
6
|
module_function
|
10
7
|
|
@@ -12,17 +9,14 @@ module RubyLLM
|
|
12
9
|
accumulator = StreamAccumulator.new
|
13
10
|
|
14
11
|
response = connection.post stream_url, payload do |req|
|
15
|
-
# Merge additional headers, with existing headers taking precedence
|
16
12
|
req.headers = additional_headers.merge(req.headers) unless additional_headers.empty?
|
17
|
-
if
|
18
|
-
|
19
|
-
req.options.on_data = handle_stream do |chunk|
|
13
|
+
if faraday_1?
|
14
|
+
req.options[:on_data] = handle_stream do |chunk|
|
20
15
|
accumulator.add chunk
|
21
16
|
block.call chunk
|
22
17
|
end
|
23
18
|
else
|
24
|
-
|
25
|
-
req.options[:on_data] = handle_stream do |chunk|
|
19
|
+
req.options.on_data = handle_stream do |chunk|
|
26
20
|
accumulator.add chunk
|
27
21
|
block.call chunk
|
28
22
|
end
|
@@ -30,7 +24,7 @@ module RubyLLM
|
|
30
24
|
end
|
31
25
|
|
32
26
|
message = accumulator.to_message(response)
|
33
|
-
RubyLLM.logger.debug "Stream completed: #{message.
|
27
|
+
RubyLLM.logger.debug "Stream completed: #{message.content}"
|
34
28
|
message
|
35
29
|
end
|
36
30
|
|
@@ -42,6 +36,10 @@ module RubyLLM
|
|
42
36
|
|
43
37
|
private
|
44
38
|
|
39
|
+
def faraday_1?
|
40
|
+
Faraday::VERSION.start_with?('1')
|
41
|
+
end
|
42
|
+
|
45
43
|
def to_json_stream(&)
|
46
44
|
buffer = +''
|
47
45
|
parser = EventStreamParser::Parser.new
|
@@ -50,11 +48,9 @@ module RubyLLM
|
|
50
48
|
end
|
51
49
|
|
52
50
|
def create_stream_processor(parser, buffer, &)
|
53
|
-
if
|
54
|
-
# Faraday 1.x: on_data receives (chunk, size)
|
51
|
+
if faraday_1?
|
55
52
|
legacy_stream_processor(parser, &)
|
56
53
|
else
|
57
|
-
# Faraday 2.x: on_data receives (chunk, bytes, env)
|
58
54
|
stream_processor(parser, buffer, &)
|
59
55
|
end
|
60
56
|
end
|
@@ -94,12 +90,10 @@ module RubyLLM
|
|
94
90
|
status, _message = parse_streaming_error(error_data)
|
95
91
|
parsed_data = JSON.parse(error_data)
|
96
92
|
|
97
|
-
|
98
|
-
error_response = if env
|
99
|
-
env.merge(body: parsed_data, status: status)
|
100
|
-
else
|
101
|
-
# For Faraday v1, create a simple object that responds to .status and .body
|
93
|
+
error_response = if faraday_1?
|
102
94
|
Struct.new(:body, :status).new(parsed_data, status)
|
95
|
+
else
|
96
|
+
env.merge(body: parsed_data, status: status)
|
103
97
|
end
|
104
98
|
|
105
99
|
ErrorMiddleware.parse_error(provider: self, response: error_response)
|
@@ -137,12 +131,10 @@ module RubyLLM
|
|
137
131
|
status, _message = parse_streaming_error(data)
|
138
132
|
parsed_data = JSON.parse(data)
|
139
133
|
|
140
|
-
|
141
|
-
error_response = if env
|
142
|
-
env.merge(body: parsed_data, status: status)
|
143
|
-
else
|
144
|
-
# For Faraday v1, create a simple object that responds to .status and .body
|
134
|
+
error_response = if faraday_1?
|
145
135
|
Struct.new(:body, :status).new(parsed_data, status)
|
136
|
+
else
|
137
|
+
env.merge(body: parsed_data, status: status)
|
146
138
|
end
|
147
139
|
|
148
140
|
ErrorMiddleware.parse_error(provider: self, response: error_response)
|
@@ -150,7 +142,6 @@ module RubyLLM
|
|
150
142
|
RubyLLM.logger.debug "Failed to parse error event: #{e.message}"
|
151
143
|
end
|
152
144
|
|
153
|
-
# Default implementation - providers should override this method
|
154
145
|
def parse_streaming_error(data)
|
155
146
|
error_data = JSON.parse(data)
|
156
147
|
[500, error_data['message'] || 'Unknown streaming error']
|
data/lib/ruby_llm/tool.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RubyLLM
|
4
|
-
# Parameter definition for Tool methods.
|
5
|
-
# descriptions, and whether parameters are required.
|
4
|
+
# Parameter definition for Tool methods.
|
6
5
|
class Parameter
|
7
6
|
attr_reader :name, :type, :description, :required
|
8
7
|
|
@@ -14,23 +13,7 @@ module RubyLLM
|
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
|
-
# Base class for creating tools that AI models can use
|
18
|
-
# interface for defining parameters and implementing tool behavior.
|
19
|
-
#
|
20
|
-
# Example:
|
21
|
-
# require 'tzinfo'
|
22
|
-
#
|
23
|
-
# class TimeInfo < RubyLLM::Tool
|
24
|
-
# description 'Gets the current time in various timezones'
|
25
|
-
# param :timezone, desc: "Timezone name (e.g., 'UTC', 'America/New_York')"
|
26
|
-
#
|
27
|
-
# def execute(timezone:)
|
28
|
-
# time = TZInfo::Timezone.get(timezone).now.strftime('%Y-%m-%d %H:%M:%S')
|
29
|
-
# "Current time in #{timezone}: #{time}"
|
30
|
-
# rescue StandardError => e
|
31
|
-
# { error: e.message }
|
32
|
-
# end
|
33
|
-
# end
|
16
|
+
# Base class for creating tools that AI models can use
|
34
17
|
class Tool
|
35
18
|
# Stops conversation continuation after tool execution
|
36
19
|
class Halt
|
data/lib/ruby_llm/tool_call.rb
CHANGED
@@ -2,15 +2,6 @@
|
|
2
2
|
|
3
3
|
module RubyLLM
|
4
4
|
# Represents a function call from an AI model to a Tool.
|
5
|
-
# Encapsulates the function name, arguments, and execution results
|
6
|
-
# in a clean Ruby interface.
|
7
|
-
#
|
8
|
-
# Example:
|
9
|
-
# tool_call = ToolCall.new(
|
10
|
-
# id: "call_123",
|
11
|
-
# name: "calculator",
|
12
|
-
# arguments: { expression: "2 + 2" }
|
13
|
-
# )
|
14
5
|
class ToolCall
|
15
6
|
attr_reader :id, :name, :arguments
|
16
7
|
|
data/lib/ruby_llm/utils.rb
CHANGED
@@ -5,10 +5,6 @@ module RubyLLM
|
|
5
5
|
module Utils
|
6
6
|
module_function
|
7
7
|
|
8
|
-
def format_text_file_for_llm(text_file)
|
9
|
-
"<file name='#{text_file.filename}' mime_type='#{text_file.mime_type}'>#{text_file.content}</file>"
|
10
|
-
end
|
11
|
-
|
12
8
|
def hash_get(hash, key)
|
13
9
|
hash[key.to_sym] || hash[key.to_s]
|
14
10
|
end
|
@@ -36,12 +32,12 @@ module RubyLLM
|
|
36
32
|
value.is_a?(Date) ? value : Date.parse(value.to_s)
|
37
33
|
end
|
38
34
|
|
39
|
-
def deep_merge(
|
40
|
-
|
41
|
-
if
|
42
|
-
deep_merge(
|
35
|
+
def deep_merge(original, overrides)
|
36
|
+
original.merge(overrides) do |_key, original_value, overrides_value|
|
37
|
+
if original_value.is_a?(Hash) && overrides_value.is_a?(Hash)
|
38
|
+
deep_merge(original_value, overrides_value)
|
43
39
|
else
|
44
|
-
|
40
|
+
overrides_value
|
45
41
|
end
|
46
42
|
end
|
47
43
|
end
|
data/lib/ruby_llm/version.rb
CHANGED
data/lib/ruby_llm_community.rb
CHANGED
@@ -4,6 +4,8 @@ require 'base64'
|
|
4
4
|
require 'event_stream_parser'
|
5
5
|
require 'faraday'
|
6
6
|
require 'faraday/retry'
|
7
|
+
require 'faraday/multipart'
|
8
|
+
|
7
9
|
require 'json'
|
8
10
|
require 'logger'
|
9
11
|
require 'securerandom'
|
@@ -23,12 +25,13 @@ loader.inflector.inflect(
|
|
23
25
|
'gpustack' => 'GPUStack',
|
24
26
|
'mistral' => 'Mistral',
|
25
27
|
'pdf' => 'PDF',
|
26
|
-
'version' => 'VERSION'
|
28
|
+
'version' => 'VERSION',
|
29
|
+
'vertexai' => 'VertexAI',
|
30
|
+
'xai' => 'XAI',
|
31
|
+
'UI' => 'UI'
|
27
32
|
)
|
28
33
|
loader.ignore("#{__dir__}/shims")
|
29
34
|
loader.ignore("#{__dir__}/tasks")
|
30
|
-
loader.ignore("#{__dir__}/ruby_llm/railtie")
|
31
|
-
loader.ignore("#{__dir__}/ruby_llm/active_record")
|
32
35
|
loader.ignore("#{__dir__}/generators")
|
33
36
|
loader.setup
|
34
37
|
|
@@ -37,8 +40,6 @@ module RubyLlmCommunity
|
|
37
40
|
end
|
38
41
|
|
39
42
|
# A delightful Ruby interface to modern AI language models.
|
40
|
-
# Provides a unified way to interact with models from OpenAI, Anthropic and others
|
41
|
-
# with a focus on developer happiness and convention over configuration.
|
42
43
|
module RubyLLM
|
43
44
|
class Error < StandardError; end
|
44
45
|
|
@@ -97,6 +98,8 @@ RubyLLM::Provider.register :ollama, RubyLLM::Providers::Ollama
|
|
97
98
|
RubyLLM::Provider.register :openai, RubyLLM::Providers::OpenAI
|
98
99
|
RubyLLM::Provider.register :openrouter, RubyLLM::Providers::OpenRouter
|
99
100
|
RubyLLM::Provider.register :perplexity, RubyLLM::Providers::Perplexity
|
101
|
+
RubyLLM::Provider.register :vertexai, RubyLLM::Providers::VertexAI
|
102
|
+
RubyLLM::Provider.register :xai, RubyLLM::Providers::XAI
|
100
103
|
|
101
104
|
if defined?(Rails::Railtie)
|
102
105
|
require 'ruby_llm/railtie'
|