Class: ClaudeAgentSDK::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/claude_agent_sdk.rb

Overview

Client for bidirectional, interactive conversations with Claude Code

This client provides full control over the conversation flow with support for streaming, hooks, permission callbacks, and dynamic message sending.

Examples:

Basic usage

Async do
  client = ClaudeAgentSDK::Client.new
  client.connect

  client.query("What is the capital of France?")
  client.receive_response do |msg|
    puts msg if msg.is_a?(ClaudeAgentSDK::AssistantMessage)
  end

  client.disconnect
end

With hooks

options = ClaudeAgentOptions.new(
  hooks: {
    'PreToolUse' => [
      HookMatcher.new(
        matcher: 'Bash',
        hooks: [
          ->(input, tool_use_id, context) {
            # Return hook output
            {}
          }
        ]
      )
    ]
  }
)
client = ClaudeAgentSDK::Client.new(options: options)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options: nil) ⇒ Client

Returns a new instance of Client.



101
102
103
104
105
106
107
# File 'lib/claude_agent_sdk.rb', line 101

def initialize(options: nil)
  @options = options || ClaudeAgentOptions.new
  @transport = nil
  @query_handler = nil
  @connected = false
  ENV['CLAUDE_CODE_ENTRYPOINT'] = 'sdk-rb-client'
end

Instance Attribute Details

#query_handlerObject (readonly)

Returns the value of attribute query_handler.



99
100
101
# File 'lib/claude_agent_sdk.rb', line 99

def query_handler
  @query_handler
end

Instance Method Details

#connect(prompt = nil) ⇒ Object

Connect to Claude with optional initial prompt

Parameters:

  • prompt (String, Enumerator, nil) (defaults to: nil)

    Initial prompt or message stream



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/claude_agent_sdk.rb', line 111

def connect(prompt = nil)
  return if @connected

  # Validate and configure permission settings
  configured_options = @options
  if @options.can_use_tool
    # can_use_tool requires streaming mode
    if prompt.is_a?(String)
      raise ArgumentError, 'can_use_tool callback requires streaming mode'
    end

    # can_use_tool and permission_prompt_tool_name are mutually exclusive
    if @options.permission_prompt_tool_name
      raise ArgumentError, 'can_use_tool callback cannot be used with permission_prompt_tool_name'
    end

    # Set permission_prompt_tool_name to stdio for control protocol
    configured_options = @options.dup_with(permission_prompt_tool_name: 'stdio')
  end

  # Create transport
  actual_prompt = prompt || ''
  @transport = SubprocessCLITransport.new(actual_prompt, configured_options)
  @transport.connect

  # Extract SDK MCP servers
  sdk_mcp_servers = {}
  if configured_options.mcp_servers.is_a?(Hash)
    configured_options.mcp_servers.each do |name, config|
      sdk_mcp_servers[name] = config[:instance] if config.is_a?(Hash) && config[:type] == 'sdk'
    end
  end

  # Convert hooks to internal format
  hooks = convert_hooks_to_internal_format(configured_options.hooks) if configured_options.hooks

  # Create Query handler
  @query_handler = Query.new(
    transport: @transport,
    is_streaming_mode: true,
    can_use_tool: configured_options.can_use_tool,
    hooks: hooks,
    sdk_mcp_servers: sdk_mcp_servers
  )

  # Start query handler and initialize
  @query_handler.start
  @query_handler.initialize_protocol

  @connected = true
end

#disconnectObject

Disconnect from Claude



229
230
231
232
233
234
235
236
# File 'lib/claude_agent_sdk.rb', line 229

def disconnect
  return unless @connected

  @query_handler&.close
  @query_handler = nil
  @transport = nil
  @connected = false
end

#interruptObject

Send interrupt signal

Raises:



203
204
205
206
# File 'lib/claude_agent_sdk.rb', line 203

def interrupt
  raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected
  @query_handler.interrupt
end

#query(prompt, session_id: 'default') ⇒ Object

Send a query to Claude

Parameters:

  • prompt (String)

    The prompt to send

  • session_id (String) (defaults to: 'default')

    Session identifier

Raises:



166
167
168
169
170
171
172
173
174
175
176
# File 'lib/claude_agent_sdk.rb', line 166

def query(prompt, session_id: 'default')
  raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected

  message = {
    type: 'user',
    message: { role: 'user', content: prompt },
    parent_tool_use_id: nil,
    session_id: session_id
  }
  @transport.write(JSON.generate(message) + "\n")
end

#receive_messages {|Message| ... } ⇒ Object

Receive all messages from Claude

Yields:

  • (Message)

    Each message received

Raises:



180
181
182
183
184
185
186
187
188
189
# File 'lib/claude_agent_sdk.rb', line 180

def receive_messages(&block)
  return enum_for(:receive_messages) unless block

  raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected

  @query_handler.receive_messages do |data|
    message = MessageParser.parse(data)
    block.call(message)
  end
end

#receive_response {|Message| ... } ⇒ Object

Receive messages until a ResultMessage is received

Yields:

  • (Message)

    Each message received



193
194
195
196
197
198
199
200
# File 'lib/claude_agent_sdk.rb', line 193

def receive_response(&block)
  return enum_for(:receive_response) unless block

  receive_messages do |message|
    block.call(message)
    break if message.is_a?(ResultMessage)
  end
end

#server_infoHash?

Get server initialization info

Returns:

  • (Hash, nil)

    Server info or nil



224
225
226
# File 'lib/claude_agent_sdk.rb', line 224

def server_info
  @query_handler&.instance_variable_get(:@initialization_result)
end

#set_model(model) ⇒ Object

Change the AI model during conversation

Parameters:

  • model (String, nil)

    Model name or nil for default

Raises:



217
218
219
220
# File 'lib/claude_agent_sdk.rb', line 217

def set_model(model)
  raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected
  @query_handler.set_model(model)
end

#set_permission_mode(mode) ⇒ Object

Change permission mode during conversation

Parameters:

  • mode (String)

    Permission mode (‘default’, ‘acceptEdits’, ‘bypassPermissions’)

Raises:



210
211
212
213
# File 'lib/claude_agent_sdk.rb', line 210

def set_permission_mode(mode)
  raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected
  @query_handler.set_permission_mode(mode)
end