ruby_llm 0.1.0.pre36 → 0.1.0.pre37

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed17bc0b342342484bd1e92b57f3b88a74d77cd43daeb1a569b132188025bafd
4
- data.tar.gz: '0970e337a393e85cff88a449e723aa7c3e3e189b1923e16cf619f95d1bf65b03'
3
+ metadata.gz: 8befc508f1a0bdbaf7b113f3a2f8584f78fbe756ac07b22344af9ea90bc47f31
4
+ data.tar.gz: 389cb1518cacfa6448f30891d45e573536c768aa8092f8d1fbac156ff4c2d4c5
5
5
  SHA512:
6
- metadata.gz: 1e8b35980c57cd61e10c50b3eb97dbedbe138e2720b11940646c74807ada4c8b260aff3cbee8ed84abfa4b998d3d2747ff5f2421731fcf73ea038306774a2dc9
7
- data.tar.gz: f0211b49713b10e00f1070fa7abb00a151ee7084e3f5e14b047be2c567afe4fcd5ade1ce662697a776470ab4e6c21e98ab1c453526e36b4ec29d6f7f6b9f6c0c
6
+ metadata.gz: 67493fd05b3c9f0765b8d7bd72d295756e615ad6ab8b133181c8a472d28a64ce83e8aaedf48f556de8e9ddc1d39c59fdd4e7cdf4f0521eff9b9d34726a6b6bcd
7
+ data.tar.gz: e4569279dc890b62881c3d8da2cd03370fd8a87f6c20f112fe0bbce2d61aec0acba726d9d89252b724f4f4a2cc97ce383f229bddc8ea9d6c204fbcc66e71f6de
@@ -0,0 +1,53 @@
1
+ name: Deploy docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'docs/**'
8
+ - '.github/workflows/docs.yml'
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+ pages: write
14
+ id-token: write
15
+
16
+ concurrency:
17
+ group: "pages"
18
+ cancel-in-progress: false
19
+
20
+ jobs:
21
+ build:
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - name: Checkout
25
+ uses: actions/checkout@v4
26
+ - name: Setup Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: '3.3'
30
+ bundler-cache: true
31
+ working-directory: docs
32
+ - name: Setup Pages
33
+ uses: actions/configure-pages@v4
34
+ - name: Build with Jekyll
35
+ working-directory: docs
36
+ run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
37
+ env:
38
+ JEKYLL_ENV: production
39
+ - name: Upload artifact
40
+ uses: actions/upload-pages-artifact@v3
41
+ with:
42
+ path: docs/_site
43
+
44
+ deploy:
45
+ environment:
46
+ name: github-pages
47
+ url: ${{ steps.deployment.outputs.page_url }}
48
+ runs-on: ubuntu-latest
49
+ needs: build
50
+ steps:
51
+ - name: Deploy to GitHub Pages
52
+ id: deployment
53
+ uses: actions/deploy-pages@v4
data/.rspec_status CHANGED
@@ -1,35 +1,7 @@
1
- example_id | status | run_time |
2
- -------------------------------------------------- | ------ | --------------- |
3
- ./spec/integration/chat_spec.rb[1:1:1:1] | passed | 0.84333 seconds |
4
- ./spec/integration/chat_spec.rb[1:1:1:2] | passed | 3.81 seconds |
5
- ./spec/integration/chat_spec.rb[1:1:2:1] | passed | 0.54605 seconds |
6
- ./spec/integration/chat_spec.rb[1:1:2:2] | passed | 1.25 seconds |
7
- ./spec/integration/chat_spec.rb[1:1:3:1] | passed | 0.66439 seconds |
8
- ./spec/integration/chat_spec.rb[1:1:3:2] | passed | 2.84 seconds |
9
- ./spec/integration/content_spec.rb[1:1:1] | passed | 3.51 seconds |
10
- ./spec/integration/content_spec.rb[1:1:2] | passed | 1.11 seconds |
11
- ./spec/integration/content_spec.rb[1:1:3] | passed | 1.77 seconds |
12
- ./spec/integration/content_spec.rb[1:2:1] | passed | 1.68 seconds |
13
- ./spec/integration/content_spec.rb[1:2:2] | passed | 2.01 seconds |
14
- ./spec/integration/embeddings_spec.rb[1:1:1:1] | passed | 0.28694 seconds |
15
- ./spec/integration/embeddings_spec.rb[1:1:1:2] | passed | 0.32456 seconds |
16
- ./spec/integration/embeddings_spec.rb[1:1:2:1] | passed | 0.85006 seconds |
17
- ./spec/integration/embeddings_spec.rb[1:1:2:2] | passed | 0.82832 seconds |
18
- ./spec/integration/error_handling_spec.rb[1:1] | passed | 0.19746 seconds |
19
- ./spec/integration/image_generation_spec.rb[1:1:1] | passed | 10.73 seconds |
20
- ./spec/integration/image_generation_spec.rb[1:1:2] | passed | 16.95 seconds |
21
- ./spec/integration/image_generation_spec.rb[1:1:3] | passed | 0.00024 seconds |
22
- ./spec/integration/rails_spec.rb[1:1] | passed | 3.39 seconds |
23
- ./spec/integration/rails_spec.rb[1:2] | passed | 1.74 seconds |
24
- ./spec/integration/streaming_spec.rb[1:1:1:1] | passed | 0.56418 seconds |
25
- ./spec/integration/streaming_spec.rb[1:1:1:2] | passed | 6.33 seconds |
26
- ./spec/integration/streaming_spec.rb[1:1:2:1] | passed | 0.51911 seconds |
27
- ./spec/integration/streaming_spec.rb[1:1:2:2] | passed | 2.31 seconds |
28
- ./spec/integration/streaming_spec.rb[1:1:3:1] | passed | 0.78299 seconds |
29
- ./spec/integration/streaming_spec.rb[1:1:3:2] | passed | 3.82 seconds |
30
- ./spec/integration/tools_spec.rb[1:1:1:1] | passed | 3.89 seconds |
31
- ./spec/integration/tools_spec.rb[1:1:1:2] | passed | 7.78 seconds |
32
- ./spec/integration/tools_spec.rb[1:1:2:1] | passed | 1.25 seconds |
33
- ./spec/integration/tools_spec.rb[1:1:2:2] | passed | 2.1 seconds |
34
- ./spec/integration/tools_spec.rb[1:1:3:1] | passed | 1.59 seconds |
35
- ./spec/integration/tools_spec.rb[1:1:3:2] | passed | 3.05 seconds |
1
+ example_id | status | run_time |
2
+ ------------------------------------------- | ------ | ------------ |
3
+ ./spec/ruby_llm/chat_content_spec.rb[1:1:1] | passed | 3.59 seconds |
4
+ ./spec/ruby_llm/chat_content_spec.rb[1:1:2] | passed | 1.51 seconds |
5
+ ./spec/ruby_llm/chat_content_spec.rb[1:1:3] | passed | 2.29 seconds |
6
+ ./spec/ruby_llm/chat_content_spec.rb[1:2:1] | passed | 2.06 seconds |
7
+ ./spec/ruby_llm/chat_content_spec.rb[1:2:2] | passed | 2.04 seconds |
data/.rubocop.yml CHANGED
@@ -1,5 +1,10 @@
1
- require:
1
+ plugins:
2
2
  - rubocop-rake
