TailMessages: skip serde parse for non-message objects

Use memchr::memmem to check for "type":"user" or "type":"assistant"
in raw bytes before parsing. Avoids deserializing large tool_result
and system objects entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kent Overstreet 2026-03-22 03:32:59 -04:00
parent ecc2cb7b20
commit e83d0184ea

View file

@ -203,13 +203,19 @@ impl Iterator for TailMessages {
let obj_bytes = &self.mmap[open..=close]; let obj_bytes = &self.mmap[open..=close];
// Quick byte check: skip objects that aren't user/assistant
// messages. Avoids serde-parsing megabyte tool_result objects.
let is_user = memchr::memmem::find(obj_bytes, b"\"type\":\"user\"").is_some();
let is_assistant = !is_user
&& memchr::memmem::find(obj_bytes, b"\"type\":\"assistant\"").is_some();
if !is_user && !is_assistant { continue; }
let obj: Value = match serde_json::from_slice(obj_bytes) { let obj: Value = match serde_json::from_slice(obj_bytes) {
Ok(v) => v, Ok(v) => v,
Err(_) => continue, Err(_) => continue,
}; };
let msg_type = obj.get("type").and_then(|v| v.as_str()).unwrap_or(""); let msg_type = if is_user { "user" } else { "assistant" };
if msg_type != "user" && msg_type != "assistant" { continue; }
let msg = obj.get("message").unwrap_or(&obj); let msg = obj.get("message").unwrap_or(&obj);
let text = match msg.get("content") { let text = match msg.get("content") {