ruby_llm 0.1.0.pre36 → 0.1.0.pre38

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.
@@ -20,8 +20,7 @@ module RubyLLM
20
20
  # @return [Integer] the maximum output tokens
21
21
  def determine_max_tokens(model_id)
22
22
  case model_id
23
- when /claude-3-7-sonnet/ then 8_192 # Can be increased to 64K with extended thinking
24
- when /claude-3-5/ then 8_192
23
+ when /claude-3-(7-sonnet|5)/ then 8_192 # Can be increased to 64K with extended thinking
25
24
  else 4_096 # Claude 3 Opus and Haiku
26
25
  end
27
26
  end
@@ -35,7 +35,7 @@ module RubyLLM
35
35
 
36
36
  def extract_text_content(blocks)
37
37
  text_blocks = blocks.select { |c| c['type'] == 'text' }
38
- text_blocks.map { |c| c['text'] }.join('')
38
+ text_blocks.map { |c| c['text'] }.join
39
39
  end
40
40
 
41
41
  def build_message(data, content, tool_use)
@@ -68,8 +68,7 @@ module RubyLLM
68
68
 
69
69
  def convert_role(role)
70
70
  case role
71
- when :tool then 'user'
72
- when :user then 'user'
71
+ when :tool, :user then 'user'
73
72
  else 'assistant'
74
73
  end
75
74
  end
@@ -65,8 +65,8 @@ module RubyLLM
65
65
  # Determines if the model supports JSON mode
66
66
  # @param model_id [String] the model identifier
67
67
  # @return [Boolean] true if the model supports JSON mode
68
- def supports_json_mode?(model_id)
69
- model_id.match?(/deepseek-chat/) # Only deepseek-chat supports JSON mode
68
+ def supports_json_mode?(_model_id)
69
+ false # DeepSeek function calling is unstable
70
70
  end
71
71
 
72
72
  # Returns a formatted display name for the model
@@ -95,7 +95,6 @@ module RubyLLM
95
95
  # @return [Symbol] the model family
96
96
  def model_family(model_id)
97
97
  case model_id
98
- when /deepseek-chat/ then :chat
99
98
  when /deepseek-reasoner/ then :reasoner
100
99
  else :chat # Default to chat family
101
100
  end
@@ -97,7 +97,7 @@ module RubyLLM
97
97
  .join(' ')
98
98
  .gsub(/(\d+\.\d+)/, ' \1') # Add space before version numbers
99
99
  .gsub(/\s+/, ' ') # Clean up multiple spaces
100
- .gsub(/Aqa/, 'AQA') # Special case for AQA
100
+ .gsub('Aqa', 'AQA') # Special case for AQA
101
101
  .strip
102
102
  end
103
103
 
@@ -15,9 +15,7 @@ module RubyLLM
15
15
  when /o1-2024/, /o3-mini/, /o3-mini-2025/ then 200_000
16
16
  when /gpt-4o/, /gpt-4o-mini/, /gpt-4-turbo/, /o1-mini/ then 128_000
17
17
  when /gpt-4-0[0-9]{3}/ then 8_192
18
- when /gpt-3.5-turbo-instruct/ then 4_096
19
- when /gpt-3.5/ then 16_385
20
- when /babbage-002/, /davinci-002/ then 16_384
18
+ when /gpt-3.5-turbo$/, /babbage-002/, /davinci-002/, /16k/ then 16_385
21
19
  else 4_096
22
20
  end
23
21
  end
@@ -25,16 +23,12 @@ module RubyLLM
25
23
  # Returns the maximum output tokens for the given model ID
26
24
  # @param model_id [String] the model identifier
27
25
  # @return [Integer] the maximum output tokens
28
- def max_tokens_for(model_id) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
26
+ def max_tokens_for(model_id)
29
27
  case model_id
30
28
  when /o1-2024/, /o3-mini/, /o3-mini-2025/ then 100_000
31
29
  when /o1-mini-2024/ then 65_536
32
- when /gpt-4o-2024-05-13/ then 4_096
33
- when /gpt-4o-realtime/, /gpt-4o-mini-realtime/ then 4_096
34
- when /gpt-4o/, /gpt-4o-mini/, /gpt-4o-audio/, /gpt-4o-mini-audio/ then 16_384
30
+ when /gpt-4o/, /gpt-4o-mini/, /gpt-4o-audio/, /gpt-4o-mini-audio/, /babbage-002/, /davinci-002/ then 16_384
35
31
  when /gpt-4-0[0-9]{3}/ then 8_192
