claude-agent-sdk 0.37.0 → 1.1.0

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/README.md +6 -2
  4. data/UPGRADING-1.0.md +151 -0
  5. data/docs/client.md +11 -0
  6. data/docs/configuration.md +42 -0
  7. data/docs/errors.md +6 -0
  8. data/docs/sessions.md +20 -1
  9. data/docs/types.md +17 -14
  10. data/lib/claude_agent_sdk/cli_installer.rb +1 -1
  11. data/lib/claude_agent_sdk/deprecation.rb +1 -40
  12. data/lib/claude_agent_sdk/errors.rb +10 -0
  13. data/lib/claude_agent_sdk/query.rb +320 -56
  14. data/lib/claude_agent_sdk/session_resume.rb +11 -5
  15. data/lib/claude_agent_sdk/subprocess_cli_transport.rb +25 -0
  16. data/lib/claude_agent_sdk/types/attributes.rb +14 -49
  17. data/lib/claude_agent_sdk/types/base.rb +2 -0
  18. data/lib/claude_agent_sdk/types/messages.rb +7 -1
  19. data/lib/claude_agent_sdk/types/options.rb +69 -12
  20. data/lib/claude_agent_sdk/version.rb +1 -1
  21. data/lib/claude_agent_sdk.rb +28 -18
  22. data/sig/claude_agent_sdk/cancellation_signal.rbs +14 -0
  23. data/sig/claude_agent_sdk/configuration.rbs +14 -0
  24. data/sig/claude_agent_sdk/errors.rbs +86 -0
  25. data/sig/claude_agent_sdk/observer.rbs +42 -0
  26. data/sig/claude_agent_sdk/railtie.rbs +10 -0
  27. data/sig/claude_agent_sdk/sdk_mcp_server.rbs +76 -0
  28. data/sig/claude_agent_sdk/session_store.rbs +105 -0
  29. data/sig/claude_agent_sdk/streaming.rbs +15 -0
  30. data/sig/claude_agent_sdk/transport.rbs +98 -0
  31. data/sig/claude_agent_sdk/types/base.rbs +39 -0
  32. data/sig/claude_agent_sdk/types/content_blocks.rbs +79 -0
  33. data/sig/claude_agent_sdk/types/hooks.rbs +528 -0
  34. data/sig/claude_agent_sdk/types/mcp.rbs +216 -0
  35. data/sig/claude_agent_sdk/types/messages.rbs +586 -0
  36. data/sig/claude_agent_sdk/types/option_values.rbs +245 -0
  37. data/sig/claude_agent_sdk/types/options.rbs +297 -0
  38. data/sig/claude_agent_sdk/types/permissions.rbs +108 -0
  39. data/sig/claude_agent_sdk/types/sessions.rbs +66 -0
  40. data/sig/claude_agent_sdk.rbs +231 -0
  41. data/sig/manifest.yaml +5 -0
  42. metadata +23 -2
