Class: ClaudeAgentSDK::Query
- Inherits:
-
Object
- Object
- ClaudeAgentSDK::Query
- Defined in:
- lib/claude_agent_sdk/query.rb
Overview
Handles bidirectional control protocol on top of Transport
This class manages:
-
Control request/response routing
-
Hook callbacks
-
Tool permission callbacks
-
Message streaming
-
Initialization handshake
Instance Attribute Summary collapse
-
#is_streaming_mode ⇒ Object
readonly
Returns the value of attribute is_streaming_mode.
-
#sdk_mcp_servers ⇒ Object
readonly
Returns the value of attribute sdk_mcp_servers.
-
#transport ⇒ Object
readonly
Returns the value of attribute transport.
Instance Method Summary collapse
-
#close ⇒ Object
Close the query and transport.
-
#get_mcp_status ⇒ Hash
Get current MCP server connection status (only works with streaming mode).
-
#initialize(transport:, is_streaming_mode:, can_use_tool: nil, hooks: nil, sdk_mcp_servers: nil) ⇒ Query
constructor
A new instance of Query.
-
#initialize_protocol ⇒ Hash?
Initialize control protocol if in streaming mode.
-
#interrupt ⇒ Object
Send interrupt control request.
-
#receive_messages(&block) ⇒ Object
Receive SDK messages (not control messages).
-
#rewind_files(user_message_uuid) ⇒ Object
Rewind files to a previous checkpoint (v0.1.15+) Restores file state to what it was at the given user message Requires enable_file_checkpointing to be true in options.
-
#set_model(model) ⇒ Object
Change the AI model.
-
#set_permission_mode(mode) ⇒ Object
Change permission mode.
-
#start ⇒ Object
Start reading messages from transport.
-
#stream_input(stream) ⇒ Object
Stream input messages to transport.
Constructor Details
#initialize(transport:, is_streaming_mode:, can_use_tool: nil, hooks: nil, sdk_mcp_servers: nil) ⇒ Query
Returns a new instance of Query.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/claude_agent_sdk/query.rb', line 22 def initialize(transport:, is_streaming_mode:, can_use_tool: nil, hooks: nil, sdk_mcp_servers: nil) @transport = transport @is_streaming_mode = is_streaming_mode @can_use_tool = can_use_tool @hooks = hooks || {} @sdk_mcp_servers = sdk_mcp_servers || {} # Control protocol state @pending_control_responses = {} @pending_control_results = {} @hook_callbacks = {} @hook_callback_timeouts = {} @next_callback_id = 0 @request_counter = 0 @inflight_control_request_tasks = {} # Message stream @message_queue = Async::Queue.new @task = nil @initialized = false @closed = false @initialization_result = nil end |
Instance Attribute Details
#is_streaming_mode ⇒ Object (readonly)
Returns the value of attribute is_streaming_mode.
20 21 22 |
# File 'lib/claude_agent_sdk/query.rb', line 20 def is_streaming_mode @is_streaming_mode end |
#sdk_mcp_servers ⇒ Object (readonly)
Returns the value of attribute sdk_mcp_servers.
20 21 22 |
# File 'lib/claude_agent_sdk/query.rb', line 20 def sdk_mcp_servers @sdk_mcp_servers end |
#transport ⇒ Object (readonly)
Returns the value of attribute transport.
20 21 22 |
# File 'lib/claude_agent_sdk/query.rb', line 20 def transport @transport end |
Instance Method Details
#close ⇒ Object
Close the query and transport
659 660 661 662 663 |
# File 'lib/claude_agent_sdk/query.rb', line 659 def close @closed = true @task&.stop @transport.close end |
#get_mcp_status ⇒ Hash
Get current MCP server connection status (only works with streaming mode)
597 598 599 |
# File 'lib/claude_agent_sdk/query.rb', line 597 def get_mcp_status send_control_request({ subtype: 'mcp_status' }) end |
#initialize_protocol ⇒ Hash?
Initialize control protocol if in streaming mode
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/claude_agent_sdk/query.rb', line 48 def initialize_protocol return nil unless @is_streaming_mode # Build hooks configuration for initialization hooks_config = {} if @hooks && !@hooks.empty? @hooks.each do |event, matchers| next if matchers.nil? || matchers.empty? hooks_config[event] = [] matchers.each do |matcher| callback_ids = [] (matcher[:hooks] || []).each do |callback| callback_id = "hook_#{@next_callback_id}" @next_callback_id += 1 @hook_callbacks[callback_id] = callback @hook_callback_timeouts[callback_id] = matcher[:timeout] if matcher[:timeout] callback_ids << callback_id end hooks_config[event] << { matcher: matcher[:matcher], hookCallbackIds: callback_ids } end end end # Send initialize request request = { subtype: 'initialize', hooks: hooks_config.empty? ? nil : hooks_config } response = send_control_request(request) @initialized = true @initialization_result = response response end |
#interrupt ⇒ Object
Send interrupt control request
602 603 604 |
# File 'lib/claude_agent_sdk/query.rb', line 602 def interrupt send_control_request({ subtype: 'interrupt' }) end |
#receive_messages(&block) ⇒ Object
Receive SDK messages (not control messages)
646 647 648 649 650 651 652 653 654 655 656 |
# File 'lib/claude_agent_sdk/query.rb', line 646 def (&block) return enum_for(:receive_messages) unless block loop do = @message_queue.dequeue break if [:type] == 'end' raise [:error] if [:type] == 'error' block.call() end end |
#rewind_files(user_message_uuid) ⇒ Object
Rewind files to a previous checkpoint (v0.1.15+) Restores file state to what it was at the given user message Requires enable_file_checkpointing to be true in options
626 627 628 629 630 631 |
# File 'lib/claude_agent_sdk/query.rb', line 626 def rewind_files() send_control_request({ subtype: 'rewind_files', userMessageUuid: }) end |
#set_model(model) ⇒ Object
Change the AI model
615 616 617 618 619 620 |
# File 'lib/claude_agent_sdk/query.rb', line 615 def set_model(model) send_control_request({ subtype: 'set_model', model: model }) end |
#set_permission_mode(mode) ⇒ Object
Change permission mode
607 608 609 610 611 612 |
# File 'lib/claude_agent_sdk/query.rb', line 607 def (mode) send_control_request({ subtype: 'set_permission_mode', mode: mode }) end |
#start ⇒ Object
Start reading messages from transport
88 89 90 91 92 93 94 |
# File 'lib/claude_agent_sdk/query.rb', line 88 def start return if @task @task = Async do |task| task.async { } end end |
#stream_input(stream) ⇒ Object
Stream input messages to transport
634 635 636 637 638 639 640 641 642 643 |
# File 'lib/claude_agent_sdk/query.rb', line 634 def stream_input(stream) stream.each do || break if @closed @transport.write(JSON.generate() + "\n") end @transport.end_input rescue StandardError => e # Log error but don't raise warn "Error streaming input: #{e.}" end |