Skip to content

Commit 00e69ae

Browse files
authored
Merge branch 'main' into prompt-caching
2 parents 5c31698 + 24bc957 commit 00e69ae

File tree

192 files changed

+13308
-10755
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

192 files changed

+13308
-10755
lines changed

.gitattributes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Binary files tracked with Git LFS
2+
*.mp3 filter=lfs diff=lfs merge=lfs -text
3+
*.wav filter=lfs diff=lfs merge=lfs -text
4+
*.png filter=lfs diff=lfs merge=lfs -text
5+
*.pdf filter=lfs diff=lfs merge=lfs -text

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,4 @@ contact_links:
55
about: Questions about using RubyLLM, implementation approaches, or general discussion
66
- name: 📖 Documentation
77
url: https://rubyllm.com
8-
about: Check the docs first - guides and examples
9-
- name: 🚀 Priority Development
10-
url: mailto:[email protected]
11-
about: Need a feature implemented quickly? Paid development available
8+
about: Check the docs first - guides and examples

.github/pull_request_template.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
- [ ] I ran `overcommit --install` and all hooks pass
2323
- [ ] I tested my changes thoroughly
24+
- [ ] For provider changes: Re-recorded VCR cassettes with `bundle exec rake vcr:record[provider_name]`
25+
- [ ] All tests pass: `bundle exec rspec`
2426
- [ ] I updated documentation if needed
2527
- [ ] I didn't modify auto-generated files manually (`models.json`, `aliases.json`)
2628

.github/workflows/cicd.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ jobs:
4949

5050
steps:
5151
- uses: actions/checkout@v4
52+
with:
53+
lfs: true
5254

5355
- name: Set up Ruby
5456
uses: ruby/setup-ruby@v1
@@ -97,6 +99,8 @@ jobs:
9799

98100
steps:
99101
- uses: actions/checkout@v4
102+
with:
103+
lfs: true
100104

101105
- name: Set up Ruby
102106
uses: ruby/setup-ruby@v1

.github/workflows/docs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ jobs:
2424
steps:
2525
- name: Checkout
2626
uses: actions/checkout@v4
27+
with:
28+
lfs: true
2729

2830
- name: Setup Ruby for models guide generation (root Gemfile)
2931
uses: ruby/setup-ruby@v1

.overcommit.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,20 @@ PreCommit:
2424
description: 'Update appraisal gemfiles'
2525
command: ['bundle', 'exec', 'appraisal', 'update']
2626

27+
PrePush:
28+
GitLfs:
29+
enabled: true
30+
description: 'Push LFS objects to remote'
31+
command: ['bash', '-c', 'git lfs pre-push "$@"', '--']
32+
2733
PostCheckout:
2834
ALL: # Special hook name that customizes all hooks of this type
2935
quiet: true # Change all post-checkout hooks to only display output on failure
3036

3137
IndexTags:
32-
enabled: true # Generate a tags file with `ctags` each time HEAD changes
38+
enabled: true # Generate a tags file with `ctags` each time HEAD changes
39+
40+
LfsInstall:
41+
enabled: true
42+
description: 'Ensure Git LFS files are pulled'
43+
command: ['git', 'lfs', 'pull']

CONTRIBUTING.md

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,79 @@
11
# Contributing to RubyLLM
22

3-
Thanks for considering contributing! Here's what you need to know.
3+
## Did you find a bug?
44

5-
## Philosophy & Scope
5+
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/crmne/ruby_llm/issues).
66

7-
RubyLLM does one thing well: **LLM communication in Ruby**.
7+
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/crmne/ruby_llm/issues/new). Include a **title and clear description**, relevant information, and a **code sample** demonstrating the issue.
88

9-
### ✅ We Want
10-
- LLM provider integrations and new provider features
11-
- Convenience that benefits most users (Rails generators, etc.)
12-
- Performance and API consistency improvements
9+
* **Verify it's a RubyLLM bug**, not your application code, before opening an issue.
1310

14-
### ❌ We Don't Want
15-
- Application architecture (testing, persistence, error tracking)
16-
- One-off solutions you can build in your app
17-
- Auxiliary features unrelated to LLM communication
11+
## Did you write a patch that fixes a bug?
1812

