rubric_llm 0.5.0 → 0.6.0.rc1
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/CHANGELOG.md +13 -0
- data/README.md +43 -5
- data/lib/rubric_llm/config.rb +5 -4
- data/lib/rubric_llm/judge.rb +3 -8
- data/lib/rubric_llm/version.rb +1 -1
- data/lib/rubric_llm.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d32ed4cba47a2fac15973d05bbf531317fa8d80f4c42b277dae5c302884ae57
|
|
4
|
+
data.tar.gz: a4bfbbc318593df77c33d36d41eda2e3d2f1b0cd4d0485fe9b8a61e72ee1519b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a63b324d6f721297415feb55f6232b2771d58a7ca86a4a2ff0903abffec3c5fc5ad638c3d32632ed27bbf6cafea666a8247dcfa418d3454df61e3856c6c83b0a
|
|
7
|
+
data.tar.gz: 424912623b5f7f8157c91c10310c4e8ebe34e7406fcc146a3c146bd4e9de0cbe9b0100acc4b7a9a98174153f53178961f9c8233b120b3d3d23c11a5bf29bb360
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.6.0.rc1] - 2026-09-08
|
|
9
|
+
|
|
10
|
+
This prerelease targets RubyLLM `2.0.0.rc1` and supports RubyLLM 2 only. Applications that use RubyLLM 1.x should stay on RubricLLM `0.5.x`. Stable `0.6.0` waits for the final RubyLLM 2.0 release and the complete Ruby 3.4 and 4.0 test matrix.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Require the exact RubyLLM `2.0.0.rc1` prerelease while the compatibility release is under review; Ruby >= 3.4 remains supported
|
|
15
|
+
- Keep `max_tokens` and `RUBRIC_MAX_TOKENS` as the public RubricLLM setting while RubyLLM maps the limit to the selected provider and protocol
|
|
16
|
+
- Treat explicit `temperature: nil` as an instruction to omit temperature from the provider request. Before 0.6.0.rc1, it selected `RUBRIC_TEMPERATURE` or `0.0`; an omitted temperature still reads `RUBRIC_TEMPERATURE` and defaults to `0.0`
|
|
17
|
+
- Use OpenAI Responses by default through RubyLLM 2. OpenAI-compatible gateways that only accept Chat Completions can set `config.openai_protocol = :chat_completions`
|
|
18
|
+
- Keep RubyLLM transport retries and RubricLLM judge retries separate. With RubyLLM's default `config.max_retries = 3` and RubricLLM's default `max_retries: 2`, a retryable metric failure can produce up to `(3 + 1) * (2 + 1) = 12` HTTP attempts
|
|
19
|
+
- Keep Rails persistence migrations separate. Applications that use RubyLLM's Rails records must follow RubyLLM's upstream 2.0 migration guide
|
|
20
|
+
|
|
8
21
|
## [0.5.0] - 2026-08-23
|
|
9
22
|
|
|
10
23
|
### Fixed
|
data/README.md
CHANGED
|
@@ -8,18 +8,29 @@ Lightweight LLM evaluation framework for Ruby, inspired by [DeepEval](https://gi
|
|
|
8
8
|
|
|
9
9
|
Provider-agnostic evaluation with pluggable metrics, statistical A/B comparison, and test framework integration: no Rails, no ActiveRecord, no UI. Works anywhere Ruby runs.
|
|
10
10
|
|
|
11
|
+
`0.6.0.rc1` is a prerelease for RubyLLM `2.0.0.rc1`. It supports RubyLLM 2 only. Applications that use RubyLLM 1.x should stay on RubricLLM `0.5.x`. Stable `0.6.0` waits for the final RubyLLM 2.0 release and the complete Ruby 3.4 and 4.0 test matrix.
|
|
12
|
+
|
|
11
13
|
## Installation
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
Install the release candidate with both exact prerelease constraints in the same Gemfile change:
|
|
14
16
|
|
|
15
17
|
```ruby
|
|
16
|
-
gem "rubric_llm"
|
|
18
|
+
gem "rubric_llm", "0.6.0.rc1"
|
|
19
|
+
gem "ruby_llm", "2.0.0.rc1"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then resolve both gems together:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bundle update rubric_llm ruby_llm
|
|
17
26
|
```
|
|
18
27
|
|
|
28
|
+
RubyLLM's upstream prerelease pin command is `bundle add ruby_llm --version 2.0.0.rc1`. If the application still has a RubyLLM 1.x constraint, update both constraints before running Bundler.
|
|
29
|
+
|
|
19
30
|
Or install directly:
|
|
20
31
|
|
|
21
32
|
```bash
|
|
22
|
-
gem install rubric_llm
|
|
33
|
+
gem install rubric_llm --version 0.6.0.rc1 --pre
|
|
23
34
|
```
|
|
24
35
|
|
|
25
36
|
## Quick Start
|
|
@@ -62,6 +73,25 @@ RubricLLM.configure do |c|
|
|
|
62
73
|
end
|
|
63
74
|
```
|
|
64
75
|
|
|
76
|
+
`max_tokens` remains RubricLLM's public setting, and `RUBRIC_MAX_TOKENS` remains its environment variable. RubyLLM 2 maps this shared limit to the selected provider and protocol.
|
|
77
|
+
|
|
78
|
+
When `temperature` is omitted, RubricLLM reads `RUBRIC_TEMPERATURE` and uses `0.0` when the variable is not set. Before 0.6.0.rc1, an explicit `temperature: nil` selected that environment value or `0.0`; it now means that RubricLLM omits temperature from the provider request, so the provider chooses its default:
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
RubricLLM::Config.new # RUBRIC_TEMPERATURE, otherwise 0.0
|
|
82
|
+
RubricLLM::Config.new(temperature: nil) # omit temperature from the request
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
RubyLLM 2 uses the OpenAI Responses protocol by default when the selected model supports it. For an OpenAI-compatible gateway that only accepts Chat Completions, configure RubyLLM before evaluating:
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
RubyLLM.configure do |config|
|
|
89
|
+
config.openai_protocol = :chat_completions
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Structured output support depends on the selected provider and model. RubricLLM sends its schema when RubyLLM reports structured output support. Otherwise it requests JSON text and validates the response object and score locally. Check the target provider's support before relying on a schema or a specific protocol. See RubyLLM's [2.0 upgrade guide](https://rubyllm.com/next/upgrading/), [request control guide](https://rubyllm.com/next/chat-request-control/), and [structured output support](https://rubyllm.com/next/structured-output/).
|
|
94
|
+
|
|
65
95
|
### Environment Variables
|
|
66
96
|
|
|
67
97
|
All config fields can be set via environment variables:
|
|
@@ -100,6 +130,14 @@ RubricLLM.configure do |c|
|
|
|
100
130
|
end
|
|
101
131
|
```
|
|
102
132
|
|
|
133
|
+
RubricLLM has no Rails models or database migrations. If the application also uses RubyLLM's Rails persistence, follow RubyLLM's 2.0 upgrade guide and run its phased migrations separately.
|
|
134
|
+
|
|
135
|
+
### Retries
|
|
136
|
+
|
|
137
|
+
RubyLLM transport retries and RubricLLM judge retries remain separate. With RubyLLM's default `config.max_retries = 3` and RubricLLM's default `max_retries: 2`, one retryable metric failure can produce up to `(3 + 1) * (2 + 1) = 12` HTTP attempts. Set `RUBRIC_MAX_RETRIES` and `RUBRIC_RETRY_BASE_DELAY` for RubricLLM's layer, and set RubyLLM's `config.max_retries` and related transport settings for its layer. RubricLLM 0.6 does not combine or redesign these retry layers.
|
|
138
|
+
|
|
139
|
+
RubyLLM classifies OpenAI's HTTP 429 `insufficient_quota` response as a rate-limit error, so an exhausted account uses both retry budgets and their delays before the error is returned.
|
|
140
|
+
|
|
103
141
|
## Metrics
|
|
104
142
|
|
|
105
143
|
### LLM-as-Judge Metrics
|
|
@@ -323,7 +361,7 @@ result.overall # => mean of non-nil scores only
|
|
|
323
361
|
|
|
324
362
|
```bash
|
|
325
363
|
bundle install
|
|
326
|
-
bundle exec rake test
|
|
364
|
+
bundle exec rake test test_contract
|
|
327
365
|
bundle exec rubocop
|
|
328
366
|
```
|
|
329
367
|
|
|
@@ -365,7 +403,7 @@ Deep dives live in the [project wiki](https://github.com/dpaluy/rubric_llm/wiki)
|
|
|
365
403
|
## Requirements
|
|
366
404
|
|
|
367
405
|
- Ruby >= 3.4
|
|
368
|
-
- [ruby_llm](https://github.com/crmne/ruby_llm)
|
|
406
|
+
- [ruby_llm](https://github.com/crmne/ruby_llm) = 2.0.0.rc1 for RubricLLM 0.6.0.rc1
|
|
369
407
|
- An API key for your chosen LLM provider (set via RubyLLM configuration)
|
|
370
408
|
|
|
371
409
|
## Contributing
|
data/lib/rubric_llm/config.rb
CHANGED
|
@@ -5,11 +5,12 @@ module RubricLLM
|
|
|
5
5
|
attr_accessor :judge_model, :judge_provider, :temperature, :max_tokens, :custom_prompt,
|
|
6
6
|
:max_retries, :retry_base_delay, :concurrency
|
|
7
7
|
|
|
8
|
-
def initialize(judge_model: nil, judge_provider: nil,
|
|
8
|
+
def initialize(judge_model: nil, judge_provider: nil, # rubocop:disable Metrics/ParameterLists
|
|
9
|
+
temperature: Float(ENV.fetch("RUBRIC_TEMPERATURE", "0.0")), max_tokens: nil,
|
|
9
10
|
custom_prompt: nil, max_retries: nil, retry_base_delay: nil, concurrency: nil, validate: false)
|
|
10
11
|
@judge_model = judge_model || ENV.fetch("RUBRIC_JUDGE_MODEL", "gpt-4o")
|
|
11
12
|
@judge_provider = (judge_provider || ENV.fetch("RUBRIC_JUDGE_PROVIDER", "openai")).to_sym
|
|
12
|
-
@temperature = temperature
|
|
13
|
+
@temperature = temperature
|
|
13
14
|
@max_tokens = max_tokens || Integer(ENV.fetch("RUBRIC_MAX_TOKENS", "4096"))
|
|
14
15
|
@custom_prompt = custom_prompt
|
|
15
16
|
@max_retries = max_retries || Integer(ENV.fetch("RUBRIC_MAX_RETRIES", "2"))
|
|
@@ -61,9 +62,9 @@ module RubricLLM
|
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
def validate_temperature
|
|
64
|
-
return if temperature.is_a?(Numeric) && temperature.between?(0.0, 2.0)
|
|
65
|
+
return if temperature.nil? || (temperature.is_a?(Numeric) && temperature.between?(0.0, 2.0))
|
|
65
66
|
|
|
66
|
-
raise ConfigurationError, "temperature must be between 0.0 and 2.0"
|
|
67
|
+
raise ConfigurationError, "temperature must be nil or between 0.0 and 2.0"
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
def validate_max_tokens
|
data/lib/rubric_llm/judge.rb
CHANGED
|
@@ -51,14 +51,13 @@ module RubricLLM
|
|
|
51
51
|
attempts += 1
|
|
52
52
|
chat = RubyLLM.chat(model: config.judge_model, provider: config.judge_provider)
|
|
53
53
|
chat.with_temperature(config.temperature)
|
|
54
|
-
chat.
|
|
54
|
+
chat.with_max_output_tokens(config.max_tokens)
|
|
55
55
|
apply_response_schema(chat)
|
|
56
56
|
|
|
57
57
|
full_system_prompt = build_system_prompt(system_prompt)
|
|
58
58
|
chat.with_instructions(full_system_prompt)
|
|
59
59
|
response = chat.ask(user_prompt)
|
|
60
|
-
|
|
61
|
-
validate_response!(content.is_a?(Hash) ? content : parse_json(content))
|
|
60
|
+
validate_response!(parse_json(response.content))
|
|
62
61
|
rescue StandardError => e
|
|
63
62
|
raise wrap_error(e) unless transient?(e) && attempts <= config.max_retries
|
|
64
63
|
|
|
@@ -100,17 +99,13 @@ module RubricLLM
|
|
|
100
99
|
end
|
|
101
100
|
|
|
102
101
|
def apply_response_schema(chat)
|
|
103
|
-
return chat unless chat.respond_to?(:with_schema)
|
|
104
102
|
return chat unless structured_output_supported?(chat)
|
|
105
103
|
|
|
106
104
|
chat.with_schema(METRIC_RESPONSE_SCHEMA)
|
|
107
105
|
end
|
|
108
106
|
|
|
109
107
|
def structured_output_supported?(chat)
|
|
110
|
-
|
|
111
|
-
return true unless chat.model.respond_to?(:structured_output?)
|
|
112
|
-
|
|
113
|
-
chat.model.structured_output?
|
|
108
|
+
chat.model.supports?(:structured_output)
|
|
114
109
|
end
|
|
115
110
|
|
|
116
111
|
def validate_response!(response)
|
data/lib/rubric_llm/version.rb
CHANGED
data/lib/rubric_llm.rb
CHANGED
|
@@ -143,7 +143,7 @@ module RubricLLM
|
|
|
143
143
|
def apply_custom_prompt(config, custom_prompt)
|
|
144
144
|
return config unless custom_prompt
|
|
145
145
|
|
|
146
|
-
Config.new(**config.to_h
|
|
146
|
+
Config.new(**config.to_h, custom_prompt:)
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
def normalize_sample(sample)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubric_llm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Paluy
|
|
@@ -27,16 +27,16 @@ dependencies:
|
|
|
27
27
|
name: ruby_llm
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
|
-
- -
|
|
30
|
+
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: 2.0.0.rc1
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- -
|
|
37
|
+
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
39
|
+
version: 2.0.0.rc1
|
|
40
40
|
description: Provider-agnostic LLM evaluation with pluggable metrics, statistical
|
|
41
41
|
A/B comparison, and test framework integration. Ragas for Ruby, powered by RubyLLM.
|
|
42
42
|
email:
|