36
- when /gpt-4-turbo/, /gpt-3.5-turbo/ then 4_096
37
- when /babbage-002/, /davinci-002/ then 16_384
38
32
  else 4_096
39
33
  end
40
34
  end
@@ -211,7 +205,7 @@ module RubyLLM
211
205
  # @return [String] the humanized model name
212
206
  def humanize(id)
213
207
  id.tr('-', ' ')
214
- .split(' ')
208
+ .split
215
209
  .map(&:capitalize)
216
210
  .join(' ')
217
211
  end
@@ -229,12 +223,12 @@ module RubyLLM
229
223
  .gsub(/^Chatgpt /, 'ChatGPT-')
230
224
  .gsub(/^Tts /, 'TTS-')
231
225
  .gsub(/^Dall E /, 'DALL-E-')
232
- .gsub(/3\.5 /, '3.5-')
233
- .gsub(/4 /, '4-')
226
+ .gsub('3.5 ', '3.5-')
227
+ .gsub('4 ', '4-')
234
228
  .gsub(/4o (?=Mini|Preview|Turbo|Audio|Realtime)/, '4o-')
235
229
  .gsub(/\bHd\b/, 'HD')
236
- .gsub(/Omni Moderation/, 'Omni-Moderation')
237
- .gsub(/Text Moderation/, 'Text-Moderation')
230
+ .gsub('Omni Moderation', 'Omni-Moderation')
231
+ .gsub('Text Moderation', 'Text-Moderation')
238
232
  end
239
233
  end
240
234
  end
@@ -25,7 +25,7 @@ module RubyLLM
25
25
  vectors = data['data'].map { |d| d['embedding'] }
26
26
 
27
27
  # If we only got one embedding, return it as a single vector
28
- vectors = vectors.size == 1 ? vectors.first : vectors
28
+ vectors = vectors.first if vectors.size == 1
29
29
 
30
30
  Embedding.new(
31
31
  vectors: vectors,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyLLM
4
- VERSION = '0.1.0.pre36'
4
+ VERSION = '0.1.0.pre38'
5
5
  end
@@ -70,8 +70,8 @@ namespace :models do # rubocop:disable Metrics/BlockLength
70
70
  RubyLLM.configure do |config|
71
71
  config.openai_api_key = ENV.fetch('OPENAI_API_KEY')
72
72
  config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY')
73
- config.gemini_api_key = ENV['GEMINI_API_KEY']
74
- config.deepseek_api_key = ENV['DEEPSEEK_API_KEY']
73
+ config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil)
74
+ config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil)
75
75
  end
76
76
 
77
77
  # Get all models
data/ruby_llm.gemspec CHANGED
@@ -9,19 +9,21 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ['carmine@paolino.me']
10
10
 
11
11
  spec.summary = 'Beautiful Ruby interface to modern AI'
12
- spec.description = 'A delightful Ruby way to work with AI. Chat in text, analyze and generate images, understand' \
13
- ' audio, and use tools through a unified interface to OpenAI, Anthropic, Google, and DeepSeek.' \
14
- ' Built for developer happiness with automatic token counting, proper streaming, and Rails' \
15
- ' integration. No wrapping your head around multiple APIs - just clean Ruby code that works.'
16
- spec.homepage = 'https://github.com/crmne/ruby_llm'
12
+ spec.description = 'A delightful Ruby way to work with AI. Chat in text, analyze and generate images, understand ' \
13
+ 'audio, and use tools through a unified interface to OpenAI, Anthropic, Google, and DeepSeek. ' \
14
+ 'Built for developer happiness with automatic token counting, proper streaming, and Rails ' \
15
+ 'integration. No wrapping your head around multiple APIs - just clean Ruby code that works.'
16
+ spec.homepage = 'https://rubyllm.com'
17
17
  spec.license = 'MIT'
18
18
  spec.required_ruby_version = Gem::Requirement.new('>= 3.1.0')
19
19
 
20
20
  spec.metadata['homepage_uri'] = spec.homepage
21
- spec.metadata['source_code_uri'] = spec.homepage
22
- spec.metadata['changelog_uri'] = "#{spec.homepage}/commits/main"
21
+ spec.metadata['source_code_uri'] = 'https://github.com/crmne/ruby_llm'
22
+ spec.metadata['changelog_uri'] = "#{spec.metadata['source_code_uri']}/commits/main"
23
23
  spec.metadata['documentation_uri'] = spec.homepage
24
- spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
24
+ spec.metadata['bug_tracker_uri'] = "#{spec.metadata['source_code_uri']}/issues"
25
+
26
+ spec.metadata['rubygems_mfa_required'] = 'true'
25
27
 
