diff --git a/Cargo.toml b/Cargo.toml
index 1ba1872d..ac388c21 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,7 +28,6 @@ unstable = [
"unstable_nes",
"unstable_plan_operations",
"unstable_session_fork",
- "unstable_session_usage",
"unstable_end_turn_token_usage",
"unstable_message_id",
"unstable_boolean_config",
@@ -46,7 +45,6 @@ unstable_mcp_over_acp = []
unstable_nes = []
unstable_plan_operations = []
unstable_session_fork = []
-unstable_session_usage = []
unstable_end_turn_token_usage = []
unstable_message_id = []
unstable_boolean_config = []
diff --git a/docs/docs.json b/docs/docs.json
index d5176526..94629aae 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -209,11 +209,7 @@
},
{
"group": "Preview",
- "pages": [
- "rfds/rust-sdk-v1",
- "rfds/session-usage",
- "rfds/message-id"
- ]
+ "pages": ["rfds/rust-sdk-v1", "rfds/message-id"]
},
{
"group": "Completed",
@@ -221,6 +217,7 @@
"rfds/introduce-rfd-process",
"rfds/session-config-options",
"rfds/session-list",
+ "rfds/session-usage",
"rfds/session-delete",
"rfds/session-info-update",
"rfds/meta-propagation",
diff --git a/docs/protocol/v1/draft/prompt-turn.mdx b/docs/protocol/v1/draft/prompt-turn.mdx
index 49576d54..3a5d3e30 100644
--- a/docs/protocol/v1/draft/prompt-turn.mdx
+++ b/docs/protocol/v1/draft/prompt-turn.mdx
@@ -185,6 +185,31 @@ If the model requested tool calls, these are also reported immediately:
}
```
+#### Session Usage Updates
+
+The Agent **MAY** also report current session context and cumulative cost state with a `usage_update`:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "session/update",
+ "params": {
+ "sessionId": "sess_abc123def456",
+ "update": {
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": {
+ "amount": 0.045,
+ "currency": "USD"
+ }
+ }
+ }
+}
+```
+
+`used` and `size` are required and non-null token counts for the current session context. `cost` is optional and, if present, `amount` and `currency` are required. `currency` is an ISO 4217 currency code like `"USD"`.
+
### 4. Check for Completion
If there are no pending tool calls, the turn ends and the Agent **MUST** respond to the original `session/prompt` request with a `StopReason`:
diff --git a/docs/protocol/v1/draft/schema.mdx b/docs/protocol/v1/draft/schema.mdx
index 02bf656a..2d1f7350 100644
--- a/docs/protocol/v1/draft/schema.mdx
+++ b/docs/protocol/v1/draft/schema.mdx
@@ -3514,10 +3514,6 @@ A change in `messageId` indicates a new message has started.
## Cost
-**UNSTABLE**
-
-This capability is not part of the spec yet, and may be removed or changed at any point.
-
Cost information for a session.
**Type:** Object
@@ -7502,10 +7498,6 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d
-**UNSTABLE**
-
-This capability is not part of the spec yet, and may be removed or changed at any point.
-
Context window and cost update for the session.
@@ -8193,10 +8185,6 @@ Token usage information for a prompt turn.
## UsageUpdate
-**UNSTABLE**
-
-This capability is not part of the spec yet, and may be removed or changed at any point.
-
Context window and cost update for a session.
**Type:** Object
diff --git a/docs/protocol/v1/prompt-turn.mdx b/docs/protocol/v1/prompt-turn.mdx
index 973c8462..98568ce7 100644
--- a/docs/protocol/v1/prompt-turn.mdx
+++ b/docs/protocol/v1/prompt-turn.mdx
@@ -182,6 +182,31 @@ If the model requested tool calls, these are also reported immediately:
}
```
+#### Session Usage Updates
+
+The Agent **MAY** also report current session context and cumulative cost state with a `usage_update`:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "session/update",
+ "params": {
+ "sessionId": "sess_abc123def456",
+ "update": {
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": {
+ "amount": 0.045,
+ "currency": "USD"
+ }
+ }
+ }
+}
+```
+
+`used` and `size` are required and non-null token counts for the current session context. `cost` is optional and, if present, `amount` and `currency` are required. `currency` is an ISO 4217 currency code like `"USD"`.
+
### 4. Check for Completion
If there are no pending tool calls, the turn ends and the Agent **MUST** respond to the original `session/prompt` request with a `StopReason`:
diff --git a/docs/protocol/v1/schema.mdx b/docs/protocol/v1/schema.mdx
index 00341558..78e17ddf 100644
--- a/docs/protocol/v1/schema.mdx
+++ b/docs/protocol/v1/schema.mdx
@@ -1908,6 +1908,21 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
A single item of content
+## Cost
+
+Cost information for a session.
+
+**Type:** Object
+
+**Properties:**
+
+
+ Total cumulative cost for session.
+
+
+ ISO 4217 currency code (e.g., "USD", "EUR").
+
+
## CurrentModeUpdate
The current mode of the session has changed
@@ -3589,6 +3604,41 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
+
+Context window and cost update for the session.
+
+
+
+
+ The _meta property is reserved by ACP to allow clients and agents to attach additional
+metadata to their interactions. Implementations MUST NOT make assumptions about values at
+these keys.
+
+See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/extensibility)
+
+
+Cost | null>} >
+ Cumulative session cost (optional).
+
+
+ The discriminator value. Must be `"usage_update"`.
+
+
+ Total context window size in tokens.
+
+ - Minimum: `0`
+
+
+
+ Tokens currently in context.
+
+ - Minimum: `0`
+
+
+
+
+
+
## StopReason
Reasons why an agent stops processing a prompt turn.
@@ -4036,3 +4086,35 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
A hint to display when the input hasn't been provided yet
+
+## UsageUpdate
+
+Context window and cost update for a session.
+
+**Type:** Object
+
+**Properties:**
+
+
+ The _meta property is reserved by ACP to allow clients and agents to attach additional
+metadata to their interactions. Implementations MUST NOT make assumptions about values at
+these keys.
+
+See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/extensibility)
+
+
+Cost | null>} >
+ Cumulative session cost (optional).
+
+
+ Total context window size in tokens.
+
+ - Minimum: `0`
+
+
+
+ Tokens currently in context.
+
+ - Minimum: `0`
+
+
diff --git a/docs/protocol/v2/draft/prompt-turn.mdx b/docs/protocol/v2/draft/prompt-turn.mdx
index 833b5d2c..3b6f0185 100644
--- a/docs/protocol/v2/draft/prompt-turn.mdx
+++ b/docs/protocol/v2/draft/prompt-turn.mdx
@@ -189,6 +189,31 @@ If the model requested tool calls, these are also reported immediately:
}
```
+#### Session Usage Updates
+
+The Agent **MAY** also report current session context and cumulative cost state with a `usage_update`:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "session/update",
+ "params": {
+ "sessionId": "sess_abc123def456",
+ "update": {
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": {
+ "amount": 0.045,
+ "currency": "USD"
+ }
+ }
+ }
+}
+```
+
+`used` and `size` are required and non-null token counts for the current session context. `cost` is optional and, if present, `amount` and `currency` are required. `currency` is an ISO 4217 currency code like `"USD"`.
+
### 4. Check for Completion
If there are no pending tool calls, the turn ends and the Agent **MUST** respond to the original `session/prompt` request with a `StopReason`:
diff --git a/docs/protocol/v2/draft/schema.mdx b/docs/protocol/v2/draft/schema.mdx
index ae94493d..dd59cf96 100644
--- a/docs/protocol/v2/draft/schema.mdx
+++ b/docs/protocol/v2/draft/schema.mdx
@@ -3065,10 +3065,6 @@ A change in `messageId` indicates a new message has started.
## Cost
-**UNSTABLE**
-
-This capability is not part of the spec yet, and may be removed or changed at any point.
-
Cost information for a session.
**Type:** Object
@@ -7088,10 +7084,6 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/d
-**UNSTABLE**
-
-This capability is not part of the spec yet, and may be removed or changed at any point.
-
Context window and cost update for the session.
@@ -7812,10 +7804,6 @@ Token usage information for a prompt turn.
## UsageUpdate
-**UNSTABLE**
-
-This capability is not part of the spec yet, and may be removed or changed at any point.
-
Context window and cost update for a session.
**Type:** Object
diff --git a/docs/protocol/v2/prompt-turn.mdx b/docs/protocol/v2/prompt-turn.mdx
index de17eb26..b2c1ebd3 100644
--- a/docs/protocol/v2/prompt-turn.mdx
+++ b/docs/protocol/v2/prompt-turn.mdx
@@ -186,6 +186,31 @@ If the model requested tool calls, these are also reported immediately:
}
```
+#### Session Usage Updates
+
+The Agent **MAY** also report current session context and cumulative cost state with a `usage_update`:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "session/update",
+ "params": {
+ "sessionId": "sess_abc123def456",
+ "update": {
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": {
+ "amount": 0.045,
+ "currency": "USD"
+ }
+ }
+ }
+}
+```
+
+`used` and `size` are required and non-null token counts for the current session context. `cost` is optional and, if present, `amount` and `currency` are required. `currency` is an ISO 4217 currency code like `"USD"`.
+
### 4. Check for Completion
If there are no pending tool calls, the turn ends and the Agent **MUST** respond to the original `session/prompt` request with a `StopReason`:
diff --git a/docs/protocol/v2/schema.mdx b/docs/protocol/v2/schema.mdx
index 8259b059..6338f386 100644
--- a/docs/protocol/v2/schema.mdx
+++ b/docs/protocol/v2/schema.mdx
@@ -1491,6 +1491,21 @@ A change in `messageId` indicates a new message has started.
+## Cost
+
+Cost information for a session.
+
+**Type:** Object
+
+**Properties:**
+
+
+ Total cumulative cost for session.
+
+
+ ISO 4217 currency code (e.g., "USD", "EUR").
+
+
## Diff
A diff representing file modifications.
@@ -3339,6 +3354,41 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/e
+
+Context window and cost update for the session.
+
+
+
+
+ The _meta property is reserved by ACP to allow clients and agents to attach additional
+metadata to their interactions. Implementations MUST NOT make assumptions about values at
+these keys.
+
+See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/extensibility)
+
+
+Cost | null>} >
+ Cumulative session cost (optional).
+
+
+ The discriminator value. Must be `"usage_update"`.
+
+
+ Total context window size in tokens.
+
+ - Minimum: `0`
+
+
+
+ Tokens currently in context.
+
+ - Minimum: `0`
+
+
+
+
+
+
Custom or future session update.
@@ -3788,3 +3838,35 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/e
A hint to display when the input hasn't been provided yet
+
+## UsageUpdate
+
+Context window and cost update for a session.
+
+**Type:** Object
+
+**Properties:**
+
+
+ The _meta property is reserved by ACP to allow clients and agents to attach additional
+metadata to their interactions. Implementations MUST NOT make assumptions about values at
+these keys.
+
+See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/extensibility)
+
+
+Cost | null>} >
+ Cumulative session cost (optional).
+
+
+ Total context window size in tokens.
+
+ - Minimum: `0`
+
+
+
+ Tokens currently in context.
+
+ - Minimum: `0`
+
+
diff --git a/docs/rfds/session-usage.mdx b/docs/rfds/session-usage.mdx
index f510330d..4bcf0df6 100644
--- a/docs/rfds/session-usage.mdx
+++ b/docs/rfds/session-usage.mdx
@@ -190,7 +190,6 @@ Agents may bill in different currencies:
- European agents might bill in EUR
- Asian agents might bill in JPY or CNY
-- Some agents might use credits or points
- Currency conversion rates change
Agents should report the actual billing currency and let clients convert if needed.
@@ -246,3 +245,4 @@ For agents that only provide usage during active prompting, the client UI may no
- 2025-12-19: Renamed `sessionUpdate: "context_update"` to `sessionUpdate: "usage_update"` to better reflect the payload semantics (includes both context window info and cumulative cost).
- 2026-06-02: Split end-turn token accounting into a separate draft RFD.
- 2026-06-03: Moved to Preview.
+- 2026-06-05: Moved to Completed.
diff --git a/docs/rfds/updates.mdx b/docs/rfds/updates.mdx
index 73212e8b..e05c8e25 100644
--- a/docs/rfds/updates.mdx
+++ b/docs/rfds/updates.mdx
@@ -6,6 +6,13 @@ rss: true
This page tracks lifecycle changes for ACP Requests for Dialog. For broader ACP announcements, see [Updates](/updates).
+
+## Session Context Size and Cost RFD moves to Completed
+
+The RFD for `usage_update` session notifications has been stabilized and is now a part of the protocol. Agents can report session-level context window size and optional cumulative cost through `session/update`. Please review the [documentation](/protocol/v1/prompt-turn#session-usage-updates) for more information.
+
+
+
## session/delete RFD moves to Completed
diff --git a/schema/schema.json b/schema/schema.json
index 6ad6dbd6..ff9eb911 100644
--- a/schema/schema.json
+++ b/schema/schema.json
@@ -1097,6 +1097,22 @@
"required": ["content"],
"type": "object"
},
+ "Cost": {
+ "description": "Cost information for a session.",
+ "properties": {
+ "amount": {
+ "description": "Total cumulative cost for session.",
+ "format": "double",
+ "type": "number"
+ },
+ "currency": {
+ "description": "ISO 4217 currency code (e.g., \"USD\", \"EUR\").",
+ "type": "string"
+ }
+ },
+ "required": ["amount", "currency"],
+ "type": "object"
+ },
"CreateTerminalRequest": {
"description": "Request to create a new terminal and execute a command.",
"properties": {
@@ -3267,6 +3283,22 @@
},
"required": ["sessionUpdate"],
"type": "object"
+ },
+ {
+ "allOf": [
+ {
+ "$ref": "#/$defs/UsageUpdate"
+ }
+ ],
+ "description": "Context window and cost update for the session.",
+ "properties": {
+ "sessionUpdate": {
+ "const": "usage_update",
+ "type": "string"
+ }
+ },
+ "required": ["sessionUpdate"],
+ "type": "object"
}
]
},
@@ -3860,6 +3892,42 @@
"required": ["hint"],
"type": "object"
},
+ "UsageUpdate": {
+ "description": "Context window and cost update for a session.",
+ "properties": {
+ "_meta": {
+ "additionalProperties": true,
+ "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)",
+ "type": ["object", "null"]
+ },
+ "cost": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/Cost"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Cumulative session cost (optional).",
+ "x-deserialize-default-on-error": true
+ },
+ "size": {
+ "description": "Total context window size in tokens.",
+ "format": "uint64",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "used": {
+ "description": "Tokens currently in context.",
+ "format": "uint64",
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": ["used", "size"],
+ "type": "object"
+ },
"WaitForTerminalExitRequest": {
"description": "Request to wait for a terminal command to exit.",
"properties": {
diff --git a/schema/schema.unstable.json b/schema/schema.unstable.json
index 6185e38e..88f71f51 100644
--- a/schema/schema.unstable.json
+++ b/schema/schema.unstable.json
@@ -1861,7 +1861,7 @@
"type": "object"
},
"Cost": {
- "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCost information for a session.",
+ "description": "Cost information for a session.",
"properties": {
"amount": {
"description": "Total cumulative cost for session.",
@@ -6575,7 +6575,7 @@
"$ref": "#/$defs/UsageUpdate"
}
],
- "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for the session.",
+ "description": "Context window and cost update for the session.",
"properties": {
"sessionUpdate": {
"const": "usage_update",
@@ -7607,7 +7607,7 @@
"type": "object"
},
"UsageUpdate": {
- "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for a session.",
+ "description": "Context window and cost update for a session.",
"properties": {
"_meta": {
"additionalProperties": true,
diff --git a/schema/schema.v2.unstable.json b/schema/schema.v2.unstable.json
index 14cb6be0..02db56f8 100644
--- a/schema/schema.v2.unstable.json
+++ b/schema/schema.v2.unstable.json
@@ -1840,7 +1840,7 @@
"type": "object"
},
"Cost": {
- "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCost information for a session.",
+ "description": "Cost information for a session.",
"properties": {
"amount": {
"description": "Total cumulative cost for session.",
@@ -6490,7 +6490,7 @@
"$ref": "#/$defs/UsageUpdate"
}
],
- "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for the session.",
+ "description": "Context window and cost update for the session.",
"properties": {
"sessionUpdate": {
"const": "usage_update",
@@ -7571,7 +7571,7 @@
"type": "object"
},
"UsageUpdate": {
- "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for a session.",
+ "description": "Context window and cost update for a session.",
"properties": {
"_meta": {
"additionalProperties": true,
diff --git a/src/v1/client.rs b/src/v1/client.rs
index 941636f9..3fb87e3e 100644
--- a/src/v1/client.rs
+++ b/src/v1/client.rs
@@ -128,12 +128,7 @@ pub enum SessionUpdate {
ConfigOptionUpdate(ConfigOptionUpdate),
/// Session metadata has been updated (title, timestamps, custom metadata)
SessionInfoUpdate(SessionInfoUpdate),
- /// **UNSTABLE**
- ///
- /// This capability is not part of the spec yet, and may be removed or changed at any point.
- ///
/// Context window and cost update for the session.
- #[cfg(feature = "unstable_session_usage")]
UsageUpdate(UsageUpdate),
}
@@ -274,12 +269,7 @@ impl SessionInfoUpdate {
}
}
-/// **UNSTABLE**
-///
-/// This capability is not part of the spec yet, and may be removed or changed at any point.
-///
/// Context window and cost update for a session.
-#[cfg(feature = "unstable_session_usage")]
#[serde_as]
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
@@ -304,7 +294,6 @@ pub struct UsageUpdate {
pub meta: Option,
}
-#[cfg(feature = "unstable_session_usage")]
impl UsageUpdate {
#[must_use]
pub fn new(used: u64, size: u64) -> Self {
@@ -335,12 +324,7 @@ impl UsageUpdate {
}
}
-/// **UNSTABLE**
-///
-/// This capability is not part of the spec yet, and may be removed or changed at any point.
-///
/// Cost information for a session.
-#[cfg(feature = "unstable_session_usage")]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
@@ -351,7 +335,6 @@ pub struct Cost {
pub currency: String,
}
-#[cfg(feature = "unstable_session_usage")]
impl Cost {
#[must_use]
pub fn new(amount: f64, currency: impl Into) -> Self {
@@ -2235,6 +2218,51 @@ mod tests {
);
}
+ #[test]
+ fn test_usage_update_serialization() {
+ use serde_json::json;
+
+ assert_eq!(
+ serde_json::to_value(SessionUpdate::UsageUpdate(UsageUpdate::new(
+ 53_000, 200_000
+ )))
+ .unwrap(),
+ json!({
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000
+ })
+ );
+
+ assert_eq!(
+ serde_json::to_value(SessionUpdate::UsageUpdate(
+ UsageUpdate::new(53_000, 200_000).cost(Cost::new(0.045, "USD"))
+ ))
+ .unwrap(),
+ json!({
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": {
+ "amount": 0.045,
+ "currency": "USD"
+ }
+ })
+ );
+
+ let SessionUpdate::UsageUpdate(update) = serde_json::from_value(json!({
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": null
+ }))
+ .unwrap() else {
+ panic!("expected usage update");
+ };
+
+ assert_eq!(update.cost, None);
+ }
+
#[cfg(feature = "unstable_nes")]
#[test]
fn test_client_capabilities_position_encodings_serialization() {
diff --git a/src/v2/client.rs b/src/v2/client.rs
index cfe85491..c5d277ee 100644
--- a/src/v2/client.rs
+++ b/src/v2/client.rs
@@ -117,12 +117,7 @@ pub enum SessionUpdate {
ConfigOptionUpdate(ConfigOptionUpdate),
/// Session metadata has been updated (title, timestamps, custom metadata)
SessionInfoUpdate(SessionInfoUpdate),
- /// **UNSTABLE**
- ///
- /// This capability is not part of the spec yet, and may be removed or changed at any point.
- ///
/// Context window and cost update for the session.
- #[cfg(feature = "unstable_session_usage")]
UsageUpdate(UsageUpdate),
/// Custom or future session update.
///
@@ -201,20 +196,19 @@ impl<'de> Deserialize<'de> for OtherSessionUpdate {
}
fn is_known_session_update(session_update: &str) -> bool {
- match session_update {
+ matches!(
+ session_update,
"user_message_chunk"
- | "agent_message_chunk"
- | "agent_thought_chunk"
- | "tool_call"
- | "tool_call_update"
- | "plan_update"
- | "available_commands_update"
- | "config_option_update"
- | "session_info_update" => true,
- #[cfg(feature = "unstable_session_usage")]
- "usage_update" => true,
- _ => false,
- }
+ | "agent_message_chunk"
+ | "agent_thought_chunk"
+ | "tool_call"
+ | "tool_call_update"
+ | "plan_update"
+ | "available_commands_update"
+ | "config_option_update"
+ | "session_info_update"
+ | "usage_update"
+ )
}
fn other_session_update_schema(schema: &mut Schema) {
@@ -233,7 +227,6 @@ fn other_session_update_schema(schema: &mut Schema) {
"session_info_update",
#[cfg(feature = "unstable_plan_operations")]
"plan_removed",
- #[cfg(feature = "unstable_session_usage")]
"usage_update",
],
);
@@ -336,12 +329,7 @@ impl SessionInfoUpdate {
}
}
-/// **UNSTABLE**
-///
-/// This capability is not part of the spec yet, and may be removed or changed at any point.
-///
/// Context window and cost update for a session.
-#[cfg(feature = "unstable_session_usage")]
#[serde_as]
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
@@ -366,7 +354,6 @@ pub struct UsageUpdate {
pub meta: Option,
}
-#[cfg(feature = "unstable_session_usage")]
impl UsageUpdate {
#[must_use]
pub fn new(used: u64, size: u64) -> Self {
@@ -397,12 +384,7 @@ impl UsageUpdate {
}
}
-/// **UNSTABLE**
-///
-/// This capability is not part of the spec yet, and may be removed or changed at any point.
-///
/// Cost information for a session.
-#[cfg(feature = "unstable_session_usage")]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
@@ -413,7 +395,6 @@ pub struct Cost {
pub currency: String,
}
-#[cfg(feature = "unstable_session_usage")]
impl Cost {
#[must_use]
pub fn new(amount: f64, currency: impl Into) -> Self {
@@ -1477,6 +1458,51 @@ mod tests {
);
}
+ #[test]
+ fn test_usage_update_serialization() {
+ use serde_json::json;
+
+ assert_eq!(
+ serde_json::to_value(SessionUpdate::UsageUpdate(UsageUpdate::new(
+ 53_000, 200_000
+ )))
+ .unwrap(),
+ json!({
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000
+ })
+ );
+
+ assert_eq!(
+ serde_json::to_value(SessionUpdate::UsageUpdate(
+ UsageUpdate::new(53_000, 200_000).cost(Cost::new(0.045, "USD"))
+ ))
+ .unwrap(),
+ json!({
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": {
+ "amount": 0.045,
+ "currency": "USD"
+ }
+ })
+ );
+
+ let SessionUpdate::UsageUpdate(update) = serde_json::from_value(json!({
+ "sessionUpdate": "usage_update",
+ "used": 53000,
+ "size": 200000,
+ "cost": null
+ }))
+ .unwrap() else {
+ panic!("expected usage update");
+ };
+
+ assert_eq!(update.cost, None);
+ }
+
#[test]
fn session_update_preserves_unknown_variant() {
use serde_json::json;
diff --git a/src/v2/conversion.rs b/src/v2/conversion.rs
index 94ac3152..ce2c2b42 100644
--- a/src/v2/conversion.rs
+++ b/src/v2/conversion.rs
@@ -873,7 +873,6 @@ impl IntoV1 for super::SessionUpdate {
Self::SessionInfoUpdate(value) => {
crate::v1::SessionUpdate::SessionInfoUpdate(value.into_v1()?)
}
- #[cfg(feature = "unstable_session_usage")]
Self::UsageUpdate(value) => crate::v1::SessionUpdate::UsageUpdate(value.into_v1()?),
Self::Other(value) => {
return Err(unknown_v2_enum_variant(
@@ -927,7 +926,6 @@ impl IntoV2 for crate::v1::SessionUpdate {
Self::SessionInfoUpdate(value) => {
super::SessionUpdate::SessionInfoUpdate(value.into_v2()?)
}
- #[cfg(feature = "unstable_session_usage")]
Self::UsageUpdate(value) => super::SessionUpdate::UsageUpdate(value.into_v2()?),
})
}
@@ -997,7 +995,6 @@ impl IntoV2 for crate::v1::SessionInfoUpdate {
}
}
-#[cfg(feature = "unstable_session_usage")]
impl IntoV1 for super::UsageUpdate {
type Output = crate::v1::UsageUpdate;
@@ -1017,7 +1014,6 @@ impl IntoV1 for super::UsageUpdate {
}
}
-#[cfg(feature = "unstable_session_usage")]
impl IntoV2 for crate::v1::UsageUpdate {
type Output = super::UsageUpdate;
@@ -1037,7 +1033,6 @@ impl IntoV2 for crate::v1::UsageUpdate {
}
}
-#[cfg(feature = "unstable_session_usage")]
impl IntoV1 for super::Cost {
type Output = crate::v1::Cost;
@@ -1050,7 +1045,6 @@ impl IntoV1 for super::Cost {
}
}
-#[cfg(feature = "unstable_session_usage")]
impl IntoV2 for crate::v1::Cost {
type Output = super::Cost;
@@ -8924,6 +8918,9 @@ mod tests {
#[cfg(feature = "unstable_plan_operations")]
v1::SessionUpdate::PlanRemoved(v1::PlanRemoved::new("plan-1")),
v1::SessionUpdate::SessionInfoUpdate(v1::SessionInfoUpdate::new().title("hi")),
+ v1::SessionUpdate::UsageUpdate(
+ v1::UsageUpdate::new(53_000, 200_000).cost(v1::Cost::new(0.045, "USD")),
+ ),
];
for update in cases {
let notification = v1::SessionNotification::new("sess", update);