claude-agent-sdk 1.1.0 → 1.2.1
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/.yardopts +10 -0
- data/CHANGELOG.md +99 -0
- data/README.md +43 -31
- data/docs/cli-installer.md +26 -4
- data/docs/client.md +29 -11
- data/docs/configuration.md +164 -1
- data/docs/errors.md +32 -2
- data/docs/hooks-and-permissions.md +30 -10
- data/docs/mcp-servers.md +30 -9
- data/docs/observability.md +61 -10
- data/docs/options.md +232 -0
- data/docs/rails.md +263 -18
- data/docs/sessions.md +40 -12
- data/docs/subagents.md +1 -1
- data/docs/types.md +100 -11
- data/lib/claude_agent_sdk/cli_installer.rb +140 -19
- data/lib/claude_agent_sdk/command_builder.rb +83 -108
- data/lib/claude_agent_sdk/fiber_boundary.rb +45 -2
- data/lib/claude_agent_sdk/instrumentation/otel.rb +90 -28
- data/lib/claude_agent_sdk/option_forms.rb +379 -0
- data/lib/claude_agent_sdk/query/run_lifecycle.rb +373 -0
- data/lib/claude_agent_sdk/query.rb +266 -364
- data/lib/claude_agent_sdk/railtie.rb +27 -2
- data/lib/claude_agent_sdk/sdk_mcp_server.rb +78 -26
- data/lib/claude_agent_sdk/session_assembly.rb +311 -0
- data/lib/claude_agent_sdk/session_mutations.rb +112 -92
- data/lib/claude_agent_sdk/session_resume.rb +360 -43
- data/lib/claude_agent_sdk/session_store.rb +31 -2
- data/lib/claude_agent_sdk/sessions.rb +720 -138
- data/lib/claude_agent_sdk/subprocess_cli_transport.rb +228 -29
- data/lib/claude_agent_sdk/testing/session_store_conformance.rb +18 -7
- data/lib/claude_agent_sdk/transcript_mirror_batcher.rb +45 -37
- data/lib/claude_agent_sdk/transport.rb +28 -12
- data/lib/claude_agent_sdk/types/attributes.rb +9 -0
- data/lib/claude_agent_sdk/types/base.rb +85 -15
- data/lib/claude_agent_sdk/types/hooks.rb +73 -0
- data/lib/claude_agent_sdk/types/mcp.rb +37 -1
- data/lib/claude_agent_sdk/types/option_values.rb +186 -4
- data/lib/claude_agent_sdk/types/options.rb +35 -5
- data/lib/claude_agent_sdk/types/permissions.rb +18 -9
- data/lib/claude_agent_sdk/version.rb +1 -1
- data/lib/claude_agent_sdk.rb +223 -418
- data/lib/generators/claude_agent_sdk/install/templates/claude_agent_sdk.rb.tt +6 -0
- data/sig/claude_agent_sdk/types/hooks.rbs +6 -3
- data/sig/claude_agent_sdk/types/option_values.rbs +23 -6
- data/sig/claude_agent_sdk/types/options.rbs +11 -7
- data/sig/claude_agent_sdk/types/permissions.rbs +4 -2
- metadata +9 -4
|
@@ -18,8 +18,10 @@ module ClaudeAgentSDK
|
|
|
18
18
|
|
|
19
19
|
# Claude Agent Options for configuring queries
|
|
20
20
|
class ClaudeAgentOptions < Type
|
|
21
|
-
# `env` routinely carries credentials (ANTHROPIC_API_KEY, ...).
|
|
22
|
-
|
|
21
|
+
# `env` routinely carries credentials (ANTHROPIC_API_KEY, ...). So does
|
|
22
|
+
# `settings` (its own `env`, `apiKeyHelper`), as a Hash or a JSON String,
|
|
23
|
+
# and an `extra_args` value can be one.
|
|
24
|
+
inspect_filtered :env, :settings, :extra_args
|
|
23
25
|
|
|
24
26
|
attr_accessor :allowed_tools, :system_prompt, :mcp_servers, :permission_mode,
|
|
25
27
|
:resume, :resume_session_at, :session_id, :max_turns, :disallowed_tools,
|
|
@@ -345,16 +347,44 @@ module ClaudeAgentSDK
|
|
|
345
347
|
self.callback_scheduling = :thread if callback_scheduling.nil?
|
|
346
348
|
end
|
|
347
349
|
|
|
350
|
+
# `mcp_servers` holds typed configs, which filter themselves, next to raw
|
|
351
|
+
# Hash configs carrying the same credentials: those are rendered by
|
|
352
|
+
# Type#inspect_mcp_server_config. Anything but a Hash (the JSON of a
|
|
353
|
+
# config as a String, or the path to one) is replaced outright, like a
|
|
354
|
+
# String `settings`.
|
|
355
|
+
def inspect_attributes
|
|
356
|
+
super.map { |name, value| [name, name == 'mcp_servers' ? inspect_mcp_servers(value) : value] }
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
def inspect_mcp_servers(servers)
|
|
360
|
+
return '[FILTERED]' unless servers.is_a?(Hash)
|
|
361
|
+
|
|
362
|
+
servers.to_h { |name, config| [name, config.is_a?(Hash) ? inspect_mcp_server_config(config) : config] }
|
|
363
|
+
rescue StandardError
|
|
364
|
+
'[FILTERED]'
|
|
365
|
+
end
|
|
366
|
+
|
|
348
367
|
# Strict key validation: unlike other Type subclasses (which silently drop
|
|
349
368
|
# unknown keys for forward-compat with newer CLI output), ClaudeAgentOptions
|
|
350
369
|
# is a developer-facing config object — typos should fail loudly.
|
|
351
370
|
def assign_attribute(name, value)
|
|
352
|
-
setter =
|
|
353
|
-
raise ArgumentError, "unknown ClaudeAgentOptions option: #{name.inspect}" unless
|
|
371
|
+
setter = option_setter(normalize_name(name))
|
|
372
|
+
raise ArgumentError, "unknown ClaudeAgentOptions option: #{name.inspect}" unless setter
|
|
354
373
|
|
|
355
374
|
public_send(setter, value)
|
|
356
375
|
end
|
|
357
376
|
|
|
377
|
+
# The writer of the option with this normalized name, nil when the name
|
|
378
|
+
# is not an option. An option is a declared attribute, or a setter user
|
|
379
|
+
# code defined (on a subclass, a module it includes, or the object);
|
|
380
|
+
# respond_to? alone would also answer for '[]' (#[]=) and '=' (#==).
|
|
381
|
+
def option_setter(normalized)
|
|
382
|
+
setter = :"#{normalized}="
|
|
383
|
+
return unless respond_to?(setter)
|
|
384
|
+
|
|
385
|
+
setter if self.class.attribute?(normalized) || user_defined_method?(setter)
|
|
386
|
+
end
|
|
387
|
+
|
|
358
388
|
# Merge caller-provided attributes with configured defaults.
|
|
359
389
|
# Only keys the caller explicitly passed are treated as overrides;
|
|
360
390
|
# method-signature defaults ([], {}, false) are NOT present unless the caller wrote them.
|
|
@@ -403,7 +433,7 @@ module ClaudeAgentSDK
|
|
|
403
433
|
# reports the typo exactly as the developer wrote it.
|
|
404
434
|
def option_key(name)
|
|
405
435
|
normalized = normalize_name(name)
|
|
406
|
-
|
|
436
|
+
option_setter(normalized) ? normalized.to_sym : name
|
|
407
437
|
end
|
|
408
438
|
end
|
|
409
439
|
end
|
|
@@ -34,20 +34,21 @@ module ClaudeAgentSDK
|
|
|
34
34
|
@rules = value&.map { |rule| rule.is_a?(Hash) ? PermissionRuleValue.new(rule) : rule }
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
# The wire form. The CLI validates the updatedPermissions of a
|
|
38
|
+
# can_use_tool reply as one unit and drops the whole array when a single
|
|
39
|
+
# entry does not fit its schema, so two things it rejects are never
|
|
40
|
+
# written: a rule without content has no ruleContent key (the schema
|
|
41
|
+
# wants a String or no key, not null), and an update that has a type but
|
|
42
|
+
# no destination goes to 'session' — the narrowest one: it lasts for this
|
|
43
|
+
# run and writes no settings file (the default Python PR #1330 proposes).
|
|
37
44
|
def to_h
|
|
38
45
|
result = { type: @type }
|
|
39
|
-
|
|
46
|
+
destination = @destination || ('session' unless @type.nil?)
|
|
47
|
+
result[:destination] = destination if destination
|
|
40
48
|
|
|
41
49
|
case @type
|
|
42
50
|
when 'addRules', 'replaceRules', 'removeRules'
|
|
43
|
-
if @rules
|
|
44
|
-
result[:rules] = @rules.map do |rule|
|
|
45
|
-
{
|
|
46
|
-
toolName: rule.tool_name,
|
|
47
|
-
ruleContent: rule.rule_content
|
|
48
|
-
}
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
+
result[:rules] = @rules.map { |rule| rule_to_h(rule) } if @rules
|
|
51
52
|
result[:behavior] = @behavior if @behavior
|
|
52
53
|
when 'setMode'
|
|
53
54
|
result[:mode] = @mode if @mode
|
|
@@ -57,6 +58,14 @@ module ClaudeAgentSDK
|
|
|
57
58
|
|
|
58
59
|
result
|
|
59
60
|
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def rule_to_h(rule)
|
|
65
|
+
wire_rule = { toolName: rule.tool_name }
|
|
66
|
+
wire_rule[:ruleContent] = rule.rule_content unless rule.rule_content.nil?
|
|
67
|
+
wire_rule
|
|
68
|
+
end
|
|
60
69
|
end
|
|
61
70
|
|
|
62
71
|
# Tool permission context delivered to `can_use_tool` callbacks.
|