From 12747384c6ddcc53148502f809d4baa55da2db63 Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Fri, 22 May 2026 11:39:57 +0800 Subject: [PATCH] fix(agent): tolerate unknown Claude stream message types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer Claude Code CLIs emit stream message types the bundled SDK was not compiled against — `rate_limit_event` being the one that surfaced — and serde aborted the whole chat stream on the first one ("unknown variant rate_limit_event"). The `Message` enum gains a `#[serde(other)] Unknown` catch-all so any unmodelled `type` deserializes cleanly instead of failing the parse; `hooks.rs` and `chat_claude.rs` match it as a silent no-op (an unknown event carries no hook payload and no chat turn). --- crates/op-host-desktop/src/chat_claude.rs | 11 ++++++++--- vendor/anthropic-agent-sdk/src/hooks.rs | 2 ++ vendor/anthropic-agent-sdk/src/types/messages.rs | 8 ++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/crates/op-host-desktop/src/chat_claude.rs b/crates/op-host-desktop/src/chat_claude.rs index be4765f6e..65ca8851b 100644 --- a/crates/op-host-desktop/src/chat_claude.rs +++ b/crates/op-host-desktop/src/chat_claude.rs @@ -213,9 +213,14 @@ async fn handle_message(msg: Message, tx: &mpsc::Sender) -> Option<(b }; Some((true, reason)) } - Message::System { .. } | Message::User { .. } | Message::StreamEvent { .. } => { - // Init / context / partial-stream events — the chat - // widget doesn't surface them today; silent. + Message::System { .. } + | Message::User { .. } + | Message::StreamEvent { .. } + | Message::Unknown => { + // Init / context / partial-stream events plus any + // message type the SDK doesn't model (e.g. + // `rate_limit_event`) — the chat widget doesn't surface + // them today; silent. None } } diff --git a/vendor/anthropic-agent-sdk/src/hooks.rs b/vendor/anthropic-agent-sdk/src/hooks.rs index c1b10e25d..937ca96a4 100644 --- a/vendor/anthropic-agent-sdk/src/hooks.rs +++ b/vendor/anthropic-agent-sdk/src/hooks.rs @@ -576,6 +576,8 @@ impl HookManager { } Message::StreamEvent { .. } => {} + // Unmodelled message types carry no hook payload. + Message::Unknown => {} } Ok(outputs) diff --git a/vendor/anthropic-agent-sdk/src/types/messages.rs b/vendor/anthropic-agent-sdk/src/types/messages.rs index 13717f47d..f3f496c2f 100644 --- a/vendor/anthropic-agent-sdk/src/types/messages.rs +++ b/vendor/anthropic-agent-sdk/src/types/messages.rs @@ -220,6 +220,14 @@ pub enum Message { #[serde(skip_serializing_if = "Option::is_none")] parent_tool_use_id: Option, }, + /// Any message `type` this SDK build does not model. Newer + /// Claude Code CLIs emit events the SDK was not compiled + /// against — e.g. `rate_limit_event` — and serde would + /// otherwise abort the whole stream on the first one. Routing + /// unknown tags here keeps the stream alive; downstream + /// consumers simply ignore an `Unknown`. + #[serde(other)] + Unknown, } #[cfg(test)]