ruby_llm 1.0.1 → 1.1.0rc1

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -12
  3. data/lib/ruby_llm/active_record/acts_as.rb +46 -7
  4. data/lib/ruby_llm/aliases.json +65 -0
  5. data/lib/ruby_llm/aliases.rb +56 -0
  6. data/lib/ruby_llm/chat.rb +10 -9
  7. data/lib/ruby_llm/configuration.rb +4 -0
  8. data/lib/ruby_llm/error.rb +15 -4
  9. data/lib/ruby_llm/models.json +1163 -303
  10. data/lib/ruby_llm/models.rb +40 -11
  11. data/lib/ruby_llm/provider.rb +32 -39
  12. data/lib/ruby_llm/providers/anthropic/capabilities.rb +8 -9
  13. data/lib/ruby_llm/providers/anthropic/chat.rb +31 -4
  14. data/lib/ruby_llm/providers/anthropic/streaming.rb +12 -6
  15. data/lib/ruby_llm/providers/anthropic.rb +4 -0
  16. data/lib/ruby_llm/providers/bedrock/capabilities.rb +168 -0
  17. data/lib/ruby_llm/providers/bedrock/chat.rb +108 -0
  18. data/lib/ruby_llm/providers/bedrock/models.rb +84 -0
  19. data/lib/ruby_llm/providers/bedrock/signing.rb +831 -0
  20. data/lib/ruby_llm/providers/bedrock/streaming/base.rb +46 -0
  21. data/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb +63 -0
  22. data/lib/ruby_llm/providers/bedrock/streaming/message_processing.rb +79 -0
  23. data/lib/ruby_llm/providers/bedrock/streaming/payload_processing.rb +90 -0
  24. data/lib/ruby_llm/providers/bedrock/streaming/prelude_handling.rb +91 -0
  25. data/lib/ruby_llm/providers/bedrock/streaming.rb +36 -0
  26. data/lib/ruby_llm/providers/bedrock.rb +83 -0
  27. data/lib/ruby_llm/providers/deepseek/chat.rb +17 -0
  28. data/lib/ruby_llm/providers/deepseek.rb +5 -0
  29. data/lib/ruby_llm/providers/gemini/capabilities.rb +50 -34
  30. data/lib/ruby_llm/providers/gemini/chat.rb +8 -15
  31. data/lib/ruby_llm/providers/gemini/images.rb +5 -10
  32. data/lib/ruby_llm/providers/gemini/streaming.rb +35 -76
  33. data/lib/ruby_llm/providers/gemini/tools.rb +12 -12
  34. data/lib/ruby_llm/providers/gemini.rb +4 -0
  35. data/lib/ruby_llm/providers/openai/capabilities.rb +146 -206
  36. data/lib/ruby_llm/providers/openai/streaming.rb +9 -13
  37. data/lib/ruby_llm/providers/openai.rb +4 -0
  38. data/lib/ruby_llm/streaming.rb +96 -0
  39. data/lib/ruby_llm/version.rb +1 -1
  40. data/lib/ruby_llm.rb +6 -3
  41. data/lib/tasks/browser_helper.rb +97 -0
  42. data/lib/tasks/capability_generator.rb +123 -0
  43. data/lib/tasks/capability_scraper.rb +224 -0
  44. data/lib/tasks/cli_helper.rb +22 -0
  45. data/lib/tasks/code_validator.rb +29 -0
  46. data/lib/tasks/model_updater.rb +66 -0
  47. data/lib/tasks/models.rake +28 -193
  48. data/lib/tasks/vcr.rake +13 -30
  49. metadata +27 -19
  50. data/.github/workflows/cicd.yml +0 -158
  51. data/.github/workflows/docs.yml +0 -53
  52. data/.gitignore +0 -59
  53. data/.overcommit.yml +0 -26
  54. data/.rspec +0 -3
  55. data/.rubocop.yml +0 -10
  56. data/.yardopts +0 -12
  57. data/CONTRIBUTING.md +0 -207
  58. data/Gemfile +0 -33
  59. data/Rakefile +0 -9
  60. data/bin/console +0 -17
  61. data/bin/setup +0 -6
  62. data/ruby_llm.gemspec +0 -44
