Repository navigation
v0.25.0
Added
- Opt-in fiber-native callback execution:
callback_scheduling: :inline(#47). By default the SDK hops every user callback (message blocks, hooks, permission callbacks, SDK MCP handlers, observers) to a plain thread so thread-keyed libraries (ActiveRecord, pg, …) never see the async gem's Fiber scheduler. Hosts that are fiber-isolated end to end — e.g. solid_queue fiber workers (fibers: N) withActiveSupport::IsolatedExecutionState.isolation_level = :fiber— can now run callbacks in place on the reactor fiber:Fiber.scheduleris live inside callbacks, no per-call threads exist to strand AR connections, and the session can live directly on the job fiber. Matches the Python SDK's execution model. Default behavior is unchanged.- In
:inlinemode hook timeouts become cooperative cancellations (interrupted at the next suspension point,ensureblocks run) instead of hard thread abandonment — and a hook'srescue StandardErrorcannot swallow the cancellation. SessionStoreadapter calls intentionally stay on threads so a wedged adapter can never stall the reactor.- Warns once when
:inlineis enabled underisolation_level == :thread. - Sessions with different modes sharing one SDK MCP server stay fully isolated (mode travels via a scoped, invalidatable fiber-storage carrier — the server instance is never mutated).
- In
ClaudeAgentSDK.offload { }— public escape hatch for:inlinehosts: runs a heavy piece of a callback on a plain thread instead of the reactor fiber. Shields the reactor from scheduler-opaque blocking that releases the GVL; turns pure-Ruby CPU work into GVL time-slicing instead of a hard stall. (A C extension that holds the GVL still freezes the process — use a subprocess.) No-op outside a reactor.
Usage
# config/initializers/claude_agent_sdk.rb — solid_queue fiber-worker processes
ClaudeAgentSDK.configure do |config|
config.default_options = { callback_scheduling: :inline }
end
# Heavy work inside an inline callback:
tool = ClaudeAgentSDK.create_tool('lookup', 'Query legacy DB', { id: String }) do |args|
row = ClaudeAgentSDK.offload { legacy_client.fetch(args[:id]) }
{ content: [{ type: 'text', text: row.to_json }] }
endSee the new "Fiber workers (solid_queue) and callback_scheduling: :inline" section in docs/rails.md.
What's changed
- #48 Fiber-native callback execution: opt-in callback_scheduling: :inline (#47 phase 1) — @ya-luotao
Full Changelog: v0.24.0...v0.25.0
gem install claude-agent-sdk -v 0.25.0