ClaudeAgentSDK.Message (claude_agent_sdk v0.18.0)

Copy Markdown View Source

Represents a message from Claude Code CLI.

Messages are the core data structure returned by the Claude Code SDK. They represent different types of communication during a conversation with Claude, including system initialization, user inputs, assistant responses, and final results.

This SDK is CLI-faithful: when the Claude CLI emits distinct message frames, the Elixir SDK prefers surfacing them directly even if the current Python SDK filters some unknown message types for forward compatibility.

Message Types

  • :system - Session initialization messages with metadata
  • :user - User input messages (echoed back from CLI)
  • :assistant - Claude's response messages containing the actual AI output
  • :rate_limit_event - Rate limit state changes emitted by the CLI
  • :result - Final result messages with cost, duration, and completion status

Assistant messages may optionally include an error code when the CLI surfaces an issue (e.g., :rate_limit or :authentication_failed).

Result Subtypes

  • :success - Successful completion
  • :error_max_turns - Terminated due to max turns limit
  • :error_during_execution - Error occurred during execution

System Subtypes

  • :init - Initial system message with session setup

Examples

# Assistant message
%ClaudeAgentSDK.Message{
  type: :assistant,
  subtype: nil,
  data: %{
    message: %{"content" => "Hello! How can I help?"},
    session_id: "session-123"
  }
}

# Assistant message with error metadata
%ClaudeAgentSDK.Message{
  type: :assistant,
  subtype: nil,
  data: %{
    message: %{"content" => "Please try again later."},
    session_id: "session-123",
    error: :rate_limit
  }
}

# Result message
%ClaudeAgentSDK.Message{
  type: :result,
  subtype: :success,
  data: %{
    total_cost_usd: 0.001,
    duration_ms: 1500,
    num_turns: 2,
    session_id: "session-123"
  }
}

Summary

Functions

Returns the Agent/Task tool's typed completion output from a user frame's tool_use_result, or nil when the result is not an agent completion.

Returns true if a system/init frame advertises the given capability string (e.g. "interrupt_receipt_v1", CLI 2.1.205+).

Returns true when a command_lifecycle state is terminal (completed/cancelled/discarded).

Returns parsed content blocks for :user and :assistant messages.

Returns true when a result's terminal_reason indicates a dead turn — one that failed or was cancelled under the hood rather than completing cleanly (CLI 2.1.204+).

Checks if the message indicates an error.

Checks if the message is a final result message.

Parses a JSON message from Claude Code into a Message struct.

Returns the live (non-terminal) background tasks from a background_tasks_changed system frame.

Returns the typed peer provenance of a user-role message, or nil.

Gets the session ID from a message.

Returns true when a task status is terminal (from either the task_notification or task_updated vocabulary).

Returns the checkpoint UUID from a user message, or nil.

Types

assistant_data()

@type assistant_data() :: %{
  :message => map(),
  :session_id => String.t() | nil,
  optional(:parent_tool_use_id) => String.t() | nil,
  optional(:error) => assistant_error() | nil
}

assistant_error()

@type assistant_error() :: ClaudeAgentSDK.AssistantError.t()

message_type()

@type message_type() ::
  :assistant
  | :user
  | :result
  | :system
  | :stream_event
  | :rate_limit_event
  | :command_lifecycle
  | :unknown
  | String.t()

rate_limit_data()

@type rate_limit_data() :: %{
  rate_limit_info: rate_limit_info(),
  uuid: String.t(),
  session_id: String.t()
}

rate_limit_info()

@type rate_limit_info() :: %{
  :status => String.t(),
  optional(:resets_at) => integer() | nil,
  optional(:rate_limit_type) => String.t() | nil,
  optional(:utilization) => float() | integer() | nil,
  optional(:is_using_overage) => boolean() | nil,
  optional(:overage_status) => String.t() | nil,
  optional(:overage_resets_at) => integer() | nil,
  optional(:overage_disabled_reason) => String.t() | nil,
  optional(:error_code) => String.t() | nil,
  optional(:can_user_purchase_credits) => boolean() | nil,
  optional(:has_chargeable_saved_payment_method) => boolean() | nil,
  optional(:model_scoped) => [map()] | nil,
  optional(:raw) => map()
}

result_subtype()

@type result_subtype() ::
  :success | :error_max_turns | :error_during_execution | String.t()

system_subtype()