26
28
  # Specify which files should be added to the gem when it is released.
27
29
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -38,28 +40,4 @@ Gem::Specification.new do |spec|
38
40
  spec.add_dependency 'faraday-multipart', '>= 1.0'
39
41
  spec.add_dependency 'faraday-retry', '>= 2.0'
40
42
  spec.add_dependency 'zeitwerk', '>= 2.6'
41
-
42
- # Rails integration dependencies
43
- spec.add_development_dependency 'activerecord', '>= 6.0', '< 9.0'
44
- spec.add_development_dependency 'activesupport', '>= 6.0', '< 9.0'
45
-
46
- # Development dependencies
47
- spec.add_development_dependency 'bundler', '>= 2.0'
48
- spec.add_development_dependency 'codecov'
49
- spec.add_development_dependency 'dotenv'
50
- spec.add_development_dependency 'irb'
51
- spec.add_development_dependency 'nokogiri'
52
- spec.add_development_dependency 'overcommit', '>= 0.66'
53
- spec.add_development_dependency 'pry', '>= 0.14'
54
- spec.add_development_dependency 'rake', '>= 13.0'
55
- spec.add_development_dependency 'rdoc'
56
- spec.add_development_dependency 'reline'
57
- spec.add_development_dependency 'rspec', '~> 3.12'
58
- spec.add_development_dependency 'rubocop', '>= 1.0'
59
- spec.add_development_dependency 'rubocop-rake', '>= 0.6'
60
- spec.add_development_dependency 'simplecov', '>= 0.21'
61
- spec.add_development_dependency 'simplecov-cobertura'
62
- spec.add_development_dependency 'sqlite3'
63
- spec.add_development_dependency 'webmock', '~> 3.18'
64
- spec.add_development_dependency 'yard', '>= 0.9'
65
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_llm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre36
4
+ version: 0.1.0.pre38
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carmine Paolino
@@ -86,298 +86,6 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '2.6'
89
- - !ruby/object:Gem::Dependency
90
- name: activerecord
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: '6.0'
96
- - - "<"
97
- - !ruby/object:Gem::Version
98
- version: '9.0'
99
- type: :development
100
- prerelease: false
101
- version_requirements: !ruby/object:Gem::Requirement
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: '6.0'
106
- - - "<"
107
- - !ruby/object:Gem::Version
108
- version: '9.0'
109
- - !ruby/object:Gem::Dependency
110
- name: activesupport
111
- requirement: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- version: '6.0'
116
- - - "<"
117
- - !ruby/object:Gem::Version
118
- version: '9.0'
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- version: '6.0'
126
- - - "<"
127
- - !ruby/object:Gem::Version
128
- version: '9.0'
129
- - !ruby/object:Gem::Dependency
130
- name: bundler
131
- requirement: !ruby/object:Gem::Requirement
132
- requirements:
133
- - - ">="
134
- - !ruby/object:Gem::Version
135
- version: '2.0'
136
- type: :development
137
- prerelease: false
138
- version_requirements: !ruby/object:Gem::Requirement
139
- requirements:
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- version: '2.0'
143
- - !ruby/object:Gem::Dependency
144
- name: codecov
145
- requirement: !ruby/object:Gem::Requirement
146
- requirements:
147
- - - ">="
148
- - !ruby/object:Gem::Version
149
- version: '0'
150
- type: :development
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- requirements:
154
- - - ">="
155
- - !ruby/object:Gem::Version
156
- version: '0'
157
- - !ruby/object:Gem::Dependency
158
- name: dotenv
159
- requirement: !ruby/object:Gem::Requirement
160
- requirements:
161
- - - ">="
162
- - !ruby/object:Gem::Version
163
- version: '0'
164
- type: :development
165
- prerelease: false
166
- version_requirements: !ruby/object:Gem::Requirement
167
- requirements:
168
- - - ">="
169
- - !ruby/object:Gem::Version
170
- version: '0'
171
- - !ruby/object:Gem::Dependency
172
- name: irb
173
- requirement: !ruby/object:Gem::Requirement
174
- requirements:
175
- - - ">="
176
- - !ruby/object:Gem::Version
177
- version: '0'
178
- type: :development
179
- prerelease: false
180
- version_requirements: !ruby/object:Gem::Requirement
181
- requirements:
182
- - - ">="
183
- - !ruby/object:Gem::Version
184
- version: '0'
185
- - !ruby/object:Gem::Dependency
186
- name: nokogiri
187
- requirement: !ruby/object:Gem::Requirement
188
- requirements:
189
- - - ">="
190
- - !ruby/object:Gem::Version
191
- version: '0'
192
- type: :development
193
- prerelease: false
194
- version_requirements: !ruby/object:Gem::Requirement
195
- requirements:
196
- - - ">="
197
- - !ruby/object:Gem::Version
198
- version: '0'
199
- - !ruby/object:Gem::Dependency
200
- name: overcommit
201
- requirement: !ruby/object:Gem::Requirement
202
- requirements:
203
- - - ">="
204
- - !ruby/object:Gem::Version
205
- version: '0.66'
206
- type: :development
207
- prerelease: false
208
- version_requirements: !ruby/object:Gem::Requirement
209
- requirements:
210
- - - ">="
211
- - !ruby/object:Gem::Version
212
- version: '0.66'
213
- - !ruby/object:Gem::Dependency
214
- name: pry
215
- requirement: !ruby/object:Gem::Requirement
216
- requirements:
217
- - - ">="
218
- - !ruby/object:Gem::Version
219
- version: '0.14'
220
- type: :development
221
- prerelease: false
222
- version_requirements: !ruby/object:Gem::Requirement
223
- requirements:
224
- - - ">="
225
- - !ruby/object:Gem::Version
226
- version: '0.14'
227
- - !ruby/object:Gem::Dependency
228
- name: rake
229
- requirement: !ruby/object:Gem::Requirement
230
- requirements:
231
- - - ">="
232
- - !ruby/object:Gem::Version
233
- version: '13.0'
234
- type: :development
235
- prerelease: false
236
- version_requirements: !ruby/object:Gem::Requirement
237
- requirements:
238
- - - ">="
239
- - !ruby/object:Gem::Version
240
- version: '13.0'
241
- - !ruby/object:Gem::Dependency
242
- name: rdoc
243
- requirement: !ruby/object:Gem::Requirement
244
- requirements:
245
- - - ">="
246
- - !ruby/object:Gem::Version
247
- version: '0'
248
- type: :development
249
- prerelease: false
250
- version_requirements: !ruby/object:Gem::Requirement
251
- requirements:
252
- - - ">="
253
- - !ruby/object:Gem::Version
254
- version: '0'
255
- - !ruby/object:Gem::Dependency
256
- name: reline
257
- requirement: !ruby/object:Gem::Requirement
258
- requirements:
259
- - - ">="
260
- - !ruby/object:Gem::Version
261
- version: '0'
262
- type: :development
263
- prerelease: false
264
- version_requirements: !ruby/object:Gem::Requirement
265
- requirements:
266
- - - ">="
267
- - !ruby/object:Gem::Version
268
- version: '0'
269
- - !ruby/object:Gem::Dependency
270
- name: rspec
271
- requirement: !ruby/object:Gem::Requirement
272
- requirements:
273
- - - "~>"
274
- - !ruby/object:Gem::Version
275
- version: '3.12'
276
- type: :development
277
- prerelease: false
278
- version_requirements: !ruby/object:Gem::Requirement
279
- requirements:
280
- - - "~>"
281
- - !ruby/object:Gem::Version
282
- version: '3.12'
283
- - !ruby/object:Gem::Dependency
284
- name: rubocop
285
- requirement: !ruby/object:Gem::Requirement
286
- requirements:
287
- - - ">="
288
- - !ruby/object:Gem::Version
289
- version: '1.0'
290
- type: :development
291
- prerelease: false
292
- version_requirements: !ruby/object:Gem::Requirement
293
- requirements:
294
- - - ">="
295
- - !ruby/object:Gem::Version
296
- version: '1.0'
297
- - !ruby/object:Gem::Dependency
298
- name: rubocop-rake
299
- requirement: !ruby/object:Gem::Requirement
300
- requirements:
301
- - - ">="
302
- - !ruby/object:Gem::Version
303
- version: '0.6'
304
- type: :development
305
- prerelease: false
306
- version_requirements: !ruby/object:Gem::Requirement
307
- requirements:
308
- - - ">="
309
- - !ruby/object:Gem::Version
310
- version: '0.6'
311
- - !ruby/object:Gem::Dependency
312
- name: simplecov
313
- requirement: !ruby/object:Gem::Requirement
314
- requirements:
315
- - - ">="
316
- - !ruby/object:Gem::Version
317
- version: '0.21'
318
- type: :development
319
- prerelease: false
320
- version_requirements: !ruby/object:Gem::Requirement
321
- requirements:
322
- - - ">="
323
- - !ruby/object:Gem::Version
324
- version: '0.21'
325
- - !ruby/object:Gem::Dependency
326
- name: simplecov-cobertura
327
- requirement: !ruby/object:Gem::Requirement
328
- requirements:
329
- - - ">="
330
- - !ruby/object:Gem::Version
331
- version: '0'
332
- type: :development
333
- prerelease: false
334
- version_requirements: !ruby/object:Gem::Requirement
335
- requirements:
336
- - - ">="
337
- - !ruby/object:Gem::Version
338
- version: '0'
339
- - !ruby/object:Gem::Dependency
340
- name: sqlite3
341
- requirement: !ruby/object:Gem::Requirement
342
- requirements:
343
- - - ">="
344
- - !ruby/object:Gem::Version
345
- version: '0'
346
- type: :development
347
- prerelease: false
348
- version_requirements: !ruby/object:Gem::Requirement
349
- requirements:
350
- - - ">="
351
- - !ruby/object:Gem::Version
352
- version: '0'
353
- - !ruby/object:Gem::Dependency
354
- name: webmock
355
- requirement: !ruby/object:Gem::Requirement
356
- requirements:
357
- - - "~>"
358
- - !ruby/object:Gem::Version
359
- version: '3.18'
360
- type: :development
361
- prerelease: false
362
- version_requirements: !ruby/object:Gem::Requirement
363
- requirements:
364
- - - "~>"
365
- - !ruby/object:Gem::Version
366
- version: '3.18'
367
- - !ruby/object:Gem::Dependency
368
- name: yard
369
- requirement: !ruby/object:Gem::Requirement
370
- requirements:
371
- - - ">="
372
- - !ruby/object:Gem::Version
373
- version: '0.9'
374
- type: :development
375
- prerelease: false
376
- version_requirements: !ruby/object:Gem::Requirement
377
- requirements:
378
- - - ">="
379
- - !ruby/object:Gem::Version
380
- version: '0.9'
381
89
  description: A delightful Ruby way to work with AI. Chat in text, analyze and generate
