claude_agent 0.7.12 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/rules/testing.md +51 -10
- data/.claude/settings.json +1 -0
- data/ARCHITECTURE.md +237 -0
- data/CHANGELOG.md +45 -0
- data/CLAUDE.md +2 -0
- data/README.md +46 -1
- data/Rakefile +17 -0
- data/SPEC.md +214 -125
- data/lib/claude_agent/client/commands.rb +225 -0
- data/lib/claude_agent/client.rb +4 -204
- data/lib/claude_agent/content_blocks/generic_block.rb +39 -0
- data/lib/claude_agent/content_blocks/image_content_block.rb +54 -0
- data/lib/claude_agent/content_blocks/server_tool_result_block.rb +22 -0
- data/lib/claude_agent/content_blocks/server_tool_use_block.rb +48 -0
- data/lib/claude_agent/content_blocks/text_block.rb +19 -0
- data/lib/claude_agent/content_blocks/thinking_block.rb +19 -0
- data/lib/claude_agent/content_blocks/tool_result_block.rb +25 -0
- data/lib/claude_agent/content_blocks/tool_use_block.rb +134 -0
- data/lib/claude_agent/content_blocks.rb +8 -335
- data/lib/claude_agent/control_protocol/commands.rb +304 -0
- data/lib/claude_agent/control_protocol/lifecycle.rb +113 -0
- data/lib/claude_agent/control_protocol/messaging.rb +166 -0
- data/lib/claude_agent/control_protocol/primitives.rb +168 -0
- data/lib/claude_agent/control_protocol/request_handling.rb +231 -0
- data/lib/claude_agent/control_protocol.rb +27 -882
- data/lib/claude_agent/event_handler.rb +1 -0
- data/lib/claude_agent/get_session_info.rb +86 -0
- data/lib/claude_agent/hooks.rb +23 -2
- data/lib/claude_agent/list_sessions.rb +22 -13
- data/lib/claude_agent/message_parser.rb +26 -4
- data/lib/claude_agent/messages/conversation.rb +138 -0
- data/lib/claude_agent/messages/generic.rb +39 -0
- data/lib/claude_agent/messages/hook_lifecycle.rb +158 -0
- data/lib/claude_agent/messages/result.rb +80 -0
- data/lib/claude_agent/messages/streaming.rb +84 -0
- data/lib/claude_agent/messages/system.rb +67 -0
- data/lib/claude_agent/messages/task_lifecycle.rb +240 -0
- data/lib/claude_agent/messages/tool_lifecycle.rb +95 -0
- data/lib/claude_agent/messages.rb +11 -829
- data/lib/claude_agent/options/serializer.rb +194 -0
- data/lib/claude_agent/options.rb +11 -176
- data/lib/claude_agent/sandbox_settings.rb +3 -0
- data/lib/claude_agent/session.rb +0 -204
- data/lib/claude_agent/session_mutations.rb +148 -0
- data/lib/claude_agent/types/mcp.rb +30 -0
- data/lib/claude_agent/types/models.rb +146 -0
- data/lib/claude_agent/types/operations.rb +38 -0
- data/lib/claude_agent/types/sessions.rb +50 -0
- data/lib/claude_agent/types/tools.rb +32 -0
- data/lib/claude_agent/types.rb +6 -264
- data/lib/claude_agent/v2_session.rb +207 -0
- data/lib/claude_agent/version.rb +1 -1
- data/lib/claude_agent.rb +37 -3
- data/sig/claude_agent.rbs +144 -13
- metadata +33 -1
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
class Client
|
|
5
|
+
# CLI command delegations to the ControlProtocol.
|
|
6
|
+
#
|
|
7
|
+
# These methods provide the Client-level interface to control commands:
|
|
8
|
+
# permission/model changes, MCP management, task control, and query methods.
|
|
9
|
+
# Each enforces connection state before delegating to the protocol.
|
|
10
|
+
module Commands
|
|
11
|
+
# Change the permission mode
|
|
12
|
+
#
|
|
13
|
+
# @param mode [String] New permission mode
|
|
14
|
+
# @return [Hash] Response
|
|
15
|
+
def set_permission_mode(mode)
|
|
16
|
+
require_connection!
|
|
17
|
+
|
|
18
|
+
@protocol.set_permission_mode(mode)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Change the model
|
|
22
|
+
#
|
|
23
|
+
# @param model [String, nil] New model name (nil to use default)
|
|
24
|
+
# @return [Hash] Response
|
|
25
|
+
def set_model(model)
|
|
26
|
+
require_connection!
|
|
27
|
+
|
|
28
|
+
@protocol.set_model(model)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Rewind files to the state at a specific user message
|
|
32
|
+
#
|
|
33
|
+
# @param user_message_id [String] UUID of the user message to rewind to
|
|
34
|
+
# @param dry_run [Boolean] If true, preview changes without modifying files
|
|
35
|
+
# @return [RewindFilesResult] Result with rewind information
|
|
36
|
+
def rewind_files(user_message_id, dry_run: false)
|
|
37
|
+
require_connection!
|
|
38
|
+
|
|
39
|
+
@protocol.rewind_files(user_message_id, dry_run: dry_run)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Set maximum thinking tokens (TypeScript SDK parity)
|
|
43
|
+
#
|
|
44
|
+
# @param tokens [Integer, nil] Max thinking tokens (nil to reset)
|
|
45
|
+
# @return [Hash] Response
|
|
46
|
+
def set_max_thinking_tokens(tokens)
|
|
47
|
+
require_connection!
|
|
48
|
+
|
|
49
|
+
@protocol.set_max_thinking_tokens(tokens)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Get available slash commands (TypeScript SDK parity)
|
|
53
|
+
#
|
|
54
|
+
# @return [Array<SlashCommand>]
|
|
55
|
+
def supported_commands
|
|
56
|
+
require_connection!
|
|
57
|
+
|
|
58
|
+
@protocol.supported_commands
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Get available models (TypeScript SDK parity)
|
|
62
|
+
#
|
|
63
|
+
# @return [Array<ModelInfo>]
|
|
64
|
+
def supported_models
|
|
65
|
+
require_connection!
|
|
66
|
+
|
|
67
|
+
@protocol.supported_models
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get available agents (TypeScript SDK v0.2.63 parity)
|
|
71
|
+
#
|
|
72
|
+
# @return [Array<AgentInfo>]
|
|
73
|
+
def supported_agents
|
|
74
|
+
require_connection!
|
|
75
|
+
|
|
76
|
+
@protocol.supported_agents
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Get MCP server status (TypeScript SDK parity)
|
|
80
|
+
#
|
|
81
|
+
# @return [Array<McpServerStatus>]
|
|
82
|
+
def mcp_server_status
|
|
83
|
+
require_connection!
|
|
84
|
+
|
|
85
|
+
@protocol.mcp_server_status
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Get account information (TypeScript SDK parity)
|
|
89
|
+
#
|
|
90
|
+
# @return [AccountInfo]
|
|
91
|
+
def account_info
|
|
92
|
+
require_connection!
|
|
93
|
+
|
|
94
|
+
@protocol.account_info
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Get full initialization result (TypeScript SDK parity)
|
|
98
|
+
#
|
|
99
|
+
# @return [InitializationResult]
|
|
100
|
+
def initialization_result
|
|
101
|
+
require_connection!
|
|
102
|
+
|
|
103
|
+
@protocol.initialization_result
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Stop a running background task (TypeScript SDK parity)
|
|
107
|
+
#
|
|
108
|
+
# Sends a stop signal to a running task. A task_notification message
|
|
109
|
+
# with status 'stopped' will be emitted when the task stops.
|
|
110
|
+
#
|
|
111
|
+
# @param task_id [String] The task ID from task_notification events
|
|
112
|
+
# @return [void]
|
|
113
|
+
#
|
|
114
|
+
# @example
|
|
115
|
+
# client.stop_task("task-123")
|
|
116
|
+
#
|
|
117
|
+
def stop_task(task_id)
|
|
118
|
+
require_connection!
|
|
119
|
+
|
|
120
|
+
@protocol.stop_task(task_id)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Apply flag settings (TypeScript SDK v0.2.50 parity)
|
|
124
|
+
#
|
|
125
|
+
# Merges the provided settings into the flag settings layer.
|
|
126
|
+
#
|
|
127
|
+
# @param settings [Hash] Settings to merge into the flag layer
|
|
128
|
+
# @return [Hash] Response from the CLI
|
|
129
|
+
#
|
|
130
|
+
# @example
|
|
131
|
+
# client.apply_flag_settings({ "model" => "claude-sonnet-4-5-20250514" })
|
|
132
|
+
#
|
|
133
|
+
def apply_flag_settings(settings)
|
|
134
|
+
require_connection!
|
|
135
|
+
|
|
136
|
+
@protocol.apply_flag_settings(settings)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Dynamically set MCP servers for this session (TypeScript SDK parity)
|
|
140
|
+
#
|
|
141
|
+
# This replaces the current set of dynamically-added MCP servers.
|
|
142
|
+
# Servers that are removed will be disconnected, and new servers will be connected.
|
|
143
|
+
#
|
|
144
|
+
# @param servers [Hash] Map of server name to configuration
|
|
145
|
+
# @return [McpSetServersResult] Result with added, removed, and errors
|
|
146
|
+
#
|
|
147
|
+
# @example
|
|
148
|
+
# result = client.set_mcp_servers({
|
|
149
|
+
# "my-server" => { type: "stdio", command: "node", args: ["server.js"] }
|
|
150
|
+
# })
|
|
151
|
+
# puts "Added: #{result.added}"
|
|
152
|
+
# puts "Removed: #{result.removed}"
|
|
153
|
+
#
|
|
154
|
+
def set_mcp_servers(servers)
|
|
155
|
+
require_connection!
|
|
156
|
+
|
|
157
|
+
@protocol.set_mcp_servers(servers)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Reconnect to an MCP server (TypeScript SDK parity)
|
|
161
|
+
#
|
|
162
|
+
# Attempts to reconnect to a disconnected or errored MCP server.
|
|
163
|
+
#
|
|
164
|
+
# @param server_name [String] Name of the MCP server to reconnect
|
|
165
|
+
# @return [Hash] Response from the CLI
|
|
166
|
+
#
|
|
167
|
+
# @example
|
|
168
|
+
# client.mcp_reconnect("my-server")
|
|
169
|
+
#
|
|
170
|
+
def mcp_reconnect(server_name)
|
|
171
|
+
require_connection!
|
|
172
|
+
|
|
173
|
+
@protocol.mcp_reconnect(server_name)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Enable or disable an MCP server (TypeScript SDK parity)
|
|
177
|
+
#
|
|
178
|
+
# Toggles an MCP server on or off without removing its configuration.
|
|
179
|
+
#
|
|
180
|
+
# @param server_name [String] Name of the MCP server to toggle
|
|
181
|
+
# @param enabled [Boolean] Whether to enable (true) or disable (false) the server
|
|
182
|
+
# @return [Hash] Response from the CLI
|
|
183
|
+
#
|
|
184
|
+
# @example Enable a server
|
|
185
|
+
# client.mcp_toggle("my-server", enabled: true)
|
|
186
|
+
#
|
|
187
|
+
# @example Disable a server
|
|
188
|
+
# client.mcp_toggle("my-server", enabled: false)
|
|
189
|
+
#
|
|
190
|
+
def mcp_toggle(server_name, enabled:)
|
|
191
|
+
require_connection!
|
|
192
|
+
|
|
193
|
+
@protocol.mcp_toggle(server_name, enabled: enabled)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Initiate OAuth authentication for an MCP server (TypeScript SDK v0.2.52 parity)
|
|
197
|
+
#
|
|
198
|
+
# @param server_name [String] Name of the MCP server to authenticate
|
|
199
|
+
# @return [Hash] Response from the CLI
|
|
200
|
+
#
|
|
201
|
+
# @example
|
|
202
|
+
# client.mcp_authenticate("my-remote-server")
|
|
203
|
+
#
|
|
204
|
+
def mcp_authenticate(server_name)
|
|
205
|
+
require_connection!
|
|
206
|
+
|
|
207
|
+
@protocol.mcp_authenticate(server_name)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Clear stored auth credentials for an MCP server (TypeScript SDK v0.2.52 parity)
|
|
211
|
+
#
|
|
212
|
+
# @param server_name [String] Name of the MCP server to clear auth for
|
|
213
|
+
# @return [Hash] Response from the CLI
|
|
214
|
+
#
|
|
215
|
+
# @example
|
|
216
|
+
# client.mcp_clear_auth("my-remote-server")
|
|
217
|
+
#
|
|
218
|
+
def mcp_clear_auth(server_name)
|
|
219
|
+
require_connection!
|
|
220
|
+
|
|
221
|
+
@protocol.mcp_clear_auth(server_name)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
data/lib/claude_agent/client.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "client/commands"
|
|
4
|
+
|
|
3
5
|
module ClaudeAgent
|
|
4
6
|
# Interactive, bidirectional client for Claude Code CLI
|
|
5
7
|
#
|
|
@@ -32,6 +34,8 @@ module ClaudeAgent
|
|
|
32
34
|
# end
|
|
33
35
|
#
|
|
34
36
|
class Client
|
|
37
|
+
include Commands
|
|
38
|
+
|
|
35
39
|
attr_reader :options, :transport, :server_info, :cumulative_usage, :event_handler, :permission_queue
|
|
36
40
|
|
|
37
41
|
# Open a client with automatic cleanup
|
|
@@ -295,210 +299,6 @@ module ClaudeAgent
|
|
|
295
299
|
@protocol&.abort!
|
|
296
300
|
end
|
|
297
301
|
|
|
298
|
-
# Change the permission mode
|
|
299
|
-
#
|
|
300
|
-
# @param mode [String] New permission mode
|
|
301
|
-
# @return [Hash] Response
|
|
302
|
-
def set_permission_mode(mode)
|
|
303
|
-
require_connection!
|
|
304
|
-
|
|
305
|
-
@protocol.set_permission_mode(mode)
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
# Change the model
|
|
309
|
-
#
|
|
310
|
-
# @param model [String, nil] New model name (nil to use default)
|
|
311
|
-
# @return [Hash] Response
|
|
312
|
-
def set_model(model)
|
|
313
|
-
require_connection!
|
|
314
|
-
|
|
315
|
-
@protocol.set_model(model)
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# Rewind files to the state at a specific user message
|
|
319
|
-
#
|
|
320
|
-
# @param user_message_id [String] UUID of the user message to rewind to
|
|
321
|
-
# @param dry_run [Boolean] If true, preview changes without modifying files
|
|
322
|
-
# @return [RewindFilesResult] Result with rewind information
|
|
323
|
-
def rewind_files(user_message_id, dry_run: false)
|
|
324
|
-
require_connection!
|
|
325
|
-
|
|
326
|
-
@protocol.rewind_files(user_message_id, dry_run: dry_run)
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
# Set maximum thinking tokens (TypeScript SDK parity)
|
|
330
|
-
#
|
|
331
|
-
# @param tokens [Integer, nil] Max thinking tokens (nil to reset)
|
|
332
|
-
# @return [Hash] Response
|
|
333
|
-
def set_max_thinking_tokens(tokens)
|
|
334
|
-
require_connection!
|
|
335
|
-
|
|
336
|
-
@protocol.set_max_thinking_tokens(tokens)
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
# Get available slash commands (TypeScript SDK parity)
|
|
340
|
-
#
|
|
341
|
-
# @return [Array<SlashCommand>]
|
|
342
|
-
def supported_commands
|
|
343
|
-
require_connection!
|
|
344
|
-
|
|
345
|
-
@protocol.supported_commands
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
# Get available models (TypeScript SDK parity)
|
|
349
|
-
#
|
|
350
|
-
# @return [Array<ModelInfo>]
|
|
351
|
-
def supported_models
|
|
352
|
-
require_connection!
|
|
353
|
-
|
|
354
|
-
@protocol.supported_models
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
# Get MCP server status (TypeScript SDK parity)
|
|
358
|
-
#
|
|
359
|
-
# @return [Array<McpServerStatus>]
|
|
360
|
-
def mcp_server_status
|
|
361
|
-
require_connection!
|
|
362
|
-
|
|
363
|
-
@protocol.mcp_server_status
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
# Get account information (TypeScript SDK parity)
|
|
367
|
-
#
|
|
368
|
-
# @return [AccountInfo]
|
|
369
|
-
def account_info
|
|
370
|
-
require_connection!
|
|
371
|
-
|
|
372
|
-
@protocol.account_info
|
|
373
|
-
end
|
|
374
|
-
|
|
375
|
-
# Get full initialization result (TypeScript SDK parity)
|
|
376
|
-
#
|
|
377
|
-
# @return [InitializationResult]
|
|
378
|
-
def initialization_result
|
|
379
|
-
require_connection!
|
|
380
|
-
|
|
381
|
-
@protocol.initialization_result
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
# Stop a running background task (TypeScript SDK parity)
|
|
385
|
-
#
|
|
386
|
-
# Sends a stop signal to a running task. A task_notification message
|
|
387
|
-
# with status 'stopped' will be emitted when the task stops.
|
|
388
|
-
#
|
|
389
|
-
# @param task_id [String] The task ID from task_notification events
|
|
390
|
-
# @return [void]
|
|
391
|
-
#
|
|
392
|
-
# @example
|
|
393
|
-
# client.stop_task("task-123")
|
|
394
|
-
#
|
|
395
|
-
def stop_task(task_id)
|
|
396
|
-
require_connection!
|
|
397
|
-
|
|
398
|
-
@protocol.stop_task(task_id)
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
# Apply flag settings (TypeScript SDK v0.2.50 parity)
|
|
402
|
-
#
|
|
403
|
-
# Merges the provided settings into the flag settings layer.
|
|
404
|
-
#
|
|
405
|
-
# @param settings [Hash] Settings to merge into the flag layer
|
|
406
|
-
# @return [Hash] Response from the CLI
|
|
407
|
-
#
|
|
408
|
-
# @example
|
|
409
|
-
# client.apply_flag_settings({ "model" => "claude-sonnet-4-5-20250514" })
|
|
410
|
-
#
|
|
411
|
-
def apply_flag_settings(settings)
|
|
412
|
-
require_connection!
|
|
413
|
-
|
|
414
|
-
@protocol.apply_flag_settings(settings)
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
# Dynamically set MCP servers for this session (TypeScript SDK parity)
|
|
418
|
-
#
|
|
419
|
-
# This replaces the current set of dynamically-added MCP servers.
|
|
420
|
-
# Servers that are removed will be disconnected, and new servers will be connected.
|
|
421
|
-
#
|
|
422
|
-
# @param servers [Hash] Map of server name to configuration
|
|
423
|
-
# @return [McpSetServersResult] Result with added, removed, and errors
|
|
424
|
-
#
|
|
425
|
-
# @example
|
|
426
|
-
# result = client.set_mcp_servers({
|
|
427
|
-
# "my-server" => { type: "stdio", command: "node", args: ["server.js"] }
|
|
428
|
-
# })
|
|
429
|
-
# puts "Added: #{result.added}"
|
|
430
|
-
# puts "Removed: #{result.removed}"
|
|
431
|
-
#
|
|
432
|
-
def set_mcp_servers(servers)
|
|
433
|
-
require_connection!
|
|
434
|
-
|
|
435
|
-
@protocol.set_mcp_servers(servers)
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
# Reconnect to an MCP server (TypeScript SDK parity)
|
|
439
|
-
#
|
|
440
|
-
# Attempts to reconnect to a disconnected or errored MCP server.
|
|
441
|
-
#
|
|
442
|
-
# @param server_name [String] Name of the MCP server to reconnect
|
|
443
|
-
# @return [Hash] Response from the CLI
|
|
444
|
-
#
|
|
445
|
-
# @example
|
|
446
|
-
# client.mcp_reconnect("my-server")
|
|
447
|
-
#
|
|
448
|
-
def mcp_reconnect(server_name)
|
|
449
|
-
require_connection!
|
|
450
|
-
|
|
451
|
-
@protocol.mcp_reconnect(server_name)
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
# Enable or disable an MCP server (TypeScript SDK parity)
|
|
455
|
-
#
|
|
456
|
-
# Toggles an MCP server on or off without removing its configuration.
|
|
457
|
-
#
|
|
458
|
-
# @param server_name [String] Name of the MCP server to toggle
|
|
459
|
-
# @param enabled [Boolean] Whether to enable (true) or disable (false) the server
|
|
460
|
-
# @return [Hash] Response from the CLI
|
|
461
|
-
#
|
|
462
|
-
# @example Enable a server
|
|
463
|
-
# client.mcp_toggle("my-server", enabled: true)
|
|
464
|
-
#
|
|
465
|
-
# @example Disable a server
|
|
466
|
-
# client.mcp_toggle("my-server", enabled: false)
|
|
467
|
-
#
|
|
468
|
-
def mcp_toggle(server_name, enabled:)
|
|
469
|
-
require_connection!
|
|
470
|
-
|
|
471
|
-
@protocol.mcp_toggle(server_name, enabled: enabled)
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
# Initiate OAuth authentication for an MCP server (TypeScript SDK v0.2.52 parity)
|
|
475
|
-
#
|
|
476
|
-
# @param server_name [String] Name of the MCP server to authenticate
|
|
477
|
-
# @return [Hash] Response from the CLI
|
|
478
|
-
#
|
|
479
|
-
# @example
|
|
480
|
-
# client.mcp_authenticate("my-remote-server")
|
|
481
|
-
#
|
|
482
|
-
def mcp_authenticate(server_name)
|
|
483
|
-
require_connection!
|
|
484
|
-
|
|
485
|
-
@protocol.mcp_authenticate(server_name)
|
|
486
|
-
end
|
|
487
|
-
|
|
488
|
-
# Clear stored auth credentials for an MCP server (TypeScript SDK v0.2.52 parity)
|
|
489
|
-
#
|
|
490
|
-
# @param server_name [String] Name of the MCP server to clear auth for
|
|
491
|
-
# @return [Hash] Response from the CLI
|
|
492
|
-
#
|
|
493
|
-
# @example
|
|
494
|
-
# client.mcp_clear_auth("my-remote-server")
|
|
495
|
-
#
|
|
496
|
-
def mcp_clear_auth(server_name)
|
|
497
|
-
require_connection!
|
|
498
|
-
|
|
499
|
-
@protocol.mcp_clear_auth(server_name)
|
|
500
|
-
end
|
|
501
|
-
|
|
502
302
|
# Non-blocking poll for the next pending permission request.
|
|
503
303
|
#
|
|
504
304
|
# Returns the next {PermissionRequest} from the queue, or nil if
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
# Generic content block for unknown/future block types
|
|
5
|
+
#
|
|
6
|
+
# Wraps unrecognized content block types so they can be inspected
|
|
7
|
+
# without losing type information. Supports dynamic field access via
|
|
8
|
+
# `[]` and `method_missing`.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# block = GenericBlock.new(block_type: "citation", raw: { text: "ref", url: "https://example.com" })
|
|
12
|
+
# block.type # => :citation
|
|
13
|
+
# block[:text] # => "ref"
|
|
14
|
+
# block.url # => "https://example.com"
|
|
15
|
+
# block.to_h # => { text: "ref", url: "https://example.com" }
|
|
16
|
+
#
|
|
17
|
+
GenericBlock = Data.define(:block_type, :raw) do
|
|
18
|
+
def type
|
|
19
|
+
block_type&.to_sym || :unknown
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_h
|
|
23
|
+
raw
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def [](key)
|
|
27
|
+
raw[key]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def respond_to_missing?(name, include_private = false)
|
|
31
|
+
raw.key?(name) || super
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def method_missing(name, *args)
|
|
35
|
+
return raw[name] if args.empty? && raw.key?(name)
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
# Image content block (TypeScript SDK parity)
|
|
5
|
+
#
|
|
6
|
+
# Supports both base64-encoded image data and URL sources.
|
|
7
|
+
#
|
|
8
|
+
# @example Base64 image
|
|
9
|
+
# block = ImageContentBlock.new(
|
|
10
|
+
# source: { type: "base64", media_type: "image/png", data: "..." }
|
|
11
|
+
# )
|
|
12
|
+
# block.source_type # => "base64"
|
|
13
|
+
# block.media_type # => "image/png"
|
|
14
|
+
#
|
|
15
|
+
# @example URL image
|
|
16
|
+
# block = ImageContentBlock.new(
|
|
17
|
+
# source: { type: "url", url: "https://example.com/image.png" }
|
|
18
|
+
# )
|
|
19
|
+
# block.url # => "https://example.com/image.png"
|
|
20
|
+
#
|
|
21
|
+
ImageContentBlock = Data.define(:source) do
|
|
22
|
+
def type
|
|
23
|
+
:image
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Get the media type if available
|
|
27
|
+
# @return [String, nil]
|
|
28
|
+
def media_type
|
|
29
|
+
source.is_a?(Hash) ? source[:media_type] : nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Get the base64 data if available
|
|
33
|
+
# @return [String, nil]
|
|
34
|
+
def data
|
|
35
|
+
source.is_a?(Hash) ? source[:data] : nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Get the URL if this is a URL-sourced image
|
|
39
|
+
# @return [String, nil]
|
|
40
|
+
def url
|
|
41
|
+
source.is_a?(Hash) ? source[:url] : nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Get the source type (base64 or url)
|
|
45
|
+
# @return [String, nil]
|
|
46
|
+
def source_type
|
|
47
|
+
source.is_a?(Hash) ? source[:type] : nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def to_h
|
|
51
|
+
{ type: "image", source: source }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
# Server tool result block
|
|
5
|
+
#
|
|
6
|
+
ServerToolResultBlock = Data.define(:tool_use_id, :content, :is_error, :server_name) do
|
|
7
|
+
def initialize(tool_use_id:, server_name:, content: nil, is_error: nil)
|
|
8
|
+
super
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def type
|
|
12
|
+
:server_tool_result
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_h
|
|
16
|
+
h = { type: "server_tool_result", tool_use_id: tool_use_id, server_name: server_name }
|
|
17
|
+
h[:content] = content unless content.nil?
|
|
18
|
+
h[:is_error] = is_error unless is_error.nil?
|
|
19
|
+
h
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
# Server tool use block (for MCP servers)
|
|
5
|
+
#
|
|
6
|
+
ServerToolUseBlock = Data.define(:id, :name, :input, :server_name) do
|
|
7
|
+
def type
|
|
8
|
+
:server_tool_use
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_h
|
|
12
|
+
{ type: "server_tool_use", id: id, name: name, input: input, server_name: server_name }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Returns the file path for file-based tools, nil otherwise.
|
|
16
|
+
# @return [String, nil]
|
|
17
|
+
def file_path
|
|
18
|
+
case name
|
|
19
|
+
when "Read", "Write", "Edit"
|
|
20
|
+
input[:file_path]
|
|
21
|
+
when "NotebookEdit"
|
|
22
|
+
input[:notebook_path]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# One-line human-readable label with server context.
|
|
27
|
+
# @return [String]
|
|
28
|
+
def display_label
|
|
29
|
+
server_name ? "#{server_name}/#{name}" : name
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Detailed summary with server context, truncated to max chars.
|
|
33
|
+
# @param max [Integer] maximum length before truncation
|
|
34
|
+
# @return [String]
|
|
35
|
+
def summary(max: 60)
|
|
36
|
+
label = display_label
|
|
37
|
+
text = "#{label}: #{input.inspect}"
|
|
38
|
+
truncate(text, max)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def truncate(str, max)
|
|
44
|
+
return str if str.length <= max
|
|
45
|
+
"#{str[0, max]}..."
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
# Text content block
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# block = TextBlock.new(text: "Hello, world!")
|
|
8
|
+
# block.text # => "Hello, world!"
|
|
9
|
+
#
|
|
10
|
+
TextBlock = Data.define(:text) do
|
|
11
|
+
def type
|
|
12
|
+
:text
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_h
|
|
16
|
+
{ type: "text", text: text }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
# Extended thinking content block
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# block = ThinkingBlock.new(thinking: "Let me consider...", signature: "abc123")
|
|
8
|
+
# block.thinking # => "Let me consider..."
|
|
9
|
+
#
|
|
10
|
+
ThinkingBlock = Data.define(:thinking, :signature) do
|
|
11
|
+
def type
|
|
12
|
+
:thinking
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_h
|
|
16
|
+
{ type: "thinking", thinking: thinking, signature: signature }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClaudeAgent
|
|
4
|
+
# Tool result block
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# block = ToolResultBlock.new(tool_use_id: "tool_123", content: "file contents", is_error: false)
|
|
8
|
+
#
|
|
9
|
+
ToolResultBlock = Data.define(:tool_use_id, :content, :is_error) do
|
|
10
|
+
def initialize(tool_use_id:, content: nil, is_error: nil)
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def type
|
|
15
|
+
:tool_result
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_h
|
|
19
|
+
h = { type: "tool_result", tool_use_id: tool_use_id }
|
|
20
|
+
h[:content] = content unless content.nil?
|
|
21
|
+
h[:is_error] = is_error unless is_error.nil?
|
|
22
|
+
h
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|