@@ -0,0 +1,76 @@
1
+ module ClaudeAgentSDK
2
+ # What an SDK MCP tool handler returns: a String (sent as one text block),
3
+ # or a Hash with a :content Array of MCP content blocks plus optional
4
+ # :is_error / :structured_content.
5
+ type tool_result = String | Hash[Symbol | String, untyped]
6
+
7
+ # An SDK MCP tool handler (the block given to ClaudeAgentSDK.create_tool).
8
+ # args is the tools/call arguments Hash (wire_hash).
9
+ interface _ToolHandler
10
+ def call: (wire_hash args) -> tool_result
11
+ end
12
+
13
+ # An SDK MCP resource reader: returns a Hash with a :contents Array.
14
+ interface _ResourceReader
15
+ def call: () -> Hash[Symbol | String, untyped]
16
+ end
17
+
18
+ # An SDK MCP prompt generator: returns a Hash with a :messages Array.
19
+ interface _PromptGenerator
20
+ def call: (Hash[Symbol | String, untyped] args) -> Hash[Symbol | String, untyped]
21
+ end
22
+
23
+ # An in-process MCP server (built by ClaudeAgentSDK.create_sdk_mcp_server).
24
+ # The list_*/call_*/read_*/get_* methods invoke it directly, outside a
25
+ # session.
26
+ class SdkMcpServer
27
+ attr_reader name: String
28
+
29
+ attr_reader version: String
30
+
31
+ attr_reader tools: Array[SdkMcpTool]
32
+
33
+ attr_reader resources: Array[SdkMcpResource]
34
+
35
+ attr_reader prompts: Array[SdkMcpPrompt]
36
+
37
+ # The underlying server object from the `mcp` gem (MCP::Server); not
38
+ # typed here so the signatures don't depend on that gem's.
39
+ attr_reader mcp_server: untyped
40
+
41
+ # Where handlers run on DIRECT invocations (a session dispatch uses the
42
+ # session's own mode). Defaults to :thread.
43
+ attr_reader callback_scheduling: :thread | :inline
44
+
45
+ # Wrapper for DIRECT invocations (a session dispatch uses the session's).
46
+ attr_reader callback_wrapper: _CallbackWrapper?
47
+
48
+ # A String is coerced to a Symbol; anything but :thread / :inline raises
49
+ # ArgumentError.
50
+ def callback_scheduling=: (:thread | :inline | "thread" | "inline" value) -> (:thread | :inline | "thread" | "inline")
51
+
52
+ # Raises ArgumentError unless value is callable or nil.
53
+ def callback_wrapper=: (_CallbackWrapper? value) -> _CallbackWrapper?
54
+
55
+ def initialize: (name: String, ?version: String, ?tools: Array[SdkMcpTool], ?resources: Array[SdkMcpResource], ?prompts: Array[SdkMcpPrompt]) -> void
56
+
57
+ # Tool definitions: { name:, description:, inputSchema:, annotations:?, _meta:? }.
58
+ def list_tools: () -> Array[Hash[Symbol, untyped]]
59
+
60
+ # Runs the tool's handler. Failures come back in-band with isError: true
61
+ # (a String handler result is wrapped into a text block).
62
+ def call_tool: (String name, Hash[Symbol | String, untyped] arguments) -> Hash[Symbol | String, untyped]
63
+
64
+ def list_resources: () -> Array[Hash[Symbol, untyped]]
65
+
66
+ # Raises when the resource does not exist or its reader returns no
67
+ # :contents.
68
+ def read_resource: (String uri) -> Hash[Symbol | String, untyped]
69
+
70
+ def list_prompts: () -> Array[Hash[Symbol, untyped]]
71
+
72
+ # Raises when the prompt does not exist or its generator returns no
73
+ # :messages.
74
+ def get_prompt: (String name, ?Hash[Symbol | String, untyped] arguments) -> Hash[Symbol | String, untyped]
75
+ end
76
+ end
@@ -0,0 +1,105 @@
1
+ module ClaudeAgentSDK
2
+ # Values of ClaudeAgentOptions#session_store_flush.
3
+ SESSION_STORE_FLUSH_MODES: Array[String]
4
+
5
+ # A SessionStore key. String keys: 'project_key' and 'session_id' always;
6
+ # 'subpath' (e.g. "subagents/agent-<id>") only for a subagent transcript.
7
+ type session_key = Hash[String, String?]
8
+
9
+ # A session summary as built by ClaudeAgentSDK.fold_session_summary:
10
+ # { 'session_id' => String, 'mtime' => Integer, 'data' => Hash[String, untyped] }.
11
+ type session_summary = Hash[String, untyped]
12
+
13
+ # The duck type ClaudeAgentOptions#session_store and the session functions'
14
+ # session_store: accept. Only #append and #load are required; an adapter
15
+ # need not subclass SessionStore. Keys and entries cross this boundary as
16
+ # String-keyed Hashes (docs/types.md#hash-keys).
17
+ #
18
+ # The SDK also probes (SessionStore.implements?) for these OPTIONAL methods
19
+ # and uses them when present — they cannot be expressed as optional
20
+ # interface members, so they are listed here:
21
+ #
22
+ # def list_sessions: (String project_key) -> Array[{ 'session_id' => String, 'mtime' => Integer }]
23
+ # def list_session_summaries: (String project_key) -> Array[session_summary]
24
+ # def delete: (session_key key) -> void # a main key cascades to its subkeys
25
+ # def list_subkeys: (session_key key) -> Array[String]
26
+ # def callback_scheduling: () -> (:thread | :inline) # :inline = fiber-native adapter
27
+ #
28
+ # ClaudeAgentSDK::Testing.run_session_store_conformance checks an adapter
29
+ # against the behavioral contracts.
30
+ interface _SessionStore
31
+ # Mirrors a batch of transcript entries. Must be thread-safe per key and
32
+ # should dedupe by entry['uuid'].
33
+ def append: (session_key key, Array[transcript_hash] entries) -> void
34
+
35
+ # The full transcript for key, or nil when it was never written.
36
+ def load: (session_key key) -> Array[transcript_hash]?
37
+ end
38
+
39
+ # Optional base class for adapters. Its methods raise NotImplementedError,
40
+ # which marks an optional method as absent (see .implements?).
41
+ class SessionStore
42
+ # True when store overrides method rather than inheriting the
43
+ # NotImplementedError default (works for duck-typed adapters too).
44
+ def self.implements?: (untyped store, Symbol | String method) -> bool
45
+
46
+ def append: (session_key key, Array[transcript_hash] entries) -> void
47
+
48
+ def load: (session_key key) -> Array[transcript_hash]?
49
+
50
+ def list_sessions: (String project_key) -> Array[Hash[String, String | Integer]]
51
+
52
+ def list_session_summaries: (String project_key) -> Array[session_summary]
53
+
54
+ def delete: (session_key key) -> void
55
+
56
+ def list_subkeys: (session_key key) -> Array[String]
57
+ end
58
+
59
+ # In-memory SessionStore for tests and development; data is lost on exit.
60
+ # Implements every optional method.
61
+ class InMemorySessionStore < SessionStore
62
+ def initialize: () -> void
63
+
64
+ def append: (session_key key, Array[transcript_hash]? entries) -> void
65
+
66
+ def load: (session_key key) -> Array[transcript_hash]?
67
+
68
+ def list_sessions: (String project_key) -> Array[Hash[String, String | Integer]]
69
+
70
+ def list_session_summaries: (String project_key) -> Array[session_summary]
71
+
72
+ def delete: (session_key key) -> void
73
+
74
+ def list_subkeys: (session_key key) -> Array[String]
75
+
76
+ # Test helper: all entries for key ([] when absent).
77
+ def get_entries: (session_key key) -> Array[transcript_hash]
78
+
79
+ # Test helper: number of stored main transcripts.
80
+ def size: () -> Integer
81
+
82
+ # Test helper: removes everything.
83
+ def clear: () -> void
84
+ end
85
+
86
+ # Test helpers shipped for third-party SessionStore adapter authors.
87
+ module Testing
88
+ # Raised by run_session_store_conformance on the first violated contract.
89
+ class ConformanceError < StandardError
90
+ end
91
+
92
+ # The optional SessionStore methods skip_optional: accepts.
93
+ OPTIONAL_METHODS: Array[String]
94
+
95
+ # Asserts the SessionStore behavioral contracts against a fresh store
96
+ # from make_store (called once per contract). Raises ConformanceError on
97
+ # a violation; returns nil otherwise.
98
+ def self.run_session_store_conformance: (_StoreFactory make_store, ?skip_optional: Array[String | Symbol], ?check_uuid_dedupe: bool) -> nil
99
+
100
+ # Returns a fresh store per call.
101
+ interface _StoreFactory
102
+ def call: () -> _SessionStore
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,15 @@
1
+ module ClaudeAgentSDK
2
+ # Builders for streaming input: a prompt that is an Enumerator of JSONL
3
+ # user messages.
4
+ module Streaming
5
+ # One JSON-encoded user message, newline-terminated. content is a String
6
+ # or an Array of content-block Hashes.
7
+ def self.user_message: (String | Array[Hash[Symbol | String, untyped]] content, ?session_id: String, ?parent_tool_use_id: String?) -> String
8
+
9
+ def self.from_array: (_Each[String | Array[Hash[Symbol | String, untyped]]] messages, ?session_id: String) -> Enumerator[String, void]
10
+
11
+ # The block receives an Enumerator::Yielder; each value it yields becomes
12
+ # one user message.
13
+ def self.from_block: (?session_id: String) { (Enumerator::Yielder yielder) -> void } -> Enumerator[String, void]
14
+ end
15
+ end
@@ -0,0 +1,98 @@
1
+ module ClaudeAgentSDK
2
+ # What `query(transport:)` and Client need from a transport. A custom
3
+ # transport may subclass Transport or be any object with these methods.
4
+ # read_messages must yield each stdout line parsed with
5
+ # `JSON.parse(line, symbolize_names: true)` (see docs/types.md#hash-keys).
6
+ # #close must be idempotent. (Transport#ready? is part of the abstract
7
+ # class but the SDK never calls it, so it is not required here.)
8
+ interface _Transport
9
+ def connect: () -> void
10
+
11
+ def write: (String data) -> void
12
+
13
+ def read_messages: () { (wire_hash message) -> void } -> void
14
+
15
+ def close: () -> void
16
+
17
+ def end_input: () -> void
18
+ end
19
+
20
+ # Client's transport_class: Client calls
21
+ # `transport_class.new(options, **transport_args)`.
22
+ interface _TransportClass
23
+ def new: (ClaudeAgentOptions options, **untyped transport_args) -> _Transport
24
+ end
25
+
26
+ # Abstract base for custom transports: every method raises
27
+ # NotImplementedError until overridden.
28
+ class Transport
29
+ def connect: () -> void
30
+
31
+ def write: (String data) -> void
32
+
33
+ def read_messages: () { (wire_hash message) -> void } -> void
34
+ | () -> Enumerator[wire_hash, void]
35
+
36
+ def close: () -> void
37
+
38
+ def ready?: () -> bool
39
+
40
+ def end_input: () -> void
41
+ end
42
+
43
+ # The default transport: spawns the `claude` CLI and speaks stream-JSON
44
+ # over its stdin/stdout.
45
+ class SubprocessCLITransport < Transport
46
+ # The legacy two-argument form `new(prompt, options)` ignores prompt.
47
+ def initialize: (ClaudeAgentOptions options) -> void
48
+ | (untyped prompt, ClaudeAgentOptions options) -> void
49
+
50
+ def connect: () -> void
51
+
52
+ def write: (String data) -> void
53
+
54
+ def read_messages: () { (wire_hash message) -> void } -> void
55
+ | () -> Enumerator[wire_hash, void]
56
+
57
+ def close: () -> void
58
+
59
+ def ready?: () -> bool
60
+
61
+ def end_input: () -> void
62
+ end
63
+
64
+ # Builds the CLI argv SubprocessCLITransport would spawn (for custom
65
+ # transports that run the CLI elsewhere; see docs/client.md).
66
+ class CommandBuilder
67
+ def initialize: (String cli_path, ClaudeAgentOptions options) -> void
68
+
69
+ def build: () -> Array[String]
70
+ end
71
+
72
+ # Downloads a pinned Claude Code CLI into vendor/claude (Docker/CI deploys).
73
+ # Every failure raises CLIInstallError.
74
+ module CLIInstaller
75
+ # The CLI version this gem release is tested against.
76
+ PINNED_CLI_VERSION: String
77
+
78
+ # The directory vendor/claude resolves against (nil: the cwd at call
79
+ # time). An absolute, frozen path once set.
80
+ def self.root: () -> String?
81
+
82
+ def self.root=: ((String | Pathname)? path) -> (String | Pathname)?
83
+
84
+ # Absolute path of the default install directory.
85
+ def self.default_dir: () -> String
86
+
87
+ # Installs the CLI ('stable', 'latest' or a concrete version) and returns
88
+ # the absolute path of the binary. Idempotent and safe to run
89
+ # concurrently.
90
+ def self.install: (?version: String, ?dir: (String | Pathname)?) -> String
91
+
92
+ # Installs PINNED_CLI_VERSION.
93
+ def self.install_pinned: (?dir: (String | Pathname)?) -> String
94
+
95
+ # Path of an already-installed binary, or nil.
96
+ def self.installed_path: (?dir: (String | Pathname)?) -> String?
97
+ end
98
+ end
@@ -0,0 +1,39 @@
1
+ module ClaudeAgentSDK
2
+ # Base class of the SDK's value types (messages, content blocks, hook
3
+ # inputs/outputs, option values).
4
+ #
5
+ # Attribute names are accepted in several spellings — Symbol or String,
6
+ # snake_case or camelCase — by .new, #[] and #[]=, which reach attributes
7
+ # only. The camelCase readers (`msg.sessionId`) are public API too but are
8
+ # resolved dynamically (method_missing), so they have no static signature
9
+ # here: prefer the snake_case readers, or #[], in typed code.
10
+ class Type
11
+ # Returns object unchanged when it already is an instance, nil for nil,
12
+ # and otherwise builds one (leniently: unknown keys never raise).
13
+ def self.wrap: (untyped object) -> instance?
14
+
15
+ # Builds an instance from a Hash (leniently); nil for anything else.
16
+ def self.from_hash: (untyped hash) -> instance?
17
+
18
+ # attributes: a Hash of attribute name => value (the keyword form
19
+ # `Klass.new(name: value)` passes the same Hash). On a user-constructed
20
+ # (strict) type an unknown key raises ArgumentError; types parsed from
21
+ # CLI output ignore it.
22
+ def initialize: (?Hash[Symbol | String, untyped]? attributes) -> void
23
+
24
+ # Reads an attribute; nil for a name that is not an attribute.
25
+ def []: (Symbol | String name) -> untyped
26
+
27
+ # Writes an attribute through its setter; returns value. A name that is
28
+ # not an attribute is ignored, or raises ArgumentError on a strict type.
29
+ def []=: (Symbol | String name, untyped value) -> untyped
30
+
31
+ # The wire (CLI) form; types that are sent to the CLI override this.
32
+ def to_h: () -> Hash[Symbol, untyped]
33
+
34
+ # Bounded, credential-filtered, human-oriented rendering.
35
+ def inspect: () -> String
36
+
37
+ def to_s: () -> String
38
+ end
39
+ end
@@ -0,0 +1,79 @@
1
+ module ClaudeAgentSDK
2
+ # A raw Hash inside a content block: Symbol keys on live messages, String
3
+ # keys on blocks parsed from a transcript (SessionMessage#content_blocks).
4
+ type block_hash = wire_hash | transcript_hash
5
+
6
+ # A content block of a UserMessage / AssistantMessage / SessionMessage.
7
+ type content_block = TextBlock
8
+ | ThinkingBlock
9
+ | ToolUseBlock
10
+ | ToolResultBlock
11
+ | ServerToolUseBlock
12
+ | ServerToolResultBlock
13
+ | UnknownBlock
14
+
15
+ class TextBlock < Type
16
+ attr_accessor text: String?
17
+
18
+ def to_s: () -> String
19
+ end
20
+
21
+ class ThinkingBlock < Type
22
+ attr_accessor thinking: String?
23
+
24
+ attr_accessor signature: String?
25
+ end
26
+
27
+ class ToolUseBlock < Type
28
+ attr_accessor id: String?
29
+
30
+ attr_accessor name: String?
31
+
32
+ attr_accessor input: block_hash?
33
+ end
34
+
35
+ class ToolResultBlock < Type
36
+ attr_accessor tool_use_id: String?
37
+
38
+ # A String, or an Array of content-block Hashes.
39
+ attr_accessor content: (String | Array[block_hash])?
40
+
41
+ attr_accessor is_error: bool?
42
+ end
43
+
44
+ # A server-side tool call (advisor, web_search, code_execution, ...).
45
+ class ServerToolUseBlock < Type
46
+ attr_accessor id: String?
47
+
48
+ attr_accessor name: String?
49
+
50
+ attr_accessor input: block_hash?
51
+ end
52
+
53
+ # The result of a server-side tool call. content is passed through from
54
+ # the API as-is and its shape depends on the tool.
55
+ class ServerToolResultBlock < Type
56
+ attr_accessor tool_use_id: String?
57
+
58
+ attr_accessor content: untyped
59
+
60
+ attr_accessor is_error: bool?
61
+ end
62
+
63
+ # A block type this SDK version does not model ("document", "image", ...):
64
+ # type is the original block type, data the raw block.
65
+ class UnknownBlock < Type
66
+ attr_accessor type: String?
67
+
68
+ attr_accessor data: block_hash?
69
+ end
70
+
71
+ # A tool call a PreToolUse hook deferred (ResultMessage#deferred_tool_use).
72
+ class DeferredToolUse < Type
73
+ attr_accessor id: String?
74
+
75
+ attr_accessor name: String?
76
+
77
+ attr_accessor input: block_hash?
78
+ end
79
+ end