19-
### Requests We'll Close
20-
- **RAG support** → Use dedicated libraries
21-
- **Prompt templates** → Use ERB/Mustache in your app
22-
- **Model data fixes** → File with [Parsera](https://github.com/parsera-labs/api-llm-specs/issues)
23-
- **Auto-failover** → Use `.with_model()` (works mid-conversation, even across providers)
24-
- **Tool interface changes** → Handle in your tool's initializer
25-
- **Testing helpers** → Use dependency injection
13+
* Open a new GitHub pull request with the patch.
2614

27-
**The rule:** If you can solve it in application code, you should.
15+
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
2816

29-
## Response Times & Paid Work
17+
* Run `overcommit --install` before committing - it handles code style and tests automatically.
3018

31-
This is unpaid work I do between other priorities. I respond when I can.
19+
## Do you intend to add a new feature or change an existing one?
3220

33-
**Need something fast?** Email **[email protected]** for paid development. $200/hour, 10-hour minimum ($2000).
21+
* **First check if this belongs in RubyLLM or your application:**
22+
- ✅ Core LLM communication (provider integrations, streaming, cost tracking)
23+
- ❌ Application architecture (RAG, agents, prompt templates, testing helpers)
24+
25+
* Features we'll reject:
26+
- Multi-agent orchestration
27+
- RAG pipelines
28+
- Prompt management systems
29+
- Vector database integrations
30+
- Testing frameworks
31+
- Anything you can implement in 5-10 lines of application code
32+
33+
* Start by opening an issue to discuss the feature and its design. We want to keep RubyLLM simple and focused.
3434

3535
## Quick Start
3636

3737
```bash
3838
gh repo fork crmne/ruby_llm --clone && cd ruby_llm
3939
bundle install
40-
overcommit --install
40+
overcommit --install # Required - sets up git hooks
4141
gh issue develop 123 --checkout # or create your own branch
4242
# make changes, add tests
4343
gh pr create --web
4444
```
4545

46-
## Essential Rules
47-
48-
1. **Run `overcommit --install` before doing anything** - it auto-fixes style, runs tests, and updates model files on commit
49-
2. **Don't edit `models.json` or `aliases.json`** - overcommit regenerates them automatically
50-
3. **Write clear PR descriptions** - explain what and why
51-
52-
The git hooks handle style, tests, and file generation for you. No excuses for broken commits.
53-
5446
## Testing
5547

56-
Run linting: `bundle exec rubocop`
57-
58-
Run tests: `bundle exec rspec`
59-
60-
**Re-recording VCR cassettes?** Set API keys and run:
6148
```bash
62-
bundle exec rake vcr:record[openai,anthropic] # specific providers
63-
bundle exec rake vcr:record[all] # everything
49+
overcommit --run
50+
51+
# Re-recording VCR cassettes (requires API keys):
52+
rake vcr:record[openai,anthropic] # Specific providers
53+
rake vcr:record[all] # Everything
6454
```
6555

66-
**Then inspect the YAML files** - make sure no API keys leaked.
56+
Always check cassettes for leaked API keys before committing.
57+
58+
## Important Notes
59+
60+
* **Never edit `models.json`, `aliases.json`, or `available-models.md`** - they're auto-generated by `rake models`
61+
* **Write tests** for any new functionality
62+
* **Keep it simple** - if it needs extensive documentation, reconsider the approach
63+
* Model data comes from [Parsera](https://parsera.org). Firstly, go say thanks for their free service to the LLM dev community! They scrape LLM documentation and make it available to all of us in JSON. Secondly, [file model data issues with them](https://github.com/parsera-labs/api-llm-specs/issues).
6764

68-
## Model Registry
65+
## Response Times
6966

70-
**Don't touch these files directly:**
71-
- `models.json` - auto-generated from provider APIs + [Parsera](https://api.parsera.org/v1/llm-specs)
72-
- `aliases.json` - auto-generated from models.json
67+
This is my gift to the Ruby community.
7368

74-
**To update model info:**
75-
- Public model issues → File with [Parsera](https://github.com/parsera-labs/api-llm-specs/issues)
69+
Gifts don't come with SLAs. I respond when I can.
7670

77-
## Support the Project
71+
## Support
7872

79-
Consider [sponsoring RubyLLM](https://github.com/sponsors/crmne) to help with ongoing costs. Sponsorship supports general maintenance - for priority features, use paid development above.
73+
If RubyLLM helps you, consider [sponsoring](https://github.com/sponsors/crmne).
8074

81-
---
75+
Sponsorship is just a way to say thanks - it doesn't buy priority support or feature requests.
8276

83-
That's it. Let's make Ruby the best AI development experience possible.
77+
Go ship AI apps!
8478

8579
— Carmine

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Battle tested at [<picture><source media="(prefers-color-scheme: dark)" srcset="
1717
<a href="https://trendshift.io/repositories/13640" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13640" alt="crmne%2Fruby_llm | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
1818
</div>
1919

20+
> [!NOTE]
21+
> Using RubyLLM in production? [Share your story](https://tally.so/r/3Na02p)! Takes 5 minutes.
22+
2023
---
2124

2225
Build chatbots, AI agents, RAG applications. Works with OpenAI, Anthropic, Google, AWS, local models, and any OpenAI-compatible API.

docs/_advanced/agentic-workflows.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ class ModelRouter < RubyLLM::Tool
4040

4141
case task_type
4242
when :code
43-
RubyLLM.chat(model: 'claude-3-5-sonnet').ask(query).content
43+
RubyLLM.chat(model: '{{ site.models.best_for_code }}').ask(query).content
4444
when :creative
45-
RubyLLM.chat(model: 'gpt-4o').ask(query).content
45+
RubyLLM.chat(model: '{{ site.models.best_for_creative }}').ask(query).content
4646
when :factual
47-
RubyLLM.chat(model: 'gemini-1.5-pro').ask(query).content
47+
RubyLLM.chat(model: '{{ site.models.best_for_factual }}').ask(query).content
4848
else
4949
RubyLLM.chat.ask(query).content
5050
end
@@ -53,7 +53,7 @@ class ModelRouter < RubyLLM::Tool
5353
private
5454

5555
def classify_task(query)
56-
classifier = RubyLLM.chat(model: 'gpt-4o-mini')
56+
classifier = RubyLLM.chat(model: '{{ site.models.openai_mini }}')
5757
.with_instructions("Classify: code, creative, or factual. One word only.")
5858
classifier.ask(query).content.downcase.to_sym
5959
end
@@ -154,7 +154,7 @@ class ResearchAgent < RubyLLM::Tool
154154
param :topic, desc: "Topic to research"
155155

156156
def execute(topic:)
157-
RubyLLM.chat(model: 'gemini-1.5-pro')
157+
RubyLLM.chat(model: '{{ site.models.gemini_current }}')
158158
.ask("Research #{topic}. List key facts.")
159159
.content
160160
end
@@ -165,7 +165,7 @@ class WriterAgent < RubyLLM::Tool
165165
param :research, desc: "Research findings"
166166

167167
def execute(research:)
168-
RubyLLM.chat(model: 'claude-3-5-sonnet')
168+
RubyLLM.chat(model: '{{ site.models.anthropic_current }}')
169169
.ask("Write an article:\n#{research}")
170170
.content
171171
end
@@ -227,19 +227,19 @@ class CodeReviewSystem
227227
Async do |task|
228228
# Run reviews in parallel
229229
task.async do
230-
reviews[:security] = RubyLLM.chat(model: 'claude-3-5-sonnet')
230+
reviews[:security] = RubyLLM.chat(model: '{{ site.models.anthropic_current }}')
231231
.ask("Security review:\n#{code}")
232232
.content
233233
end
234234

235235
task.async do
236-
reviews[:performance] = RubyLLM.chat(model: 'gpt-4o')
236+
reviews[:performance] = RubyLLM.chat(model: '{{ site.models.openai_tools }}')
237237
.ask("Performance review:\n#{code}")
238238
.content
239239
end
240240

241241
task.async do
242-
reviews[:style] = RubyLLM.chat(model: 'gpt-4o-mini')
242+
reviews[:style] = RubyLLM.chat(model: '{{ site.models.openai_mini }}')
243243
.ask("Style review (Ruby conventions):\n#{code}")
244244
.content
245245
end

docs/_advanced/error-handling.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Instances of `RubyLLM::Error` (and its subclasses related to API responses) hold
110110

111111
```ruby
112112
begin
113-
chat = RubyLLM.chat(model: 'gpt-4.1-nano') # Assume this requires a specific org sometimes
113+
chat = RubyLLM.chat(model: '{{ site.models.default_chat }}') # Assume this requires a specific org sometimes
114114
response = chat.ask "Some specific query"
115115
rescue RubyLLM::ForbiddenError => e
116116
puts "Access forbidden: #{e.message}"

0 commit comments

Comments
 (0)