dspy-ruby_llm 0.1.1 → 0.1.2
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/README.md +23 -171
- data/lib/dspy/ruby_llm/README.md +29 -150
- data/lib/dspy/ruby_llm/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 954de47d2c188958e0f761dc8d4aa62d6c33feacc049f38eb9d3ddd31ba48f18
|
|
4
|
+
data.tar.gz: 2ccfa1e9a88a273627f717d9b5af87a64e04b478e6e2407e32e2b6a5c71ea50c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5816b736e227cf2661923d57485b4e1c75d447234523daa07890a1455464590846957505e43be7f3baefecbfc89ac3a910b83b5b984ac0fae5a4b98784e6ee10
|
|
7
|
+
data.tar.gz: 1b1787a237e8184298635afe70f5b9ba2e99151e3826a715d8805c246996967c0ed4e9cef2a341347d7c5e29b4579ad3e54aa5413452d6fe280bc373c468856a
|
data/README.md
CHANGED
|
@@ -6,96 +6,16 @@
|
|
|
6
6
|
[](https://oss.vicente.services/dspy.rb/)
|
|
7
7
|
[](https://discord.gg/zWBhrMqn)
|
|
8
8
|
|
|
9
|
-
**Build
|
|
9
|
+
**Build typed agents and model-backed programs in Ruby.**
|
|
10
10
|
|
|
11
|
-
DSPy.rb
|
|
12
|
-
The `1.x` line is the stable release track for production Ruby LLM applications.
|
|
11
|
+
DSPy.rb brings [DSPy](https://dspy.ai)'s signature, module, agent, and optimizer model to Ruby, with Sorbet types and Ruby-native integrations. A signature declares a task as typed inputs and outputs. A module chooses how to execute it. Ruby composes modules into programs, while `ReAct` adds a bounded loop when the model should choose the next action. DSPy.rb builds the provider request and validates the returned shape.
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
require 'dspy'
|
|
16
|
-
|
|
17
|
-
DSPy.configure do |c|
|
|
18
|
-
c.lm = DSPy::LM.new('openai/gpt-4o-mini', api_key: ENV['OPENAI_API_KEY'])
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
class Summarize < DSPy::Signature
|
|
22
|
-
description "Summarize the given text in one sentence."
|
|
23
|
-
|
|
24
|
-
input do
|
|
25
|
-
const :text, String
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
output do
|
|
29
|
-
const :summary, String
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
summarizer = DSPy::Predict.new(Summarize)
|
|
34
|
-
result = summarizer.call(text: "DSPy.rb brings structured LLM programming to Ruby...")
|
|
35
|
-
puts result.summary
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
That's it. No prompt templates. No JSON parsing. No prayer-based error handling.
|
|
39
|
-
|
|
40
|
-
## Installation
|
|
41
|
-
|
|
42
|
-
```ruby
|
|
43
|
-
# Gemfile
|
|
44
|
-
gem 'dspy'
|
|
45
|
-
gem 'dspy-openai' # For OpenAI, OpenRouter, or Ollama
|
|
46
|
-
# gem 'dspy-anthropic' # For Claude
|
|
47
|
-
# gem 'dspy-gemini' # For Gemini
|
|
48
|
-
# gem 'dspy-ruby_llm' # For 12+ providers via RubyLLM
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
bundle install
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Quick Start
|
|
56
|
-
|
|
57
|
-
### Configure Your LLM
|
|
58
|
-
|
|
59
|
-
```ruby
|
|
60
|
-
# OpenAI
|
|
61
|
-
DSPy.configure do |c|
|
|
62
|
-
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
|
|
63
|
-
api_key: ENV['OPENAI_API_KEY'],
|
|
64
|
-
structured_outputs: true)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Anthropic Claude
|
|
68
|
-
DSPy.configure do |c|
|
|
69
|
-
c.lm = DSPy::LM.new('anthropic/claude-sonnet-4-20250514',
|
|
70
|
-
api_key: ENV['ANTHROPIC_API_KEY'])
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Google Gemini
|
|
74
|
-
DSPy.configure do |c|
|
|
75
|
-
c.lm = DSPy::LM.new('gemini/gemini-2.5-flash',
|
|
76
|
-
api_key: ENV['GEMINI_API_KEY'])
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Ollama (local, free)
|
|
80
|
-
DSPy.configure do |c|
|
|
81
|
-
c.lm = DSPy::LM.new('ollama/llama3.2')
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# OpenRouter (200+ models)
|
|
85
|
-
DSPy.configure do |c|
|
|
86
|
-
c.lm = DSPy::LM.new('openrouter/deepseek/deepseek-chat-v3.1:free',
|
|
87
|
-
api_key: ENV['OPENROUTER_API_KEY'])
|
|
88
|
-
end
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Define a Signature
|
|
13
|
+
The `1.x` series is the current stable release line.
|
|
92
14
|
|
|
93
|
-
|
|
15
|
+
In a configured application, the task contract and call look like this:
|
|
94
16
|
|
|
95
17
|
```ruby
|
|
96
18
|
class Classify < DSPy::Signature
|
|
97
|
-
description "Classify sentiment of a given sentence."
|
|
98
|
-
|
|
99
19
|
class Sentiment < T::Enum
|
|
100
20
|
enums do
|
|
101
21
|
Positive = new('positive')
|
|
@@ -105,7 +25,7 @@ class Classify < DSPy::Signature
|
|
|
105
25
|
end
|
|
106
26
|
|
|
107
27
|
input do
|
|
108
|
-
const :sentence, String
|
|
28
|
+
const :sentence, String
|
|
109
29
|
end
|
|
110
30
|
|
|
111
31
|
output do
|
|
@@ -115,107 +35,39 @@ class Classify < DSPy::Signature
|
|
|
115
35
|
end
|
|
116
36
|
|
|
117
37
|
classifier = DSPy::Predict.new(Classify)
|
|
118
|
-
result = classifier.call(sentence: "This book was
|
|
119
|
-
|
|
120
|
-
result.sentiment # => #<Sentiment::Positive>
|
|
121
|
-
result.confidence # => 0.92
|
|
38
|
+
result = classifier.call(sentence: "This book was fun to read!")
|
|
122
39
|
```
|
|
123
40
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
For complex reasoning, use `ChainOfThought` to get step-by-step explanations:
|
|
127
|
-
|
|
128
|
-
```ruby
|
|
129
|
-
solver = DSPy::ChainOfThought.new(MathProblem)
|
|
130
|
-
result = solver.call(problem: "If a train travels 120km in 2 hours, what's its speed?")
|
|
131
|
-
|
|
132
|
-
result.reasoning # => "Speed = Distance / Time = 120km / 2h = 60km/h"
|
|
133
|
-
result.answer # => "60 km/h"
|
|
134
|
-
```
|
|
41
|
+
Define a typed task contract instead of maintaining an output template. Receive validated Ruby values instead of parsing provider JSON. Handle configuration, transport, and validation errors explicitly.
|
|
135
42
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Build agents that use tools to accomplish tasks:
|
|
139
|
-
|
|
140
|
-
```ruby
|
|
141
|
-
class SearchTool < DSPy::Tools::Base
|
|
142
|
-
tool_name "search"
|
|
143
|
-
tool_description "Search for information"
|
|
144
|
-
|
|
145
|
-
sig { params(query: String).returns(String) }
|
|
146
|
-
def call(query:)
|
|
147
|
-
# Your search implementation
|
|
148
|
-
"Result 1, Result 2"
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
agent = DSPy::ReAct.new(ResearchTask, tools: [SearchTool.new], max_iterations: 5)
|
|
153
|
-
result = agent.call(question: "What's the latest on Ruby 3.4?")
|
|
154
|
-
```
|
|
43
|
+
## Start Here
|
|
155
44
|
|
|
156
|
-
|
|
45
|
+
The [Quick Start](https://oss.vicente.services/dspy.rb/getting-started/quick-start/) is the complete supported path: install the core and provider gems, configure a key, save a program, and run it.
|
|
157
46
|
|
|
158
|
-
|
|
47
|
+
Use [Installation](https://oss.vicente.services/dspy.rb/getting-started/installation/) to choose a provider. The [package and capability matrix](https://oss.vicente.services/dspy.rb/getting-started/packages/) records exact gem names, require behavior, support labels, and model or SDK boundaries.
|
|
159
48
|
|
|
160
|
-
|
|
49
|
+
## Mental Model
|
|
161
50
|
|
|
162
|
-
|
|
51
|
+
- A `DSPy::Signature` defines the task contract.
|
|
52
|
+
- `DSPy::Predict` and other modules choose an execution strategy.
|
|
53
|
+
- Ordinary Ruby owns fixed sequencing, branching, persistence, permissions, and failure policy.
|
|
54
|
+
- Results cross a runtime validation boundary; validation establishes shape, not factual correctness.
|
|
163
55
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
**Optimization**: MIPROv2 (Bayesian optimization) and GEPA (genetic evolution) for prompt tuning.
|
|
167
|
-
|
|
168
|
-
**Provider Support**: OpenAI, Anthropic, Gemini, Ollama, and OpenRouter via official SDKs.
|
|
169
|
-
|
|
170
|
-
## Documentation
|
|
171
|
-
|
|
172
|
-
**[Full Documentation](https://oss.vicente.services/dspy.rb/)** — Getting started, core concepts, advanced patterns.
|
|
173
|
-
|
|
174
|
-
**[llms.txt](https://oss.vicente.services/dspy.rb/llms.txt)** — LLM-friendly reference for AI assistants.
|
|
175
|
-
|
|
176
|
-
### Claude Skill
|
|
177
|
-
|
|
178
|
-
A [Claude Skill](https://github.com/vicentereig/dspy-rb-skill) is available to help you build DSPy.rb applications:
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
# Claude Code — install from the vicentereig/engineering marketplace
|
|
182
|
-
claude install-skill vicentereig/engineering --skill dspy-rb
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
For Claude.ai Pro/Max, download the [skill ZIP](https://github.com/vicentereig/dspy-rb-skill/archive/refs/heads/main.zip) and upload via Settings > Skills.
|
|
186
|
-
|
|
187
|
-
## Examples
|
|
188
|
-
|
|
189
|
-
The [examples/](examples/) directory has runnable code for common patterns:
|
|
190
|
-
|
|
191
|
-
- Sentiment classification
|
|
192
|
-
- ReAct agents with tools
|
|
193
|
-
- Image analysis
|
|
194
|
-
- Prompt optimization
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
bundle exec ruby examples/basic_search_agent.rb
|
|
198
|
-
```
|
|
56
|
+
### ReAct Agents
|
|
199
57
|
|
|
200
|
-
|
|
58
|
+
Use `ReAct` when the model needs to choose among typed Ruby tools inside an iteration bound. The application still owns tool authorization, side effects, budgets, and errors. See [Predictors](https://oss.vicente.services/dspy.rb/core-concepts/predictors/) and [Toolsets](https://oss.vicente.services/dspy.rb/core-concepts/toolsets/).
|
|
201
59
|
|
|
202
|
-
|
|
60
|
+
## Explore
|
|
203
61
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
| `dspy-evals` | Evaluation harness with metrics and callbacks |
|
|
208
|
-
| `dspy-miprov2` | Bayesian optimization for prompt tuning |
|
|
209
|
-
| `dspy-gepa` | Genetic-Pareto prompt evolution |
|
|
210
|
-
| `dspy-o11y-langfuse` | Auto-configure Langfuse tracing |
|
|
211
|
-
| `dspy-code_act` | Think-Code-Observe agents |
|
|
212
|
-
| `dspy-deep_search` | Production DeepSearch with Exa |
|
|
62
|
+
- [Documentation](https://oss.vicente.services/dspy.rb/) — task-oriented guides and reference
|
|
63
|
+
- [Examples](examples/) — repository demos indexed by capability and prerequisites
|
|
64
|
+
- [llms.txt](https://oss.vicente.services/dspy.rb/llms.txt) — generated reference for AI assistants
|
|
213
65
|
|
|
214
|
-
|
|
66
|
+
Provider adapters, optimizers, observability exporters, datasets, and code-executing agents are separate packages when they add dependencies. Check the package matrix before selecting one; package availability does not guarantee uniform provider or model behavior.
|
|
215
67
|
|
|
216
68
|
## Contributing
|
|
217
69
|
|
|
218
|
-
|
|
70
|
+
For bugs, [open an issue](https://github.com/vicentereig/dspy.rb/issues). For suggestions, [start a discussion](https://github.com/vicentereig/dspy.rb/discussions).
|
|
219
71
|
|
|
220
72
|
Want to contribute code? Reach out: hey at vicente.services
|
|
221
73
|
|
data/lib/dspy/ruby_llm/README.md
CHANGED
|
@@ -1,174 +1,53 @@
|
|
|
1
|
-
# DSPy RubyLLM Adapter
|
|
1
|
+
# DSPy RubyLLM Adapter (Preview)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`dspy-ruby_llm` delegates model lookup, provider selection, request transport, and capability discovery to [RubyLLM](https://rubyllm.com). The package is preview: provider coverage is not a uniform capability promise.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
See the [package and capability matrix](https://oss.vicente.services/dspy.rb/getting-started/packages/) for canonical status and the files shared with the core gem.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Prerequisites
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
9
|
+
- Ruby, Bundler, and `gem "dspy-ruby_llm"`
|
|
10
|
+
- RubyLLM credentials and configuration for the selected provider
|
|
11
|
+
- a model ID recognized by RubyLLM, or an explicit `provider:` override
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
If you already have RubyLLM configured, DSPy will use your existing setup automatically:
|
|
13
|
+
## Install and Run
|
|
18
14
|
|
|
19
15
|
```ruby
|
|
20
|
-
|
|
21
|
-
RubyLLM.configure do |config|
|
|
22
|
-
config.openai_api_key = ENV['OPENAI_API_KEY']
|
|
23
|
-
config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# DSPy uses your existing config - no api_key needed!
|
|
27
|
-
lm = DSPy::LM.new("ruby_llm/gpt-4o")
|
|
28
|
-
lm = DSPy::LM.new("ruby_llm/claude-sonnet-4")
|
|
16
|
+
gem "dspy-ruby_llm"
|
|
29
17
|
```
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Use `ruby_llm/{model_id}` format where `model_id` is the RubyLLM model identifier:
|
|
19
|
+
Save this as `ruby_llm_smoke.rb`:
|
|
34
20
|
|
|
35
21
|
```ruby
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
# Or use global RubyLLM config (no api_key needed)
|
|
40
|
-
lm = DSPy::LM.new("ruby_llm/gpt-4o")
|
|
41
|
-
lm = DSPy::LM.new("ruby_llm/claude-sonnet-4")
|
|
42
|
-
lm = DSPy::LM.new("ruby_llm/gemini-1.5-pro")
|
|
22
|
+
require "dspy"
|
|
23
|
+
require "dspy/ruby_llm"
|
|
43
24
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
The adapter detects the provider from RubyLLM's model registry. For models not in the registry, use the `provider:` option.
|
|
49
|
-
|
|
50
|
-
### Provider Override
|
|
51
|
-
|
|
52
|
-
For custom deployments or models not in the registry, explicitly specify the provider:
|
|
53
|
-
|
|
54
|
-
```ruby
|
|
55
|
-
# OpenRouter
|
|
56
|
-
lm = DSPy::LM.new("ruby_llm/anthropic/claude-3-opus",
|
|
57
|
-
api_key: ENV['OPENROUTER_API_KEY'],
|
|
58
|
-
provider: 'openrouter'
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
# Custom model with explicit provider
|
|
62
|
-
lm = DSPy::LM.new("ruby_llm/my-custom-model",
|
|
63
|
-
api_key: ENV['OPENAI_API_KEY'],
|
|
64
|
-
provider: 'openai',
|
|
65
|
-
base_url: 'https://custom-endpoint.com/v1'
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
# AWS Bedrock - configure RubyLLM globally first
|
|
69
|
-
RubyLLM.configure do |c|
|
|
70
|
-
c.bedrock_api_key = ENV['AWS_ACCESS_KEY_ID']
|
|
71
|
-
c.bedrock_secret_key = ENV['AWS_SECRET_ACCESS_KEY']
|
|
72
|
-
c.bedrock_region = 'us-east-1'
|
|
25
|
+
RubyLLM.configure do |config|
|
|
26
|
+
config.openai_api_key = ENV.fetch("OPENAI_API_KEY")
|
|
73
27
|
end
|
|
74
|
-
lm = DSPy::LM.new("ruby_llm/anthropic.claude-3-5-sonnet", provider: 'bedrock')
|
|
75
28
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
c.vertexai_location = 'us-central1'
|
|
80
|
-
end
|
|
81
|
-
lm = DSPy::LM.new("ruby_llm/gemini-pro", provider: 'vertexai')
|
|
29
|
+
lm = DSPy::LM.new("ruby_llm/gpt-4o")
|
|
30
|
+
response = lm.raw_chat([{ role: "user", content: "Reply with: adapter ready" }])
|
|
31
|
+
puts response.content
|
|
82
32
|
```
|
|
83
33
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| OpenAI | `ruby_llm/gpt-4o` | In RubyLLM registry |
|
|
89
|
-
| Anthropic | `ruby_llm/claude-sonnet-4` | In RubyLLM registry |
|
|
90
|
-
| Google Gemini | `ruby_llm/gemini-1.5-pro` | In RubyLLM registry |
|
|
91
|
-
| DeepSeek | `ruby_llm/deepseek-chat` | In RubyLLM registry |
|
|
92
|
-
| Mistral | `ruby_llm/mistral-large` | In RubyLLM registry |
|
|
93
|
-
| Ollama | `ruby_llm/llama3.2` | Use `provider: 'ollama'`, no API key needed |
|
|
94
|
-
| AWS Bedrock | `ruby_llm/anthropic.claude-3-5-sonnet` | Configure RubyLLM globally |
|
|
95
|
-
| VertexAI | `ruby_llm/gemini-pro` | Configure RubyLLM globally |
|
|
96
|
-
| OpenRouter | `ruby_llm/anthropic/claude-3-opus` | Use `provider: 'openrouter'` |
|
|
97
|
-
| Perplexity | `ruby_llm/llama-3.1-sonar-large` | Use `provider: 'perplexity'` |
|
|
98
|
-
| GPUStack | `ruby_llm/model-name` | Use `provider: 'gpustack'` |
|
|
99
|
-
|
|
100
|
-
### Configuration Options
|
|
101
|
-
|
|
102
|
-
```ruby
|
|
103
|
-
lm = DSPy::LM.new("ruby_llm/gpt-4o",
|
|
104
|
-
api_key: ENV['OPENAI_API_KEY'], # API key (or use global RubyLLM config)
|
|
105
|
-
base_url: 'https://custom.com/v1', # Custom endpoint
|
|
106
|
-
timeout: 120, # Request timeout in seconds
|
|
107
|
-
max_retries: 3, # Retry count
|
|
108
|
-
structured_outputs: true # Enable JSON schema (default: true)
|
|
109
|
-
)
|
|
34
|
+
```bash
|
|
35
|
+
bundle install
|
|
36
|
+
export OPENAI_API_KEY="your-key"
|
|
37
|
+
bundle exec ruby ruby_llm_smoke.rb
|
|
110
38
|
```
|
|
111
39
|
|
|
112
|
-
|
|
40
|
+
The command prints the provider response. DSPy reuses RubyLLM's global configuration only when the `DSPy::LM` call does not supply `api_key`, `base_url`, `timeout`, or `max_retries` overrides. Supplying any of those options creates a scoped adapter configuration.
|
|
113
41
|
|
|
114
|
-
|
|
42
|
+
For a model absent from RubyLLM's registry, specify the provider explicitly:
|
|
115
43
|
|
|
116
44
|
```ruby
|
|
117
|
-
|
|
118
|
-
description "Summarize the given text"
|
|
119
|
-
|
|
120
|
-
input do
|
|
121
|
-
const :text, String
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
output do
|
|
125
|
-
const :summary, String
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
DSPy.configure do |config|
|
|
130
|
-
config.lm = DSPy::LM.new("ruby_llm/claude-sonnet-4")
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
summarizer = DSPy::Predict.new(Summarize)
|
|
134
|
-
result = summarizer.call(text: "Long article text here...")
|
|
135
|
-
puts result.summary
|
|
45
|
+
lm = DSPy::LM.new("ruby_llm/my-model", provider: "ollama")
|
|
136
46
|
```
|
|
137
47
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
```ruby
|
|
141
|
-
lm = DSPy::LM.new("ruby_llm/gpt-4o", api_key: ENV['OPENAI_API_KEY'])
|
|
142
|
-
|
|
143
|
-
response = lm.chat(messages: [{ role: 'user', content: 'Tell me a story' }]) do |chunk|
|
|
144
|
-
print chunk # Print each chunk as it arrives
|
|
145
|
-
end
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Dependencies
|
|
149
|
-
|
|
150
|
-
This gem depends on:
|
|
151
|
-
- `dspy` (>= 0.32)
|
|
152
|
-
- `ruby_llm` (~> 1.3)
|
|
153
|
-
|
|
154
|
-
RubyLLM itself has minimal dependencies (Faraday, Zeitwerk, Marcel).
|
|
155
|
-
|
|
156
|
-
## Why Use This Adapter?
|
|
157
|
-
|
|
158
|
-
1. **Unified interface** - One API for all providers
|
|
159
|
-
2. **Lightweight** - RubyLLM has only 3 dependencies
|
|
160
|
-
3. **Provider coverage** - Access Bedrock, VertexAI, DeepSeek without separate adapters
|
|
161
|
-
4. **Built-in retries** - Automatic retry with exponential backoff
|
|
162
|
-
5. **Model registry** - 500+ models with capability detection and auto provider resolution
|
|
163
|
-
|
|
164
|
-
## Error Handling
|
|
165
|
-
|
|
166
|
-
The adapter maps RubyLLM errors to DSPy error types:
|
|
48
|
+
## Capability and Failure Boundaries
|
|
167
49
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
| `ModelNotFoundError` | `AdapterError` |
|
|
173
|
-
| `BadRequestError` | `AdapterError` |
|
|
174
|
-
| `ConfigurationError` | `ConfigurationError` |
|
|
50
|
+
- A missing RubyLLM credential or unknown model/provider fails before or during the request.
|
|
51
|
+
- Registry data and capability detection vary with the installed RubyLLM version.
|
|
52
|
+
- Authentication, attachments, schemas, streaming, retries, and request options vary by underlying provider and model; document input is currently restricted to Anthropic.
|
|
53
|
+
- Error mapping preserves a DSPy boundary, but provider-specific details still come from RubyLLM and its SDKs. Test the exact model and request your application will use.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dspy-ruby_llm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vicente Reig Rincón de Arellano
|
|
@@ -86,5 +86,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
86
86
|
requirements: []
|
|
87
87
|
rubygems_version: 3.6.9
|
|
88
88
|
specification_version: 4
|
|
89
|
-
summary: RubyLLM adapter for DSPy.rb
|
|
89
|
+
summary: RubyLLM provider adapter for DSPy.rb.
|
|
90
90
|
test_files: []
|