Thanks to @a-zboon for opening #247 and asking for a public reasoning API.
Thanks to @paulp-aus for reporting #256 and #259, implementing #257, testing the live Anthropic API, and carrying the work through two review rounds.
Thanks to @lennart and his cape-and-cowl agent, @paulp-aus—Batman to his Bruce Wayne, Heisenberg to his Walter White. Skyler, wisely, declined involvement in the Anthropic adapter.
DSPy.rb 1.0.2 gives Claude a typed reasoning dial, fixes Anthropic streaming, and makes signature omission explicit. Claude may now think harder. Ruby, naturally, demands paperwork.
Claude can think on a budget
DSPy::Reasoning adds typed levels from low through max, plus exact token budgets, adaptive reasoning, and an off switch. In this release, dspy-anthropic maps those settings to provider parameters and rejects bad model, budget, token, and sampling combinations before they become expensive HTTP requests. Claude can waste tokens on its own time.
class ResearchBrief < DSPy::Signature
description "Answer a research question concisely"
input do
const :question, String
const :context, T.nilable(String), default: nil
end
output do
const :answer, String
end
end
lm = DSPy::LM.new(
"anthropic/claude-sonnet-5",
api_key: ENV.fetch("ANTHROPIC_API_KEY"),
reasoning: DSPy::Reasoning.high,
max_tokens: 8_192
)
DSPy.configure { |config| config.lm = lm }
result = DSPy::Predict.new(ResearchBrief).call(
question: "Why does the sky appear blue?"
)
puts result.answerNilable is not optional
A signature field without default: is now required, even when its type is T.nilable. To permit omission, say so:
const :context, T.nilable(String), default: nilPredict, ReAct, and CodeAct now agree on this rule. T.nilable means the value may be nil. It does not mean the field enjoys sovereign citizenship.
Anthropic repairs
- Structured outputs use the stable
output_configAPI and can share a request with reasoning. “Stable” is a technical term meaning the deprecated one finally frightened us enough. - Raw streams consume
MessageStream#text, yield each fragment once, and return the accumulated string. Previously, some streams returned the sort of profound silence usually sold as a retreat. - Fixed-sampling Claude families no longer receive DSPy.rb's implicit temperature.
temperature:andmax_tokens:are configurable and validated against model capabilities.
Smaller, useful things
- ReAct finish actions may omit
tool_input; actual tool calls may not improvise the shape of reality. - Standalone Toolset loading now loads its own base class.
- Missing-adapter errors retain the useful installation message.
- The documentation now has one 22-step quality gate, because apparently writing a sentence required an air-traffic-control tower.
- CI adds a complete non-unit RSpec lane and uses inert telemetry credentials. Computers remain the only coworkers eager to prove you wrong at four in the morning.
Gems
Four gems shipped together, because one version number would have made maintainers dangerously comfortable.
dspy1.0.2dspy-anthropic1.0.6dspy-code_act1.0.3dspy-ruby_llm0.1.2
Full history: CHANGELOG.md