Module: ClaudeAgentSDK
- Defined in:
- lib/claude_agent_sdk.rb,
lib/claude_agent_sdk/query.rb,
lib/claude_agent_sdk/types.rb,
lib/claude_agent_sdk/errors.rb,
lib/claude_agent_sdk/version.rb,
lib/claude_agent_sdk/observer.rb,
lib/claude_agent_sdk/sessions.rb,
lib/claude_agent_sdk/streaming.rb,
lib/claude_agent_sdk/transport.rb,
lib/claude_agent_sdk/configuration.rb,
lib/claude_agent_sdk/message_parser.rb,
lib/claude_agent_sdk/sdk_mcp_server.rb,
lib/claude_agent_sdk/session_mutations.rb,
lib/claude_agent_sdk/instrumentation/otel.rb,
lib/claude_agent_sdk/subprocess_cli_transport.rb
Overview
Claude Agent SDK for Ruby
Defined Under Namespace
Modules: Instrumentation, Observer, SessionMutations, Sessions, Streaming Classes: APIRetryMessage, AgentDefinition, AssistantMessage, AsyncHookJSONOutput, AuthStatusMessage, BaseHookInput, CLIConnectionError, CLIJSONDecodeError, CLINotFoundError, ClaudeAgentOptions, ClaudeSDKError, Client, CompactBoundaryMessage, CompactMetadata, ConfigChangeHookInput, Configuration, ControlRequestTimeoutError, CwdChangedHookInput, CwdChangedHookSpecificOutput, ElicitationCompleteMessage, ElicitationHookInput, ElicitationResultHookInput, FileChangedHookInput, FileChangedHookSpecificOutput, FilesPersistedMessage, ForkSessionResult, HookContext, HookMatcher, HookProgressMessage, HookResponseMessage, HookStartedMessage, InitMessage, InstructionsLoadedHookInput, LocalCommandOutputMessage, McpClaudeAIProxyServerConfig, McpHttpServerConfig, McpSSEServerConfig, McpSdkServerConfig, McpSdkServerConfigStatus, McpServerInfo, McpServerStatus, McpStatusResponse, McpStdioServerConfig, McpToolAnnotations, McpToolInfo, MessageParseError, MessageParser, NotificationHookInput, NotificationHookSpecificOutput, PermissionDeniedHookInput, PermissionDeniedHookSpecificOutput, PermissionRequestHookInput, PermissionRequestHookSpecificOutput, PermissionResultAllow, PermissionResultDeny, PermissionRuleValue, PermissionUpdate, PostCompactHookInput, PostToolUseFailureHookInput, PostToolUseFailureHookSpecificOutput, PostToolUseHookInput, PostToolUseHookSpecificOutput, PreCompactHookInput, PreToolUseHookInput, PreToolUseHookSpecificOutput, ProcessError, PromptSuggestionMessage, Query, RateLimitEvent, RateLimitInfo, ResultMessage, SDKSessionInfo, SandboxFilesystemConfig, SandboxNetworkConfig, SandboxSettings, SdkMcpPrompt, SdkMcpResource, SdkMcpServer, SdkMcpTool, SdkPluginConfig, SessionEndHookInput, SessionMessage, SessionStartHookInput, SessionStartHookSpecificOutput, SessionStateChangedMessage, SetupHookInput, SetupHookSpecificOutput, StatusMessage, StopFailureHookInput, StopHookInput, StreamEvent, SubagentStartHookInput, SubagentStartHookSpecificOutput, SubagentStopHookInput, SubprocessCLITransport, SyncHookJSONOutput, SystemMessage, SystemPromptFile, SystemPromptPreset, TaskBudget, TaskCompletedHookInput, TaskCreatedHookInput, TaskNotificationMessage, TaskProgressMessage, TaskStartedMessage, TaskUsage, TeammateIdleHookInput, TextBlock, ThinkingBlock, ThinkingConfigAdaptive, ThinkingConfigDisabled, ThinkingConfigEnabled, ToolPermissionContext, ToolProgressMessage, ToolResultBlock, ToolUseBlock, ToolUseSummaryMessage, ToolsPreset, Transport, UnknownBlock, UserMessage, UserPromptSubmitHookInput, UserPromptSubmitHookSpecificOutput, WorktreeCreateHookInput, WorktreeRemoveHookInput
Constant Summary collapse
- PERMISSION_MODES =
Type constants for permission modes
%w[default acceptEdits plan bypassPermissions dontAsk auto].freeze
- SETTING_SOURCES =
Type constants for setting sources
%w[user project local].freeze
- EFFORT_LEVELS =
Effort levels for ‘ClaudeAgentOptions#effort`. The CLI (Claude Code 2.1.111+) accepts these values; the set of supported levels is model-dependent (e.g. `xhigh` is only supported on Opus 4.7 and falls back to `high` on Opus 4.6 / Sonnet 4.6). An Integer is also accepted and forwarded verbatim.
%w[low medium high xhigh max].freeze
- PERMISSION_UPDATE_DESTINATIONS =
Type constants for permission update destinations
%w[userSettings projectSettings localSettings session].freeze
- PERMISSION_BEHAVIORS =
Type constants for permission behaviors
%w[allow deny ask].freeze
- HOOK_EVENTS =
Type constants for hook events
%w[ PreToolUse PostToolUse PostToolUseFailure Notification UserPromptSubmit SessionStart SessionEnd Stop StopFailure SubagentStart SubagentStop PreCompact PostCompact PermissionRequest PermissionDenied Setup TeammateIdle TaskCreated TaskCompleted Elicitation ElicitationResult ConfigChange WorktreeCreate WorktreeRemove InstructionsLoaded CwdChanged FileChanged ].freeze
- ASSISTANT_MESSAGE_ERRORS =
Type constants for assistant message errors
%w[authentication_failed billing_error rate_limit invalid_request server_error max_output_tokens unknown].freeze
- SDK_BETAS =
Type constants for SDK beta features Available beta features that can be enabled via the betas option
%w[context-1m-2025-08-07].freeze
- TASK_NOTIFICATION_STATUSES =
Task lifecycle notification statuses
%w[completed failed stopped].freeze
- RATE_LIMIT_STATUSES =
Type constants for rate limit statuses
%w[allowed allowed_warning rejected].freeze
- RATE_LIMIT_TYPES =
Type constants for rate limit types
%w[five_hour seven_day seven_day_opus seven_day_sonnet overage].freeze
- MCP_SERVER_CONNECTION_STATUSES =
MCP server connection status values
%w[connected failed needs-auth pending disabled].freeze
- VERSION =
'0.15.0'
Class Method Summary collapse
-
.configuration ⇒ Configuration
Get the configuration object.
-
.configure {|Configuration| ... } ⇒ Object
Configure the SDK with default options.
-
.create_prompt(name:, description: nil, arguments: nil, &generator) ⇒ SdkMcpPrompt
Helper function to create a prompt definition.
-
.create_resource(uri:, name:, description: nil, mime_type: nil, &reader) ⇒ SdkMcpResource
Helper function to create a resource definition.
-
.create_sdk_mcp_server(name:, version: '1.0.0', tools: [], resources: [], prompts: []) ⇒ Hash
Create an SDK MCP server.
-
.create_tool(name, description, input_schema, annotations: nil, meta: nil, &handler) ⇒ SdkMcpTool
Helper function to create a tool definition.
-
.deep_symbolize_keys(obj) ⇒ Object
Recursively convert all hash keys to symbols.
-
.default_options ⇒ Hash
Get merged default options for use with ClaudeAgentOptions.
-
.delete_session(session_id:, directory: nil) ⇒ Object
Delete a session by removing its JSONL file (hard delete).
-
.flexible_fetch(hash, camel_key, snake_key) ⇒ Object
Look up a value in a hash that may use symbol or string keys in camelCase or snake_case.
-
.fork_session(session_id:, directory: nil, up_to_message_id: nil, title: nil) ⇒ ForkSessionResult
Fork a session into a new branch with fresh UUIDs.
-
.get_session_info(session_id:, directory: nil) ⇒ SDKSessionInfo?
Read metadata for a single session by ID (no full directory scan).
-
.get_session_messages(session_id:, directory: nil, limit: nil, offset: 0) ⇒ Array<SessionMessage>
Get messages from a session transcript.
-
.list_sessions(directory: nil, limit: nil, offset: 0, include_worktrees: true) {|Message| ... } ⇒ Enumerator, Array<SDKSessionInfo>
Query Claude Code for one-shot or unidirectional streaming interactions.
-
.notify_observers(observers, method, *args) ⇒ Object
Safely call a method on each observer, suppressing any errors.
- .query(prompt:, options: nil, &block) ⇒ Object
-
.rename_session(session_id:, title:, directory: nil) ⇒ Object
Rename a session by appending a custom-title entry.
-
.reset_configuration ⇒ Object
Reset configuration to defaults (useful for testing).
-
.resolve_observers(observers) ⇒ Object
Resolve observers array: callables (Proc/lambda) are invoked to produce a fresh instance per query/session (thread-safe); plain objects are used as-is.
-
.tag_session(session_id:, tag:, directory: nil) ⇒ Object
Tag a session.
Class Method Details
.configuration ⇒ Configuration
Get the configuration object
58 59 60 |
# File 'lib/claude_agent_sdk/configuration.rb', line 58 def configuration @configuration ||= Configuration.new end |
.configure {|Configuration| ... } ⇒ Object
Configure the SDK with default options
51 52 53 |
# File 'lib/claude_agent_sdk/configuration.rb', line 51 def configure yield(configuration) end |
.create_prompt(name:, description: nil, arguments: nil, &generator) ⇒ SdkMcpPrompt
Helper function to create a prompt definition
523 524 525 526 527 528 529 530 531 532 |
# File 'lib/claude_agent_sdk/sdk_mcp_server.rb', line 523 def self.create_prompt(name:, description: nil, arguments: nil, &generator) raise ArgumentError, 'Block required for prompt generator' unless generator SdkMcpPrompt.new( name: name, description: description, arguments: arguments, generator: generator ) end |
.create_resource(uri:, name:, description: nil, mime_type: nil, &reader) ⇒ SdkMcpResource
Helper function to create a resource definition
465 466 467 468 469 470 471 472 473 474 475 |
# File 'lib/claude_agent_sdk/sdk_mcp_server.rb', line 465 def self.create_resource(uri:, name:, description: nil, mime_type: nil, &reader) raise ArgumentError, 'Block required for resource reader' unless reader SdkMcpResource.new( uri: uri, name: name, description: description, mime_type: mime_type, reader: reader ) end |
.create_sdk_mcp_server(name:, version: '1.0.0', tools: [], resources: [], prompts: []) ⇒ Hash
Create an SDK MCP server
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 |
# File 'lib/claude_agent_sdk/sdk_mcp_server.rb', line 575 def self.create_sdk_mcp_server(name:, version: '1.0.0', tools: [], resources: [], prompts: []) server = SdkMcpServer.new( name: name, version: version, tools: tools, resources: resources, prompts: prompts ) # Return configuration for ClaudeAgentOptions { type: 'sdk', name: name, instance: server } end |
.create_tool(name, description, input_schema, annotations: nil, meta: nil, &handler) ⇒ SdkMcpTool
Helper function to create a tool definition
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/claude_agent_sdk/sdk_mcp_server.rb', line 404 def self.create_tool(name, description, input_schema, annotations: nil, meta: nil, &handler) raise ArgumentError, 'Block required for tool handler' unless handler # Auto-populate _meta with maxResultSizeChars from annotations if present = if .nil? && annotations max_chars = annotations[:maxResultSizeChars] || annotations['maxResultSizeChars'] = { 'anthropic/maxResultSizeChars' => max_chars } if max_chars end SdkMcpTool.new( name: name, description: description, input_schema: input_schema, handler: handler, annotations: annotations, meta: ) end |
.deep_symbolize_keys(obj) ⇒ Object
Recursively convert all hash keys to symbols
7 8 9 10 11 12 13 |
# File 'lib/claude_agent_sdk/sdk_mcp_server.rb', line 7 def self.deep_symbolize_keys(obj) case obj when Hash then obj.transform_keys(&:to_sym).transform_values { |v| deep_symbolize_keys(v) } when Array then obj.map { |v| deep_symbolize_keys(v) } else obj end end |
.default_options ⇒ Hash
Get merged default options for use with ClaudeAgentOptions
70 71 72 |
# File 'lib/claude_agent_sdk/configuration.rb', line 70 def configuration. || {} end |
.delete_session(session_id:, directory: nil) ⇒ Object
Delete a session by removing its JSONL file (hard delete).
129 130 131 |
# File 'lib/claude_agent_sdk.rb', line 129 def self.delete_session(session_id:, directory: nil) SessionMutations.delete_session(session_id: session_id, directory: directory) end |
.flexible_fetch(hash, camel_key, snake_key) ⇒ Object
Look up a value in a hash that may use symbol or string keys in camelCase or snake_case. Returns the first non-nil value found, preserving false as a meaningful value.
41 42 43 44 45 46 47 |
# File 'lib/claude_agent_sdk.rb', line 41 def self.flexible_fetch(hash, camel_key, snake_key) val = hash[camel_key.to_sym] val = hash[camel_key.to_s] if val.nil? val = hash[snake_key.to_sym] if val.nil? val = hash[snake_key.to_s] if val.nil? val end |
.fork_session(session_id:, directory: nil, up_to_message_id: nil, title: nil) ⇒ ForkSessionResult
Fork a session into a new branch with fresh UUIDs.
139 140 141 142 |
# File 'lib/claude_agent_sdk.rb', line 139 def self.fork_session(session_id:, directory: nil, up_to_message_id: nil, title: nil) SessionMutations.fork_session(session_id: session_id, directory: directory, up_to_message_id: , title: title) end |
.get_session_info(session_id:, directory: nil) ⇒ SDKSessionInfo?
Read metadata for a single session by ID (no full directory scan)
96 97 98 |
# File 'lib/claude_agent_sdk.rb', line 96 def self.get_session_info(session_id:, directory: nil) Sessions.get_session_info(session_id: session_id, directory: directory) end |
.get_session_messages(session_id:, directory: nil, limit: nil, offset: 0) ⇒ Array<SessionMessage>
Get messages from a session transcript
106 107 108 |
# File 'lib/claude_agent_sdk.rb', line 106 def self.(session_id:, directory: nil, limit: nil, offset: 0) Sessions.(session_id: session_id, directory: directory, limit: limit, offset: offset) end |
.list_sessions(directory: nil, limit: nil, offset: 0, include_worktrees: true) {|Message| ... } ⇒ Enumerator, Array<SDKSessionInfo>
Query Claude Code for one-shot or unidirectional streaming interactions
This function is ideal for simple, stateless queries where you don’t need bidirectional communication or conversation management.
List sessions for a directory (or all sessions)
88 89 90 |
# File 'lib/claude_agent_sdk.rb', line 88 def self.list_sessions(directory: nil, limit: nil, offset: 0, include_worktrees: true) Sessions.list_sessions(directory: directory, limit: limit, offset: offset, include_worktrees: include_worktrees) end |
.notify_observers(observers, method, *args) ⇒ Object
Safely call a method on each observer, suppressing any errors.
31 32 33 34 35 36 37 |
# File 'lib/claude_agent_sdk.rb', line 31 def self.notify_observers(observers, method, *args) observers.each do |obs| obs.send(method, *args) rescue StandardError nil end end |
.query(prompt:, options: nil, &block) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/claude_agent_sdk.rb', line 144 def self.query(prompt:, options: nil, &block) return enum_for(:query, prompt: prompt, options: ) unless block ||= ClaudeAgentOptions.new = if .can_use_tool if prompt.is_a?(String) raise ArgumentError, 'can_use_tool callback requires streaming mode. Please provide prompt as an Enumerator instead of a String.' end raise ArgumentError, 'can_use_tool callback cannot be used with permission_prompt_tool_name' if . = .dup_with(permission_prompt_tool_name: 'stdio') end # Resolve callable observers into fresh instances (thread-safe for global defaults) resolved_observers = ClaudeAgentSDK.resolve_observers(.observers) Async do # Always use streaming mode with control protocol (matches Python SDK). # This sends agents via initialize request instead of CLI args, # avoiding OS ARG_MAX limits. transport = SubprocessCLITransport.new() begin transport.connect # Extract SDK MCP servers sdk_mcp_servers = {} if .mcp_servers.is_a?(Hash) .mcp_servers.each do |name, config| sdk_mcp_servers[name] = config[:instance] if config.is_a?(Hash) && config[:type] == 'sdk' end end hooks = nil if .hooks hooks = {} .hooks.each do |event, matchers| next if matchers.nil? || matchers.empty? entries = [] matchers.each do |matcher| config = { matcher: matcher.matcher, hooks: matcher.hooks } config[:timeout] = matcher.timeout if matcher.timeout entries << config end hooks[event.to_s] = entries unless entries.empty? end hooks = nil if hooks.empty? end # Create Query handler for control protocol query_handler = Query.new( transport: transport, is_streaming_mode: true, can_use_tool: .can_use_tool, hooks: hooks, agents: .agents, sdk_mcp_servers: sdk_mcp_servers ) # Start reading messages in background query_handler.start # Initialize the control protocol (sends agents) query_handler.initialize_protocol # Send prompt(s) as user messages, then close stdin if prompt.is_a?(String) ClaudeAgentSDK.notify_observers(resolved_observers, :on_user_prompt, prompt) = { type: 'user', message: { role: 'user', content: prompt }, parent_tool_use_id: nil, session_id: '' } transport.write(JSON.generate() + "\n") query_handler.wait_for_result_and_end_input elsif prompt.is_a?(Enumerator) || prompt.respond_to?(:each) Async do query_handler.stream_input(prompt) end end # Read and yield messages from the query handler (filters out control messages) query_handler. do |data| = MessageParser.parse(data) if ClaudeAgentSDK.notify_observers(resolved_observers, :on_message, ) block.call() end end ensure ClaudeAgentSDK.notify_observers(resolved_observers, :on_close) # query_handler.close stops the background read task and closes the transport if query_handler query_handler.close else transport.close end end end.wait end |
.rename_session(session_id:, title:, directory: nil) ⇒ Object
Rename a session by appending a custom-title entry
114 115 116 |
# File 'lib/claude_agent_sdk.rb', line 114 def self.rename_session(session_id:, title:, directory: nil) SessionMutations.rename_session(session_id: session_id, title: title, directory: directory) end |
.reset_configuration ⇒ Object
Reset configuration to defaults (useful for testing)
63 64 65 |
# File 'lib/claude_agent_sdk/configuration.rb', line 63 def reset_configuration @configuration = Configuration.new end |
.resolve_observers(observers) ⇒ Object
Resolve observers array: callables (Proc/lambda) are invoked to produce a fresh instance per query/session (thread-safe); plain objects are used as-is. Array() guards against nil (e.g., when observers: nil is passed explicitly).
24 25 26 27 28 |
# File 'lib/claude_agent_sdk.rb', line 24 def self.resolve_observers(observers) Array(observers).map do |obs| obs.respond_to?(:call) ? obs.call : obs end end |
.tag_session(session_id:, tag:, directory: nil) ⇒ Object
Tag a session. Pass nil to clear the tag.
122 123 124 |
# File 'lib/claude_agent_sdk.rb', line 122 def self.tag_session(session_id:, tag:, directory: nil) SessionMutations.tag_session(session_id: session_id, tag: tag, directory: directory) end |