Skip to content

DSPy.rb 1.0.2: Claude Can Think. We Added Types Anyway.

Latest

Choose a tag to compare

@vicentereig vicentereig released this 18 Jul 16:28
· 10 commits to main since this release

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.answer

Nilable 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: nil

Predict, 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_config API 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: and max_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.

  • dspy 1.0.2
  • dspy-anthropic 1.0.6
  • dspy-code_act 1.0.3
  • dspy-ruby_llm 0.1.2

Full history: CHANGELOG.md