3
+ - rubocop-rspec
3
4
 
4
5
  AllCops:
5
- TargetRubyVersion: 3.1
6
+ NewCops: enable
7
+ TargetRubyVersion: 3.1
8
+ Exclude:
9
+ - docs/**/*
10
+ - vendor/**/*
data/.yardopts ADDED
@@ -0,0 +1,12 @@
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/Gemfile CHANGED
@@ -3,3 +3,30 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
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 'webmock', '~> 3.18'
31
+ gem 'yard', '>= 0.9'
32
+ end
data/bin/console CHANGED
@@ -8,10 +8,10 @@ require 'dotenv/load'
8
8
  require 'irb'
9
9
 
10
10
  RubyLLM.configure do |config|
11
- config.openai_api_key = ENV['OPENAI_API_KEY']
12
- config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
13
- config.gemini_api_key = ENV['GEMINI_API_KEY']
14
- config.deepseek_api_key = ENV['DEEPSEEK_API_KEY']
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
15
  end
16
16
 
17
17
  IRB.start(__FILE__)
data/docs/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ _site/
2
+ .sass-cache/
3
+ .jekyll-cache/
4
+ .jekyll-metadata
5
+ # Ignore folders generated by Bundler
6
+ .bundle/
7
+ vendor/
data/docs/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'jekyll', '~> 4.3'
4
+ gem 'just-the-docs', '~> 0.7.0'
5
+ gem 'webrick', '~> 1.8'
6
+
7
+ # GitHub Pages plugins
8
+ group :jekyll_plugins do
9
+ gem 'jekyll-remote-theme'
10
+ gem 'jekyll-seo-tag'
11
+ end
data/docs/_config.yml ADDED
@@ -0,0 +1,43 @@
1
+ title: RubyLLM
2
+ description: A delightful Ruby way to work with AI
3
+ url: https://crmne.github.io/ruby_llm
4
+ baseurl: /ruby_llm
5
+ remote_theme: just-the-docs/just-the-docs
6
+
7
+ # Enable search
8
+ search_enabled: true
9
+ search:
10
+ heading_level: 2
11
+ previews: 3
12
+ preview_words_before: 5
13
+ preview_words_after: 10
14
+ tokenizer_separator: /[\s/]+/
15
+ rel_url: true
16
+ button: false
17
+
18
+ # Navigation structure
19
+ nav_external_links:
20
+ - title: RubyLLM on GitHub
21
+ url: https://github.com/crmne/ruby_llm
22
+ hide_icon: false
23
+
24
+ # Footer content
25
+ footer_content: "Copyright &copy; 2025 <a href='https://paolino.me'>Carmine Paolino</a>. Distributed under an <a href=\"https://github.com/crmne/ruby_llm/tree/main/LICENSE\">MIT license.</a>"
26
+
27
+ # Enable copy button on code blocks
28
+ enable_copy_code_button: true
29
+
30
+ # Make Anchor links show on hover
31
+ heading_anchors: true
32
+
33
+ # Color scheme
34
+ color_scheme: light
35
+
36
+ # Google Analytics
37
+ ga_tracking:
38
+ ga_tracking_anonymize_ip: true
39
+
40
+ # Custom plugins (GitHub Pages allows these)
41
+ plugins:
42
+ - jekyll-remote-theme
43
+ - jekyll-seo-tag
@@ -0,0 +1,25 @@
1
+ - title: Home
2
+ url: /
3
+ - title: Installation
4
+ url: /installation
5
+ - title: Guides
6
+ url: /guides/
7
+ subfolderitems:
8
+ - title: Getting Started
9
+ url: /guides/getting-started
10
+ - title: Chat
11
+ url: /guides/chat
12
+ - title: Tools
13
+ url: /guides/tools
14
+ - title: Streaming
15
+ url: /guides/streaming
16
+ - title: Rails Integration
17
+ url: /guides/rails
18
+ - title: Image Generation
19
+ url: /guides/image-generation
20
+ - title: Embeddings
21
+ url: /guides/embeddings
22
+ - title: Error Handling
23
+ url: /guides/error-handling
24
+ - title: GitHub
25
+ url: https://github.com/crmne/ruby_llm
@@ -0,0 +1,206 @@
1
+ ---
2
+ layout: default
3
+ title: Chat
4
+ parent: Guides
5
+ nav_order: 2
6
+ permalink: /guides/chat
7
+ ---
8
+
9
+ # Chatting with AI Models
10
+
11
+ RubyLLM's chat interface provides a natural way to interact with various AI models. This guide covers everything from basic chatting to advanced features like multimodal inputs and streaming responses.
12
+
13
+ ## Basic Chat
14
+
15
+ Creating a chat and asking questions is straightforward:
16
+
17
+ ```ruby
18
+ # Create a chat with the default model
19
+ chat = RubyLLM.chat
20
+
21
+ # Ask a question
22
+ response = chat.ask "What's the best way to learn Ruby?"
23
+
24
+ # The response is a Message object
25
+ puts response.content
26
+ puts "Role: #{response.role}"
27
+ puts "Model: #{response.model_id}"
28
+ puts "Tokens: #{response.input_tokens} input, #{response.output_tokens} output"
29
+ ```
30
+
31
+ ## Choosing Models
32
+
33
+ You can specify which model to use when creating a chat:
34
+
35
+ ```ruby
36
+ # Create a chat with a specific model
37
+ chat = RubyLLM.chat(model: 'gpt-4o-mini')
38
+
39
+ # Use Claude instead
40
+ claude_chat = RubyLLM.chat(model: 'claude-3-5-sonnet-20241022')
41
+
42
+ # Or change the model for an existing chat
43
+ chat.with_model('gemini-2.0-flash')
44
+ ```
45
+
46
+ ## Multi-turn Conversations
47
+
48
+ Chats maintain conversation history automatically:
49
+
50
+ ```ruby
51
+ chat = RubyLLM.chat
52
+
53
+ # Start a conversation
54
+ chat.ask "What's your favorite programming language?"
55
+
56
+ # Follow up
57
+ chat.ask "Why do you like that language?"
58
+
59
+ # Continue the conversation
60
+ chat.ask "What are its weaknesses?"
61
+
62
+ # Access the conversation history
63
+ chat.messages.each do |message|
64
+ puts "#{message.role}: #{message.content[0..50]}..."
65
+ end
66
+ ```
67
+
68
+ ## Working with Images
69
+
70
+ Vision-capable models can understand images:
71
+
72
+ ```ruby
73
+ chat = RubyLLM.chat
74
+
75
+ # Ask about an image (local file)
76
+ chat.ask "What's in this image?", with: { image: "path/to/image.jpg" }
77
+
78
+ # Or use an image URL
79
+ chat.ask "Describe this picture", with: { image: "https://example.com/image.jpg" }
80
+
81
+ # Include multiple images
82
+ chat.ask "Compare these two charts", with: {
83
+ image: ["chart1.png", "chart2.png"]
84
+ }
85
+
86
+ # Combine text and image
87
+ chat.ask "Is this the Ruby logo?", with: { image: "logo.png" }
88
+ ```
89
+
90
+ ## Working with Audio
91
+
92
+ Models with audio capabilities can process spoken content:
93
+
94
+ ```ruby
95
+ chat = RubyLLM.chat(model: 'gpt-4o-audio-preview')
96
+
97
+ # Analyze audio content
98
+ chat.ask "What's being said in this recording?", with: {
99
+ audio: "meeting.wav"
100
+ }
101
+
102
+ # Ask follow-up questions about the audio
103
+ chat.ask "Summarize the key points mentioned"
104
+ ```
105
+
106
+ ## Streaming Responses
107
+
108
+ For a more interactive experience, you can stream responses as they're generated:
109
+
110
+ ```ruby
111
+ chat = RubyLLM.chat
112
+
113
+ # Stream the response with a block
114
+ chat.ask "Tell me a story about a Ruby programmer" do |chunk|
115
+ # Each chunk is a partial response
116
+ print chunk.content
117
+ $stdout.flush # Ensure output is displayed immediately
118
+ end
119
+
120
+ # Useful for long responses or real-time displays
121
+ chat.ask "Write a detailed essay about programming paradigms" do |chunk|
122
+ add_to_ui(chunk.content) # Your method to update UI
123
+ end
124
+ ```
125
+
126
+ ## Temperature Control
127
+
128
+ Control the creativity and randomness of AI responses:
129
+
130
+ ```ruby
131
+ # Higher temperature (more creative)
132
+ creative_chat = RubyLLM.chat.with_temperature(0.9)
133
+ creative_chat.ask "Write a poem about Ruby programming"
134
+
135
+ # Lower temperature (more deterministic)
136
+ precise_chat = RubyLLM.chat.with_temperature(0.1)
137
+ precise_chat.ask "Explain how Ruby's garbage collector works"
138
+ ```
139
+
140
+ ## Access Token Usage
141
+
142
+ RubyLLM automatically tracks token usage for billing and quota management:
143
+
144
+ ```ruby
145
+ chat = RubyLLM.chat
146
+ response = chat.ask "Explain quantum computing"
147
+
148
+ # Check token usage
149
+ puts "Input tokens: #{response.input_tokens}"
150
+ puts "Output tokens: #{response.output_tokens}"
151
+ puts "Total tokens: #{response.input_tokens + response.output_tokens}"
152
+
153
+ # Estimate cost (varies by model)
154
+ model = RubyLLM.models.find(response.model_id)
155
+ input_cost = response.input_tokens * model.input_price_per_million / 1_000_000
156
+ output_cost = response.output_tokens * model.output_price_per_million / 1_000_000
157
+ puts "Estimated cost: $#{(input_cost + output_cost).round(6)}"
158
+ ```
159
+
160
+ ## Registering Event Handlers
161
+
162
+ You can register callbacks for chat events:
163
+
164
+ ```ruby
165
+ chat = RubyLLM.chat
166
+
167
+ # Called when a new assistant message starts
168
+ chat.on_new_message do
169
+ puts "Assistant is typing..."
170
+ end
171
+
172
+ # Called when a message is complete
173
+ chat.on_end_message do |message|
174
+ puts "Response complete!"
175
+ puts "Used #{message.input_tokens + message.output_tokens} tokens"
176
+ end
177
+
178
+ # These callbacks work with both streaming and non-streaming responses
179
+ chat.ask "Tell me about Ruby's history"
180
+ ```
181
+
182
+ ## Multiple Parallel Chats
183
+
184
+ You can maintain multiple separate chat instances:
185
+
186
+ ```ruby
187
+ # Create multiple chat instances
188
+ ruby_chat = RubyLLM.chat
189
+ python_chat = RubyLLM.chat
190
+
191
+ # Each has its own conversation history
192
+ ruby_chat.ask "What's great about Ruby?"
193
+ python_chat.ask "What's great about Python?"
194
+
195
+ # Continue separate conversations
196
+ ruby_chat.ask "How does Ruby handle metaprogramming?"
197
+ python_chat.ask "How does Python handle decorators?"
198
+ ```
199
+
200
+ ## Next Steps
201
+
202
+ Now that you understand chat basics, you might want to explore:
203
+
204
+ - [Using Tools]({% link guides/tools.md %}) to let AI use your Ruby code
205
+ - [Streaming Responses]({% link guides/streaming.md %}) for real-time interactions
206
+ - [Rails Integration]({% link guides/rails.md %}) to persist conversations in your apps