382
90
  images, understand audio, and use tools through a unified interface to OpenAI, Anthropic,
383
91
  Google, and DeepSeek. Built for developer happiness with automatic token counting,
@@ -390,17 +98,34 @@ extensions: []
390
98
  extra_rdoc_files: []
391
99
  files:
392
100
  - ".github/workflows/cicd.yml"
101
+ - ".github/workflows/docs.yml"
393
102
  - ".gitignore"
394
103
  - ".overcommit.yml"
395
104
  - ".rspec"
396
105
  - ".rspec_status"
397
106
  - ".rubocop.yml"
107
+ - ".yardopts"
398
108
  - Gemfile
399
109
  - LICENSE
400
110
  - README.md
401
111
  - Rakefile
402
112
  - bin/console
403
113
  - bin/setup
114
+ - docs/.gitignore
115
+ - docs/Gemfile
116
+ - docs/_config.yml
117
+ - docs/_data/navigation.yml
118
+ - docs/guides/chat.md
119
+ - docs/guides/embeddings.md
120
+ - docs/guides/error-handling.md
121
+ - docs/guides/getting-started.md
122
+ - docs/guides/image-generation.md
123
+ - docs/guides/index.md
124
+ - docs/guides/rails.md
125
+ - docs/guides/streaming.md
126
+ - docs/guides/tools.md
127
+ - docs/index.md
128
+ - docs/installation.md
404
129
  - lib/ruby_llm.rb
405
130
  - lib/ruby_llm/active_record/acts_as.rb
406
131
  - lib/ruby_llm/chat.rb
@@ -443,15 +168,16 @@ files:
443
168
  - lib/ruby_llm/version.rb
444
169
  - lib/tasks/models.rake
445
170
  - ruby_llm.gemspec
446
- homepage: https://github.com/crmne/ruby_llm
171
+ homepage: https://rubyllm.com
447
172
  licenses:
448
173
  - MIT
449
174
  metadata:
450
- homepage_uri: https://github.com/crmne/ruby_llm
175
+ homepage_uri: https://rubyllm.com
451
176
  source_code_uri: https://github.com/crmne/ruby_llm
452
177
  changelog_uri: https://github.com/crmne/ruby_llm/commits/main
453
- documentation_uri: https://github.com/crmne/ruby_llm
178
+ documentation_uri: https://rubyllm.com
454
179
  bug_tracker_uri: https://github.com/crmne/ruby_llm/issues
180
+ rubygems_mfa_required: 'true'
455
181
  post_install_message:
456
182
  rdoc_options: []
457
183
  require_paths: