claude-agent-sdk 0.32.0 → 0.33.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/CHANGELOG.md +35 -0
- data/README.md +3 -2
- data/docs/client.md +4 -0
- data/docs/configuration.md +33 -0
- data/docs/hooks-and-permissions.md +66 -2
- data/docs/sessions.md +28 -0
- data/docs/subagents.md +198 -0
- data/docs/types.md +34 -4
- data/lib/claude_agent_sdk/cancellation_signal.rb +28 -0
- data/lib/claude_agent_sdk/message_parser.rb +3 -1
- data/lib/claude_agent_sdk/query.rb +113 -24
- data/lib/claude_agent_sdk/sdk_mcp_server.rb +10 -0
- data/lib/claude_agent_sdk/session_mutations.rb +2 -4
- data/lib/claude_agent_sdk/sessions.rb +37 -0
- data/lib/claude_agent_sdk/types.rb +224 -12
- data/lib/claude_agent_sdk/version.rb +1 -1
- data/lib/claude_agent_sdk.rb +43 -0
- metadata +8 -6
|
@@ -421,12 +421,51 @@ module ClaudeAgentSDK
|
|
|
421
421
|
# Task started system message (subagent/background task started)
|
|
422
422
|
class TaskStartedMessage < SystemMessage
|
|
423
423
|
attr_accessor :task_id, :description, :uuid, :session_id, :tool_use_id, :task_type,
|
|
424
|
-
:workflow_name, :prompt
|
|
424
|
+
:workflow_name, :prompt,
|
|
425
|
+
:subagent_type # Subagent type, for Task/Agent tool subagents; nil otherwise
|
|
426
|
+
|
|
427
|
+
# Whether the task was registered in the background (`true`) or in the
|
|
428
|
+
# foreground with the spawning tool call blocking on it (`false`). `nil`
|
|
429
|
+
# means the CLI did not say (the field is optional, and only set for
|
|
430
|
+
# `local_agent` and `local_bash` tasks) — so test `== false`, never
|
|
431
|
+
# falsiness, to detect a foreground/blocking task. A resumed subagent is
|
|
432
|
+
# always registered in the background. A later move to the background does
|
|
433
|
+
# not re-emit task_started; it arrives as {TaskUpdatedMessage#is_backgrounded}.
|
|
434
|
+
#
|
|
435
|
+
# @return [Boolean, nil]
|
|
436
|
+
attr_accessor :is_backgrounded
|
|
437
|
+
|
|
438
|
+
# Nesting depth of a spawned subagent (`local_agent`) task: 1 for a
|
|
439
|
+
# top-level spawn, N+1 when spawned from inside a depth-N agent. `nil` on
|
|
440
|
+
# other task types and on CLIs that do not report it.
|
|
441
|
+
#
|
|
442
|
+
# @return [Integer, nil]
|
|
443
|
+
attr_accessor :spawn_depth
|
|
444
|
+
|
|
445
|
+
# Display flags, passed through for the host to act on — the SDK never
|
|
446
|
+
# filters frames or computes activity from them. Both are optional
|
|
447
|
+
# Booleans: `nil` when absent, an explicit `false` preserved.
|
|
448
|
+
#
|
|
449
|
+
# - `skip_transcript`: an ambient/housekeeping task. Hide it from the
|
|
450
|
+
# inline transcript; it may still appear in a tasks panel.
|
|
451
|
+
# - `ambient`: true for tasks that are not activity — every
|
|
452
|
+
# `skip_transcript` task, plus every live-update watcher (requested or
|
|
453
|
+
# auto-started). Exclude these from activity indicators.
|
|
454
|
+
#
|
|
455
|
+
# @return [Boolean, nil]
|
|
456
|
+
attr_accessor :skip_transcript, :ambient
|
|
425
457
|
end
|
|
426
458
|
|
|
427
|
-
# Task progress system message (periodic update from a running task)
|
|
459
|
+
# Task progress system message (periodic update from a running task).
|
|
460
|
+
#
|
|
461
|
+
# `summary` is an optional one-line status for the task's row — `nil` on any
|
|
462
|
+
# frame that lacks one. For a `local_agent` task it is the model-generated
|
|
463
|
+
# progress summary, which the CLI produces only while generation is enabled
|
|
464
|
+
# (see {ClaudeAgentOptions#agent_progress_summaries}); for a backgrounded
|
|
465
|
+
# `mcp_task` it is the MCP server's own status message and needs no option.
|
|
428
466
|
class TaskProgressMessage < SystemMessage
|
|
429
|
-
attr_accessor :task_id, :description, :usage, :uuid, :session_id, :tool_use_id, :last_tool_name, :summary
|
|
467
|
+
attr_accessor :task_id, :description, :usage, :uuid, :session_id, :tool_use_id, :last_tool_name, :summary,
|
|
468
|
+
:subagent_type # Subagent type, for Task/Agent tool subagents; nil otherwise
|
|
430
469
|
end
|
|
431
470
|
|
|
432
471
|
# Task notification system message (task completed/failed/stopped).
|
|
@@ -437,6 +476,42 @@ module ClaudeAgentSDK
|
|
|
437
476
|
# should clear them on a terminal status from *either* message.
|
|
438
477
|
class TaskNotificationMessage < SystemMessage
|
|
439
478
|
attr_accessor :task_id, :status, :output_file, :summary, :uuid, :session_id, :tool_use_id, :usage
|
|
479
|
+
|
|
480
|
+
# Machine-readable cause, set only when the task did not end through an
|
|
481
|
+
# ordinary completion, failure, or stop. The one known value is
|
|
482
|
+
# `'worker_restart'` (the worker process restarted and the resumed process
|
|
483
|
+
# found the task orphaned; always with status `'stopped'`). Documentation,
|
|
484
|
+
# not validation: newer CLIs may add values.
|
|
485
|
+
#
|
|
486
|
+
# @return [String, nil]
|
|
487
|
+
attr_accessor :reason
|
|
488
|
+
|
|
489
|
+
# For a backgrounded MCP task (`task_type: 'mcp_task'`) that completed: the
|
|
490
|
+
# `resource_link` content blocks of its final result — the files it
|
|
491
|
+
# returned by reference. A backgrounded task's tool_result is placeholder
|
|
492
|
+
# text, so this is where a host learns which files the call produced; join
|
|
493
|
+
# to the originating call via `tool_use_id`. `nil` when the result had
|
|
494
|
+
# none or the task is any other type.
|
|
495
|
+
#
|
|
496
|
+
# Passed through from the CLI untouched, so each element is a Hash whose
|
|
497
|
+
# keys are **Symbols with the wire spelling preserved**: `:uri` and `:name`
|
|
498
|
+
# (Strings, always present), and optionally `:title`, `:description`,
|
|
499
|
+
# `:mimeType` (camelCase — a `:mime_type` lookup returns nil), `:size` (a
|
|
500
|
+
# Number, not necessarily an Integer), `:annotations` (a Hash of arbitrary
|
|
501
|
+
# values). Elements carry no `type: 'resource_link'` discriminator. The CLI
|
|
502
|
+
# describes its own output as at most 50 links / 64 KiB serialized; that is
|
|
503
|
+
# a producer-side note, and the SDK neither enforces nor truncates.
|
|
504
|
+
#
|
|
505
|
+
# @return [Array<Hash{Symbol => Object}>, nil]
|
|
506
|
+
attr_accessor :resource_links
|
|
507
|
+
|
|
508
|
+
# Display flags with the same meaning as on {TaskStartedMessage}:
|
|
509
|
+
# `skip_transcript` (hide from the inline transcript) and `ambient` (not
|
|
510
|
+
# activity — exclude from activity indicators). Optional Booleans: `nil`
|
|
511
|
+
# when absent, an explicit `false` preserved. The SDK does not act on them.
|
|
512
|
+
#
|
|
513
|
+
# @return [Boolean, nil]
|
|
514
|
+
attr_accessor :skip_transcript, :ambient
|
|
440
515
|
end
|
|
441
516
|
|
|
442
517
|
# Task updated system message (background task lifecycle state change).
|
|
@@ -455,18 +530,105 @@ module ClaudeAgentSDK
|
|
|
455
530
|
# or absent patch falls back to {}; and `task_id` defaults to "" (never nil,
|
|
456
531
|
# matching the Python SDK) so consumers can rely on it always being a String.
|
|
457
532
|
# The full patch is preserved on `#patch` for callers that need more than the
|
|
458
|
-
#
|
|
533
|
+
# derived readers.
|
|
534
|
+
#
|
|
535
|
+
# A patch carries only the fields that changed, so every derived reader is
|
|
536
|
+
# `nil` when its field is absent. That matters most for `is_backgrounded`:
|
|
537
|
+
# `true` means the task just moved to the background (e.g. after
|
|
538
|
+
# {Client#background_tasks}), while `nil` means "this patch does not mention
|
|
539
|
+
# it" — not "foreground". Merge patches into your own task map rather than
|
|
540
|
+
# reading any single one as the task's full state.
|
|
459
541
|
class TaskUpdatedMessage < SystemMessage
|
|
460
|
-
attr_accessor :task_id, :patch, :status, :uuid, :session_id
|
|
542
|
+
attr_accessor :task_id, :patch, :status, :uuid, :session_id,
|
|
543
|
+
:description, # patch[:description] — String, nil when unchanged
|
|
544
|
+
:error, # patch[:error] — String, nil when unchanged
|
|
545
|
+
:end_time, # patch[:end_time] — Integer (epoch ms), nil when unchanged
|
|
546
|
+
:total_paused_ms, # patch[:total_paused_ms] — Integer, nil when unchanged
|
|
547
|
+
:is_backgrounded # patch[:is_backgrounded] — true/false, nil when unchanged
|
|
461
548
|
|
|
462
549
|
def initialize(attributes = {})
|
|
463
550
|
super
|
|
464
551
|
@task_id ||= ''
|
|
465
552
|
@patch = {} unless @patch.is_a?(Hash)
|
|
466
|
-
@status =
|
|
553
|
+
@status = patch_value(:status)
|
|
554
|
+
@description = patch_value(:description)
|
|
555
|
+
@error = patch_value(:error)
|
|
556
|
+
@end_time = patch_value(:end_time)
|
|
557
|
+
@total_paused_ms = patch_value(:total_paused_ms)
|
|
558
|
+
@is_backgrounded = patch_value(:is_backgrounded)
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
private
|
|
562
|
+
|
|
563
|
+
# The parser always hands over a symbol-keyed patch; a hand-built message
|
|
564
|
+
# may use string keys. `fetch` with a block (not `||`) keeps an explicit
|
|
565
|
+
# `false` from falling through to the string-key lookup's nil.
|
|
566
|
+
def patch_value(key)
|
|
567
|
+
@patch.fetch(key) { @patch[key.to_s] }
|
|
467
568
|
end
|
|
468
569
|
end
|
|
469
570
|
|
|
571
|
+
# Background tasks changed system message: the full set of live background
|
|
572
|
+
# tasks, emitted whenever membership changes (start, completion, kill, a
|
|
573
|
+
# foreground agent being backgrounded) or an entry's `ambient` flag flips.
|
|
574
|
+
#
|
|
575
|
+
# A **level** signal with **REPLACE semantics** — `tasks` is every live
|
|
576
|
+
# background task after the change, so swap your set for each payload rather
|
|
577
|
+
# than pairing task_started / task_notification edges; a missed edge then
|
|
578
|
+
# cannot wedge a stale "running" indicator. Per the CLI's contract:
|
|
579
|
+
#
|
|
580
|
+
# - Ordering relative to the edge frames for the same transition is
|
|
581
|
+
# unspecified, and the payload carries ids only — do not correlate it
|
|
582
|
+
# with the edge stream.
|
|
583
|
+
# - The level is per-process: nothing is emitted at startup, so reset to the
|
|
584
|
+
# empty set whenever the session's CLI process (re)starts.
|
|
585
|
+
# - `tasks: []` is an authoritative empty snapshot for that process, not a
|
|
586
|
+
# missing value.
|
|
587
|
+
# - A repeated `initialize` on an already-running process is answered with a
|
|
588
|
+
# snapshot of the current set (even an empty one) right behind its success
|
|
589
|
+
# response; older CLIs send nothing there. This SDK initializes once per
|
|
590
|
+
# connection, so that only matters to custom transports that reconnect.
|
|
591
|
+
# - It covers *background* tasks only. A foreground subagent (the spawning
|
|
592
|
+
# tool call still blocking) is not listed until it is backgrounded.
|
|
593
|
+
#
|
|
594
|
+
# `tasks` is passed through untouched: an Array of symbol-keyed Hashes
|
|
595
|
+
# `{ task_id:, task_type:, description:, ambient: }`. `:ambient` is optional;
|
|
596
|
+
# true marks tasks that are not activity (housekeeping, live-update
|
|
597
|
+
# watchers), which hosts should exclude from activity indicators.
|
|
598
|
+
#
|
|
599
|
+
# The SDK itself deliberately does not consume this frame for its own
|
|
600
|
+
# stdin-close bookkeeping; it is typed purely for consumers.
|
|
601
|
+
class BackgroundTasksChangedMessage < SystemMessage
|
|
602
|
+
attr_accessor :tasks, :uuid, :session_id
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
# Permission denied system message: a tool call was auto-denied without an
|
|
606
|
+
# interactive permission prompt (auto-mode classifier, dontAsk mode,
|
|
607
|
+
# headless-agent auto-deny, a deny rule, or — with no can_use_tool callback —
|
|
608
|
+
# an "ask" decision that nobody can answer). The "ask" path with a callback
|
|
609
|
+
# surfaces through can_use_tool instead.
|
|
610
|
+
#
|
|
611
|
+
# **Best-effort advisory, not a complete denial feed**:
|
|
612
|
+
# {ResultMessage#permission_denials} is the authoritative record. In rare
|
|
613
|
+
# races a booked denial has no frame, or a frame has no booked denial — so do
|
|
614
|
+
# not derive counts or permission state from this stream. Not covered at all:
|
|
615
|
+
# PreToolUse hook denies, deny-rule overrides of a hook's allow/ask decision,
|
|
616
|
+
# Read/Edit/Write calls refused by a path-scoped deny rule (all resolve before
|
|
617
|
+
# the permission check), and the MCP `--permission-prompt-tool` surface.
|
|
618
|
+
#
|
|
619
|
+
# `agent_id` is a subagent id for host-side routing; it is NOT a permission
|
|
620
|
+
# `request_id`, and this message is not a pending permission request.
|
|
621
|
+
# `decision_reason_type` is an open String (the values below are examples,
|
|
622
|
+
# not an enum). The CLI's `decision_reason_code` is marked internal and is
|
|
623
|
+
# left to `#data` with no stability promise.
|
|
624
|
+
class PermissionDeniedMessage < SystemMessage
|
|
625
|
+
attr_accessor :uuid, :session_id, :tool_name, :tool_use_id,
|
|
626
|
+
:agent_id, # Subagent ID when the denied call originated inside a subagent; nil otherwise
|
|
627
|
+
:decision_reason_type, # Open String, e.g. "classifier", "asyncAgent", "mode", "rule"; nil when not reported
|
|
628
|
+
:decision_reason, # Human-readable reason from the deciding component; nil when not reported
|
|
629
|
+
:message # The rejection message returned to the model in the tool_result
|
|
630
|
+
end
|
|
631
|
+
|
|
470
632
|
# Result message with cost and usage information
|
|
471
633
|
class ResultMessage < Type
|
|
472
634
|
# model_usage maps model name => per-model usage Hash, passed through
|
|
@@ -742,8 +904,10 @@ module ClaudeAgentSDK
|
|
|
742
904
|
# `decision_reason`) so the SDK consumer can render the same prompt UI
|
|
743
905
|
# the CLI would have shown. Older fields (`signal`, `suggestions`,
|
|
744
906
|
# `tool_use_id`, `agent_id`) remain unchanged.
|
|
907
|
+
# `signal` is a CancellationSignal on dispatched callbacks; `request_id`
|
|
908
|
+
# identifies this permission request (distinct from the tool invocation).
|
|
745
909
|
class ToolPermissionContext < Type
|
|
746
|
-
attr_accessor :signal, :suggestions, :tool_use_id, :agent_id,
|
|
910
|
+
attr_accessor :signal, :request_id, :suggestions, :tool_use_id, :agent_id,
|
|
747
911
|
:title, :display_name, :description,
|
|
748
912
|
:blocked_path, :decision_reason
|
|
749
913
|
|
|
@@ -786,9 +950,10 @@ module ClaudeAgentSDK
|
|
|
786
950
|
end
|
|
787
951
|
end
|
|
788
952
|
|
|
789
|
-
# Hook context passed to hook callbacks
|
|
953
|
+
# Hook context passed to hook callbacks. Dispatched hooks receive the control
|
|
954
|
+
# request ID and a CancellationSignal (including on HookMatcher timeout).
|
|
790
955
|
class HookContext < Type
|
|
791
|
-
attr_accessor :signal
|
|
956
|
+
attr_accessor :signal, :request_id
|
|
792
957
|
end
|
|
793
958
|
|
|
794
959
|
# Base hook input with common fields
|
|
@@ -828,8 +993,11 @@ module ClaudeAgentSDK
|
|
|
828
993
|
end
|
|
829
994
|
|
|
830
995
|
# Stop hook input
|
|
996
|
+
# Snapshot arrays are passed through unchanged. nil means unavailable;
|
|
997
|
+
# [] means the CLI provided an empty snapshot. They cover the parent
|
|
998
|
+
# session's background work, NOT all foreground and background agents.
|
|
831
999
|
class StopHookInput < BaseHookInput
|
|
832
|
-
attr_accessor :stop_hook_active, :last_assistant_message
|
|
1000
|
+
attr_accessor :stop_hook_active, :last_assistant_message, :background_tasks, :session_crons
|
|
833
1001
|
|
|
834
1002
|
def initialize(attributes = {})
|
|
835
1003
|
super
|
|
@@ -841,7 +1009,7 @@ module ClaudeAgentSDK
|
|
|
841
1009
|
# SubagentStop hook input
|
|
842
1010
|
class SubagentStopHookInput < BaseHookInput
|
|
843
1011
|
attr_accessor :stop_hook_active, :agent_id, :agent_transcript_path, :agent_type,
|
|
844
|
-
:last_assistant_message
|
|
1012
|
+
:last_assistant_message, :background_tasks, :session_crons
|
|
845
1013
|
|
|
846
1014
|
def initialize(attributes = {})
|
|
847
1015
|
super
|
|
@@ -1888,6 +2056,34 @@ module ClaudeAgentSDK
|
|
|
1888
2056
|
@forward_subagent_text = coerce_boolean(value)
|
|
1889
2057
|
end
|
|
1890
2058
|
|
|
2059
|
+
# Request model-generated progress summaries for subagent (`local_agent`)
|
|
2060
|
+
# tasks. `true` *requests* generation: while the CLI has it enabled, a
|
|
2061
|
+
# subagent's {TaskProgressMessage#summary} **may** carry a one-line status.
|
|
2062
|
+
# `summary` stays optional on the wire even then — not every progress
|
|
2063
|
+
# frame has one — so read it nil-safely. `false` / `nil` do not enable
|
|
2064
|
+
# generation; they do not promise that `summary` is absent (a process that
|
|
2065
|
+
# already enabled summaries keeps them, and a backgrounded `mcp_task`
|
|
2066
|
+
# reports its own status there regardless of this option). Matches the
|
|
2067
|
+
# CLI's `agentProgressSummaries` initialize field.
|
|
2068
|
+
#
|
|
2069
|
+
# Defaults to `nil` (unset): the key is omitted from the `initialize`
|
|
2070
|
+
# control request. `true` and `false` are forwarded verbatim. This is an
|
|
2071
|
+
# enable switch, not a live toggle: CLI 2.1.278 only acts on a truthy
|
|
2072
|
+
# value, so `false` is schema-valid but equivalent to leaving the option
|
|
2073
|
+
# unset — it does not switch summaries off on a process that already
|
|
2074
|
+
# enabled them. Both {ClaudeAgentSDK.query} and {Client} run the control
|
|
2075
|
+
# protocol, so the option applies to either entry point.
|
|
2076
|
+
#
|
|
2077
|
+
# Assigning coerces to a Boolean and keeps `nil` as `nil`.
|
|
2078
|
+
#
|
|
2079
|
+
# @return [Boolean, nil]
|
|
2080
|
+
attr_reader :agent_progress_summaries
|
|
2081
|
+
|
|
2082
|
+
# @see #agent_progress_summaries
|
|
2083
|
+
def agent_progress_summaries=(value)
|
|
2084
|
+
@agent_progress_summaries = coerce_boolean(value)
|
|
2085
|
+
end
|
|
2086
|
+
|
|
1891
2087
|
CALLBACK_SCHEDULING_MODES = %i[thread inline].freeze
|
|
1892
2088
|
|
|
1893
2089
|
# Where user callbacks (hooks, can_use_tool, SDK MCP handlers, message
|
|
@@ -1952,6 +2148,12 @@ module ClaudeAgentSDK
|
|
|
1952
2148
|
# Merge caller-provided attributes with configured defaults.
|
|
1953
2149
|
# Only keys the caller explicitly passed are treated as overrides;
|
|
1954
2150
|
# method-signature defaults ([], {}, false) are NOT present unless the caller wrote them.
|
|
2151
|
+
#
|
|
2152
|
+
# Both sides are keyed by the option they name, not by their literal
|
|
2153
|
+
# spelling: Type accepts symbol/string and snake_case/camelCase names, so a
|
|
2154
|
+
# caller's `'permissionMode' => nil` must still inherit a configured
|
|
2155
|
+
# `permission_mode:` (and a Hash must still merge into it) rather than
|
|
2156
|
+
# riding along as a second entry that overwrites the default on assignment.
|
|
1955
2157
|
def merge_with_defaults(attributes)
|
|
1956
2158
|
return attributes unless defined?(ClaudeAgentSDK) && ClaudeAgentSDK.respond_to?(:default_options)
|
|
1957
2159
|
|
|
@@ -1962,8 +2164,10 @@ module ClaudeAgentSDK
|
|
|
1962
2164
|
# duped so per-instance mutation (options.allowed_tools << 'Bash')
|
|
1963
2165
|
# can never corrupt the global defaults; non-container leaves
|
|
1964
2166
|
# (Strings, Procs, SdkMcpServer instances) intentionally keep identity.
|
|
1965
|
-
result =
|
|
2167
|
+
result = {}
|
|
2168
|
+
defaults.each { |key, value| result[option_key(key)] = deep_dup_containers(value) }
|
|
1966
2169
|
attributes.each do |key, value|
|
|
2170
|
+
key = option_key(key)
|
|
1967
2171
|
default_val = result[key]
|
|
1968
2172
|
result[key] = if value.nil?
|
|
1969
2173
|
default_val # nil means "no preference" — keep the configured default
|
|
@@ -1976,6 +2180,14 @@ module ClaudeAgentSDK
|
|
|
1976
2180
|
result
|
|
1977
2181
|
end
|
|
1978
2182
|
|
|
2183
|
+
# The canonical Symbol for a known option, whatever its spelling. An
|
|
2184
|
+
# unknown name is returned untouched so assign_attribute's strict check
|
|
2185
|
+
# reports the typo exactly as the developer wrote it.
|
|
2186
|
+
def option_key(name)
|
|
2187
|
+
normalized = normalize_name(name)
|
|
2188
|
+
respond_to?(:"#{normalized}=") ? normalized.to_sym : name
|
|
2189
|
+
end
|
|
2190
|
+
|
|
1979
2191
|
# Recurse ONLY into Hash/Array; leaves keep object identity (observer
|
|
1980
2192
|
# factories, callbacks, SDK MCP server instances must not be duped).
|
|
1981
2193
|
# Rebuild via dup.clear (never Hash#to_h / Array#map) to preserve
|
data/lib/claude_agent_sdk.rb
CHANGED
|
@@ -302,6 +302,15 @@ module ClaudeAgentSDK
|
|
|
302
302
|
Sessions.list_subagents(session_id: session_id, directory: directory)
|
|
303
303
|
end
|
|
304
304
|
|
|
305
|
+
# Read a subagent's optional metadata (not live status) from local disk.
|
|
306
|
+
# @param session_id [String] The parent session UUID
|
|
307
|
+
# @param agent_id [String] The subagent ID, without the agent- prefix
|
|
308
|
+
# @param directory [String, nil] Project directory to search in
|
|
309
|
+
# @return [Hash{String => Object}, nil] CLI metadata, or nil if unavailable
|
|
310
|
+
def self.get_subagent_metadata(session_id:, agent_id:, directory: nil)
|
|
311
|
+
Sessions.get_subagent_metadata(session_id: session_id, agent_id: agent_id, directory: directory)
|
|
312
|
+
end
|
|
313
|
+
|
|
305
314
|
# Read a subagent's conversation messages from local disk
|
|
306
315
|
# @param session_id [String] The session UUID
|
|
307
316
|
# @param agent_id [String] The subagent ID (without the agent- prefix)
|
|
@@ -394,6 +403,13 @@ module ClaudeAgentSDK
|
|
|
394
403
|
Sessions.list_subagents_from_store(session_store: session_store, session_id: session_id, directory: directory)
|
|
395
404
|
end
|
|
396
405
|
|
|
406
|
+
# Read the latest subagent metadata from a SessionStore, without its synthetic type marker.
|
|
407
|
+
# @return [Hash{String => Object}, nil]
|
|
408
|
+
def self.get_subagent_metadata_from_store(session_store:, session_id:, agent_id:, directory: nil)
|
|
409
|
+
Sessions.get_subagent_metadata_from_store(session_store: session_store, session_id: session_id,
|
|
410
|
+
agent_id: agent_id, directory: directory)
|
|
411
|
+
end
|
|
412
|
+
|
|
397
413
|
# Read a subagent's conversation messages from a SessionStore.
|
|
398
414
|
# @return [Array<SessionMessage>]
|
|
399
415
|
def self.get_subagent_messages_from_store(session_store:, session_id:, agent_id:, directory: nil, limit: nil,
|
|
@@ -572,6 +588,7 @@ module ClaudeAgentSDK
|
|
|
572
588
|
system_prompt_snapshot: ClaudeAgentSDK.extract_system_prompt_snapshot(configured_options.system_prompt),
|
|
573
589
|
skills: configured_options.skills,
|
|
574
590
|
forward_subagent_text: configured_options.forward_subagent_text?,
|
|
591
|
+
agent_progress_summaries: configured_options.agent_progress_summaries,
|
|
575
592
|
callback_scheduling: callback_scheduling,
|
|
576
593
|
callback_wrapper: callback_wrapper
|
|
577
594
|
)
|
|
@@ -969,6 +986,31 @@ module ClaudeAgentSDK
|
|
|
969
986
|
@query_handler.stop_task(task_id)
|
|
970
987
|
end
|
|
971
988
|
|
|
989
|
+
# Background in-flight foreground tasks (Bash commands and subagents) — the
|
|
990
|
+
# control-request equivalent of pressing Ctrl+B in the terminal. Each
|
|
991
|
+
# blocking tool call returns a "running in the background" tool_result and
|
|
992
|
+
# the turn continues; the task keeps running and emits a
|
|
993
|
+
# TaskNotificationMessage when it settles.
|
|
994
|
+
#
|
|
995
|
+
# The targeted form reports its outcome: `{ backgrounded: true }`, or
|
|
996
|
+
# `{ backgrounded: false }` — a definitive miss (no matching foreground
|
|
997
|
+
# task), so do not wait for an event after it. The all-tasks form returns
|
|
998
|
+
# `{}` and says nothing about whether any task existed. Observe
|
|
999
|
+
# TaskUpdatedMessage#is_backgrounded / BackgroundTasksChangedMessage for the
|
|
1000
|
+
# lifecycle state that follows.
|
|
1001
|
+
#
|
|
1002
|
+
# @param tool_use_id [String, nil] The id of the tool_use block that spawned
|
|
1003
|
+
# the task — NOT a task_id or agent_id. nil is the explicit all-tasks form.
|
|
1004
|
+
# Never substitute nil or '' for a per-task id you do not have yet
|
|
1005
|
+
# (TaskStartedMessage#tool_use_id is optional on the wire)
|
|
1006
|
+
# @return [Hash] `{ backgrounded: true/false }` when tool_use_id was given,
|
|
1007
|
+
# `{}` otherwise
|
|
1008
|
+
# @raise [ArgumentError] if tool_use_id is neither nil nor a non-empty String
|
|
1009
|
+
def background_tasks(tool_use_id: nil)
|
|
1010
|
+
raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected
|
|
1011
|
+
@query_handler.background_tasks(tool_use_id: tool_use_id)
|
|
1012
|
+
end
|
|
1013
|
+
|
|
972
1014
|
# Rewind files to a previous checkpoint (v0.1.15+)
|
|
973
1015
|
# Restores file state to what it was at the given user message
|
|
974
1016
|
# Requires enable_file_checkpointing to be true in options
|
|
@@ -1102,6 +1144,7 @@ module ClaudeAgentSDK
|
|
|
1102
1144
|
system_prompt_snapshot: system_prompt_snapshot,
|
|
1103
1145
|
skills: configured_options.skills,
|
|
1104
1146
|
forward_subagent_text: configured_options.forward_subagent_text?,
|
|
1147
|
+
agent_progress_summaries: configured_options.agent_progress_summaries,
|
|
1105
1148
|
callback_scheduling: @callback_scheduling,
|
|
1106
1149
|
callback_wrapper: @callback_wrapper
|
|
1107
1150
|
)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: claude-agent-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.33.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Community Contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: async
|
|
@@ -30,20 +30,20 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0.
|
|
33
|
+
version: '0.20'
|
|
34
34
|
- - "<"
|
|
35
35
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: '
|
|
36
|
+
version: '2'
|
|
37
37
|
type: :runtime
|
|
38
38
|
prerelease: false
|
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
40
|
requirements:
|
|
41
41
|
- - ">="
|
|
42
42
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: '0.
|
|
43
|
+
version: '0.20'
|
|
44
44
|
- - "<"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
46
|
+
version: '2'
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: bundler
|
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -119,9 +119,11 @@ files:
|
|
|
119
119
|
- docs/observability.md
|
|
120
120
|
- docs/rails.md
|
|
121
121
|
- docs/sessions.md
|
|
122
|
+
- docs/subagents.md
|
|
122
123
|
- docs/types.md
|
|
123
124
|
- lib/claude-agent-sdk.rb
|
|
124
125
|
- lib/claude_agent_sdk.rb
|
|
126
|
+
- lib/claude_agent_sdk/cancellation_signal.rb
|
|
125
127
|
- lib/claude_agent_sdk/cli_installer.rb
|
|
126
128
|
- lib/claude_agent_sdk/command_builder.rb
|
|
127
129
|
- lib/claude_agent_sdk/configuration.rb
|