,
+ /// Human-readable composer pill label
+ pub title: String,
+ /// Attachment type discriminator
+ pub r#type: SendAttachmentExtensionContextType,
+}
+
+/// Slim input shape for extension_context attachments; identity fields are runtime-derived.
+///
+///
+///
+/// **Experimental.** This type is part of an experimental wire-protocol surface
+/// and may change or be removed in future SDK or CLI releases.
+///
+///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ExtensionContextPushInput {
+ /// Caller-supplied JSON payload
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub payload: Option,
+ /// Human-readable composer pill label
+ pub title: String,
+ /// Attachment type discriminator
+ pub r#type: ExtensionContextPushInputType,
+}
+
+/// Parameters for session.extensions.sendAttachmentsToMessage.
+///
+///
+///
+/// **Experimental.** This type is part of an experimental wire-protocol surface
+/// and may change or be removed in future SDK or CLI releases.
+///
+///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SendAttachmentsToMessageParams {
+ /// Attachments to push into the next user-message turn. extension_context entries take the slim shape; standard variants take their full SendAttachment shape.
+ pub attachments: Vec,
+ /// Optional canvas instance binding the push for provenance. When supplied, the runtime resolves the canvas, verifies it is owned by the calling extension, and stamps canvasId/instanceId onto each extension_context entry. When omitted, no resolution runs and those fields stay unset on the attachment.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub instance_id: Option,
+ /// Target session identifier
+ pub session_id: SessionId,
+}
+
/// List of Copilot models available to the resolved user, including capabilities and billing metadata.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -15302,3 +15376,19 @@ pub enum WorkspacesWorkspaceDetailsHostType {
#[serde(other)]
Unknown,
}
+
+/// Attachment type discriminator
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum SendAttachmentExtensionContextType {
+ #[serde(rename = "extension_context")]
+ #[default]
+ ExtensionContext,
+}
+
+/// Attachment type discriminator
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum ExtensionContextPushInputType {
+ #[serde(rename = "extension_context")]
+ #[default]
+ ExtensionContext,
+}
diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs
index 422bf7b83..bae8ed800 100644
--- a/rust/src/generated/rpc.rs
+++ b/rust/src/generated/rpc.rs
@@ -2409,6 +2409,38 @@ impl<'a> SessionRpcExtensions<'a> {
.await?;
Ok(())
}
+
+ /// Push attachments into the next user-message turn from an extension. The host should surface them as composer pills and forward them via the next session.send call. Callable only by extension-owned connections.
+ ///
+ /// Wire method: `session.extensions.sendAttachmentsToMessage`.
+ ///
+ /// # Parameters
+ ///
+ /// * `params` - Parameters for session.extensions.sendAttachmentsToMessage.
+ ///
+ ///
+ ///
+ /// **Experimental.** This API is part of an experimental wire-protocol surface
+ /// and may change or be removed in future SDK or CLI releases. Pin both the
+ /// SDK and CLI versions if your code depends on it.
+ ///
+ ///
+ pub async fn send_attachments_to_message(
+ &self,
+ params: SendAttachmentsToMessageParams,
+ ) -> Result<(), Error> {
+ let mut wire_params = serde_json::to_value(params)?;
+ wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string());
+ let _value = self
+ .session
+ .client()
+ .call(
+ rpc_methods::SESSION_EXTENSIONS_SENDATTACHMENTSTOMESSAGE,
+ Some(wire_params),
+ )
+ .await?;
+ Ok(())
+ }
}
/// `session.fleet.*` RPCs.
diff --git a/rust/src/generated/session_events.rs b/rust/src/generated/session_events.rs
index cc88b3d86..d749e6f18 100644
--- a/rust/src/generated/session_events.rs
+++ b/rust/src/generated/session_events.rs
@@ -183,6 +183,8 @@ pub enum SessionEventType {
SessionCanvasRegistryChanged,
#[serde(rename = "mcp_app.tool_call_complete")]
McpAppToolCallComplete,
+ #[serde(rename = "session.extensions.attachments_pushed")]
+ SessionExtensionsAttachmentsPushed,
/// Unknown event type for forward compatibility.
#[default]
#[serde(other)]
@@ -369,6 +371,8 @@ pub enum SessionEventData {
SessionCanvasRegistryChanged(SessionCanvasRegistryChangedData),
#[serde(rename = "mcp_app.tool_call_complete")]
McpAppToolCallComplete(McpAppToolCallCompleteData),
+ #[serde(rename = "session.extensions.attachments_pushed")]
+ SessionExtensionsAttachmentsPushed(SessionExtensionsAttachmentsPushedData),
}
/// A session event with typed data payload.
@@ -3319,6 +3323,14 @@ pub struct McpAppToolCallCompleteData {
pub tool_name: String,
}
+/// Session event "session.extensions.attachments_pushed".
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SessionExtensionsAttachmentsPushedData {
+ /// Attachments contributed by an extension; the host should surface these as composer pills and forward them via the next session.send call.
+ pub attachments: Vec,
+}
+
/// Hosting platform type of the repository (github or ado)
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum WorkingDirectoryContextHostType {