@type system_subtype() ::
  :init
  | :task_started
  | :task_progress
  | :task_notification
  | :task_updated
  | :background_tasks_changed
  | :model_fallback
  | :hook_started
  | :hook_response
  | :mirror_error
  | String.t()

t()

@type t() :: %ClaudeAgentSDK.Message{
  data: assistant_data() | map(),
  raw: map(),
  subtype: result_subtype() | system_subtype() | nil,
  type: message_type()
}

Functions

agent_tool_completed(message)

@spec agent_tool_completed(t()) :: map() | nil

Returns the Agent/Task tool's typed completion output from a user frame's tool_use_result, or nil when the result is not an agent completion.

Upstream publishes this shape as AgentToolCompletedOutput (TS v0.3.207): the subagent's final report (content) plus run totals. Raw camelCase keys are preserved alongside the snake_case ones.

capability?(message, capability)

@spec capability?(t(), String.t()) :: boolean()

Returns true if a system/init frame advertises the given capability string (e.g. "interrupt_receipt_v1", CLI 2.1.205+).

command_terminal?(state)

@spec command_terminal?(t() | String.t() | nil) :: boolean()

Returns true when a command_lifecycle state is terminal (completed/cancelled/discarded).

Accepts a command_lifecycle Message, a state string, or nil. Non-terminal states are queued and started; unknown states are not terminal.

content_blocks(message)

@spec content_blocks(t()) :: [map()]

Returns parsed content blocks for :user and :assistant messages.

This is an ergonomic alternative to the Python SDK's typed content-block objects.

dead_turn?(reason)

@spec dead_turn?(t() | String.t() | nil) :: boolean()

Returns true when a result's terminal_reason indicates a dead turn — one that failed or was cancelled under the hood rather than completing cleanly (CLI 2.1.204+).

Accepts a result Message, a terminal_reason string, or nil. Unknown and absent reasons are not dead turns.

error?(arg1)

@spec error?(t()) :: boolean()

Checks if the message indicates an error.

Returns true for result messages with error subtypes (:error_max_turns or :error_during_execution).

final?(arg1)

@spec final?(t()) :: boolean()

Checks if the message is a final result message.

Final messages indicate the end of a conversation or query.

Parameters

  • message - The message to check

Returns

true if the message is a final result, false otherwise.

Examples

iex> ClaudeAgentSDK.Message.final?(%ClaudeAgentSDK.Message{type: :result})
true

iex> ClaudeAgentSDK.Message.final?(%ClaudeAgentSDK.Message{type: :assistant})
false

from_json(json_string)

@spec from_json(String.t()) :: {:ok, t()} | {:error, term()}

Parses a JSON message from Claude Code into a Message struct.

Parameters

  • json_string - Raw JSON string from Claude CLI

Returns

  • {:ok, message} - Successfully parsed message
  • {:error, reason} - Parsing failed

Examples

iex> ClaudeAgentSDK.Message.from_json(~s({"type":"assistant","message":{"content":"Hello"}}))
{:ok, %ClaudeAgentSDK.Message{type: :assistant, ...}}

live_background_tasks(message)

@spec live_background_tasks(t()) :: [map()]

Returns the live (non-terminal) background tasks from a background_tasks_changed system frame.

The frame is level-based — tasks is the full current set — and tasks without a status are live, so this only drops tasks whose status is terminal. Returns [] for any other message.

peer_origin(message)

@spec peer_origin(t()) :: map() | nil

Returns the typed peer provenance of a user-role message, or nil.

User frames carry an optional origin union describing where the message came from (absent or "human" means keyboard input). For peer messages (kind: "peer", TS v0.3.205) this surfaces the sender's addressable identity (from), the normalized display name, the decoded message body with the peer envelope stripped, and sender_task_id for in-process background subagents. Raw keys are preserved alongside.

session_id(arg1)

@spec session_id(t()) :: String.t() | nil

Gets the session ID from a message.

Returns nil if the message does not contain a session ID.

terminal_task_status?(status)

@spec terminal_task_status?(String.t() | atom() | nil) :: boolean()

Returns true when a task status is terminal (from either the task_notification or task_updated vocabulary).

user_uuid(arg1)

@spec user_uuid(t()) :: String.t() | nil

Returns the checkpoint UUID from a user message, or nil.

Used with file checkpointing to identify rewind targets.