data/.rubocop.yml DELETED
@@ -1,10 +0,0 @@
1
- plugins:
2
- - rubocop-rake
3
- - rubocop-rspec
4
-
5
- AllCops:
6
- NewCops: enable
7
- TargetRubyVersion: 3.1
8
- Exclude:
9
- - docs/**/*
10
- - vendor/**/*
data/.yardopts DELETED
@@ -1,12 +0,0 @@
1
- --markup markdown
2
- --markup-provider redcarpet
3
- --title "RubyLLM API Documentation"
4
- --protected
5
- --private
6
- --embed-mixins
7
- --output-dir doc/yard
8
- --readme README.md
9
- lib/**/*.rb
10
- -
11
- LICENSE
12
-
data/CONTRIBUTING.md DELETED
@@ -1,207 +0,0 @@
1
- # Contributing to RubyLLM
2
-
3
- First off, thank you for considering contributing to RubyLLM! It's people like you that make RubyLLM such a great tool.
4
-
5
- ## Development Setup
6
-
7
- Here's how to get started:
8
-
9
- ```bash
10
- # Clone the repository
11
- gh repo clone crmne/ruby_llm
12
- cd ruby_llm
13
-
14
- # Install dependencies
15
- bundle install
16
-
17
- # Set up git hooks
18
- overcommit --install
19
-
20
- # Run the tests (uses VCR cassettes)
21
- bundle exec rspec
22
- ```
23
-
24
- ## Development Workflow
25
-
26
- We recommend using GitHub CLI to simplify the workflow:
27
-
28
- ```bash
29
- # Create a new branch for your feature
30
- gh repo fork crmne/ruby_llm --clone
31
- cd ruby_llm
32
-
33
- # Find or make an issue for the feature on GitHub and then:
34
- gh issue develop 123 --checkout # Substitute 123 with the issue number
35
-
36
- # Make your changes and test them
37
- # ...
38
-
39
- # Commit your changes
40
- git commit
41
-
42
- # Create a PR
43
- gh pr create --web
44
- ```
45
-
46
- ## Model Naming Convention & Provider Strategy
47
-
48
- When adding new providers to RubyLLM, please follow these guidelines:
49
-
50
- ### Normalized Model IDs
51
-
52
- We use a consistent approach separating **what** (model) from **where** (provider):
53
-
54
- ```ruby
55
- # Default way (from the native provider)
56
- chat = RubyLLM.chat(model: "claude-3-5-sonnet")
57
-
58
- # Same model via different provider
59
- chat = RubyLLM.chat(model: "claude-3-5-sonnet", provider: :bedrock)
60
- ```
61
-
62
- ### Implementing a Provider
63
-
64
- If you're adding a new provider:
65
-
66
- 1. **Use normalized model IDs** - Don't include provider prefixes in the model ID itself
67
- 2. **Add provider mapping** - Map the normalized IDs to your provider's specific format internally
68
- 3. **Preserve capabilities** - Ensure models accessed through your provider report the same capabilities as their native counterparts
69
- 4. **Update models.json** - Include your provider's models in models.json
70
- 5. **Update aliases.json** - Add entries to aliases.json for models accessible through your provider
71
- 6. **Implement refresh mechanism** - Ensure your provider supports the `list_models` method for refreshing
72
-
73
- ### Model Aliases
74
-
75
- For providers that use complex model identifiers (like Bedrock's `anthropic.claude-3-5-sonnet-20241022-v2:0:200k`), add mappings to the global aliases.json file:
76
-
77
- ```json
78
- {
79
- "claude-3-5-sonnet": {
80
- "anthropic": "claude-3-5-sonnet-20241022",
81
- "bedrock": "anthropic.claude-3-5-sonnet-20241022-v2:0:200k",
82
- "openrouter": "anthropic/claude-3.5-sonnet"
83
- },
84
- "gpt-4o": {
85
- "openai": "gpt-4o-2024-05-13",
86
- "bedrock": "anthropic.gpt-4o-2024-05-13",
87
- "openrouter": "openai/gpt-4o"
88
- }
89
- }
90
- ```
91
-
92
- If a model can't be found with the provided ID and provider, a `ModelNotFoundError` will be raised with an informative message. Your implementation should make this error helpful by suggesting available alternatives.
93
-
94
- When the same model has multiple versions and context windows e.g.
95
-
96
- ```
97
- anthropic.claude-3-5-sonnet-20240620-v1:0
98
- anthropic.claude-3-5-sonnet-20240620-v1:0:18k
99
- anthropic.claude-3-5-sonnet-20240620-v1:0:200k
100
- anthropic.claude-3-5-sonnet-20240620-v1:0:51k
101
- anthropic.claude-3-5-sonnet-20241022-v2:0
102
- anthropic.claude-3-5-sonnet-20241022-v2:0:18k
103
- anthropic.claude-3-5-sonnet-20241022-v2:0:200k
104
- anthropic.claude-3-5-sonnet-20241022-v2:0:51k
105
- ```
106
-
107
- We default all aliases to the biggest context window, and the main alias (without date) to the latest version:
108
-
109
- ```json
110
- "claude-3-5-sonnet": {
111
- "anthropic": "claude-3-5-sonnet-20241022",
112
- "bedrock": "anthropic.claude-3-5-sonnet-20241022-v2:0:200k",
113
- "openrouter": "anthropic/claude-3.5-sonnet"
114
- },
115
- "claude-3-5-sonnet-20241022": {
116
- "anthropic": "claude-3-5-sonnet-20241022",
117
- "bedrock": "anthropic.claude-3-5-sonnet-20241022-v2:0:200k",
118
- "openrouter": "anthropic/claude-3.5-sonnet"
119
- },
120
- "claude-3-5-sonnet-20240620": {
121
- "anthropic": "claude-3-5-sonnet-20240620",
122
- "bedrock": "anthropic.claude-3-5-sonnet-20240620-v1:0:200k"
123
- },
124
- ```
125
-
126
- ## Running Tests
127
-
128
- Tests automatically use VCR to record and replay HTTP interactions, so you don't need real API keys for testing:
129
-
130
- ```bash
131
- # Run all tests (using existing VCR cassettes)
132
- bundle exec rspec
133
-
134
- # Run a specific test file
135
- bundle exec rspec spec/ruby_llm/chat_spec.rb
136
- ```
137
-
138
- ### Recording VCR Cassettes
139
-
140
- When you make changes that affect API interactions, you can record new VCR cassettes.
141
-
142
- If you have keys for all providers:
143
-
144
- ```bash
145
- # Re-record all cassettes
146
- bundle exec rake vcr:record[all]
147
- ```
148
-
149
- If you only have keys for specific providers (e.g., just OpenAI):
150
-
151
- ```bash
152
- # Set the API keys you have
153
- export OPENAI_API_KEY=your_openai_key
154
-
155
- # Find and remove only cassettes for OpenAI, then run tests to re-record them
156
- bundle exec rake vcr:record[openai]
157
-
158
- # You can also specify multiple providers
159
- bundle exec rake vcr:record[openai,anthropic]
160
- ```
161
-
162
- Important: After recording new cassettes, please **manually check** them for any sensitive information that might have been missed by the automatic filters.
163
-
164
- ## Adding New Tests
165
-
166
- Tests automatically create VCR cassettes based on their descriptions, so make sure your test descriptions are unique and descriptive.
167
-
168
- ## Coding Style
169
-
170
- We follow the [Standard Ruby](https://github.com/testdouble/standard) style. Please ensure your contributions adhere to this style.
171
-
172
- ```bash
173
- # Check your code style
174
- bundle exec rubocop
175
-
176
- # Auto-fix style issues where possible
177
- bundle exec rubocop -A
178
- ```
179
-
180
- ## Documentation
181
-
182
- When adding new features, please include documentation updates:
183
-
184
- - Update relevant guides in the `docs/guides/` directory
185
- - Add inline documentation using YARD comments
186
- - Keep the README clean and focused on helping new users get started quickly
187
-
188
- ## Philosophy
189
-
190
- RubyLLM follows certain design philosophies and conventions. Please refer to our [Philosophy Guide](https://rubyllm.com/philosophy) to ensure your contributions align with the project's vision.
191
-
192
- ## Discussions and Issues
193
-
194
- - For questions and discussions, please use [GitHub Discussions](https://github.com/crmne/ruby_llm/discussions)
195
- - For bugs and feature requests, please use [GitHub Issues](https://github.com/crmne/ruby_llm/issues)
196
-
197
- ## Release Process
198
-
199
- Gem versioning follows [Semantic Versioning](https://semver.org/):
200
-
201
- 1. MAJOR version for incompatible API changes
202
- 2. MINOR version for backwards-compatible functionality
203
- 3. PATCH version for backwards-compatible bug fixes
204
-
205
- Releases are handled by the maintainers through the CI/CD pipeline.
206
-
207
- Thanks for helping make RubyLLM better!
data/Gemfile DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- gemspec
6
-
7
- group :development do
8
- # Rails integration dependencies
9
- gem 'activerecord', '>= 6.0', '< 9.0'
10
- gem 'activesupport', '>= 6.0', '< 9.0'
11
-
12
- # Development dependencies
13
- gem 'bundler', '>= 2.0'
14
- gem 'codecov'
15
- gem 'dotenv'
16
- gem 'irb'
17
- gem 'nokogiri'
18
- gem 'overcommit', '>= 0.66'
19
- gem 'pry', '>= 0.14'
20
- gem 'rake', '>= 13.0'
21
- gem 'rdoc'
22
- gem 'reline'
23
- gem 'rspec', '~> 3.12'
24
- gem 'rubocop', '>= 1.0'
25
- gem 'rubocop-rake', '>= 0.6'
26
- gem 'rubocop-rspec'
27
- gem 'simplecov', '>= 0.21'
28
- gem 'simplecov-cobertura'
29
- gem 'sqlite3'
30
- gem 'vcr'
31
- gem 'webmock', '~> 3.18'
32
- gem 'yard', '>= 0.9'
33
- end
data/Rakefile DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'bundler/gem_tasks'
5
- require 'rake/clean'
6
-
7
- Dir.glob('lib/tasks/**/*.rake').each { |r| load r }
8
-
9
- task default: %w[build]
data/bin/console DELETED
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/setup'
5
- require 'ruby_llm'
6
- require 'dotenv/load'
7
-
8
- require 'irb'
9
-
10
- RubyLLM.configure do |config|
11
- config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil)
12
- config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil)
13
- config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil)
14
- config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil)
15
- end
16
-
17
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
data/ruby_llm.gemspec DELETED
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'lib/ruby_llm/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'ruby_llm'
7
- spec.version = RubyLLM::VERSION
8
- spec.authors = ['Carmine Paolino']
9
- spec.email = ['carmine@paolino.me']
10
-
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://rubyllm.com'
17
- spec.license = 'MIT'
18
- spec.required_ruby_version = Gem::Requirement.new('>= 3.1.0')
19
-
20
- spec.metadata['homepage_uri'] = spec.homepage
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
- spec.metadata['documentation_uri'] = spec.homepage
24
- spec.metadata['bug_tracker_uri'] = "#{spec.metadata['source_code_uri']}/issues"
25
-
26
- spec.metadata['rubygems_mfa_required'] = 'true'
27
-
28
- # Specify which files should be added to the gem when it is released.
29
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
31
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|docs)/}) }
32
- end
33
- spec.bindir = 'exe'
34
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
- spec.require_paths = ['lib']
36
-
37
- # Runtime dependencies
38
- spec.add_dependency 'base64'
39
- spec.add_dependency 'event_stream_parser', '~> 1'
40
- spec.add_dependency 'faraday', '~> 2'
41
- spec.add_dependency 'faraday-multipart', '~> 1'
42
- spec.add_dependency 'faraday-retry', '~> 2'
43
- spec.add_dependency 'zeitwerk', '~> 2'
44
- end