ruby_llm_community 0.0.5 → 1.0.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 +73 -91
- data/lib/generators/ruby_llm/install/templates/create_models_migration.rb.tt +34 -0
- data/lib/generators/ruby_llm/install/templates/initializer.rb.tt +5 -0
- data/lib/generators/ruby_llm/install/templates/model_model.rb.tt +6 -0
- data/lib/generators/ruby_llm/install_generator.rb +27 -2
- data/lib/ruby_llm/active_record/acts_as.rb +168 -24
- data/lib/ruby_llm/aliases.json +62 -5
- data/lib/ruby_llm/aliases.rb +7 -25
- data/lib/ruby_llm/chat.rb +10 -17
- data/lib/ruby_llm/configuration.rb +5 -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 +21 -0
- data/lib/ruby_llm/message.rb +6 -6
- 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 +2485 -676
- data/lib/ruby_llm/models.rb +65 -34
- data/lib/ruby_llm/provider.rb +8 -8
- 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 +0 -1
- 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 +0 -2
- 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 +0 -1
- 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 +1 -6
- 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 +0 -1
- data/lib/ruby_llm/providers/openai/response.rb +120 -29
- data/lib/ruby_llm/providers/openai/response_media.rb +2 -2
- data/lib/ruby_llm/providers/openai/streaming.rb +107 -47
- data/lib/ruby_llm/providers/openai/tools.rb +1 -1
- 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/railtie.rb +0 -1
- data/lib/ruby_llm/stream_accumulator.rb +72 -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/version.rb +1 -1
- data/lib/ruby_llm_community.rb +5 -3
- data/lib/tasks/models.rake +525 -0
- data/lib/tasks/release.rake +37 -2
- data/lib/tasks/vcr.rake +0 -7
- metadata +13 -4
- 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/embedding.rb
CHANGED
data/lib/ruby_llm/error.rb
CHANGED
@@ -3,13 +3,6 @@
|
|
3
3
|
module RubyLLM
|
4
4
|
# Custom error class that wraps API errors from different providers
|
5
5
|
# into a consistent format with helpful error messages.
|
6
|
-
#
|
7
|
-
# Example:
|
8
|
-
# begin
|
9
|
-
# chat.ask "What's 2+2?"
|
10
|
-
# rescue RubyLLM::Error => e
|
11
|
-
# puts "Couldn't chat with AI: #{e.message}"
|
12
|
-
# end
|
13
6
|
class Error < StandardError
|
14
7
|
attr_reader :response
|
15
8
|
|
@@ -36,7 +29,6 @@ module RubyLLM
|
|
36
29
|
class UnauthorizedError < Error; end
|
37
30
|
|
38
31
|
# Faraday middleware that maps provider-specific API errors to RubyLLM errors.
|
39
|
-
# Uses provider's parse_error method to extract meaningful error messages.
|
40
32
|
class ErrorMiddleware < Faraday::Middleware
|
41
33
|
def initialize(app, options = {})
|
42
34
|
super(app)
|
data/lib/ruby_llm/image.rb
CHANGED
@@ -2,24 +2,22 @@
|
|
2
2
|
|
3
3
|
module RubyLLM
|
4
4
|
# Represents a generated image from an AI model.
|
5
|
-
# Provides an interface to image generation capabilities
|
6
|
-
# from providers like DALL-E and Gemini's Imagen.
|
7
5
|
class Image
|
8
|
-
attr_reader :url, :data, :mime_type, :revised_prompt, :model_id
|
6
|
+
attr_reader :url, :data, :mime_type, :revised_prompt, :model_id, :usage
|
9
7
|
|
10
|
-
def initialize(url: nil, data: nil, mime_type: nil, revised_prompt: nil, model_id: nil)
|
8
|
+
def initialize(url: nil, data: nil, mime_type: nil, revised_prompt: nil, model_id: nil, usage: {}) # rubocop:disable Metrics/ParameterLists
|
11
9
|
@url = url
|
12
10
|
@data = data
|
13
11
|
@mime_type = mime_type
|
14
12
|
@revised_prompt = revised_prompt
|
15
13
|
@model_id = model_id
|
14
|
+
@usage = usage
|
16
15
|
end
|
17
16
|
|
18
17
|
def base64?
|
19
18
|
!@data.nil?
|
20
19
|
end
|
21
20
|
|
22
|
-
# Returns the raw binary image data regardless of source
|
23
21
|
def to_blob
|
24
22
|
if base64?
|
25
23
|
Base64.decode64 @data
|
@@ -29,7 +27,6 @@ module RubyLLM
|
|
29
27
|
end
|
30
28
|
end
|
31
29
|
|
32
|
-
# Saves the image to a file path
|
33
30
|
def save(path)
|
34
31
|
File.binwrite(File.expand_path(path), to_blob)
|
35
32
|
path
|
@@ -40,14 +37,32 @@ module RubyLLM
|
|
40
37
|
provider: nil,
|
41
38
|
assume_model_exists: false,
|
42
39
|
size: '1024x1024',
|
43
|
-
context: nil
|
40
|
+
context: nil,
|
41
|
+
with: nil,
|
42
|
+
params: {})
|
44
43
|
config = context&.config || RubyLLM.config
|
45
44
|
model ||= config.default_image_model
|
46
45
|
model, provider_instance = Models.resolve(model, provider: provider, assume_exists: assume_model_exists,
|
47
46
|
config: config)
|
48
47
|
model_id = model.id
|
49
48
|
|
50
|
-
provider_instance.paint(prompt, model: model_id, size:)
|
49
|
+
provider_instance.paint(prompt, model: model_id, size:, with:, params:)
|
50
|
+
end
|
51
|
+
|
52
|
+
def total_cost
|
53
|
+
input_cost + output_cost
|
54
|
+
end
|
55
|
+
|
56
|
+
def model_info
|
57
|
+
@model_info ||= RubyLLM.models.find(model_id)
|
58
|
+
end
|
59
|
+
|
60
|
+
def input_cost
|
61
|
+
usage['input_tokens'] * model_info.input_price_per_million / 1_000_000
|
62
|
+
end
|
63
|
+
|
64
|
+
def output_cost
|
65
|
+
usage['output_tokens'] * model_info.output_price_per_million / 1_000_000
|
51
66
|
end
|
52
67
|
end
|
53
68
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyLLM
|
4
|
+
# A class representing a file attachment that is an image generated by an LLM.
|
5
|
+
class ImageAttachment < Attachment
|
6
|
+
attr_reader :image, :content, :id, :reasoning_id
|
7
|
+
|
8
|
+
def initialize(data:, mime_type:, model_id:, id: nil, reasoning_id: nil)
|
9
|
+
super(nil, filename: nil)
|
10
|
+
@image = Image.new(data:, mime_type:, model_id:)
|
11
|
+
@content = Base64.strict_decode64(data)
|
12
|
+
@mime_type = mime_type
|
13
|
+
@id = id
|
14
|
+
@reasoning_id = reasoning_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def image?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ruby_llm/message.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RubyLLM
|
4
|
-
# A single message in a chat conversation.
|
5
|
-
# AI responses, or tool interactions. Tracks token usage and handles
|
6
|
-
# the complexities of tool calls and responses.
|
4
|
+
# A single message in a chat conversation.
|
7
5
|
class Message
|
8
6
|
ROLES = %i[system user assistant tool].freeze
|
9
7
|
|
10
8
|
attr_reader :role, :tool_calls, :tool_call_id, :input_tokens, :output_tokens, :model_id, :raw,
|
11
|
-
:cached_tokens, :cache_creation_tokens
|
9
|
+
:cached_tokens, :cache_creation_tokens, :reasoning_id
|
12
10
|
attr_writer :content
|
13
11
|
|
14
12
|
def initialize(options = {})
|
@@ -21,6 +19,7 @@ module RubyLLM
|
|
21
19
|
@tool_call_id = options[:tool_call_id]
|
22
20
|
@cached_tokens = options[:cached_tokens]
|
23
21
|
@cache_creation_tokens = options[:cache_creation_tokens]
|
22
|
+
@reasoning_id = options[:reasoning_id]
|
24
23
|
@raw = options[:raw]
|
25
24
|
|
26
25
|
ensure_valid_role
|
@@ -56,7 +55,8 @@ module RubyLLM
|
|
56
55
|
output_tokens: output_tokens,
|
57
56
|
model_id: model_id,
|
58
57
|
cache_creation_tokens: cache_creation_tokens,
|
59
|
-
cached_tokens: cached_tokens
|
58
|
+
cached_tokens: cached_tokens,
|
59
|
+
reasoning_id: reasoning_id
|
60
60
|
}.compact
|
61
61
|
end
|
62
62
|
|
@@ -70,7 +70,7 @@ module RubyLLM
|
|
70
70
|
case content
|
71
71
|
when String then Content.new(content)
|
72
72
|
when Hash then Content.new(content[:text], content)
|
73
|
-
else content
|
73
|
+
else content
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
data/lib/ruby_llm/model/info.rb
CHANGED
@@ -3,18 +3,22 @@
|
|
3
3
|
module RubyLLM
|
4
4
|
module Model
|
5
5
|
# Information about an AI model's capabilities, pricing, and metadata.
|
6
|
-
# Used by the Models registry to help developers choose the right model
|
7
|
-
# for their needs.
|
8
|
-
#
|
9
|
-
# Example:
|
10
|
-
# model = RubyLLM.models.find('gpt-4')
|
11
|
-
# model.supports_vision? # => true
|
12
|
-
# model.supports_functions? # => true
|
13
|
-
# model.input_price_per_million # => 30.0
|
14
6
|
class Info
|
15
7
|
attr_reader :id, :name, :provider, :family, :created_at, :context_window, :max_output_tokens, :knowledge_cutoff,
|
16
8
|
:modalities, :capabilities, :pricing, :metadata
|
17
9
|
|
10
|
+
# Create a default model with assumed capabilities
|
11
|
+
def self.default(model_id, provider)
|
12
|
+
new(
|
13
|
+
id: model_id,
|
14
|
+
name: model_id.tr('-', ' ').capitalize,
|
15
|
+
provider: provider,
|
16
|
+
capabilities: %w[function_calling streaming vision structured_output],
|
17
|
+
modalities: { input: %w[text image], output: %w[text] },
|
18
|
+
metadata: { warning: 'Assuming model exists, capabilities may not be accurate' }
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
18
22
|
def initialize(data)
|
19
23
|
@id = data[:id]
|
20
24
|
@name = data[:name]
|
@@ -30,7 +34,6 @@ module RubyLLM
|
|
30
34
|
@metadata = data[:metadata] || {}
|
31
35
|
end
|
32
36
|
|
33
|
-
# Capability methods
|
34
37
|
def supports?(capability)
|
35
38
|
capabilities.include?(capability.to_s)
|
36
39
|
end
|
@@ -41,7 +44,6 @@ module RubyLLM
|
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
44
|
-
# Backward compatibility methods
|
45
47
|
def display_name
|
46
48
|
name
|
47
49
|
end
|
@@ -3,12 +3,10 @@
|
|
3
3
|
module RubyLLM
|
4
4
|
module Model
|
5
5
|
# A collection that manages and provides access to different categories of pricing information
|
6
|
-
# (text tokens, images, audio tokens, embeddings)
|
7
6
|
class Pricing
|
8
7
|
def initialize(data)
|
9
8
|
@data = {}
|
10
9
|
|
11
|
-
# Initialize pricing categories
|
12
10
|
%i[text_tokens images audio_tokens embeddings].each do |category|
|
13
11
|
@data[category] = PricingCategory.new(data[category]) if data[category] && !empty_pricing?(data[category])
|
14
12
|
end
|
@@ -33,7 +31,6 @@ module RubyLLM
|
|
33
31
|
private
|
34
32
|
|
35
33
|
def empty_pricing?(data)
|
36
|
-
# Check if all pricing values in this category are zero or nil
|
37
34
|
return true unless data
|
38
35
|
|
39
36
|
%i[standard batch].each do |tier|
|
@@ -11,7 +11,6 @@ module RubyLLM
|
|
11
11
|
@batch = PricingTier.new(data[:batch] || {}) unless empty_tier?(data[:batch])
|
12
12
|
end
|
13
13
|
|
14
|
-
# Shorthand methods that default to standard tier
|
15
14
|
def input
|
16
15
|
standard&.input_per_million
|
17
16
|
end
|
@@ -24,7 +23,6 @@ module RubyLLM
|
|
24
23
|
standard&.cached_input_per_million
|
25
24
|
end
|
26
25
|
|
27
|
-
# Get value for a specific tier
|
28
26
|
def [](key)
|
29
27
|
key == :batch ? batch : standard
|
30
28
|
end
|